Creating a quick DNS server with a Rapsberry Pi2 and FreeBSD 11.0-RC1

Raspberry Pi 2 and FreeBSD 11 and bind 9.9 for a name server

Just thought I'd outline the steps to bring a Raspberry Pi 2 up with FreeBSD and then create a DNS server with bind. This is for the Raspberry Pi2, but the only difference between this and any other supported board is the file you grab.

The TL;DR version

Download the image, use xz to decompress and dd to a SD card. Boot the SD card with a serial console, create a new account to log into. Install the appropriate packages. Configure named. Tell the world about it (router and registrar). Profit! All quite simple, though there were a few snags that are in the 'Long Version'

Long Version, so much detail

First, download the FreeBSD image from https://www.freebsd.org/where.html. I'm doing the SD Card Image for FreeBSD 11.0-RC1. This gave me the file FreeBSD-11.0-RC1-arm-armv6-RPI2.img.xz in my downloads area. If you're doing a different image, adjust below.

Next, I needed to create a microSD card for the RPi-2. I plugged a 4GB SD Card into my USB adapter, and the device appeared as da2 on my FreeBSD box.
 xz -d < ~/FreeBSD-11.0-RC1-arm-armv6-RPI2.img.xz | sudo dd of=/dev/da2 bs=1m
will uncompress it and splat it onto the SD card.

Next, I connected to my RPi2's serial port with tip and the Adafruit USB to TTY Adapter:
tip -115200 ucom1
When booting, I got this log. Yours might not be identical, but the login: at the end should be the same.

U-Boot 2015.04 (Aug 12 2016 - 16:50:57)

DRAM:  944 MiB
WARNING: Caches not enabled
RPI 2 Model B
MMC:   bcm2835_sdhci: 0
reading uboot.env

** Unable to read "uboot.env" from mmc0:1 **
Using default environment

In:    serial
Out:   lcd
Err:   lcd
Net:   Net Initialization Skipped
No ethernet found.
Hit any key to stop autoboot:  0 
Booting from: mmc 0 ubldr
reading ubldr
272013 bytes read in 213 ms (1.2 MiB/s)
## Starting application at 0x02000098 ...
Consoles: U-Boot console  
Compatible U-Boot API signature found @0x3ab4a4c8

FreeBSD/armv6 U-Boot loader, Revision 1.2
(root@releng2.nyi.freebsd.org, Fri Aug 12 17:05:59 UTC 2016)

Number of U-Boot devices: 1
U-Boot env: loaderdev='mmc 0'
Found U-Boot device: disk
  Checking unit=0 slice= partition=... good.
Booting from disk0s2a:
/boot/kernel/kernel data=0x72a864+0x17979c syms=[0x4+0x7e120+0x4+0x90fad]

Hit [Enter] to boot immediately, or any other key for command prompt.
Booting [/boot/kernel/kernel]...               
Using DTB provided by U-Boot at address 0x100.
Kernel entry at 0x0x2200100...
Kernel args: (null)
Copyright (c) 1992-2016 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 11.0-RC1 #0 r303979: Fri Aug 12 17:12:13 UTC 2016
    root@releng2.nyi.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI2 arm
FreeBSD clang version 3.8.0 (tags/RELEASE_380/final 262564) (based on LLVM 3.8.0)
VT: init without driver.
CPU: Cortex A7 rev 5 (Cortex-A core)
 Supported features: ARM_ISA THUMB2 JAZELLE THUMBEE ARMv4 Security_Ext
 WB enabled LABT branch prediction disabled
LoUU:2 LoC:3 LoUIS:2 
Cache level 1: 
 32KB/64B 4-way data cache WB Read-Alloc Write-Alloc
 32KB/32B 2-way instruction cache Read-Alloc
Cache level 2: 
 512KB/64B 8-way unified cache WB Read-Alloc Write-Alloc
