NetBSD Raspberry PI

Fun installing NetBSD 9.0 on a Raspberry Pi B+

Published · 8min

One of the consequences of being on a lockdown is that you find time to do things you’ve been putting off for a while. One of mine is setting up a small bastion server on my home network. Having already set up dynamic DNS with Duck DNS, I found one of my old Raspberry Pis when I was digging through some unopened boxes from when I’d last moved. I spent an inordinate amount of time getting an OS onto it after spending far too long believing that it was a RPi 2 B rather than the original B+ it actually was. Unfortunately the Pibow case it’s in obscured that particular bit of information.

Still, I managed to get NetBSD 9.0 up and running on it after going through my cache of micro SD cards to find a healthy one and following the sometimes obtuse “NetBSD/evbarm on Raspberry Pi” page, I got it booting. The initial experience was slightly better. I recall when I first used NetBSD on a MiniITX box about a decade ago that I had to do some weird USB-related device wrangling, but everything just worked. Well, almost: the USB WiFi dongle in the RPi was recognised but couldn’t scan for networks successfully, so had to drop back to wired access. Not the end of the world, mind.

I set up a user:

# useradd -m -G wheel keith
# passwd keith

Ensured multicast DNS would work on the next reboot:

# echo "mdnsd=YES" >> /etc/rc.conf

And edited /etc/ssh/sshd_config to allow password-based login.

This is when the actual fun began.

I shut down the RPi (with shutdown -p now), wired it up, waited a while, and ssh’d in successfully. The nice thing about enabling mdnsd is that I could just type ssh rpi.local, and it just worked. I pinged a few IPs to make sure everything worked, and everything looked good, so I figured it was time to make sure the basics were present.

I tried typing pkgin, with no luck. I recalled that NetBSD still has pkg_add, so switched to root with su and ran pkg_add pkgin. Here’s what happened:

# pkg_add pkgin
pkg_add: no pkg found for 'pkgin', sorry.
pkg_add: 1 package addition failed
# export PKG_PATH="https://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/earmv6hf/9.0/All/"
# pkg_add -v pkgin
PGPV_BN_cmp failed
1623256064:error:14199077:SSL routines:tls_construct_cke_rsa:bad rsa encrypt:/usr/src/crypto/external/bsd/openssl/dist/ssl/statem/statem_clnt.c:3019:
pkg_add: Can't process https://ftp.netbsd.org:443/pub/pkgsrc/packages/NetBSD/earmv6hf/9.0/All//pkgin*: Authentication error
pkg_add: no pkg found for 'pkgin', sorry.
pkg_add: 1 package addition failed

After some flailing around, I gave up on expecting pkg_add to be network aware, so resorted to downloading packages and installing them (I’m omitting a lot here):

# ftp https://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/earmv6hf/9.0/All/pkgin-0.14.0.tgz
# ftp https://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/earmv6hf/9.0/All/pkg_install-20191008.tgz
# pkg_add pkg_install-20191008.tgz
# pkg_add pkgin-0.14.0.tgz

Progress! So, let’s download the repo database:

