THOUGHTS.txt (65608B)
1 Thu Sep 22 00:12:42 BST 2022 2 3 Making quite reasonable progress, though only running under emulation. 4 Since almost everything so far has been a recap of nixwrt, that's to 5 be expected. 6 7 The example config starts some services at boot, or at least attempts 8 to. Next we shoud 9 10 - add some network config to run-qemu 11 - implement udhcp and odhcp properly to write outputs 12 and create resolv.conf and all that 13 - write some kind of test so we can refactor the crap 14 - not let the tests write random junk everywhere 15 16 Thu Sep 22 12:46:36 BST 2022 17 18 We can store outputs in the s6 scan directory, it seems: 19 20 > There is, however, a guarantee that s6-supervise will never touch subdirectories named data or env. So if you need to store user information in the service directory with the guarantee that it will never be mistaken for a configuration file, no matter the version of s6, you should store that information in the data or env subdirectories of the service directory. 21 22 https://skarnet.org/software/s6/servicedir.html 23 24 > process 'store/pj0b27l5728cypa5mmagz0q8ibzpik0h-execline-mips-unknown-linux-musl-2.9.0.1-bin/bin/execlineb' started with executable stack 25 26 https://skarnet.org/lists/skaware/1550.html 27 28 29 Thu Sep 22 16:14:49 BST 2022 30 31 what network peers do we want to model for testing? 32 33 - wan: pppoe 34 - wan: ip over ethernet, w/ dhcp service provided 35 - wan: l2tp over (ip over ethernet, w/ dhcp service provided) 36 - lan: something with a dhcp client 37 38 https://accel-ppp.readthedocs.io/en/latest/ could use this for testing 39 pppoe and l2tp? 40 41 42 Thu Sep 22 22:57:47 BST 2022 43 44 To build a nixos vm with accel-ppp installed (not yet configured) 45 46 nix-build '<nixpkgs/nixos>' -A vm -I nixos-config=./tests/ppp-server-configuration.nix -o ppp-server 47 QEMU_OPTS="-display none -serial mon:stdio -nographic" ./ppp-server/bin/run-nixos-vm 48 49 To test it's configured I thought I'd run it against an OpenWrt qemu 50 install, so, fun with qemu networking ensues. This config in ../openwrt-qemu 51 is using two multicast socket networks - 52 53 nix-shell -p qemu --run "./run.sh ./openwrt-22.03.0-x86-64-generic-kernel.bin openwrt-22.03.0-x86-64-generic-ext4-rootfs.img " 54 55 so hopefully we can spin up other VMs connected either to its lan or 56 its wan: *however* we do first need to configure its wan to use pppoe 57 58 uci set network.wan=interface 59 uci set network.wan.device='eth1' 60 uci set network.wan.proto='pppoe' 61 uci set network.wan.username='db123@a.1' 62 uci set network.wan.password='NotReallyTheSecret' 63 64 (it's ext4 so this will probably stick) 65 66 67 Fri Sep 23 10:27:22 BST 2022 68 69 * mcast=230.0.0.1:1234 : access (interconnect between router and isp) 70 * mcast=230.0.0.1:1235 : lan 71 * mcast=230.0.0.1:1236 : world (the internet) 72 73 74 Sun Sep 25 20:56:28 BST 2022 75 76 TODO - bugs, missing bits, other infelicities as they occur to me: 77 78 DONE 1) shutdown doesn't work as its using the busybox one not s6. 79 80 2) perhaps we shouldn't have process-based services like dhcp, ppp 81 implement "address provider interface" - instead have a separate 82 service for interface address that depends on the service and uses its 83 output 84 85 * ppp is not like dhcp because dhcp finds addresses for an existing 86 interface but ppp makes a new one 87 88 3) when I killed ppp it restarted, but I don't think it reran 89 defaultroute which is supposed to depend on it. (Might be important 90 e.g. if we'd been assigned a different IP address). Investigate 91 semantics of s6-rc service dependencies 92 93 DONE 4) make the pppoe test run unattended 94 95 5) write a test for udhcp 96 97 6) squashfs size is ~ 14MB for a configuration with not much in it, 98 look for obvious wastes of space 99 100 7) some of the pppoe config should be moved into a ppp service 101 102 8) some of configuration.nix (e.g. defining routes) should be moved into 103 tools 104 105 DONE 9) split tools up instead of having it all one file 106 107 10) is it OK to depend on squashfs pseudofiles if we might want to 108 switch to ubifs? will there always be a squashfs underneath? might 109 we want to change the pseudofiles in an overlay? 110 111 11) haven't done (overlayfs) overlays at all 112 113 12) overlay.nix needs splitting up 114 115 13) upgrade ppp to something with an ipv6-up-script option 116 117 14) add ipv6 support generally 118 119 15) "ip address add" seems to magically recognise v4 vs v6 but 120 is that specified or fluke? 121 122 16) tighten up the module specs. (DONE) services.foo should be a s6-rc 123 service, (DONE) kernel config should be checked in some way 124 125 DONE 17) rename nixwrt references in kernel builder 126 127 18) maybe stop suffixing all the service names with .service 128 129 19) syslogd - use busybox or s6? 130 131 chat -s -S ogin:--ogin: root / "ip address show dev ppp0 | grep ppp0" 192.168.100.1 "/nix/store/*-s6-linux-init-*/bin/s6-linux-init-hpr -p" 132 133 134 Working towards a general goal of having a derivation we can 135 usefully run `nix path-info` on - or some other tool that will 136 tell us what's making the images big. The squashfs doesn't 137 have this information. 138 139 Towards that end (really? can't remember how ...) what would be a 140 way for packages to declare "I want to add files to /etc"? Is that 141 even a good idea? 142 143 Thinking we should turn s6-init-files back into a real derivation. 144 145 Tue Sep 27 00:31:45 BST 2022 146 147 > Thinking we should turn s6-init-files back into a real derivation. 148 149 This turns out to be Not That Simple, because it contains weird shit 150 (sticky bits and fifos). 151 152 Tue Sep 27 09:50:44 BST 2022 153 154 * allow modules to register activation scripts that are run on the 155 root filesystem once all packages are installed 156 157 - do they run on build or on host? if we're upgrading in place 158 how do we ship filesystem changes to the host? 159 160 or: 161 162 * allow modules to declare environment.*, use pseudofile on build and 163 create real files on host. will need to keep the implementation on 164 host faily simple because restricted environment 165 166 Tue Sep 27 16:14:18 BST 2022 167 168 TODO list is getting both longer and shorter, though longer on 169 average. 170 171 2) perhaps we shouldn't use process-based services like [ou]dhcp as 172 queryable endpoint for interface addresses (e.g. when adding routes). 173 Instead have a separate service for interface address that depends on 174 the *dhcp and uses its output 175 176 3) when I killed ppp it restarted, but I don't think it reran 177 defaultroute which is supposed to depend on it. (Might be important 178 e.g. if we'd been assigned a different IP address). Investigate 179 semantics of s6-rc service dependencies 180 181 4) figure out a nice way to fit ppp into this model as it actually 182 creates the interface instead of using an existing unconfigured one 183 184 5) write a test for udhcp 185 186 7) some of the pppoe config should be moved into a ppp service 187 188 11) haven't done (overlayfs) overlays at all 189 190 13) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 191 192 14) add ipv6 support generally 193 194 15) "ip address add" seems to magically recognise v4 vs v6 but 195 is that specified or fluke? 196 197 19) ship logs somehow to log collection system 198 199 21) dhcp, dns, hostap service for lan 200 201 22) support real hardware 202 203 Tue Sep 27 22:00:36 BST 2022 204 205 Found the cause of huge image size: rp-pppoe ships with scripts that 206 reference build-time packages, so we have x86-64 glibc in there 207 208 We don't need syslog just to accommodate ppp, there's an underdocumented 209 option for it to log to a file descriptor 210 211 Wed Sep 28 16:04:02 BST 2022 212 213 Based on https://unix.stackexchange.com/a/431953 if we can forge 214 ethernet packets we might be able to write tests for e.g. "is the vm 215 running a dhcp server" 216 217 Wed Sep 28 21:29:05 BST 2022 218 219 We can use Python "scapy" to generate dhcp request packets, and Python 220 'socket' model to send them encapsulated in UDP. Win 221 222 It's extremely janky python 223 224 Thu Sep 29 15:24:37 BST 2022 225 226 Two points to ponder 227 228 1) where service config depends on outputs of other services, we 229 do that rather ugly "$(cat ${output ....})" construct. Can we improve on 230 that? Maybe we could have some kind of tooling to read them as environment 231 variables ... 232 233 2) we have given no consideration yet to secrets. we want the secrets to 234 be not in the store; we want some way of refreshing them when they change 235 236 Sat Oct 1 14:24:21 BST 2022 237 238 The MAC80211_HWSIM kernel config creates virtual wlan[01] devices 239 which hostapd will work with, and a hwsim0 which we can use to monitor 240 (though not inject) trafic. Could we use this for wifi tests? How do 241 we make the guest hwsim0 visible to the host? 242 243 244 Sat Oct 1 18:41:31 BST 2022 245 246 virtual serial ports: I struggled with qemu for ages to get this to work. 247 You also need the unhelpfully named CONFIG_VIRTIO_CONSOLE option in 248 kconfig 249 250 QEMU_OPTIONS="-nodefaults -chardev socket,path=/tmp/wlan,server=on,wait=off,id=wlan -device virtio-serial-pci -device virtserialport,name=wlan,chardev=wlan" 251 252 Sun Oct 2 09:34:48 BST 2022 253 254 We could implement the secrets store as a service, then the secrets 255 are outputs. 256 257 Things we can do in qemu 258 259 1) make interface address service that depends on dhcp, instead of 260 being set by it directly 261 2) check out restart behaviour of dependent services when depended-on 262 service dies 263 3) pppd _creates_ an interface, work out how to fit it into this model 264 5) add bridge support for lan 265 8) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 266 9) get ipv6 address from pppoe 267 10) get ipv6 delegation from pppoe and add prefix to lan 268 11) support dhcp6 in dnsmasq, and advertise prefix on lan 269 12) firewalling and nat 270 - default deny or zero trust? 271 14) write secrets holder as a service with outputs 272 20) should we check that references to outputs actually correspond with 273 those provided by a service 274 275 Things we probably do on hardware 276 277 6) writable filesystem (ubifs?) 278 7) overlay with squashfs/ubifs - useful? think about workflows for 279 how this thing is installed 280 16) gl-ar750 281 17) mediatek device - gl-mt300 or whatever I have lying around 282 18) some kind of arm (banana pi router?) 283 19) should we give routeros a hardware ethernet and maybe an l2tp upstream, 284 then we could dogfood the hardware devices. we could run an l2tp service 285 at mythic-beasts, got a /48 there 286 287 288 289 https://skarnet.org/software/s6/s6-fghack.html looks like a handy thing 290 we hope we'll never have to use 291 292 Sun Oct 2 22:22:17 BST 2022 293 294 > make interface address service that depends on dhcp, instead of being set by it directly 295 296 We can do this for dhcp, but we can't do it for ppp. Running the ppp service 297 creates a ppp[012n] interface and assigns it an ipv4 address and there's not 298 a whole lot we can easily do to unbundle that. 299 300 So 301 302 - the ppp service needs to behave as if it were a "link" service 303 - either it *also* needs to behave as an address service, or we could 304 have an address service that subscribes to it and does nothing other than 305 translate output formats 306 307 Note regarding that second bullet: at the moment the static address 308 service has no outputs anyway! 309 310 311 Tue Oct 4 22:43:02 BST 2022 312 313 While trying to make the TFTP workflow not awful I seem to have written 314 a TFTP server. 315 316 317 Thu Oct 6 19:26:40 BST 2022 318 319 We have a booting kernel on gl-ar750, but we aren't at a point that it can 320 find a root filesystem 321 322 I'd *like* to be able to use the same delivery mechanism (kernel uimage 323 concatenated monolithic 324 325 326 Sat Oct 8 11:12:09 BST 2022 327 328 We have it booting on hardware, mounting root fs, running getty :-) 329 330 For NixWRT TFTP boots we used a single image with both kernel and squashfs, and 331 relied on CONFIG_MTD_SPLIT_FIRMWARE to identify where the boundary was and create 332 /dev/mdtn devices at the right offsets so that the kernel could find the 333 squashfs 334 335 For Liminix we're not going to do that. 336 337 * CONFIG_MTD_SPLIT_FIRMWARE is only available in OpenWrt patches 338 * it's an uncomfortable level of automagic just to save us doing two TFTPs 339 instea of one 340 * the generated image is anyway not the one we'd write to flash (has unneeded 341 PHRAM support) 342 * it means we need to memmap out enough ram for the whole image inc kernel when really 343 all we need to reserve is the rootfs bit 344 345 346 Sat Oct 8 11:23:08 BST 2022 347 348 "halt" and "reboot" don't work on gl-ar750 349 350 Sat Oct 8 13:10:00 BST 2022 351 352 Where do we go with this ar750? 353 354 - wired networking 355 - wifi 356 357 358 Sun Oct 9 09:57:35 BST 2022 359 360 We want to be able to package kernel modules as regular derivations, so that 361 they get added to the filesystem 362 363 This means they need access to kernel.modulesupport 364 365 This means kernel.modulesupport needs to be in pkgs too? 366 367 This is fine, probably, but we'd like to avoid closing over vmlinux because 368 there's no need for it to be in the filesystem 369 370 Mon Oct 10 22:57:23 BST 2022 371 372 The problem is that kernel kconfig options are manipulated in the 373 liminix modules, which means that data must be (transitively) available 374 to modules, so they can't be regular packages as they're tied so tightly 375 to the exact config. Unless we define a second overlay that references 376 the configuration object, but my head hurts when I start to think about that 377 so maybe not. 378 379 Tue Oct 11 00:00:13 BST 2022 380 381 Building ag71xx (ethernet driver) as a module doesn't work because 382 it references a symbol ath79_pll_base in the kernel that hasn't been 383 marked with EXPORT_SYMBOL. 384 385 We could forge an object file that "declares" it with a gross and disgusting hack like this 386 387 $ echo > empty # not actually "empty", objcopy complains about that 388 $ grep ath79_pll_base /nix/store/jcc114cd13xa8aa4mil35rlnmxnlmv09-vmlinux-mips-unknown-linux-musl-modulesupport/System.map 389 ffffffff807b2094 B ath79_pll_base 390 $ mips-unknown-linux-musl-objcopy -I binary -O elf32-big --add-section .bss=empty --add-symbol ath79_pll_base=.bss:0x807b2094 empty f.o 391 392 I don't claim this is a good idea, just an idea. Thought was that we would not 393 have to declare its type this way. Also it might not work with kaslr 394 https://stackoverflow.com/a/68903503 395 396 397 Backstory: why are we trying to build this as a module? because the 398 openwrt fork of it seems to be a bit more advanced than the mainline, 399 and I *suspect* that the mainline version doesn't work with our 400 openwrt-based device tree which ahs the mdio as a nested node inside 401 the ag71xx node - in mainline the driver seems to have all the mdio 402 stuff inline. So, could we build the openwrt driver without patching 403 the crap out of our kernel 404 405 Sun Oct 16 15:25:33 BST 2022 406 407 Executive decision: let's use the openwrt kernel (at least for 408 gl-ar750). Mainline kernel doesn’t have devicetree support for this 409 device or the SoC it’s based on, and the OpenWrt dts for it doesn’t 410 have the same "compatible"s, which makes me think that an indefinite 411 amount of patching will be necessary to make dts/modules for one of 412 them work with a kernel for the other 413 414 As a result: now we have eth0 appearing, but not eth1? Guessing we 415 need to add some kconfig for the switch 416 417 Mon Oct 17 21:23:37 BST 2022 418 419 we are spending ridiculous amounts of cpu/io time copying kernel source 420 trees from place to place, because we have kernel tree preparation 421 and actual building as two separate derivations. 422 423 I think the answer is to have a generic kernel build derivation 424 in the overlay, and then have the device overlays override it with 425 an additional phase to do openwrt patching or whatever else they 426 need to do. 427 428 Tue Oct 18 23:02:43 BST 2022 429 430 * previous TODO list is Aug 02, need to review 431 * dts is hardcoded to gl-ar750, that needs cleaning up 432 * figure out persistent addresses for ethernet 433 * fix halt/reboot 434 * "link" services have a "device" attribute, would much rather 435 have everything referenced using outputs than having two 436 different mechanisms for reading similar things 437 * Kconfig.local do we still need it? 438 * check all config instead of differentiating config/checkedConfig 439 440 Sun Feb 5 18:14:02 GMT 2023 441 442 We have resumed. 443 commit eb4efab6a215bf03cf5aab10d4ac909e83e9c148 444 Author: Daniel Barlow <dan@telent.net> 445 Date: Sat Jan 28 23:18:28 2023 +0000 446 447 448 * find out what works 449 * add that stuff to hydra 450 * fix the rest 451 * add that stuff to hydra 452 * convert to flake 453 * check if routeros can be run interactively 454 * some per-device docs in a form that can be transcluded for website 455 456 457 ci builds 458 459 * each of the tests has hardcoded device/config/etc 460 * build an "empty" configuration for each target device 461 * build an unstable configuration for qemu 462 463 464 Wed Feb 8 16:52:22 GMT 2023 465 466 We have hydra builds for all the previously-working devices, though we 467 don't yet know if any of those builds actually boots or does anything 468 useful. 469 470 [DONE] Would be nice to clean up the run-qemu and connect-qemu scripts 471 and put them in the buildEnv 472 473 Some thought needed about how to hook up the gl-ar750 to the internets, 474 ideally in a way that mirrors typical real uses. AAISP have an L2TP 475 service, but I would prefer to use pppoe on the device, so how to 476 translate one to t'other on an intermediary/gateway machine? 477 https://www.rfc-archive.org/getrfc.php?rfc=3817#gsc.tab=0 exists 478 as an RFC but I can't find anything that actually implements it 479 480 Actual Documentation (e.g. user and developer manuals) should live in 481 the liminix repo so it corresponds with the code, and can be rsynced 482 from there to the web site, maybe with a deploy hook or something. 483 Haven't decided what a good doc format is yet 484 485 If we create a flake for Hydra to run on, that _more or less_ means we 486 don't have any manual hydra jobset configuration to document. 487 488 There are still some tests that need adding to CI 489 490 [DONE] Should the per-device config be a module not an overlay? Given that 491 half of what's in it is kernel config (a module could set this) 492 and the rest is source tarball download specs (needs nixpkgs, 493 a module has this and could set it too) I wonder why it isn't already 494 495 [ALREADY DOES] Can we make Hydra report output sizes so we can plot closure size 496 trends and see if it all goes awful? 497 498 Thu Feb 9 08:14:39 GMT 2023 499 500 For better developer experience, I am thinking that either (1) 501 swap tasks 2 and 3 (writable filesystem before module system) 502 or (2) add NBD support so I can iterate on a real device without 503 full rebuilds every time 504 505 506 Fri Feb 10 06:18:25 PM GMT 2023 507 508 did the overlay->module thing 509 510 [DONE] Need to fix all the configuration around PHRAM, I can't see how it 511 would ever work 512 513 Sat Feb 11 14:37:45 GMT 2023 514 515 Consolidated TODO 516 517 * figure out persistent addresses for ethernet (?) 518 [SEEMS DONE] * fix halt/reboot 519 [DONE, NO] * Kconfig.local do we still need it? 520 [DONE] * check all config instead of differentiating config/checkedConfig 521 522 Things we can do in qemu 523 524 * "link" services have a "device" attribute, would much rather 525 have everything referenced using outputs than having two 526 different mechanisms for reading similar things 527 1) make interface address service that depends on dhcp, instead of 528 being set by it directly 529 2) check out restart behaviour of dependent services when depended-on 530 service dies 531 3) pppd _creates_ an interface, work out how to fit it into this model 532 5) add bridge support for lan 533 8) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 534 9) get ipv6 address from pppoe 535 10) get ipv6 delegation from pppoe and add prefix to lan 536 11) support dhcp6 in dnsmasq, and advertise prefix on lan 537 12) firewalling and nat 538 - default deny or zero trust? 539 14) write secrets holder as a service with outputs 540 20) should we check that references to outputs actually correspond with 541 those provided by a service 542 * Actual Documentation (e.g. user and developer manuals) 543 * make a flake 544 * There are still some tests that need adding to CI 545 546 Things we probably do on hardware 547 548 [DONE] * dts is hardcoded to gl-ar750, that needs cleaning up 549 6) writable filesystem (ubifs?) 550 7) overlay with squashfs/ubifs - useful? think about workflows for 551 how this thing is installed 552 16) gl-ar750 553 [DONE] * decide how to hook up the gl-ar750 to the internets 554 17) mediatek device - gl-mt300 or whatever I have lying around 555 18) some kind of arm (banana pi router?) 556 [DONE DIFERENTLY] 19) should we give routeros a hardware ethernet and maybe an l2tp upstream, 557 then we could dogfood the hardware devices. we could run an l2tp service 558 at mythic-beasts, got a /48 there 559 560 561 Sat Feb 11 15:57:31 GMT 2023 562 563 The reason we would like to run PPPoE instead of L2TP on the "rotuer" device is 564 565 - closer to real world scenario 566 - means no need to run dhcp client on the wan interface before we 567 even get to start the l2tpd 568 569 570 Sun Feb 12 14:57:28 GMT 2023 571 572 https://github.com/katalix/go-l2tp#kpppoed 573 574 575 Mon Feb 13 04:44:09 PM GMT 2023 576 577 if the gl-ar750 is connected to an ethernet card that linux is ignoring, 578 we're going to have to set up _some_ qemu thing just to run tftp from. 579 580 Tue Feb 14 17:59:34 GMT 2023 581 582 We should do a derivation that creates an ISO image and a qemu shell 583 script based on a configuration.nix, and put it in buildEnv. We'll 584 call it "borderNetVm" : 585 586 > A broadband remote access server (BRAS, B-RAS or BBRAS) routes 587 traffic to and from broadband remote access devices such as digital 588 subscriber line access multiplexers (DSLAM) on an Internet service 589 provider's (ISP) network.[1][2] BRAS can also be referred to as a 590 broadband network gateway or border network gateway (BNG).[3] 591 592 (for consistency we should rename the "access" qemu socket network to 593 match whatever we call this) 594 595 rm border.qcow2 ; nix-shell --argstr liminix `pwd` --argstr nixpkgs `pwd`/../nixpkgs --argstr unstable `pwd`/../unstable-nixpkgs/ ci.nix -A buildEnv --run "run-border-vm" 596 597 Wed Feb 15 22:56:59 GMT 2023 598 599 configuration for border vm needs to come from somewhere so it's good 600 for more people than just me 601 602 - pci device for setting up the ethernet 603 - lns address 604 - uid so it can do 9p shares? do we need to map things here? 605 606 also need to document the host-side bits so that people can set up 607 their spare ethernet as vfio 608 609 next step for hacking is to figure out what I was doing with pppoe 610 611 Wed Feb 15 22:59:56 GMT 2023 612 613 docs ... 614 615 * introduction 616 617 * user guide 618 ** how to build it 619 ** how to flash it on your device 620 ** what to put in configuration.nix 621 ** modules 622 623 * developer guide 624 ** building/running with qemu 625 *** emulated upstream 626 ** building/running on hardware 627 *** run in place with TFTP 628 *** emulated upstream 629 ** CI 630 ** Roadmap 631 ** Contributing 632 633 634 635 nix-shell -p sphinx --run "make -C doc html" 636 637 https://francis.begyn.be/blog/nixos-home-router contains information about avahi reflector 638 639 640 Fri Feb 17 00:09:34 GMT 2023 641 642 29 11.282085831 81.187.76.242 → 8.8.8.8 ICMP 106 Echo (ping) request id=0x0187, seq=2/512, 4 643 30 11.286314642 90.155.53.19 → 81.187.76.242 ICMP 78 Destination unreachable (Communication admin) 644 645 We're getting packets over the pppoe-l2tp relay thing. Just have to 646 work out now why we're not routing 647 648 Fri Feb 17 16:54:41 GMT 2023 649 650 Haha. We weren't routing because we'd used the wrong CHAP password 651 652 653 654 Fri Feb 17 16:58:27 GMT 2023 655 656 This TODO is for nlnet task 1 and for bits of subsequent tasks that 657 are annoying enough that I might poke at them anyway: 658 659 660 1) gl-ar750, why do we get "ag71xx 19000000.eth: invalid MAC address, using random address" 661 2) gl-ar750, wifi 662 3) document services so I can remember how they work. Refer back to Oct 18 for notes that no longer make sense 663 4) check out restart behaviour of dependent services when depended-on service dies 664 5) pppd _creates_ an interface, work out how to fit it into this model 665 6) add bridge support for lan 666 7) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 667 8) get ipv6 address from pppoe 668 9) get ipv6 delegation from pppoe and add prefix to lan 669 10) support dhcp6 in dnsmasq, and advertise prefix on lan 670 11) firewalling and nat - default deny or zero trust? 671 13) should we check that references to outputs actually correspond with 672 14) make a flake? 673 15) see if there are other tests that need adding to CI 674 15a) is bordervm derivation tested? 675 18) gl-mt300a 676 19) gl-mt300n-v2 677 20) publish the manual using CI 678 679 12) write secrets holder as a service with outputs 680 16) writable filesystem (ubifs?) 681 17) overlay with squashfs/ubifs - useful? think about workflows for how this thing is installed 682 683 684 I could plug tninkpad into the gl-ar750 LAN port to dogfood the wired 685 networking 686 687 Sat Feb 18 14:26:45 GMT 2023 688 689 Apparently we're not currently doing anything special with busybox, 690 just using the default nixos build with the default applets. 691 692 We'd like to be able to say in modules which applets they need, 693 so that we build all necessary applets but don't waste any space. 694 But we don't want to build a busybox for each module because that 695 would be a big waste of space. 696 697 One option: 698 - add busybox configuration to `config` so that modules can maul it 699 - add a busybox module that builds it with union of all config and 700 adds link in /bin 701 - make everything else look in /bin instead of referencing pkgs.busybox 702 703 It would be good if services could assert somehow that their required 704 config is present 705 706 Sat Feb 18 23:45:13 GMT 2023 707 708 # lsmod 709 710 cd /lib/modules/mac80211 711 insmod ./compat/compat.ko 712 insmod ./net/wireless/cfg80211.ko 713 insmod ./net/mac80211/mac80211.ko 714 insmod ./drivers/net/wireless/ath/ath.ko 715 insmod ./drivers/net/wireless/ath/ath9k/ath9k_hw.ko 716 insmod ./drivers/net/wireless/ath/ath9k/ath9k_common.ko 717 insmod ./drivers/net/wireless/ath/ath9k/ath9k.ko 718 insmod ./drivers/net/wireless/ath/ath10k/ath10k_core.ko 719 insmod ./drivers/net/wireless/ath/ath10k/ath10k_pci.ko 720 721 [21.344930] ath9k 18100000.wmac: failed to load calibration data from mtd device 722 [21.352728] ath: phy0: parsing configuration from OF node 723 [21.362576] ath: phy0: serialize_regmode is 0 724 [21.367092] ath: phy0: UNDEFINED -> AWAKE 725 [21.372051] ath: phy0: Trying EEPROM access at Address 0x03ff 726 [21.377999] ath: phy0: Trying EEPROM access at Address 0x0fff 727 [21.383940] ath: phy0: Trying EEPROM access at Address 0x01ff 728 [21.389879] ath: phy0: Trying OTP access at Address 0x03ff 729 [21.400396] Data bus error, epc == 8027964c, ra == 83125880 730 [21.406156] Oops[#1]: 731 732 733 Sun Feb 19 18:15:27 GMT 2023 734 735 We have ath9k listening for packets. To make this ready to use: 736 737 - need to load the modules 738 - enable bridging lan with wlan 739 - packet forwarding 740 - firewall 741 742 743 Mon Feb 20 20:41:17 GMT 2023 744 745 need to fix all the other broken ci jobs :-( 746 747 The wlan test is failing because we moved mac80211 to a module and 748 there's nothing running to insmod it 749 750 Wed Feb 22 18:17:17 GMT 2023 751 752 bridge is e2b3738d0f8c3f2fd76ebcef65612de502a7b121 but it's the wrong 753 way around: the master interface needs to be up whether or not all 754 of its children are, so members depend on master not vice versa 755 756 Next steps: 757 - re-implement bridge, enable bridging lan with wlan 758 - packet forwarding 759 - firewall 760 - ath10k 761 - ipv6 762 763 Fri Feb 24 23:37:56 GMT 2023 764 765 bridging wlan was made complex because can't add a device to a bridge 766 until it's operational, and wlan0 is not operational until hostapd 767 has churned awhile. Therefore, "waitup" listens for netlink messages 768 and notifies s6 readiness stuff 769 770 we have a firewall nft script but we're not running it on boot 771 772 we have forwarding but no dns, maybe because we haven't told 773 dnsmasq about any upstream servers 774 775 Sun Feb 26 21:08:47 GMT 2023 776 777 to add firmware we need to put files in /lib/firmware, which means 778 a module 779 780 i guess we should do that in the device module 781 782 we can create the firmware files as packages 783 784 785 for the cal data we would like to get it from the device MTD "art" 786 partition at 787 boot time. 788 789 f 790 ====from openwrt 791 792 793 794 case "$FIRMWARE" in 795 "ath10k/cal-pci-0000:00:00.0.bin") 796 case $board in 797 allnet,all-wap02860ac|\ 798 araknis,an-500-ap-i-ac|\ 799 araknis,an-700-ap-i-ac|\ 800 engenius,eap1200h|\ 801 engenius,enstationac-v1|\ 802 glinet,gl-x750|\ 803 watchguard,ap300) 804 caldata_extract "art" 0x5000 0x844 805 ath10k_patch_mac $(macaddr_add $(mtd_get_mac_binary art 0x0) 2) 806 807 808 809 810 caldata_extract part offset count 811 caldata_dd $mtd /lib/firmware/$FIRMWARE $count $offset || \ 812 caldata_die "failed to extract calibration data from $mtd" 813 dd if=$source of=$target iflag=skip_bytes,fullblock bs=$count skip=$offset count=1 2>/dev/null 814 815 ======= 816 817 part=$(basename $(dirname $(grep -l art /sys/class/mtd/*/name))) 818 dd if=/dev/$part \ 819 of=/run/cal-pci-0000:00:00.0.bin iflag=skip_bytes,fullblock \ 820 bs=0x844 skip=0x5000 count=1 821 822 Mon Feb 27 22:46:37 GMT 2023 823 824 Found and fixed a bunchg of things that were stopping ath10k from 825 working. The remaining problem is (I think) that insmod is not 826 synchronous, so "ip link set up dev wlan1" doesn't work immediately 827 after the module is inserted. Maybe we need another netlink thing 828 to wait until the interface is present. 829 830 831 Wed Mar 1 18:26:44 GMT 2023 832 833 ath10k works, but the wlan module loading stuff is quite kludgey 834 835 I wonder if wlan0, wlan1, eth0, eth1 etc should be defined per-device 836 - how does the aplication config know which devices exist? If we 837 decide to switch to some form of persistent device naming, the names 838 will differ from one device to the next. Perhaps the device should 839 also provide standard names where possible? 840 841 services.network.links = { 842 lan = interface { ... }; 843 wan = interface { ... }; 844 wlan_24 = interface { ... }; 845 wlan_5 = interface { ... }; 846 } 847 848 Thu Mar 2 22:45:11 GMT 2023 849 850 We have a flashable image! 851 852 Now we can use the gl-ar750 for internet access in the shed, we can 853 apppropriate the other device that's in there and try Liminix on it 854 855 Fri Mar 3 23:08:58 GMT 2023 856 857 If we're going to unplug serial console from the gl-ar750 maybe we 858 should install an ssh server first. 859 860 0) set a root password 861 1) allow setting a root password from configuration.nix 862 (means defining config.users properly) 863 2) allow authorizedKeys per user 864 3) dropbear service 865 4) see if the wired lan works! :-) 866 867 868 Sat Mar 4 12:31:07 GMT 2023 869 870 To improve logging, each service should have its own s6-log service 871 which prefixes the service name onto the log line and then sends to 872 stdout 873 874 https://skarnet.org/software/s6/servicedir.html 875 https://skarnet.org/software/s6/s6-log.html 876 877 As far as I can tell, the `log` directory inside the service 878 directory should itself be a service directory for the s6-log 879 process that does this 880 881 .... hahaha no that doesn't work 882 883 s6-rc, for some reason, ignores the `log` directory and requires 884 that loggers be done with consumer-for and producer-for instead 885 886 887 Sat Mar 4 23:27:00 GMT 2023 888 889 notes for this week's news update 890 891 * ath10k kernel support and and firmware 892 893 - 5GHz wifi works 894 895 - need to retrieve the firmware from a special - partition on the 896 device itself, so we do that using a service that - the wlan 897 interface depends on 898 899 * replace waitup with more generally useful ifwait 900 901 to make the ath10k load at boot, we need to insert the module and then 902 wait for it to do something or other in the background before we can 903 configure the interface. so we need something like waitup but 904 for presence not operational state 905 906 it turns out that a program that just waits for a particular interface 907 state and then exits is quite simple to add into run scripts and 908 we don't need all that notification-fd stuff anyway 909 910 * move FW_LOADER* config to modules/base 911 912 * rejig config a bit. 913 - device hardware characteristics are now under 914 the `hardware` key and include the available network interfaces. 915 - options for users and groups are now defined a bit more 916 specifically than "attrset", making it possible to e.g. set a 917 root password 918 - dts is moved from `boot` to `hardware` 919 920 921 * now producing flashable images, so you can generate a liminix config 922 and write it to the device instead of having to boot using TFTP and 923 a serial console every time 924 925 * ssh support 926 927 * prefix logs with the service name 928 929 Sun Mar 5 22:51:21 GMT 2023 930 931 Added swconfig: it was a straight copy from nixwrt and hasn't changed 932 upstream since. But don't need it, because the lan port works fine 933 without it (I assume both lan ports and the cpu are all connected 934 untagged) 935 936 Mon Mar 6 09:42:33 GMT 2023 937 938 Today I plugged in the mt300a. 939 940 echo 17 >/sys/class/gpio/export 941 echo out >/sys/class/gpio/gpio17/direction 942 943 944 why are our images getting big 945 946 - lua links ncurses 947 - hostapd links openssl and sqlite 948 - nftables needs 949 - iptables? 950 - jansson? what is that? 951 - libedit/readline 952 - ifwait needs bash 953 954 955 File: result/squashfs 956 Size: 10371072 Blocks: 20256 IO Block: 4096 regular file 957 958 with smaller nftables: 9617408 Blocks: 18784 959 960 hostapd wqithout sqlite 9003008 Blocks: 17584 961 962 without bash: 8622080 Blocks: 16840 IO Block: 4096 regular file 963 964 without lua readline: bigger?! 8769536 Blocks: 17128 IO Block: 4096 regular file 965 966 967 Mon Mar 6 20:57:49 GMT 2023 968 969 [ 0.539992] mtk_soc_eth 10100000.ethernet: mdio-bus disabled 970 [ 10.493918] platform regulatory.0: Direct firmware load for regulatory.db fail 971 ed with error -2 972 [ 10.502828] cfg80211: failed to load regulatory.db 973 974 Check in morning, but whichever port the ethernet cable is plugged into, 975 is considered by the kernel as port 0 - which I think we should treat as 976 WAN 977 978 VLAN 1: 979 vid: 1 980 ports: 1 2 3 4 5 6t 981 VLAN 2: 982 vid: 2 983 ports: 0 6t 984 985 ip link add link eth0 name lan type vlan id 1 986 ip link add link eth0 name wan type vlan id 2 987 988 figure out how to add these to gl-mt300a device config 989 then extedner.nix can add a bridge 990 991 Tue Mar 7 20:13:15 GMT 2023 992 993 We need NTP or some other way to get accurate time 994 995 [done] Need to add regulatory.db somewhere standard, maybe modules/wlan? 996 997 Tue Mar 7 21:43:56 GMT 2023 998 999 When we get to phase 2, need to review how network interfaces and 1000 their addresses interplay. It should be possible to have a network 1001 interface and interrogate the addresses associated with it - esp 1002 with ipv6 where there are multiple addresses for the device 1003 1004 This thought prompted by looking at the loopback interface, which is 1005 a bundle of addresses and therefore we can't see what any of them are 1006 1007 1008 Tue Mar 7 22:05:44 GMT 2023 1009 1010 [phase 1] 1011 20) publish the manual using CI 1012 30) document flashing process 1013 31) go through all the unexpected dmesg and triage it 1014 25) ntp or some other accurate time source 1015 1016 [phase 1.5] 1017 26) ssh keys 1018 8) get ipv6 address from pppoe 1019 9) get ipv6 delegation from pppoe and add prefix to lan 1020 10) support dhcp6 in dnsmasq, and advertise prefix on lan 1021 11) firewalling and nat - default deny or zero trust? 1022 7) upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 1023 32) set up iperf and do some performance measurement 1024 35) also we need to check our wireless country code 1025 1026 1027 [phase 2] 1028 3) document services so I can remember how they work. Refer back to Oct 18 for notes that no longer make sense 1029 4) check out restart behaviour of dependent services when depended-on service dies 1030 13) check that references to outputs correspond with declared outputs 1031 33) network interfaces vs the services that manage their addresses 1032 34) write a short guide explaining how to use s6-svc 1033 1034 [phase n] 1035 12) write secrets holder as a service with outputs 1036 16) writable filesystem (ubifs?) 1037 17) overlay with squashfs/ubifs - useful? think about workflows for how this thing is installed 1038 1039 1040 dmesg lines to investigate for gl-mt300a: 1041 [ 0.467314] OF: Bad cell count for /palmbus@10000000/spi@b00/flash@0/partition 1042 [ 0.539709] mtk_soc_eth 10100000.ethernet: mdio-bus disabled ? 1043 [ 8.778513] compat: loading out-of-tree module taints kernel. 1044 [ 17.686561] ieee80211 phy0: rt2800_wait_bbp_rf_ready: Error - BBP/RF register access failed, aborting 1045 [ 17.696025] ieee80211 phy0: rt2800_loft_iq_calibration: Warning - RF RX busy in LOFT IQ calibration 1046 [ 17.875147] ieee80211 phy0: rt2800_rxiq_calibration: Warning - Timeout waiting for MAC status in RXIQ calibration 1047 1048 for gl-ar750: 1049 [ 0.000000] Unknown kernel command line parameters "earlyprintk=serial,ttyS0", will be passed to user space. 1050 [ 0.416679] OF: Bad cell count for /ahb/spi@1f000000/flash@0/partitions 1051 [ 0.825495] ag71xx 19000000.eth: Could not connect to PHY device. Deferring probe. 1052 [ 1.632700] pci_bus 0000:00: root bus resource [mem 0x10000000-0x13ffffff] 1053 [ 1.639824] pci_bus 0000:00: root bus resource [io 0x0000] 1054 [ 1.645601] pci_bus 0000:00: No busn resource found for root bus, will use [bus 00-ff] 1055 [ 32.032326] ath10k_pci 0000:00:00.0: pdev param 0 not supported by firmware 1056 [ 36.627844] ath10k_pci 0000:00:00.0: failed to receive initialized event from target: 00000000 1057 1058 1059 Fri Mar 10 13:17:56 GMT 2023 1060 1061 Lunchtime notes on images for real devices, vs ci.nix 1062 1063 * successfully building an image doesn't mean that the image boots 1064 or does anything useful 1065 1066 * don't want to faff with serial wires on every device every time 1067 to test it. so 1068 1069 * ideally, build ram-based images of rotuer, extneder, arhcive in CI 1070 with a watchdog timer that will reboot if it can't see the network 1071 1072 * figure out how to boot into the new image from an ssh connection. I 1073 assume the challenging bit here is grabbing x MB of contiguous phys 1074 mem after boot: I think we'd have to reserve it at _first_ boot and 1075 then somehow copy into it before rebooting 1076 1077 An easier first goal might be a tool to flash from the shell command line, 1078 but that runs a greater risk of bricking 1079 1080 1081 Fri Mar 10 14:35:40 GMT 2023 1082 1083 programs.busybox = { 1084 enable = true; 1085 applets = [... ]; 1086 config = { 1087 }; 1088 } 1089 1090 Fri Mar 10 23:49:04 GMT 2023 1091 1092 Well, we have the backup host config up and running - though haven't 1093 plugged it back into its disk yet. 1094 1095 For task 1 what remains is 1096 1097 1) ntp sync 1098 2) write up the flashing procedure 1099 3) a video? 1100 1101 1102 Sat Mar 11 13:58:20 GMT 2023 1103 1104 ================== for video 1105 1106 what is liminix 1107 - nix-based system for creating OS images for routers 1108 - not "nixos on your router" 1109 - nixos-like module system, 1110 - musl for libc 1111 - s6/s6-rc for services 1112 - entirely cross-compiled 1113 1114 why am i making a video? 1115 - unless you have a suitable spare device to install on, 1116 and you want to take it apart, it's currently hard to 1117 take liminix for a spin 1118 - I have these things, so I can give you a tour 1119 1120 let's have a look at how the hardware's hooked up 1121 1122 web site & manual 1123 1124 a config file: 1125 - observe the comments: 1126 - not going to spend ages on this because it's not in its final form. 1127 - as we get more configs for more use cases, we will 1128 get a better feel for what can be abstracted 1129 - that will come later: work so far has been on the 1130 hardware support side 1131 1132 to show that it builds, we're going to add a package. otherwise, 1133 everything from this build is probably already cached 1134 1135 build the config 1136 1137 tftpboot on hardware 1138 1139 flash on hardware 1140 1141 show ci 1142 1143 show a qemu target 1144 1145 Mon Mar 13 22:46:46 GMT 2023 1146 1147 1) rsync on arhcive is failing because no nogroup group 1148 1149 "/nix/store/gfzzl157r8xyp38lpcfxydkiiy6zrs3c-rsync-3.2.6/bin/rsync" "--verbose" "--stats" "--password-file" "/etc/nixos/secrets/arhcive-rsync" "-rltgoDz" "/var/spool/backup" "backup@arhcive.lan::srv/" 1150 @ERROR: invalid gid nogroup 1151 rsync error: error starting client-server protocol (code 5) at main.c(1837) [sender=3.2.6] 1152 1153 2) we can run findfs in a loop until the disk appears 1154 1155 3) still haven't decided how to do ntp but maybe we should just use 1156 the busybox one 1157 1158 4) some way to do upgrades over the wire 1159 1160 - boot with reserved mem and a phram device at 110-128MB even in the 1161 flashable version 1162 1163 - watchdog timer in kernel 1164 1165 - kexec in kernel 1166 1167 - userland service to feed the dog as long as local network is up 1168 (may need to start it a couple of minutes after boot, how do we 1169 do that?) 1170 1171 - can we use flashcp on a phram mtd? 1172 1173 5) maybe setup a vhost for hydra or something 1174 1175 [nix-shell:~/t]$ wget --reject-regex '\?' -D localhost -N -r --exclude-directories=/api --level=2 --convert-links -e robots=off http://localhost:3003/jobset/liminix/build/ 1176 1177 is almost a mirror 1178 1179 Tue Mar 14 20:17:35 GMT 2023 1180 1181 - do we have a phram mtd? need config for size and location 1182 1183 - how do we set the boot device 1184 - for first boot need to boot real flash, use dtb, ignore bootloader args 1185 - for kexec, boot phram, specify args somehow (could rewrite dtb) 1186 1187 => can use same kernel for both if we can give kexec a dtb with 1188 different params, which seems to be possible 1189 1190 so we need a module for the initial kernel to say 1191 - create phram mtd 1192 - boot from real mtd (will be index + 1) 1193 - enable KEXEC in kernel 1194 - add kexec-tools 1195 1196 and for the kernel we boot into 1197 - most of the above 1198 - except for the boot device 1199 - create an output with objects that kexec(8) can parse 1200 1201 Could be same module for both with different outputs 1202 1203 what do we call this thing? "revertable" 1204 1205 Wed Mar 15 19:11:09 GMT 2023 1206 1207 "revertable" implies mtd support for the rootfs and a ramdisk at 1208 defined location 1209 1210 "tftpboot" implies "revertable", because it will use the same ramdisk 1211 1212 1213 Fri Mar 17 11:44:40 GMT 2023 1214 1215 - patch the kernel kexec code to pass DTB to new kernel unconditionally 1216 - unpatch pernel to pass command line to kexec (breaks DTB passing) 1217 - decide how we specify rootfs. doing it by number is awkward 1218 - may be phram 1219 - may be real mtd root 1220 - may be real mtd root but renumbered becuase phram exists 1221 1222 Wild idea: we could probably get rid of the need for declaring a phram 1223 device in the first kernel, if we can use kexec to copy the squashfs into 1224 physical ram. As far as I can see this is a simple(sic) matter of 1225 specifying it as a segment, but we would have to extend kexec-tools 1226 to do this and it's quite a niche option if we make it do all the 1227 mtd setup. 1228 1229 kexec --dtb=foo.dtb --map-file=squashfs@0x120000 1230 1231 1232 Sat Mar 18 18:02:26 GMT 2023 1233 What if: we added derivations for "apply openwrt changes" as packages, 1234 which could then be called from the kernel derivation's extraPatchPhase? 1235 There could be one for generic and one for each openwrt targetop 1236 1237 Mon Mar 20 18:40:53 GMT 2023 1238 1239 - kexec patch is sent to mailing list, keep an eye for replies 1240 - watchdog 1241 - ntp 1242 - rebuild images for live devices 1243 - can we build a static busybox with flashcp applet and scp it 1244 to arhcive etc? 1245 - [DONE] install mailman and hyperkitty on myhtic, create mailing list 1246 1247 Tue Mar 21 22:59:54 GMT 2023 1248 1249 I haven't found a way to arm the watchdog before userland runs, which 1250 would be really nice: although there's WATCHDOG_HANDLE_BOOT_ENABLED 1251 and WATCHDOG_OPEN_TIMEOUT it doesn't seem to be sufficient, Maybe 1252 those options work only when the hardware watchdog is already 1253 armed. It might not be completely awful insofar as any failure to 1254 mount root usually results in panic anyway, so provided we start 1255 watching early in boot then there's not a big window for anything 1256 to go wrong 1257 1258 What should the watchdog service do? Ideally we want something that 1259 "ratchets" : can be started in early boot and signals health as long 1260 as the system is starting up, then once the system is in "steady 1261 state" it stops pinging as soon as any part of that steady state 1262 becomes unhealthy. This feels like a refinement for a much later 1263 phase though. 1264 1265 Maybe the health criteria might be 1266 (sshd and lan services are running) or (time since boot < 120s) 1267 1268 Thu Mar 23 00:11:23 GMT 2023 1269 1270 tftpboot and (kexecboot || flashable) have incompatible DTB-finding 1271 strategies which is painful if you add both modules and then 1272 expect tftp booting to still work 1273 1274 Maybe we could patch the kernel to use some better strategy for when 1275 to use/ignore the bootloader command line: e.g "only if it 1276 contains the string 'liminix'". Could do this by patching 1277 arch/mips/kernel/setup.c bootcmdline_init to 1278 1279 if(strstr(arcs_cmdline, "liminix") == NULL) arcs_cmdline[0] = '\0' 1280 and then defining CONFIG_MIPS_CMDLINE_DTB_EXTEND. The 1281 bootloader command line then needs to specify only the 1282 _additional_ parameters that weren't in the DTB 1283 1284 (later: that turned out to be quite straighforward) 1285 1286 Fri Mar 24 23:45:12 GMT 2023 1287 1288 - add ntp support 1289 - [DONE] expose hydra to internet 1290 - check MAC address weirdness? 1291 - call Task 1 "done" 1292 1293 Sun Mar 26 00:19:15 GMT 2023 1294 1295 Would be nice to have a flash.sh built in outputs.flashable 1296 1297 Sun Mar 26 15:27:14 BST 2023 1298 1299 Let's think about services and modules. 1300 1301 Module 1302 + can change global config 1303 * add users, groups etc 1304 * change kernel config 1305 * change busybox config 1306 + well-typed parameters 1307 - is a "singleton": can't have the same module included twice 1308 with different config. e.g. can't have two hostap modules running on 1309 different wlan radios. 1310 - can't express dependencies: a depends on b 1311 1312 suppose: 1313 1314 * modules add service functions to the config? then there's no 1315 way to define a service while forgetting to import the module 1316 1317 * we use the lib.types stuff for service function arguments 1318 1319 * maybe we stop naming services.foo for every damn thing 1320 1321 * but remember, s6 services do need unique names 1322 1323 1324 imports = [ ../modules/dhcp4 ]; 1325 1326 services.dhcp4 = config.services.udhcp { 1327 interface = lan.device; 1328 options = { 1329 foo = true; 1330 bar = 42; 1331 }; 1332 depends = [ services.some_other_thing ]; 1333 } 1334 1335 modules/dhcp4 udhcp fn needs to define a type for its argument, then 1336 use something like 1337 1338 if arg_type.check def.value then res 1339 else throw "The option value `${showOption loc}' in `${def.file}' is not a ${arg_type.name}.") 1340 1341 (where def comes from I don't know yet) 1342 1343 Tue Mar 28 10:44:40 BST 2023 1344 1345 we should reserve the name "service" for actual instantiated 1346 services. This means we need a name for the functions that 1347 make services. "class", "template", "fn", "maker", "factory"? 1348 And a namespace name so they're not interleaved with real 1349 services, which sort of suggests they are packages 1350 1351 if we want to do services = { 1352 foo = longrun { ... }; 1353 bar = longrun { ... }; 1354 } 1355 1356 without repeating the `name` as an attribute of the longrun, 1357 then longrun can't return a derivation: it has to return some 1358 function that accepts `name` as a parameter. 1359 1360 where services.a depends on services.b, at the time its builder is run 1361 it needs to know what name s6-rc will use for service b 1362 1363 maybe an s6 service definition should be an attrset not a derivation. 1364 1365 maybe this is outside scope for phase 2 1366 1367 Tue Mar 28 13:22:06 BST 2023 1368 1369 Reading nixos/doc/manual/development/building-parts.chapter.md it 1370 suggests to me that we should rename config.outputs to 1371 config.system.outputs. The more general question here is whether it's 1372 good to be augmenting a variable called "config" with all this 1373 generated stuff that is patently not configuration - perhaps putting 1374 it under a "system" key will keep it all in one place 1375 1376 Tue Mar 28 13:32:30 BST 2023 1377 1378 how should we handle filesystem state? e.g. resolvconf service 1379 1380 if a service provides a file at a known global pathname, it can't be 1381 parametrised - it must be a singleton. 1382 1383 Tue Mar 28 20:25:20 BST 2023 1384 1385 wondering if we should swap phases 2 and 3. We can't really address 1386 modules without addressing services, which is phase +n, whereas we 1387 can tackle overlay/ubi whenever 1388 1389 nand flash may have bad blocks 1390 nor flash (supposedly) doesn't 1391 1392 ubi provides erase counts and bad block remapping on top of the mtd 1393 interface. this means we should avoid flashcp of a ubi image straight 1394 onto (nand) mtd as we will lose the erase counts and bad block information 1395 that UBI tracks. 1396 1397 overlayfs works on a filename basis, so might not be very effective : 1398 any change that results in a new store path will mean the entire package 1399 appears in two places. I think it's reasonable to offer squashfs or 1400 ubifs without overlay. 1401 1402 open questions: 1403 1404 1) if uboot doesn't support UBI, we can't boot a kernel on a ubifs 1405 so we need reserved space for the kernel. 1406 1407 - unless we add some padding after the kernel, every new kernel 1408 that's bigger than its predecessor will trash the start of the 1409 ubi space (and wipe out its erase count) 1410 - This suggests we should build more stuff as modules and less as 1411 compiled-in 1412 1413 2) once a device has had a ubi volume created on it, probably we want 1414 to use ubi-aware tools to update that volume in future instead of a 1415 whole new flash, because we wish to preserve erase counts. This means 1416 running ubiformat --image-file=foo.ubi on the device instead of flashcp 1417 1418 we can add a "ubi-flashable" output that creates a .ubi image and 1419 a flashcp image that wraps it, with instructions on which to use. 1420 1421 Fri Mar 31 22:13:54 BST 2023 1422 1423 Error: too small LEB size 3968, minimum is 15360 1424 1425 > This error means that you are trying to mount too small UBI 1426 volume. Probably because your flash is too small? Try to use JFFS2, 1427 then, because it suits small flashes better since it has much lower 1428 space overhead. Indeed, UBIFS stores much more indexing information on 1429 the flash media than JFFS2, so it has much higher overhead. Also, UBI 1430 has some overhead (see here). Thus, if you have a small flash device 1431 (e.g., about 64MiB), it makes sense to consider using JFFS2. 1432 1433 1434 Argh. Oh well, 1435 1436 Sat Apr 1 15:27:39 BST 2023 1437 1438 There's limited value in recreating pseudofiles for jffs2 because 1439 the system is writable - changes made to /bin, /dev etc in config.filesystem 1440 should take effect on a running system. 1441 1442 Can we take inspiration from https://grahamc.com/blog/erase-your-darlings/ ? 1443 1444 in early boot: 1445 mount ramfs on / 1446 mount the writeable filesystem on /persist/ 1447 bind mount /persist/nix on /nix 1448 run script to populate rootfs from pseudofiles 1449 1450 on a router, do we need _anything_ persistent that's outside the store? 1451 1452 - state for dhcp leases and stuff 1453 - secrets 1454 - maybe, files that the user has downloaded 1455 1456 this will probably require initramfs. if just use jffs2 as the rootfs and 1457 don't worry about /persist, we can skip that step. 1458 1459 1460 1461 1462 [ aside: I think we may be putting two busyboxes in the image: 1463 see modules/s6/default.nix s6-init-scripts has buildInputs = [busybox]; ] 1464 1465 Mon Apr 3 18:34:26 BST 2023 1466 1467 suppose 1468 - we boot the system with systemConfig=/nix/store/eeeeee-system 1469 - the early-init script runs /target/$systemConfig/create-root /target 1470 after mounting /target 1471 - then it runs chroot /target $systemConfig/bin/init "$@" 1472 1473 or maybe we could combine those steps? 1474 or maybe it doesn't matter too much ... 1475 1476 Thu Apr 6 21:25:41 BST 2023 1477 1478 what now? 1479 1480 - put a jffs2 onto some hardware device 1481 - what do we do with uboot? 1482 - should we pad the kernel? 1483 - maybe kernel module support would be good if we're making it 1484 hard to do kernel updates 1485 - try the nix-copy-closure thing and work out what else we don't know 1486 - [done] detect endian correctly 1487 1488 1489 to ask a different question, what else do we need to dogfood a router? 1490 1491 Sun Apr 9 10:06:08 BST 2023 1492 1493 - rename outputs.flashable to outputs.flashimage 1494 - rename modules/flashable to modules/flashable_ro 1495 - create outputs.flashable in modules/jffs2 1496 - rename modules/jffs2 to modules/flashable_rw 1497 - add enable config to both? 1498 - enable kernel module compilation 1499 1500 1501 Mon Apr 10 23:50:41 BST 2023 1502 1503 - initramfs parses /proc/cmdline to find root fs, might not play 1504 nice with defaulting 1505 1506 - how to build kernel modules 1507 1508 - look at closure size, is it this big because we've broken it 1509 or is jffs2 usually this much bigger than squashfs 1510 1511 - maybe squashfs with overlay might be better if we could 1512 ensure hardlinks? 1513 1514 - maybe there's something like overlayfs but content-addressable? 1515 1516 Sat Apr 15 18:57:46 BST 2023 1517 1518 for the same configuration: 1519 1520 -r--r--r-- 1 root root 6066176 Jan 1 1970 /nix/store/0x271rg45mcjjgbma9wi31h1yd109fpy-frob-squashfs 1521 -r--r--r-- 1 root root 12255232 Jan 1 1970 /nix/store/zx11adagcbzqsnqkyz5kgvr392vhlrpr-make-jffs2 1522 1523 may want to reconsider not using squashfs with overlay 1524 1525 Wed Apr 19 22:22:48 BST 2023 1526 1527 Where next? 1528 1529 Sun Apr 23 18:24:34 BST 2023 1530 1531 - we are down to ~ 11MB image for a barely functional (IPV4) router 1532 this is by avoiding all dependencies on openssl or gnutls 1533 - rotuer is not recognising when I set the hostname 1534 - I may have forgotten the root password :-( 1535 - why is hello world 70K unless hardeningDisable? 1536 1537 Fri Apr 28 20:51:52 BST 2023 1538 1539 To do nix-copy-closure we need nix-store, which is a symlink to nix, 1540 which is 1541 1542 -rwxr-xr-x 1 dan users 2.3M Apr 28 21:08 nix 1543 1544 (stripped). This is a lot bigger than, say, a simple script to 1545 loop through the closure of a derivation and copy only the store 1546 folders that don't exist already. 1547 1548 * we'd like to only transmit the packages that aren't already present 1549 1550 * we'd like to use a single ssh connection 1551 1552 1553 S: here is a list of package names 1554 C: these are the names of the packages I want 1555 S: here are the packages 1556 1557 while read $f ; do 1558 test -d $f || echo $f 1559 end 1560 1561 Tue May 2 21:53:08 BST 2023 1562 1563 1) we have a script that runs on the receiver, which 1564 1565 - accepts a list of store paths 1566 - prints the missing store paths 1567 - runs cpio -i < stdio 1568 1569 2) we need a script for the sender that 1570 1571 - refs=$(nix-store -q --references $1 && echo end) 1572 - opens ssh connection 1573 - print ssh $refs 1574 - needed= capture result until "end" received 1575 - find needed | cpio -o > ssh-connection 1576 - close connection 1577 1578 3) to have a reasonable hope of testing this we should do it with qemu. It would be nice 1579 if we could connect without faff to the qemu lan interface : either we do this by bringing up 1580 another qemu vm (preferably with the host store shared, otherwise it has to build a mips cross 1581 compiler/libc) or maybe we could do something unholy with ssh ProxyCommand 1582 1583 ssh -o ProxyCommand "socat - UDP4-DATAGRAM:230.0.0.1:1234,sourceport=1234,reuseaddr,ip-add-membership=230.0.0.1:127.0.0.1" 1584 1585 1586 1587 4) we haven't solved garbage collection, though I think "remove everything not in 1588 nix-path-registration" might be what's needed there 1589 1590 Wed May 3 22:01:19 BST 2023 1591 1592 Something weird is going on with qemu net device enumeration: when I 1593 run it interactively I'm getting the access network (mac ending :02) 1594 on eth0 and the lan (mac ending :01) on eth1, and if it's behaving the 1595 same in CI then how come any of the tests work? vanilla-confinguration.nix 1596 definitely assumes lan=eth0 1597 1598 By switching from -device virtio-net-pci to -device virtio-net then 1599 I get the desired behaviour back 1600 1601 Sat May 6 18:42:28 BST 2023 1602 1603 Next: 1604 1605 - package min-copy-closure 1606 - see if we can use it on some output to copy the whole system closure 1607 - post-copying symlink munging 1608 - try it on a real device, see if it works for config file updates 1609 - collect-garbage/delete-old-generation 1610 1611 1612 Sun May 7 23:03:03 BST 2023 1613 1614 Shortly after all the work to reduce system closure size last time, I 1615 tried adding the necessary packages to support nix-copy-closure and 1616 saw it start building a complete C++ system with Boost. My fears that 1617 this would lead to quite a large increase in the system size were, it 1618 turned out, entirely founded. 1619 1620 So I wrote my own - or at least, a quite minimal substitute. The core 1621 logic is simple - on the sender, we get the list of required packages, 1622 then we check for the existence of `/nix/store/eeeeeee-foo` for 1623 each of them on the target, and whatever's missing we send across the 1624 link using cpio. 1625 1626 It sounds simple, and it should be simple, and in retrospect it _was_ 1627 simple. Along the way I went on a bit of a Qemu networking tangent and 1628 learned quite a lot about the bash `coproc` command 1629 1630 Tue May 9 21:06:53 BST 2023 1631 1632 General direction of my thoughts: 1633 1634 - get a baseline working rotuer system 1635 - prove that min-copy-closure works with it 1636 - refactor the crap out of it 1637 - configurablise the bordervm usb ethernet setup 1638 - when we have a good idea of how/whether min-copy-closure *actually* 1639 works, declare "writeable filesystem" to be done 1640 - start to get more of a feel for how the services/config hang together 1641 1642 ? why does rotuer not have a hostname? 1643 1644 ? how can we get a device hooked up to rotuer's lan port that we can 1645 control remotely 1646 1647 Sun May 14 23:25:46 BST 2023 1648 1649 the outputs.systemConfiguration attribute builds a derivation 1650 containing a single file bin/activate 1651 1652 _Presumably_, copying its closure will copy all the things, as 1653 we already use it as the roots for jffs2 creation. However, there 1654 is also a symlink created from /init at jffs2 creation 1655 1656 Mon May 15 21:32:38 BST 2023 1657 1658 Had a neat idea about uing an overlayfs combining jffs2 and ramfs 1659 to do upgrades that would otherwise be larger than the flash. 1660 Could use "overlay merge" from https://github.com/kmxz/overlayfs-tools 1661 1662 Wed May 17 15:18:55 BST 2023 1663 1664 liminix-rebuild doesn't collect garbage (this is a mising feature, not 1665 a bug). We think we can fix this using nix-path-registration: specifically, 1666 by deleting anything not in it. 1667 1668 What we're going to do: build a fresh system image for rotuer, then 1669 dogfood liminix-rebuild until we've succeeded in getting it to 1670 change its hostname 1671 1672 Also wondering if we should drop outputs.default, but maybe not 1673 1674 * systemConfiguration: used for updates 1675 * vmroot: used for qemu 1676 * flashimage: used for flashing 1677 * tftproot: used for dev/test 1678 1679 As long as we're consistently setting the default output to whichever 1680 is the appropriate "full production image" I think we're good. 1681 1682 Wed May 17 22:45:40 BST 2023 1683 1684 Random thought: when we bind mount /target/persist/nix to /target/nix 1685 we could make it read-only. worth doing? 1686 1687 Thu May 18 10:59:39 BST 2023 1688 1689 - liminix-rebuild can't find reboot: probably the PATH is just 1690 generally wrong for ssh sessions (maybe all non-login sessions?) 1691 1692 - need to copy path registration file somewhere useful and 1693 delete stuff not in it at the appropriate time. Would be safest 1694 to do that either late in the shutdown process before rebooting, 1695 or during boot. 1696 1697 Fri May 19 15:18:13 BST 2023 1698 1699 If we make min-collect-garbage - just a command you can run whenever - 1700 that will be fine for current capabilities. It won't work with the 1701 theoretical overlayfs system, though: we need to copy-down from the 1702 ramfs to real flash before rebooting, and that can't happen until 1703 there's disk space to do it 1704 1705 Sat May 20 22:35:25 BST 2023 1706 1707 We have a working min-collect-garbage (seems to, anyway ...) 1708 1709 - having ssh host key wiped on reboot is sucky. maybe we can have 1710 /persist/secrets and a service that looks there? 1711 1712 - find out what files ash sources on non-login shell startup 1713 [ set ENV=/etc/ashrc in parent process env ] 1714 1715 - services.default is suboptimal as there is no way to add to it 1716 without wiping it 1717 1718 - decide whether to use liminix- or min- as our prefix for nixy 1719 commands 1720 1721 - should we move config.outputs -> config.system.outputs ? see Mar 28 1722 1723 - less crap firewall 1724 1725 - add ipv6 support to rotuer 1726 1727 - create an l2tp configuration 1728 1729 - iperf and tuning 1730 1731 - wlan country code 1732 1733 1734 dropbear weak hashes? https://github.com/mkj/dropbear/issues/138 1735 1736 Sun May 21 11:48:07 BST 2023 1737 1738 dropbear will generate host keys on first connection. It's (probably) good that the 1739 key is generated on-device and also that we wait until there's some randomness. 1740 It's not so good that it will only write the key to DSS_PRIV_FILENAME which is 1741 hardcoded to /run 1742 1743 Sun May 21 17:27:31 BST 2023 1744 1745 What do we need for ipv6? 1746 1747 - upgrade ppp to something with an ipv6-up-script option, move ppp and pppoe derivations into their own files 1748 - get ipv6 address from pppoe 1749 - get ipv6 delegation from DHCPv6 1750 - support dhcp6 in dnsmasq, and advertise prefix on lan 1751 - firewall settings 1752 1753 Sun May 21 21:30:17 BST 2023 1754 1755 Making hydra build the docs is straightforward, but making it 1756 _publish_ the docs is outside scope, really. It can serve the files 1757 but they're all text/plain 1758 1759 Should hydra push the docs to www.liminix.org or should www.liminix.org 1760 pull? 1761 1762 TODO-at-some-point: assign uids and gids dynamically, somehow 1763 1764 Tue May 23 22:56:33 BST 2023 1765 1766 following the guidance at https://support.aa.net.uk/IPv6: 1767 1768 we run odhcp6c to do router solicitation/advertisement dance 1769 1770 1771 odhcp6c environment variables: 1772 1773 RA_ADDRESSES= 1774 RA_REACHABLE=0 1775 CER= 1776 PASSTHRU=00170020200108b0000000000000000000002020200108b0000000000000000000002021 1777 SERVER=fe80::203:97ff:fed6:0 1778 RA_MTU=0 1779 RA_ROUTES=::/0,fe80::203:97ff:fed6:0,65535,512 1780 OPTION_1=00030001e4956e4ef2fa 1781 NTP_FQDN= 1782 OPTION_2=00030001000397d60000 1783 RA_DOMAINS= 1784 DOMAINS= 1785 AFTR= 1786 SIP_IP= 1787 NTP_IP= 1788 PREFIXES=2001:8b0:de3a:40dc::/64,7198,7198 1789 RA_HOPLIMIT=64 1790 RA_DNS= 1791 RDNSS=2001:8b0::2020 2001:8b0::2021 1792 SNTP_IP= 1793 RA_RETRANSMIT=0 1794 SIP_DOMAIN= 1795 ADDRESSES=2001:8b0:1111:1111:0:ffff:51bb:4cf2/128,3598,7198 1796 1797 # ip -6 route |grep default 1798 default via fe80::203:97ff:fed6:0 dev ppp0 metric 1024 expires 65211sec 1799 1800 presumably from RA_ROUTES but why is the metric appaently doubled? 1801 1802 Tue May 30 21:25:37 BST 2023 1803 1804 We have an odhcpc script that preserves the prefix delegation from the 1805 ISP. We need a service that notices whenever the state is 1806 available/has changed, and updates the LAN IPv6 address. 1807 1808 The service can depend on odhcp 1809 1810 add inotify to packages 1811 use writeFennelScript with that dep 1812 see if it works 1813 1814 Wed May 31 23:33:00 BST 2023 1815 1816 We have a thing that sets ipv6 address on lan interface, yay us 1817 1818 A firewall would be a very good idea 1819 1820 Thu Jun 1 18:46:59 BST 2023 1821 1822 TODO for now: 1823 1824 - services.default is suboptimal as there is no way to add to it 1825 without wiping it 1826 1827 - decide whether to use liminix- or min- as our prefix for nixy 1828 commands 1829 1830 - should we move config.outputs -> config.system.outputs ? see Mar 28 1831 1832 - less crap firewall 1833 1834 - create an l2tp configuration 1835 1836 - iperf and tuning 1837 1838 - wlan country code 1839 1840 Thu Jun 1 21:26:37 BST 2023 1841 1842 how can a client machine "opt out" of using the firewall, to allow 1843 incoming connections? Most convenient would be to have a separate SSID 1844 for grownups. Assuming it shows up as a separate wlan device, we can 1845 write firewall rules to allow incoming connections on that interface 1846 (can we? only if the packet is identifiable as destined for that interface) 1847 1848 https://www.rfc-editor.org/rfc/rfc6092.html 1849 https://emailstuff.org/rfc/rfc7084 1850 1851 We could block incoming for slaac and dhcp addresses and permit it for 1852 stable private addresses. If we were fairly sure that devices won't 1853 ask for stable private addresses just for funsies. 1854 1855 https://wiki.archlinux.org/title/IPv6_#Stable_private_addresses 1856 1857 1858 1859 Fri Jun 2 14:42:43 BST 2023 1860 1861 I found a handy guide to nftables at https://ww.telent.net/2023/6/2/turning_the_nftables 1862 1863 Mon Jun 5 16:56:44 BST 2023 1864 1865 1866 How are we going to do this firewall thing then? 1867 I can see no reason to have more than one table per family, so lets 1868 just name the tables after families 1869 1870 There is nothing in nftables for functionally grouping rules by 1871 requirement that may touch multiple hooks/chains, so we need our own 1872 abstraction - and we can't call it any name that nftables uses already 1873 (so, not "ruleset"). rulegroup? 1874 1875 "policy" would be a good name except that it's already taken 1876 1877 "concern"? "requirement"? "feature"? 1878 1879 Mon Jun 19 20:45:48 BST 2023 1880 1881 why is chrony using libedit? 1882 1883 Thu Jun 22 09:52:57 BST 2023 1884 1885 - There is a lot more lua being installed (luac, docs, static 1886 libraries etc) than we really need. 1887 1888 - update User docs to include a list of supported targets 1889 1890 Thu Jun 22 23:43:06 BST 2023 1891 1892 - is there a sysfs to enable ipv6 forwarding? 1893 - we haven't an ipv4 firewall yet 1894 1895 1896 PATH=`echo /nix/store/*nftables*/bin`:$PATH 1897 nft list ruleset 1898 1899 Thu Jun 22 23:58:58 BST 2023 1900 1901 Looks like we're missing at least one kernel config setting for 1902 nftables. Would this be a good time to do a derivation for building 1903 kernel modules? 1904 1905 1906 Sun Jul 9 21:21:17 BST 2023 1907 1908 1909 Tue Jul 11 22:10:17 BST 2023 1910 1911 - s6 cheatsheet, find or write 1912 - could we have > 1 module add to services.default? 1913 - odhcp should parse values from environ and write more files, to save readers 1914 from parsing it 1915 - pkgs.liminix, who knows what thats for any more? 1916 - interface.device, as a general rule, doesn't work because the 1917 device name may be known only at runtime (e.g. for ppp) 1918 - iperf 1919 - figure out wifi regdomain 1920 1921 Tue Jul 11 23:01:59 BST 2023 1922 1923 We can make services depend on kernel modules, however not on bakedin 1924 kernel config 1925 1926 [from March: "Let's think about services and modules."] 1927 1928 Module 1929 + can change global config 1930 * add users, groups etc 1931 * change kernel config 1932 * change busybox config 1933 + well-typed parameters 1934 - is a "singleton": can't have the same module included twice 1935 with different config. e.g. can't have two hostap modules running on 1936 different wlan radios. 1937 - can't express dependencies: a depends on b 1938 1939 thought I had then was: modules provide services. requiring the 1940 ppp module causes config.services.ppp to exist, so you can 1941 1942 services.default = [ 1943 (config.services.ppp { 1944 tty = "17"; 1945 baud = "57600"; 1946 secrets = blah; 1947 }) 1948 ... 1949 ] 1950 1951 this might work. also though we should find out how to do type checking on 1952 service params 1953 1954 Wed Jul 12 23:23:02 BST 2023 1955 1956 https://github.com/NixOS/mobile-nixos/pull/406 // why mobile nixos uses 1957 mobile.outputs instead of system.build 1958 1959 suggests that system.build may not be a thing to blindly emulate 1960 1961 if a service is a derivation should we expect to want to be able to call 1962 it with .override? maybe we want to override the package containing the 1963 daemon it runs. How do we best pass service config as well? 1964 1965 Maybe a service template is a function that returns a derivation 1966 1967 1968 imports = [ ./modules/pqmud.nix ]; 1969 services.mud = system.services.pqmud { 1970 realm = "A deep cavern"; 1971 port = 4067; 1972 users = import ./allowed-users.nix; 1973 # etc etc 1974 }; 1975 services.mudBeta = let mud = 1976 system.services.pqmud { 1977 realm = "A very deep cavern"; 1978 port = 4068; 1979 users = import ./allowed-users.nix; 1980 }; 1981 in mud.overrideAttrs { pqmud = pkgs.pkmudLatest; }; 1982 1983 so we have 1984 1985 config.system.services # services provided by modules 1986 config.system.outputs # build artefacts of various types 1987 1988 the services provided by a module must be introspectable in some way 1989 so that we can compile a list of service options per module 1990 1991 service parameters are defined using the module type system. 1992 Something like this? 1993 1994 # mud.nix 1995 1996 system.services.pqmud = args : 1997 let t = { 1998 name = mkOption { type = types.str; }; 1999 realm = mkOption { type = types.str; }; 2000 port = mkOption { type = types.port; default = 12345; }; 2001 users = mkOption { type = types.any; }; 2002 }; 2003 in assert isType (submodule { options = t; }) args; longrun { 2004 inherit (args) name; 2005 run = "${pkgs.pqmud}/bin/pqmud --port ${port} ....." 2006 }; 2007 2008 Fri Jul 14 19:07:59 BST 2023 2009 2010 It works for pppoe, though typechecking error messages could be 2011 better. 2012 2013 - We need to find a good place to keep the typeCheck function so that 2014 everyone can use it. 2015 2016 - also the type_service type defn exists only locally in modules.nix, 2017 and we would like to refer to it elsewhere