real memory  = 989851648 (943 MB)
avail memory = 956411904 (912 MB)
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
random: entropy device external interface
kbd0 at kbdmux0
simplebus0: mem 0x3f000000-0x3fffffff on ofwbus0
local_intc0: mem 0x40000000-0x400000ff on simplebus0
generic_timer0: on ofwbus0
Timecounter "ARM MPCore Timecounter" frequency 19200000 Hz quality 1000
Event timer "ARM MPCore Eventtimer" frequency 19200000 Hz quality 1000
intc0: mem 0xb200-0xb3ff on simplebus0
bcmwd0: mem 0x10001c-0x100027 on simplebus0
gpio0: mem 0x200000-0x2000af on simplebus0
gpio0: read-only pins: 46,48-53.
gpio0: reserved pins: 48-53.
gpiobus0: on gpio0
gpioled0: at pin 35 on gpiobus0
gpioled1: at pin 47 on gpiobus0
gpioc0: on gpio0
iichb0: mem 0x205000-0x20501f on simplebus0
iicbus0: on iichb0
iic0: on iicbus0
iichb1: mem 0x804000-0x80401f on simplebus0
iicbus1: on iichb1
iic1: on iicbus1
spi0: mem 0x204000-0x20401f on simplebus0
spibus0: on spi0
bcm_dma0: mem 0x7000-0x7fff,0xe05000-0xe05fff on simplebus0
mbox0: mem 0xb880-0xb8bf on simplebus0
sdhci_bcm0: mem 0x300000-0x3000ff on simplebus0
mmc0: on sdhci_bcm0
uart0: mem 0x201000-0x201fff on simplebus0
uart0: console (115200,n,8,1)
vchiq0: mem 0xb800-0xb84f on simplebus0
vchiq: local ver 8 (min 3), remote ver 8.
pcm0: on vchiq0
bcm283x_dwcotg0: mem 0x980000-0x99ffff on simplebus0
usbus0 on bcm283x_dwcotg0
cpulist0: on ofwbus0
cpu0: on cpulist0
bcm2835_cpufreq0: on cpu0
cpu1: on cpulist0
cpu2: on cpulist0
cpu3: on cpulist0
fb0: on ofwbus0
fbd0 on fb0
VT: initialize with new VT driver "fb".
fb0: 1824x984(1824x984@0,0) 24bpp
fb0: fbswap: 1, pitch 5472, base 0x3d359000, screen_size 5428224
Timecounters tick every 10.000 msec
usbus0: 480Mbps High Speed USB v2.0
ugen0.1: at usbus0
uhub0: on usbus0
mmcsd0: 4GB at mmc0 41.6MHz/4bit/65535-block
bcm2835_cpufreq0: ARM 600MHz, Core 250MHz, SDRAM 400MHz, Turbo OFF
Release APs
Trying to mount root from ufs:/dev/ufs/rootfs [rw]...
warning: no time-of-day clock registered, system time will not be set accurately
uhub0: 1 port with 1 removable, self powered
Growing root partition to fill device
GEOM_PART: mmcsd0s2 was automatically resized.
  Use `gpart commit mmcsd0s2` to save changes or `gpart undo mmcsd0s2` to revert them.
