Setting up a Raspberry Pi 4 router with FreeBSD
Install
Prelude
I have had a Raspberry Pi 4 that have just been sitting in a box, more or less untouched. I had this plan of creating a little cluster of these and use as some kind of little homelab. But that never happened and it was forgotten in the closet. But now it’s use will be as a little router powering my home network, running a few services and acting as a firewall.
End goal
Setup a Raspberry Pi 4 (4gb) as a router, running FreeBSD and some small various services like an adblocker for the network.
Prerequisites
- Raspberry Pi 4
- Power Adapter
- microSD card
- microHDMI -> HDMI cable
- USB 3.0 Ethernet adapters
Instructions
$ infront of a command means you can do it as non-root.
# infront of a command means you have to do it with root privileges
All the config files can be found on codeberg
Preparing the microSD card
Start with downloading the image from the FreeBSD website, the version as of writing this is 15.0.
Extract the img file, find the name of our USB drive and write the image to it.
$ xz -d FreeBSD-15.0-RELEASE-arm64-aarch64-RPI.img.xz$ ls -l /dev/disk/by-id/usb-*# dd if=path/to/FreeBSD-15.0-RELEASE-arm64-aarch64-RPI.img of=/dev/disk/by-id/usb-Name_of_your_Flash_drive bs=4M conv=fsync oflag=direct status=progressMount the USB-drive.
To be able to get anything on my monitor when booting the Raspberry Pi, i had to add these settings to /boot/msdos/config.txt 1 on the usb drive.
max_framebuffers=2hdmi_safe=0hdmi_force_hotplug=1hdmi_group=1hdmi_drive=2hdmi_mode=16Booting up
After we are all done with the microSD card. We can now attach all the cables, a keyboard and boot up the Raspberry Pi.
When the booting sequence is finished, you will find yourself with a login screen.
There are two default users with username/password: root/root and freebsd/freebsd.
Log in as root.
Changing keymap to another one if needed, available ones are located at /usr/share/vt/keymaps/
# sysrc keymap="se.kbd"Change password for root and freebsd user.
# passwd# passwd freebsdAdd a user, add them to the wheel group
# adduserMy clock on the Raspberry Pi was not correct and that made all kind of trouble trying to connect to servers using TLS, we fix this by setting the tzdata and enabling ntpd.
# tzsetup# sysrc ntpd_enable=yes# sysrc ntpd_sync_on_start="YES"# service ntpd startNow would be a good time to update our system.
# freebsd-update fetch# freebsd-update installInstead of being logged in as root, we add doas to be able to perform actions as root. And since our user was added to the wheel group, we can now perform actions as root.
# pkg install doasSetting up SSH
We will setup SSH to log onto the server instead of having to connect keyboard and a monitor.
# sysrc sshd_enable="YES"# service sshd startAnd we need to add our ssh key to the server
scp ~/.ssh/id_ed25519.pub username@server:~/$ mkdir -p ~/.ssh$ cat ~/id_ed25519.pub >> ~/.ssh/authorized_keys$ chmod 600 ~/.ssh/authorized_keys$ chmod 700 ~/.ssh$ rm ~/id_ed2519.pubAnd we will make some changes to the sshd config file.
Port 20022 # Default port is 22, change it to something else.LoginGraceTime 60 # Default time is 2m, a little more hardening by lowering it to 60 secondsPermitRootLogin no # We never want root to able to login directlyPubkeyAuthentication yes # Use ssh keys for authenticationPasswordAuthentication no # Passwords are not allowed for authenticationRestart the sshd service
# service sshd reloadNow we can login to the server using ssh!
$ ssh username@server -p 20022Making a router
With the basics of our FreeBSD server set up, it’s time to make it into a router! I have bought these D-Link USB 3.0 Ethernet adapters and will be attaching two of them to the USB 3.0 ports. This is not enough ports for a router normally, but at the moment i only have one desktop and one server so it should be sufficient enough. In the future, if there is a rack in the homelab i will add a dedicated router.
To be sure there won’t be any connection issues while doing the routing configuration, we should do this without using SSH.
Setting up the Firewall & DHCP
We start with adding the USB adapters and checking what network interfaces we have available. I have 3:
- genet0: ethernet input
- ue0: ethernet usb adapter output
- ue1: ethernet usb adapter output
$ ifconfigSo now we will write some config to set up our little network.
# WANifconfig_genet0="DHCP"
# USB Ethernet interfacesifconfig_ue0="up"ifconfig_ue1="up"
# Bridge interfacecloned_interfaces="bridge0"ifconfig_bridge0="inet 192.168.10.1 netmask 255.255.255.0 addm ue0 addm ue1 up"
# Enable routinggateway_enable="YES"
# PF firewallpf_enable="YES"pf_rules="/etc/pf.conf"
# DHCP server on the bridge interfacedhcpd_enable="YES"dhcpd_ifaces="bridge0"#### INTERFACES ####wan = "genet0"lan = "bridge0"
#### NETWORKS ####lan_net = "192.168.10.0/24"
set block-policy dropset skip on lo
scrub in all
nat on $wan from $lan_net to any -> ($wan)
# Default deny inbound from WANblock in all
# Allow outboundpass out all keep state
#### ALLOW LAN -> ANYWHERE ####pass in on $lan from $lan_net to any keep state
#### ALLOW LAN -> ROUTER (SSH + ICMP) ####pass in on $lan proto tcp from any to $lan port { 20022 }
#### ALLOW ESTABLISHED / RELATED ####pass in quick proto tcp from any to any flags S/SA keep state
#### ALLOW DHCP ####pass in on $lan proto udp from port 68 to port 67pass out on $lan proto udp from port 67 to port 68default-lease-time 600;max-lease-time 7200;authoritative;
option domain-name-servers 9.9.9.9, 1.1.1.1;
subnet 192.168.10.0 netmask 255.255.255.0 { range 192.168.10.100 192.168.10.200; option routers 192.168.10.1; option subnet-mask 255.255.255.0;}if_bridge_load="YES"net.link.bridge.pfil_bridge=1net.link.bridge.pfil_member=0Enabling it all
# kldload if_bridge# sysctl net.link.bridge.pfil_bridge=1# sysctl net.link.bridge.pfil_member=0# sysctl net.inet.ip.forwarding 1# service netif restart# service routing restart# service pf restart# service dhcpd restartAnd there we have it. It’s a basic configuration of a Raspberry Pi 4 as a router for our homelab. We should now be able to connect our different devices to the ethernet ports of the Raspberry Pi and get a working network connection.