diary at Telent Netowrks

Solder but no wiser#

Wed, 13 Jun 2018 07:17:21 +0000

Everyone should have at least one hobby that they're no good at and/or dislike doing.

For me that was once playing guitar (still have the instrument, no longer have the calluses) but these days it's soldering. So after having stuck three short pieces of paperclip into adjacent holes inside my Trendnet TEW712BR and showered them with blobs of molten tin, I was as surprised as anybody when I plugged my USB TTL serial converter in and found I had a root console.

Notes for others who may follow this way:

It turns out I'm slightly ahead of myself in doing this right now, because although I have an image for Milestone 1 that runs on an Arduino Yun, it's too big - there is only 4MB flash in this little box. Still, at least I am able to capture a boot log and find out its partition scheme and kernel load address.

Yes, I have working wifi, and the use case for "WiFi access point/range extender" (WiFi in AP mode via hostapd, bridged to Ethernet, and a DHCP client). This entailed

Mostly fairly straightforward stuff so far - or at least, at a remove of anything up to two weeks since I did some of this work, I've forgotten whatever problems I ran into. It's all in wap.nix , which still copies a bit too much code from backuphost.nix but that will change as soon as I can get my head around fixpoints. To get it to fit into flash on the device I'm going to need a smaller kernel and perhaps a smaller busybox.

Post title goes here#

Thu, 31 May 2018 23:54:36 +0000

It's taken more than a little while to get NixWRT back into the brain again, partly due to needing a change and partly due to work/family stuff. Currently in progress: breaking the backuphost.nix monolith into composable modules, such that I (or a user, when in the fulness of time the project acquires any users) can add the various parts separately.

This was prompted by a question on the NixOS Discourse site - and the current status, which is experimental, is that a module is a function which gets some options and a pointer to nixpkgs, then operates on the big configuration attrset and returns an augmented version of it. That's handwaving, so let me show you bits of it: in modules/default.nix we have for example

  syslogd = options: nixpkgs: configuration:
    with nixpkgs;
    lib.attrsets.recursiveUpdate configuration {
      services.syslogd = {
        start = "/bin/syslogd -R ${options.loghost}";
        depends = ["eth0.2"];
      };
    };

and then in backuphost.nix we have

let modules = (import ./nixwrt/modules/default.nix);
    # ...
    wantedModules = with modules; [
      (rsyncd { password = rsyncPassword; })
      sshd
      (syslogd { loghost = "192.168.0.2"; })
      (ntpd { host = "pool.ntp.org"; })
      (dhcpClient { interface = "eth0.2"; inherit busybox; })
    ];
    configuration = lib.foldl (c: m: m nixpkgs c) baseConfiguration wantedModules;

This differs from the NixOS module system because we pass per-module config to the module itself instead of having it root around in one big configuration attrset. (In theory this means we could have two modules with the same name but differently customised, which might be useful). But it's also dependent on the order that the module functions are applied in, which makes me feel it would be nice to do some kind of fixpoint thing the way that overlays do. Or at least to find some nice way to have modules add their configuration to busybox and for them to be able to refer to busybox and for it to be the same busybox derivation used by all modules. The same consideration may very well apply to the kernel.

Anyway, it may be that I need to spend a bit more time on this before I understand why NixOS modules do it differently and I should switch to their approach, or it may be that my requirements are not those of NixOS.

In other news I have bought a proper USB TTL serial cable, so next time I crack open a new piece of router hardware I can plug it straight into a USB port on my desktop system instead of needing a Raspberry Pi as an sshable serial console. The next target is a TrendNET 712BR and I may have to think a bit about how to develop on it because unlike the MT300A or even the Yun it doesn't have an awful lot of spare RAM. Will have to think of something after I've found out how lobotomised its u-boot is or isn't.

With a brand new adventure#

Fri, 25 May 2018 13:13:29 +0000

There has been no nixwrt update this week because no nixwrt changes this week. I've done a little bit of refactoring though nothing really worth writing about - mostly I've been treating the last week or two as a nixbreak.

Instead I've been learning some cryptography and some Haskell, by means of trying to write programs that do one, using the other. Specifically, the Cryptopals challenges . Lessons:

Give me docs or give me death, I am undecided which

I have not yet reached the point of "I have type signatures, why do I need docs?". I need docs, preferably with examples. Crypto libraries, I am looking at you specifically here.

In the interests of being vaguely constructive in this criticism, here is what you do to get AES128-ECB decryption with whatever the default crypto that ships with GHC 8.2.2 is.

(Note that, as far as I understand it, there is no reason ever to use ECB mode except in educational examples which will demonstrate to you just how awful a choice it is)

import qualified Crypto.Cipher.AES as AES

decode' keytext payload = let key = AES.initAES keytext in AES.decryptECB key payload

It accepts ByteString arguments. There are probably good ways to get ByteStrings that I haven't found yet, but if you start with an ordinary string you could try

toByteString text = BS.pack (map (\c -> fromIntegral (ord c)) text)

"Yippee, strings!" said Teal

See above. There seem to be an awful lot of incompatible ways to represent "sequences of small integers that map onto ASCII characters" in Haskell. At the moment I'm using arrays of Word8 as my "primary" represnetation and converting to and from other formats when I need to do so to call library functions and stuff.

"Stop, collaborate and listen"

They're not messing about when they say "an appreciation for early-90's MTV hip-hop can't hurt either". A lot of the examples are a bit ... Vanilla?

I have implemented a plausible AES-CBC mode (using ECB as a building block), currently working on challenge 11.

Back to Nix next week

Back up to the start#

Sat, 12 May 2018 23:12:04 +0000

My backup server runs! Since last week I plugged in my actual USB external drive and added a DHCP client, USB support, ext[234]fs and a few more useful busybox apps - cp, chmod, chown, that kind of thing. Now it's running and my home desktop is backing up to it four times a day.

Because the Nix store is world-readable, I didn't want to put passwords in it - so instead I chuck them in files elsewhere and read them at script exection time. To get duplicity running in NixOS I added this stuff to my configuration.nix

 services.cron.systemCronJobs = let script = pkgs.writeScript "run-duplicity" ''
    #!${pkgs.bash}/bin/bash
    export PASSPHRASE=$(cat /var/lib/backupwrt/duplicity) 
    export RSYNC_PASSWORD=$(cat /var/lib/backupwrt/rsync) 
    ${pkgs.duplicity}/bin/duplicity / --include /home --include /etc --include /srv --exclude '**' rsync://backup@snapshto::srv/snapshots/loaclhost
''; in [
      "18 */4 * * * root ${script}"
    ];

This blog entry is super-short because after writing a much longer one I extracted all the interesting bits and turned them into an FAQ document in the Git repo. So go and read that now.

Wrt up#

Tue, 08 May 2018 21:02:54 +0000

Since "last week": I have

What's left for Milestone 0? Nothing really, apart from cleanup. There is a shockingly large amount of "arbitrary" involved in deciding what goes in which nix file, and there really ought to be some kind of principled separation of what/where/how (what the app does, the specifics of the hardware where it runs, and the implementation details), and there are other cleanups to do too. Also need to do something like overlays so that the packages defined in nixwrt override the ones in nixpkgs. Also also need to update it to work with nixpkgs master - or at least with 18.03 without my random patches. Also also also add e2fsutils so we don't have to plug the USB disk in somewhere else just to fsck it.

In other news, if you can read this then you are looking at my new shell host and the DNS for ww.telent.net has updated. Still haven't moved everything off the old one, but this is just one more step (and a large one) along the way.