jonrob.net


OpenBSD (6.0) Home Router

Something about using the black box my ISP provided to control my whole network just didn't sit right with me, so I decided to ditch it and make my own using the industrie's go-to firewall operating system: OpenBSD.

I started with an Alix2d2, a single board x86 machine with low power consumption, and a BT OpenReach modem. Both pre-owned and picked up on Ebay for very reasonable prices, I also had to buy a null modem cable to connect to the Alix, a Ralink RT2561T MiniPCI WLAN module and antenna for wireless connectivity.

The only way to install the operating system onto the Alix (apart from copying a snapshot onto the memory card) is a network install, so we will need to setup tftpd and dhcpd.

TFTPD Setup
38400 in the default baud rate for the alix2d2 so I've set that in the boot.conf
# mkdir -p /tftpboot/etc
# cd /tftpdboot
# wget http://mirror.bytemark.co.uk/pub/OpenBSD/6.0/i386/bsd.rd
# wget http://mirror.bytemark.co.uk/pub/OpenBSD/6.0/i386/pxeboot
# echo "stty com0 38400
set tty com0
boot tftp:/bsd.rd" >> etc/boot.conf
# tftpd /tftpboot
/etc/dhcpd.conf
The box we're installing from is 192.168.1.10.
 option domain-name-servers 192.168.1.1;
subnet 192.168.1.0 netmask 255.255.255.0 {
 filename "pxeboot";
 range 192.168.1.8 192.168.1.254;
 option routers 192.168.1.10;
 option broadcast-address 192.168.1.10;
 option subnet-mask 255.255.255.0;
After restarting dhcpd we are ready to start installing, connect the Alix to the box you're installing from, connect the null modem cable and boot it up.
# /etc/rc.d/dhcpd restart
# doas cu -s 3840
When on the bios screen press e for pxe boot, and from there on it's just a normal OpenBSD install, if you're dhcp server doesn't also provide an internet connection then you will need to download the sets to a flash drive and then when in the installer go to the shell, mount the flashdrive, then #> install to resume the installation where you can choose the mountpoint as the location of the sets. After completing the install and rebooting I used the following configs to turn this into a router/firewall: # cat /etc/sysctl.conf
The first two are the only essential commands.
net.inet.ip.forwarding=1 # 1=Permit forwarding (routing) of IPv4 packets
net.inet.ip.redirect=0
kern.bufcachepercent=50
net.inet.ip.ifq.maxlen=1024
net.inet.tcp.mssdflt=1440
#kern.securelevel=1 # 2 = Do not permit changes to running pf config
ddb.panic=0 # 0 = Quickly reboot after panic, skipping ddb
# cat /etc/hostname.bridge0 I use a bridge to have ral0 and vr1 on the same subnet
add vether0
add vr0
add vr1
add ral0
blocknonip vether0
blocknonip vr0
blocknonip vr1
blocknonip ral0
up
# cat /etc/hostname.pppoe0
This is the ppp config for BT OpenReach
inet 0.0.0.0 255.255.255.255 NONE mtu 1500\
 pppoedev vr0 authproto chap \
 authname bthomehub@btinternet.com authkey BT up
dest 0.0.0.1
#inet6 eui64
!/sbin/route add default -ifp pppoe0 0.0.0.1
#!/sbin/route add -inet6 default -ifp pppoe0 fe80::
# cat /etc/hostname.vether0

The subnet for ral0 and vr1
inet 192.168.1.1 255.255.255.0 192.168.1.255
up
# cat /etc/hostname.vr0
descr "WAN"
up mtu 1508
# cat hostname.vr1
up
# cat /etc/hostname.ral0
media autoselect
mediaopt hostap
nwid NETWORKNAME
wpakey NETWORKPASSWORD
chan 1
up
# cat /etc/rc.conf.local
sshd_flags=""
dhcpd_flags="vether0"
ntpd_flags="-s"
ipsec="YES"
ftpproxy_flags=""
sndiod_flags="NO" #No audio
# cat /etc/dhcpd.conf
option domain-name-servers 8.8.8.8, 8.8.4.4;
subnet 192.168.1.0 netmask 255.255.255.0 {
 option routers 192.168.1.1;
 max-lease-time 21600;
 range 192.168.1.4 192.168.1.254;
}
# cat /etc/pf.conf
int_if="{ vether0 vr1 ral0}"
ext_if="{ vr0 }"
broken="224.0.0.22 127.0.0.0/8 192.168.0.0/16 172.16.0.0/12 \
 10.0.0.0/8 169.254.0.0/16 192.0.2.0/24 \
 198.51.100.0/24, 203.0.113.0/24, \
 169.254.0.0/16 0.0.0.0/8 240.0.0.0/4 255.255.255.255/32"

set block-policy drop
set loginterface egress

#Normalise traffic and NAT
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)

#Blacklisting
set skip on lo0
antispoof quick for (egress)
block in quick on egress from { $broken no-route urpf-failed } to any
block return out quick log on egress from any to { no-route $broken }
block in quick inet6 all
block return out quick inet6 all
block in all

#Whitelisting
pass out quick inet keep state
pass in on $int_if inet
After that restarting the Alix should give us a fully functioning router, firewall, and wireless access point.