Install FreeBSD on a Raspberry Pi 4
Prelude
Section titled “Prelude”Prerequisites
Section titled “Prerequisites”Hardware
Section titled “Hardware”- Raspberry Pi 4
- Power supply (usb-c 15W 3A 5.1V)
- MicroSD-card (at least 16GB)
- MicroSD-card reader
- Micro-HDMI -> HDMI/DisplayPort cable
- USB keyboard
Software
Section titled “Software”- Disk writing tool (
ddorRaspberry Pi Imager)
Instructions
Section titled “Instructions”Preparing the microSD card
Section titled “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
Section titled “Booting 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
Section titled “Setting 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
Section titled “Making 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
Section titled “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
Section titled “Enabling 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.