mmcsd0s2 resized
ugen0.2: at usbus0
uhub1: on usbus0
uhub1: MTT enabled
mmcsd0s2a resized
super-block backups (for fsck_ffs -b #) at:
 1994944, 2493632, 2992320, 3491008,uhub1: 5 ports with 4 removable, self powered
 3989696, 4488384, 4987072, 5485760,
 5984448, 6483136, 6981824, 7480512
ugen0.3: at usbus0
smsc0: on usbus0
smsc0: chip 0xec00, rev. 0002
miibus0: on smsc0
ukphy0: PHY 1 on miibus0
ukphy0:  none, 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
ue0: on smsc0
ue0: Ethernet address: b8:27:eb:xx:xx:xx
ugen0.4: at usbus0
ukbd0: on usbus0
kbd1 at ukbd0
/etc/rc: WARNING: hostid: unable to figure out a UUID from DMI data, generating a new one
Setting hostuuid: 3b610f45-60b0-11e6-85fc-b827eb30ec4b.
Setting hostid: 0xd150b3f7.
Starting file system checks:
/dev/ufs/rootfs: clean, 745130 free (266 frags, 93108 blocks, 0.0% fragmentation)
Mounting local filesystems:.
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
random: unblocking device.
Soft Float compatibility ldconfig path:
Setting hostname: rpi2.
Feeding entropy: .
smsc0: chip 0xec00, rev. 0002
ue0: link state changed to DOWN
ue0: link state changed to UP
Starting Network: lo0 ue0.
lo0: flags=8049 metric 0 mtu 16384
inet6 ::1 prefixlen 128 
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
inet netmask 0xff000000 
groups: lo 
nd6 options=21
ue0: flags=8843 metric 0 mtu 1500
ether b8:27:eb:30:ec:4b
media: Ethernet autoselect (100baseTX )
status: active
nd6 options=29
Starting devd.
Starting dhclient.
DHCPDISCOVER on ue0 to port 67 interval 3
DHCPREQUEST on ue0 to port 67
bound to -- renewal in 3600 seconds.
add host gateway lo0 fib 0: route already in table
add host ::1: gateway lo0 fib 0: route already in table
add net fe80::: gateway ::1
add net ff02::: gateway ::1
add net ::ffff: gateway ::1
add net :: gateway ::1
Generating host.conf.
Creating and/or trimming log files.
Starting syslogd.
Clearing /tmp (X related).
Updating motd:.
Mounting late filesystems:.
Configuring vt: blanktime.
Generating RSA host key.
2048 SHA256:FXp0GIg9YQO8QKDV4laoIrXLhUPcBQPaYeusHOnn4wI root@rpi2 (RSA)
Generating ECDSA host key.
256 SHA256:lYyCJFYZHx2W8slGyhe8CF6GIc8ejZZWcO4wTlRf/YI root@rpi2 (ECDSA)
Generating ED25519 host key.
256 SHA256:L2wqTBkNdGahTGswcpzG4ysvhU9uCPyjBtLGLczi6fI root@rpi2 (ED25519)
Performing sanity check on sshd configuration.
Starting sshd.
Starting cron.
Starting background file system checks in 60 seconds.
mount: /dev/ufs/rootfs: Device busy

Fri Aug 12 17:15:15 UTC 2
FreeBSD/arm (rpi2) (ttyu0)

login: root
Aug 12 17:15:19 rpi2 login: ROOT LOGIN (root) ON ttyu0
FreeBSD 11.0-RC1 (RPI2) #0 r303979: Fri Aug 12 17:12:13 UTC 2016

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

Edit /etc/motd to change this login announcement.
root@rpi2:~ # adduser
Username: imp
Full name: M Warner Losh
Uid (Leave empty for default): 1234
Login group [imp]: 
Login group is imp. Invite imp into other groups? []: wheel
Login class [default]: 
Shell (sh csh tcsh nologin) [sh]: tcsh
Home directory [/home/imp]: 
Home directory permissions (Leave empty for default): 
Use password-based authentication? [yes]: 
Use an empty password? (yes/no) [no]: 
Use a random password? (yes/no) [no]: 
Enter password: 
Enter password again: 
Lock out the account after creation? [no]: 
Username   : imp
Password   : *****
Full Name  : M Warner Losh
Uid        : 1234
Class      : 
Groups     : imp wheel
Home       : /home/imp
Home Mode  : 
Shell      : /bin/tcsh
Locked     : no
OK? (yes/no): yes
adduser: INFO: Successfully added (imp) to the user database.
Add another user? (yes/no): no
root@rpi2:~ # logout

FreeBSD/arm (rpi2) (ttyu0)

 So, now we have a remote login (or we could have used the default freebsd/freebsd user).

Next, we need to bootstrap the packages. In the RC1 release there's a snag. The quarterly release hasn't been created yet, so you have to override the location:
# env PACKAGESITE=pkg+http://pkg.FreeBSD.org/FreeBSD:11:armv6/latest pkg boostrap
The package management tool is not yet installed on your system.Do you want to fetch and install it now? [y/N]: yBootstrapping pkg from pkg+http://pkg.FreeBSD.org/FreeBSD:11:armv6/latest, please wait...Verifying signature with trusted certificate pkg.freebsd.org.2013102301... doneInstalling pkg-1.8.5_1...Extracting pkg-1.8.5_1: 100%
root@rpi2:/home/imp # 
Now, in the RC1 release, there's another snag, you have to change quarterly to latest in /etc/pkg/FreeBSD.conf. Once you do that, you can continue. Since this is a simple box, I'm just installing sudo, bind99 and emacs-nox11 on it. Don't need anything more than that.

root@rpi2:/home/imp # pkg install sudo bind99 emacs-nox11
Updating FreeBSD repository catalogue...Fetching meta.txz: 100%    944 B   0.9kB/s    00:01    Fetching packagesite.txz: 100%    5 MiB 525.0kB/s    00:09    Processing entries: 100%FreeBSD repository update completed. 21349 packages processed.The following 18 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:sudo: 1.8.17bind99: 9.9.9P1emacs-nox11: 24.5_3,3gettext-runtime: 0.2.4libxml2: 2.9.3libedit: 3.1.20150325_2,1idnkit: 1.0_5gnutls: 3.4.13nettle: 3.2gmp: 5.1.3_3ca_root_nss: 3.22.2libtasn1: 4.8trousers: 0.3.13tpm-emulator: 0.7.4_1p11-kit: 0.23.2libffi: 3.2.1libidn: 1.31
The process will require 179 MiB more space.48 MiB to be downloaded.
Proceed with this action? [y/N]: yFetching sudo-1.8.17.txz: 100%  835 KiB 427.4kB/s    00:02    Fetching bind99-9.9.9P1.txz: 100%    4 MiB 583.4kB/s    00:08    Fetching emacs-nox11-24.5_3,3.txz: 100%   36 MiB 574.9kB/s    01:06    Fetching gettext-runtime- 100%  142 KiB 145.5kB/s    00:01    Fetching indexinfo-0.2.4.txz: 100%    5 KiB   5.0kB/s    00:01    Fetching libxml2-2.9.3.txz: 100%  735 KiB 376.5kB/s    00:02    Fetching libedit-3.1.20150325_2,1.txz: 100%  107 KiB 110.1kB/s    00:01    Fetching idnkit-1.0_5.txz: 100%  182 KiB 185.9kB/s    00:01    Fetching gnutls-3.4.13.txz: 100%    2 MiB 501.4kB/s    00:04    Fetching nettle-3.2.txz: 100%    1 MiB 378.8kB/s    00:03    Fetching gmp-5.1.3_3.txz: 100%  390 KiB 399.5kB/s    00:01    Fetching ca_root_nss-3.22.2.txz: 100%  323 KiB 330.3kB/s    00:01    Fetching libtasn1-4.8.txz: 100%  584 KiB 298.9kB/s    00:02    Fetching trousers-0.3.13.txz: 100%  390 KiB 399.6kB/s    00:01    Fetching tpm-emulator-0.7.4_1.txz: 100%   18 KiB  18.0kB/s    00:01    Fetching p11-kit-0.23.2.txz: 100%  199 KiB 203.4kB/s    00:01    Fetching libffi-3.2.1.txz: 100%   33 KiB  33.4kB/s    00:01    Fetching libidn-1.31.txz: 100%  196 KiB 200.9kB/s    00:01    Checking integrity... done (0 conflicting)[1/18] Installing indexinfo-0.2.4...[1/18] Extracting indexinfo-0.2.4: 100%[2/18] Installing gmp-5.1.3_3...[2/18] Extracting gmp-5.1.3_3: 100%[3/18] Installing gettext-runtime-[3/18] Extracting gettext-runtime- 100%[4/18] Installing ca_root_nss-3.22.2...[4/18] Extracting ca_root_nss-3.22.2: 100%[5/18] Installing libtasn1-4.8...[5/18] Extracting libtasn1-4.8: 100%[6/18] Installing tpm-emulator-0.7.4_1...===> Creating groups.Creating group '_tss' with gid '601'.===> Creating usersCreating user '_tss' with uid '601'.[6/18] Extracting tpm-emulator-0.7.4_1: 100%[7/18] Installing libffi-3.2.1...[7/18] Extracting libffi-3.2.1: 100%[8/18] Installing nettle-3.2...[8/18] Extracting nettle-3.2: 100%[9/18] Installing trousers-0.3.13...===> Creating groups.Using existing group '_tss'.===> Creating usersUsing existing user '_tss'.[9/18] Extracting trousers-0.3.13: 100%[10/18] Installing p11-kit-0.23.2...[10/18] Extracting p11-kit-0.23.2: 100%[11/18] Installing libidn-1.31...[11/18] Extracting libidn-1.31: 100%[12/18] Installing libxml2-2.9.3...[12/18] Extracting libxml2-2.9.3: 100%[13/18] Installing libedit-3.1.20150325_2,1...[13/18] Extracting libedit-3.1.20150325_2,1: 100%[14/18] Installing idnkit-1.0_5...[14/18] Extracting idnkit-1.0_5: 100%[15/18] Installing gnutls-3.4.13...[15/18] Extracting gnutls-3.4.13: 100%[16/18] Installing sudo-1.8.17...[16/18] Extracting sudo-1.8.17: 100%[17/18] Installing bind99-9.9.9P1...[17/18] Extracting bind99-9.9.9P1: 100%[18/18] Installing emacs-nox11-24.5_3,3...[18/18] Extracting emacs-nox11-24.5_3,3: 100%Message from ca_root_nss-3.22.2:********************************* WARNING *********************************
FreeBSD does not, and can not warrant that the certification authoritieswhose certificates are included in this package have in any way beenaudited for trustworthiness or RFC 3647 compliance.
Assessment and verification of trust is the complete responsibility of thesystem administrator.
*********************************** NOTE **********************************
This package installs symlinks to support root certificates discovery bydefault for software that uses OpenSSL.
This enables SSL Certificate Verification by client software without manualintervention.
If you prefer to do this manually, replace the following symlinks witheither an empty file or your site-local certificate bundle.
  * /etc/ssl/cert.pem  * /usr/local/etc/ssl/cert.pem  * /usr/local/openssl/cert.pem
***************************************************************************Message from trousers-0.3.13:To run tcsd automatically, add the following line to /etc/rc.conf:
You might want to edit /usr/local/etc/tcsd.conf to reflect your setup.
If you want to use tcsd with software TPM emulator, use the followingconfiguration in /etc/rc.conf:
To use TPM, add your_account to '_tss' group like following:
# pw groupadd _tss -m your_accountMessage from idnkit-1.0_5:===>   NOTICE:
The idnkit port currently does not have a maintainer. As a result, it ismore likely to have unresolved issues, not be up-to-date, or even be removed inthe future. To volunteer to maintain this port, please create an issue at:
More information about port maintainership is available at:
https://www.freebsd.org/doc/en/articles/contributing/ports-contributing.html#maintain-portMessage from bind99-9.9.9P1:***********************************************************************            _  _____ _____ _____ _   _ _____ ___ ___  _   _         **           / \|_   _|_   _| ____| \ | |_   _|_ _/ _ \| \ | |        **          / _ \ | |   | | |  _| |  \| | | |  | | | | |  \| |        **         / ___ \| |   | | | |___| |\  | | |  | | |_| | |\  |        **        /_/   \_\_|   |_| |_____|_| \_| |_| |___\___/|_| \_|        **                                                                    **   BIND requires configuration of rndc, including a "secret" key.   **    The easiest, and most secure way to configure rndc is to run    **   'rndc-confgen -a' to generate the proper conf file, with a new   **            random key, and appropriate file permissions.           **                                                                    **     The /usr/local/etc/rc.d/named script will do that for you.     **                                                                    ***********************************************************************root@rpi2:/home/imp # 
Although it says that the rc.d named script will do it, I went ahead and did the rndc-confgen -a:
root@rpi2:/home/imp # rndc-confgen -awrote key file "/usr/local/etc/namedb/rndc.key" 
next, we need to copy over the master zone and setup named.conf. Briefly, I commented out the part that binds to localhost and added a pointer to the master file for my zone. I setup stuff so secondaries could transfer out, and I could cross-mirror the secondaries.

So, once it was all running right, I changed rc.conf to enable it (as well as tweak the hostname from the default):
Now the fun part: telling my router to forward DNS packets (port 53) to my FreeBSD box, and then telling my registrar the new IP address of my DNS server. And after the obligatory password snafu, I was able to get everything up and happy.

Removed the default 'freebsd' account and changed the root password to something useful, and I was done.

A final though

I used to think I'd need to pay someone to host DNS for me. And that used to be cheaper in someone else's colo. However, with dirt cheap boards like the Raspberry Pi 2 and others like it, now I can host it myself for not much more than paying someone else do do it. And setting up the server was super easy. Wish blogspot would allow me to more easily attach text files, but it's an imperfect world.


David Hauweele said...

why bind9? now that unbound is in base, unbound + nsd feels like a better combo.

also any thought on the upgrade process? on Linux RPi, I use apticron but I don't know about anything similar for FreeBSD packages.

Warner Losh said...

I'm familiar with bind9.

freebsd-update should be useful to update the base.

pkg update should be useful for the rest.