# pkgin update
reading local summary...
processing local summary...
processing remote summary (https://cdn.netbsd.org/pub/pkgsrc/packages/NetBSD/evbarm/9.0/All)...
pkg_summary.gz                                                      0%    0     0.0KB/s   --:-- ETA
/!\ Warning /!\ earm doesn't match your current architecture (earmv6hf)
You probably want to modify /usr/pkg/etc/pkgin/repositories.conf.
Still want to proceed ? [y/N] y
pkg_summary.gz                                                    100%  738KB  22.4KB/s   00:33

Eh… OK. Did I choose the wrong image? Why is this somehow working?!

I need Python so I can later pave the machine properly with Ansible, so:

# pkgin install python37
calculating dependencies...done.

3 packages to install:
  libuuid-2.32.1 libffi-3.2.1nb4 python37-3.7.5

0 to refresh, 0 to upgrade, 3 to install
25M to download, 89M to install

proceed ? [Y/n] y
libuuid-2.32.1.tgz                                                100%   39KB  39.1KB/s   00:00
libffi-3.2.1nb4.tgz                                               100%   32KB  32.2KB/s   00:00
python37-3.7.5.tgz                                                100%   25MB 941.1KB/s   00:27
installing libuuid-2.32.1...
installing libffi-3.2.1nb4...
installing python37-3.7.5...
pkg_install warnings: 3, errors: 3
pkg_install error log can be found in /var/db/pkgin/pkg_install-err.log

# cat /var/db/pkgin/pkg_install-err.log
---May 07 04:45:17: installing libuuid-2.32.1...
pkg_add: Warning: package `libuuid-2.32.1' was built for a platform:
pkg_add: NetBSD/earm 9.0 (pkg) vs. NetBSD/earmv6hf 9.0 (this host)
pkg_add: 1 package addition failed
---May 07 04:45:17: installing libffi-3.2.1nb4...
pkg_add: Warning: package `libffi-3.2.1nb4' was built for a platform:
pkg_add: NetBSD/earm 9.0 (pkg) vs. NetBSD/earmv6hf 9.0 (this host)
pkg_add: 1 package addition failed
---May 07 04:45:17: installing python37-3.7.5...
pkg_add: Warning: package `python37-3.7.5' was built for a platform:
pkg_add: NetBSD/earm 9.0 (pkg) vs. NetBSD/earmv6hf 9.0 (this host)
pkg_add: 1 package addition failed

Well, how about that. What struck me as particularly odd about it was this line:

pkg_add: NetBSD/earm 9.0 (pkg) vs. NetBSD/earmv6hf 9.0 (this host)

Just… why?! If pkgin can look up the correct ABI, why does $host in its configuration translate to the wrong thing?!

I edited /usr/pkg/etc/pkgin/repositories.conf to replace $arch with earmv6hf, and tried again. This time, I was successful. And so it became time to tackle that one annoying part of every RPi: the (understandable) lack of a battery-backed clock:

# service ntpd stop
Stopping ntpd.
# ntpd -gq
14 Feb 10:03:17 ntpd[790]: ntpd 4.2.8p11-o Sat Sep 29 17:04:56 EDT 2018 (import): Starting
14 Feb 10:03:17 ntpd[790]: Command line: ntpd -gq
14 Feb 10:03:17 ntpd[790]: proto: precision = 4.000 usec (-18)
14 Feb 10:03:17 ntpd[790]: Listen and drop on 0 v6wildcard [::]:123
14 Feb 10:03:17 ntpd[790]: Listen and drop on 1 v4wildcard 0.0.0.0:123
14 Feb 10:03:17 ntpd[790]: Listen normally on 2 usmsc0 [fe80::2dfe:ee49:d966:6c2c%1]:123
14 Feb 10:03:17 ntpd[790]: Listen normally on 3 usmsc0 192.168.1.75:123
14 Feb 10:03:17 ntpd[790]: Listen normally on 4 lo0 127.0.0.1:123
14 Feb 10:03:17 ntpd[790]: Listen normally on 5 lo0 [::1]:123
14 Feb 10:03:17 ntpd[790]: Listen normally on 6 lo0 [fe80::1%2]:123
14 Feb 10:03:17 ntpd[790]: Listening on routing socket on fd #27 for interface updates

 7 May 04:26:57 ntpd[790]: ntpd: time set +7151010.203254 s
ntpd: time set +7151010.203254s
# service ntpd start
Starting ntpd.

It’s all working now, until I next reboot at least.

It’d be really good if NetBSD produced a smaller ‘headless’ image that lacked X11, as that would knock a significant chunk off the image, and if pkgin could bootstrap itself like FreeBSD’s pkgng. Some day, maybe. I’d settle for pkg_add in base having properly functioning TLS support though.

Next up: using BIND 9, dhcpd, and bozohttpd to effectively build a Pi-hole, and configure blacklistd to protect it from the big wide world.

Addendum

I ran into some issues with the authorized_key Ansible module. The solution was this:

# pkgin install mozilla-rootcerts-openssl

It’d be interesting if downloading and installing this first would’ve fixed pkg_adds issues installing pkgin in the first place.

Addendum 2 (2021-08-08)

I decided to decommission the Raspberry Pi on Friday. I hadn’t had time to do much on the project, and some months ago, it’d become uncommunicative to SSH traffic. What I discovered when I hooked a keyboard and monitor to it was a bit odd. It was as if somebody had ran sysinst on it again, wiping out the non-root users and restoring the contents of /etc to its pristine form. I still don’t know what happened. Either NetBSD commits seppuku if you don’t pay it enough attention, or somebody managed to get onto the RPi and teach me a lesson. Neither are pleasant thoughts.

Regardless, I don’t think there’s much sense in keeping it running. If I were to go back now, there are some things I’d do differently, such as disabling swap (which probably isn’t something anything) with no_swap=YES, disabling codedumps with savecore=NO (not that this ever cropped up, but still…), preventing vi from creating recovery files with virecover=NO, configuring syslog to forward its logs elsewhere, and no doubt other things too. Another idea might be to move /var/run to tmpfs, and add it to critical_filesystems_local, though I’m not sure of what the effect would be: I would hope anything under /var/run would be treated as ephemeral between reboots, and double-check that /tmp uses tmpfs too, which would allow clear_tmp=NO, as clearing it would be unnecessary. From this page, it seems like using the union flag with tmpfs preserves the underlying filesystem structure, so that might help with /var/run and others at least. Setting nodevmtime on / in addition to noatime, which I did have set would probably be wise.

I may revisit things after I inspect the SD card I had in the Pi, if only to see if I can do a better job next time around.