The ALIX Firewall Project
First things first: if you don’t yet know about PC Engines' line of single board computers, you should check out their ALIX line and decide on your next project. ;-)
Once you’re done with that, read on to find out how I built my new home router using the alix6b2 board.
The alix6b2 is a 6"x6" single board computer sporting an AMD Geode LX800 processor (500MHz), 256MB RAM, a CF card socket, and 2 NICs (among other things; have a look at the above link for the full run-down). While I don’t need to, I also have the option of installing a wireless radio in the miniPCI slot (I have a Cisco AP that does very well in my little apartment). Never having done anything with single board computers, I was pretty surprised at how compact the entire thing was:
Initial Setup
Since there is no display adapter built into the board, I had to use the serial port as the console. The initial settings for the ALIX serial console are somewhat faster than the defaults for other serial consoles: 38400 8-N-1 (as opposed to 9600 8-N-1). To make the board’s boot settings match OpenBSD’s default serial console settings, I set the line speed to 9600 in the BIOS (to do this, hit “S” during the memory test). There were a couple of other settings I needed to set as well:
- LBA Mode (I don’t guess I technically needed to enable this, but I did)
- HDD Wait (actually used to ensure that the NIC had enough time to initialize, etc., before PXE booting)
- UDMA Enable (the SanDisk Extreme III compact flash card I bought is UDMA capable – don’t enable this if your card isn’t)
- PXE Boot Enable
Through the wonders of cut-and-paste, here is the intial boot, correct BIOS settings, and then the PXE boot process (I’ll leave setting up your environment to PXE boot as an exercise for the reader, but I highly suggest reading the OpenBSD FAQ about how to boot using PXE):
PC Engines ALIX.2 v0.99
640 KB Base Memory
261120 KB Extended Memory
Waiting for HDD ...
01F0 Master 848A SanDisk SDCFX3-004G
Phys C/H/S 7964/16/63 Log C/H/S 995/128/63
BIOS setup:
*9* 9600 baud (2) 19200 baud (3) 38400 baud (5) 57600 baud (1) 115200 baud
(C) CHS mode *L* LBA mode *W* HDD wait (V) HDD slave *U* UDMA enable
(M) MFGPT workaround
(P) late PCI init
*R* Serial console enable
*E* PXE boot enable
(X) Xmodem upload
(Q) Quit
Save changes Y/N ?
Writing setup to flash... OK
640 KB Base Memory
261120 KB Extended Memory
Waiting for HDD ...
01F0 Master 848A SanDisk SDCFX3-004G
Phys C/H/S 7964/16/63 Log C/H/S 995/128/63
Intel UNDI, PXE-2.0 (build 082)
Copyright (C) 1997,1998,1999 Intel Corporation
VIA Rhine III Management Adapter v2.43 (2005/12/15)
CLIENT MAC ADDR: 00 0D B9 15 E6 9C
CLIENT IP: 192.168.1.2 MASK: 255.255.255.0 DHCP IP: 192.168.1.1
GATEWAY IP: 192.168.1.1
probing: pc0 com0 pci pxe![2.1] mem[640K 255M a20=on]
disk: hd0
net: mac 00:0d:b9:15:e6:9c, ip 192.168.1.2, server 192.168.1.1
>> OpenBSD/i386 PXEBOOT 2.03
boot>
OpenBSD Installation
Once I had the ALIX PXE booting, it was a simple matter of consulting
the OpenBSD FAQs on how to boot using a serial console. If
you look closely you might notice that the initial boot failed because
it couldn’t find the file bsd
. I could have renamed bsd.rd
to just
bsd
, but I didn’t, so I had to manually specifiy the correct
filename. This also gave me a chance to specify the option set tty com0
before booting.
640 KB Base Memory
261120 KB Extended Memory
Waiting for HDD ...
01F0 Master 848A SanDisk SDCFX3-004G
Phys C/H/S 7964/16/63 Log C/H/S 995/128/63
Intel UNDI, PXE-2.0 (build 082)
Copyright (C) 1997,1998,1999 Intel Corporation
VIA Rhine III Management Adapter v2.43 (2005/12/15)
CLIENT MAC ADDR: 00 0D B9 15 E6 9C
CLIENT IP: 192.168.1.2 MASK: 255.255.255.0 DHCP IP: 192.168.1.1
GATEWAY IP: 192.168.1.1
probing: pc0 com0 pci pxe![2.1] mem[640K 255M a20=on]
disk: hd0
net: mac 00:0d:b9:15:e6:9c, ip 192.168.1.2, server 192.168.1.1
>> OpenBSD/i386 PXEBOOT 2.03
boot>
booting tftp:/bsd: open tftp:/bsd: No such file or directory
failed(2). will try /bsd
boot>
booting tftp:/bsd: open tftp:/bsd: No such file or directory
failed(2). will try /bsd
Turning timeout off.
boot> set tty com0
switching console to com0
>> OpenBSD/i386 PXEBOOT 2.03
boot> boot bsd.rd
booting tftp:bsd.rd: 5155412+901212 [52+196192+181801]=0x6230e4
entry point at 0x200120
Initial OpenBSD Boot
Right after loading bsd.rd
over tftp, the system starts to
boot:
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
Copyright (c) 1995-2008 OpenBSD. All rights reserved. http://www.OpenBSD.org
OpenBSD 4.4 (RAMDISK_CD) #857: Tue Aug 12 17:31:49 MDT 2008
deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/RAMDISK_CD
RTC BIOS diagnostic error 80<clock_battery>
cpu0: Geode(TM) Integrated Processor by AMD PCS ("AuthenticAMD" 586-class) 499 MHz
cpu0: FPU,DE,PSE,TSC,MSR,CX8,SEP,PGE,CMOV,CFLUSH,MMX
real mem = 268009472 (255MB)
avail mem = 252563456 (240MB)
RTC BIOS diagnostic error 80<clock_battery>
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 12/10/07, BIOS32 rev. 0 @ 0xfceb2
pcibios0 at bios0: rev 2.1 @ 0xf0000/0x10000
pcibios0: pcibios_get_intr_routing - function not supported
pcibios0: PCI IRQ Routing information unavailable.
pcibios0: PCI bus #0 is the last bus
bios0: ROM list: 0xe0000/0xa800
cpu0 at mainbus0
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 1 function 0 "AMD Geode LX" rev 0x33
"AMD Geode LX Crypto" rev 0x00 at pci0 dev 1 function 2 not configured
vr0 at pci0 dev 9 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 10, address 00:0d:b9:15:e6:9c
ukphy0 at vr0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, model 0x0034
vr1 at pci0 dev 10 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 11, address 00:0d:b9:15:e6:9d
ukphy1 at vr1 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, model 0x0034
glxpcib0 at pci0 dev 15 function 0 "AMD CS5536 ISA" rev 0x03: rev 0, 32-bit 3579545Hz timer
pciide0 at pci0 dev 15 function 2 "AMD CS5536 IDE" rev 0x01: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <SanDisk SDCFX3-004G>
wd0: 4-sector PIO, LBA, 3919MB, 8027712 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 4
pciide0: channel 1 ignored (disabled)
ohci0 at pci0 dev 15 function 4 "AMD CS5536 USB" rev 0x02: irq 15, version 1.0, legacy support
ehci0 at pci0 dev 15 function 5 "AMD CS5536 USB" rev 0x02: irq 15
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 "AMD EHCI root hub" rev 2.00/1.00 addr 1
isa0 at glxpcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: console
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
usb1 at ohci0: USB revision 1.0
uhub1 at usb1 "AMD OHCI root hub" rev 1.00/1.00 addr 1
biomask f3ef netmask ffef ttymask ffff
rd0: fixed, 3800 blocks
softraid0 at root
PXE boot MAC address 00:0d:b9:15:e6:9c, interface vr0
root on rd0a swap on rd0b dump on rd0b
WARNING: clock time much less than file system time
WARNING: using file system time
WARNING: CHECK AND RESET THE DATE!
Note the three warning lines at the end of the boot process. From what
I understand the ALIX board does not have a battery-backed CMOS to keep
the time and date across power-cycles. I’ll address this a little bit
further below. Continuing on, the install process should look exactly
like any other OpenBSD install. Run through it just like you would for
any other system or follow the OpenBSD 4.4 Installation Guide
if you’re new to installing OpenBSD. However, right before the end of
the install, make sure you answer “yes” to have the installer make the
required changes to /etc/ttys
and /etc/boot.conf
specified by the
serial console FAQ.
Change the default console to com0? [no] yes
Available speeds are: 9600 19200 38400 57600 115200.
Which one should com0 use? (or 'done') [9600]
[snip]
CONGRATULATIONS! Your OpenBSD install has been successfully completed!
To boot the new system, enter halt at the command prompt. Once the
system has halted, reset the machine and boot from the disk.
# halt
syncing disks... done
First OpenBSD Boot
After power-cycling the device, OpenBSD booted for the first time on my new hardware:
PC Engines ALIX.2 v0.99
640 KB Base Memory
261120 KB Extended Memory
01F0 Master 848A SanDisk SDCFX3-004G
Phys C/H/S 7964/16/63 Log C/H/S 995/128/63
Using drive 0, partition 3;
Loading;...
probing: pc0 com0 pci mem[640K 255M a20=on]
disk: hd0
>> OpenBSD/i386 BOOT 3.02
switching console to com0
>> OpenBSD/i386 BOOT 3.02
boot>
booting hd0a:/bsd: 6238560+1041588 [52+319712+302630]=0x7896c4
entry point at 0x200120
[ using 622768 bytes of bsd ELF symbol table ]
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
Copyright (c) 1995-2008 OpenBSD. All rights reserved. http://www.OpenBSD.org
OpenBSD 4.4 (GENERIC) #1021: Tue Aug 12 17:16:55 MDT 2008
deraadt@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC
cpu0: Geode(TM) Integrated Processor by AMD PCS ("AuthenticAMD" 586-class) 499 MHz
cpu0: FPU,DE,PSE,TSC,MSR,CX8,SEP,PGE,CMOV,CFLUSH,MMX
real mem = 268009472 (255MB)
avail mem = 250716160 (239MB)
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 12/10/07, BIOS32 rev. 0 @ 0xfceb2
pcibios0 at bios0: rev 2.1 @ 0xf0000/0x10000
pcibios0: pcibios_get_intr_routing - function not supported
pcibios0: PCI IRQ Routing information unavailable.
pcibios0: PCI bus #0 is the last bus
bios0: ROM list: 0xe0000/0xa800
cpu0 at mainbus0
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 1 function 0 "AMD Geode LX" rev 0x33
glxsb0 at pci0 dev 1 function 2 "AMD Geode LX Crypto" rev 0x00: RNG AES
vr0 at pci0 dev 9 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 10, address 00:0d:b9:15:e6:9c
ukphy0 at vr0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, model 0x0034
vr1 at pci0 dev 10 function 0 "VIA VT6105M RhineIII" rev 0x96: irq 11, address 00:0d:b9:15:e6:9d
ukphy1 at vr1 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI 0x004063, model 0x0034
glxpcib0 at pci0 dev 15 function 0 "AMD CS5536 ISA" rev 0x03: rev 0, 32-bit 3579545Hz timer, watchdog, gpio
gpio0 at glxpcib0: 32 pins
pciide0 at pci0 dev 15 function 2 "AMD CS5536 IDE" rev 0x01: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <SanDisk SDCFX3-004G>
wd0: 4-sector PIO, LBA, 3919MB, 8027712 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 4
pciide0: channel 1 ignored (disabled)
ohci0 at pci0 dev 15 function 4 "AMD CS5536 USB" rev 0x02: irq 15, version 1.0, legacy support
ehci0 at pci0 dev 15 function 5 "AMD CS5536 USB" rev 0x02: irq 15
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 "AMD EHCI root hub" rev 2.00/1.00 addr 1
isa0 at glxpcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: console
pcppi0 at isa0 port 0x61
midi0 at pcppi0: <PC speaker>
spkr0 at pcppi0
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
usb1 at ohci0: USB revision 1.0
uhub1 at usb1 "AMD OHCI root hub" rev 1.00/1.00 addr 1
biomask f3ef netmask ffef ttymask ffff
mtrr: K6-family MTRR support (2 registers)
nvram: invalid checksum
softraid0 at root
root on wd0a swap on wd0b dump on wd0b
clock: unknown CMOS layout
Automatic boot in progress: starting file system checks.
/dev/rwd0a: file system is clean; not checking
/dev/rwd0h: file system is clean; not checking
/dev/rwd0f: file system is clean; not checking
/dev/rwd0e: file system is clean; not checking
/dev/rwd0d: file system is clean; not checking
setting tty flags
net.inet6.ip6.accept_rtadv: 0 -> 1
starting network
DHCPDISCOVER on vr0 to 255.255.255.255 port 67 interval 2
DHCPOFFER from 192.168.2.3
DHCPREQUEST on vr0 to 255.255.255.255 port 67
DHCPACK from 192.168.2.3
bound to 192.168.2.50 -- renewal in 345600 seconds.
IPv6 autoconf: vr0
starting system logger
starting initial daemons: ntpd.
savecore: no core dump
checking quotas: done.
building ps databases: kvm dev.
clearing /tmp
starting pre-securelevel daemons:.
setting kernel security level: kern.securelevel: 0 -> 1
creating runtime link editor directory cache.
preserving editor files.
ssh-keygen: generating new DSA host key... done.
ssh-keygen: generating new RSA host key... done.
ssh-keygen: generating new RSA1 host key... done.
openssl: generating new isakmpd RSA key... done.
starting network daemons: sendmail inetd sshd.
starting local daemons:.
standard daemons: cron.
Tue Aug 12 20:07:53 EDT 2008
OpenBSD/i386 (fw.crosse.org) (tty00)
login:
After-boot Configuration Steps
As mentioned previously, the alix6b2 doesn’t have a battery-backed CMOS,
so I needed to ensure that the time was set at boot. To do this I just
put the line /usr/sbin/ntpd -s
in /etc/rc.local
, which according to
the man page, will “[s]et the time immediately at startup.
Allows for a large time correction[…]”.
For me, other after-boot configuration consisted of copying over various config files from my old OpenBSD firewall to the alix. See the appropriate man pages for each of the following files if you don’t know what they’re used for:
- /etc/ntpd.conf
- /etc/rc.local
- /etc/fstab (to ensure that /altroot is set up properly)
- /etc/hostname.{vr0, vr1, gif0}
- /etc/pf.conf
- /etc/rc.conf.local
- /etc/resolv.conf.tail
- /etc/rtadvd.conf
- /etc/sudoers
- /etc/sysctl.conf
- /etc/dhclient.conf (to remove some requested options, like DNS servers, etc.)
Of course, none of the above files are specific for the alix; they are needed for the various services that I have running on the device (IPv4/v6 routing, 6to4 tunnel, IPv6 address assignation, firewalling via pf, etc.)
Conclusion
That’s pretty much it. The alix6b2 so far has been a great little device; outside of some initial configuration steps it’s just like any other x86 system, with robust OpenBSD support. If you’re looking for a device with a small form-factor to be a firewall, router, or just a project system with a tiny footprint, I’d suggest you take a serious look at the alix6b2 (as well as the entire ALIX line).