OpenBSD router on apu2c4

Posted by nerdcoding on April 29, 2018

This guide describes how to install and configure a router running OpenBSD on an apu2c4 board.

Connect serial console

The apu2c4 does not provide a video interface like HDMI, DVI or VGA. But the apu2c4 has an old COM port, or to be more specific, a male DB9 serial port. We need a null modem cable (also crossover cable) and a DB9 to USB converter. Plug the null modem cable into the apu2c4 and th other end, with usage of the USB adapter, into a Linux laptop.

With lsusb all USB devices are listed. Here search for the serial port:

$ lsusb
Bus 001 Device 010: ID 052a:4251 Prolific Technology, Inc. PL2303 Serial Port

Here the vendor and product number (052a:4251) are relevant. And with these we can add the usbserial module into the kernel:

$ modprobe usbserial vendor=0x052a product=0x4251

Now search the appropriate ttyUSB* device (here ttyUSB0) and make it accessible:

$ dmesg | grep 'ttyUSB'
$ sudo chmod 777 /dev/ttyUSB0

Finally we can create a serial connection Putty. Under the category Connection → Serial enter:

Serial line to connect to:	/dev/ttyUSB0
Speed: 115200
Data bits: 8
Stop bits: 1
Parity: None
Flow Control: XON/XOFF

And open the connection. Connect the apu2c4 to power and the startup screen should be shown in the Putty window.

Create OpenBSD image

Download OpenBSD file system image installXX.fs (do NOT use the ISO image installXX.iso) and write the image to an USB drive:

$ sudo dd if=install<XX>.fs of=/dev/<device-name> bs=1M

Make absolutely sure to enter the correct device name. All data on that device are deleted and you properly do not want to erase your hard drive.

Install OpenBSD on apu2c4

Connect to serial terminal with Putty, insert USB stick and start the apu2c4. Press F10 to show the boot menu and boot from the USB drive. Then the boot> prompt should be shown.

The following settings are required for proper serial console output:

stty com0 115200
set tty com0

Enter them into the boot> prompt and then start the installation with the command boot.

Configure OpenBSD

Network

The apu2c4 has three separate ethernet interfaces, whose device names could be shown with ifconfig (e.g. em0, em1 and em2). When there is a wireless card inserted into the apu2c4 then there should also be a additional device name (e.g. athn0).

Plug your DSL modem into the em0 device and add up into the file /etc/hostname.em0

$ echo "up" > /etc/hostname.em0

To connect with my ISP I used the PPPoE protocol. For the PPPoE connection create a file /etc/hostname.pppoe0 and enter:

inet 0.0.0.0 255.255.255.255 NONE pppoedev em0 authproto pap authname '<isp-username>' authkey '<isp-password>' up
dest 0.0.0.1
!/bin/sleep 5
!/sbin/route add default -ifp pppoe0 0.0.0.1

The remaining two ethernet devices and the wireless cloud be used to create three separated networks:

$ echo "inet 192.168.1.1 255.255.255.0 192.168.1.255" > /etc/hostname.em1
$ echo "inet 192.168.2.1 255.255.255.0 192.168.2.255" > /etc/hostname.em2
$ cat /etc/hostname.athn0
media autoselect mode 11n mediaopt hostap chan 1
nwid wpaid
wpakey mywpakey
inet 192.168.3.1 255.255.255.0

Restart networking with sh /etc/netstart or the whole apu2c4 with shutdown -r now and after the reboot with an ifconfig the following should be shown:

$ ifconfig
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
        index 5 priority 0 llprio 3
        groups: lo
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x6
        inet 127.0.0.1 netmask 0xff000000
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:11:22:33:44:55
        index 1 priority 0 llprio 3
        media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause)
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:11:22:33:44:55
        index 2 priority 0 llprio 3
        media: Ethernet autoselect (1000baseTX full-duplex,rxpause,txpause)
        status: active
        inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
em2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:11:22:33:44:55
        index 3 priority 0 llprio 3
        media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause)
        status: active
        inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
athn0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:11:22:33:44:55
        index 4 priority 4 llprio 3
        groups: wlan
        media: IEEE802.11 autoselect (autoselect mode 11n hostap)
        status: active
        ieee80211: nwid wpaid chan 1 bssid 00:11:22:33:44:55 wpakey wpaprotos wpa2 wpaakms psk wpaciphers ccmp wpagroupcipher ccmp
        inet 192.168.3.1 netmask 0xffffff00 broadcast 192.168.3.255
pppoe0: flags=8851<UP,POINTOPOINT,RUNNING,SIMPLEX,MULTICAST> mtu 1492
        index 6 priority 0 llprio 3
        dev: em0 state: session
        sid: 0x1936 PADI retries: 1 PADR retries: 1 time: 06:51:35
        sppp: phase network authproto pap authname "***"
        groups: pppoe egress
        status: active
        inet X.X.X.X --> X.X.X.X netmask 0xffffffff

DHCP

The DHCP server is needed to assign an IP address dynamically to clients connected to our router. We just created three different networks (192.168.1.0/24, 192.168.2.0/24 and 192.168.3.0/24) and for each of this networks the DHCP server is configured. First make sure DHCP is enabled:

$ rcctl enable dhcpd

Then add ther server configuration into the file /etc/dhcpd.conf:

option domain-name "hostname.example.com";
option domain-name-servers 9.9.9.9;
option subnet-mask 255.255.255.0;

authoritative;
default-lease-time 86400;
max-lease-time 86400;


subnet 192.168.1.0 netmask 255.255.255.0 {
        option routers 192.168.1.1;

        range 192.168.1.10 192.168.1.49;

        host fixedip {
                hardware ethernet 00:11:22:33:44:55;
                fixed-address 192.168.1.2;
        }

}

subnet 192.168.2.0 netmask 255.255.255.0 {
        option routers 192.168.2.1;

        range 192.168.2.10 192.168.2.49;
}

subnet 192.168.3.0 netmask 255.255.255.0 {
        option routers 192.168.3.1;

        range 192.168.3.10 192.168.3.49;
}

Anymore we need to configure on which devices DHCP should assign IP addresses:

$ echo "dhcpd_flags=\"em1 em2 athn0\"" > /etc/rc.conf.local

Finally the server could be started:

$ /etc/rc.d/dhcpd start

SSH

SSH should be working out of the box, so there is nothing to do here. With ps auxwww | grep sshd we could check if the SSH server is running. If not enable and start the server with:

$ rcctl enable sshd
$ rcctl start sshd

The server configuration clould be found in /etc/ssh/sshd_config.

PF (Packet Filter)

The last step is to enable and configure the firewall pf. All firewall rules are defined in the file /etc/pf.conf. Here I giva a example of a very basic firewall configuration in dependence on the offical OpenBSD FAQ.

em1_if="em1"
em2_if="em2"
wifi_if="athn0"

table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16     \
	 	   172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
	 	   192.168.0.0/16 198.18.0.0/15 198.51.100.0/24        \
	 	   203.0.113.0/24 }
set block-policy drop
set loginterface egress
set skip on lo0
match in all scrub (no-df random-id max-mss 1440)
match out on egress inet from !(egress:network) to any nat-to (egress:0)
antispoof quick for { egress $em1_if $em2_if $wifi_if }
block in quick on egress from <martians> to any
block return out quick on egress from any to <martians>
block log all
pass out quick inet
pass in on { $em1_if $em2_if $wifi_if } inet

Enable PF with the just configured rules:

$ pfctl -ef /etc/pf.conf

Disbale PF:

$ pfctl -d

Check PF logs:

tcpdump -n -e -ttt -i pflog0