Introduction

This page describes how a minimal router OS can be created using buildroot.
All configurations and build commands are documented on this page.

The resulting OS will boot, connect to the first LAN-network it can find and then start an access point.

Previous work

This post is based on another post in which a basic embedded OS is created.

Editing the minimal Buildroot OS

Configuring the access point part of the target system

With the options above all set, the Raspberry Pi 4 should boot the target system without any issues. But, because the goal is to create a router out of the Raspberry Pi 4, some extra configuration is needed.

In the menuconfig of buildroot, make the following extra changes:

  • Under Build options, the option RELRO Protection is set to partial
  • Under Target packages -> BusyBox, the option Show packages that are also provided by busybox
  • Under Target packages -> Networking applications, the option iptables is enabled, along with the following options:
    • bpfc and nfsynproxy
    • nftables compat
  • Under Target packages -> Networking applications, the option dhcp (ISC) is enabled, along with the following options:
    • dhcp server, along with:
      • Enable delayed ACK feature
  • Under Target packages -> Networking applications -> wpa_supplicant, the following options are enabled:
    • Enable nl80211 support
    • Enable AP mode
    • Enable EAP
    • Enable WPA3 support
    • Install wpa_passphrase binary
    • Enable support for the DBus control interface (optional, if control via DBus is desired)
    • Introspection support (optional, also has to do with control via DBus)
  • Under Target packages -> Hardware handling -> Firmware, the option rpi-wifi-firmware is enabled.

Using the command make linux-menuconfig, the following additional changes are made to the kernel configuration (still within Buildroot):

  • Under CPU Power Management -> CPU Frequency scaling, the option Default CPUFreq governor is set to ondemand

Adding external (network) configuration files to the target system

Some configuration files are needed by the target system in order to make the access point a reality. Normally, configuration files would be created on the target system. In this case, this is not desireable. Fortunately, Buildroot had a file called post-build.sh, located in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. This file will be used to automatically copy network configurations to the target system after it’s been built.

wpa_supplicant.conf

The tool wpa_supplicant is often used to connect to networks, but it can also be configured to act as an access point. In order to do this, it needs a configuration file called wpa_supplicant.conf.

To create a wireless access point on the target system, create a file called wpa_supplicant.conf and place it in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file has the following contents:

network={
    ssid="buildrootAP"  # network name
    psk="welcome01"     # network password
    mode=2              # act as an access point
    proto=RSN
    key_mgmt=WPA-PSK
    pairwise=CCMP
    group=CCMP          # allow only AES, not TKIP
    #frequency=5200     # uncomment to run access point on 5GHz
}

This configuration will create a WPA2 network with the name buildrootAP and password welcome01.

Frequency options are as follows:

  • For a 2.4GHz access point: 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467 or 2472
  • For a 5GHz access point: 5170, 5180, 5190, 5200, 5210, 5220, 5230, 5240, 5260, 5280, 5300, 5320, 5500, 5520, 5540, 5560, 5580, 5600, 5620, 5640, 5660, 5680 or 5700

On 5GHz, if the frequency is set too high, the signal will probably not travel through walls very well. A higher frequency does result in a faster internet speed. Not all frequencies may be supported by the wireless interface of the Raspberry Pi 4. If the network SSID does not appear after the Raspberry Pi 4 has started, change the frequency to another value.

interfaces

Another common file found in Linux-based operating systems is a file called interfaces. This file often contains configurations regarding IP addressing of certain interfaces.

To create interface configuration for the target system, create a file called interfaces and place it in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file is to contain the following configuration:

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
    udhcpc_opts -t 99 # try 99 times before giving up
    pre-up /etc/network/nfs_check
    wait-delay 15
auto wlan0
iface wlan0 inet static
    address 192.168.200.1
    netmask 255.255.255.0
    network 192.168.200.0
    gateway 192.168.200.1
    pre-up wpa_supplicant -B -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf
    post-down killall -q wpa_supplicant
    wait-delay 15
iface default inet dhcp

dhcpd.conf

Almost every modern router has a DHCP server built in. So, the target system should also have one.

To configure the DHCP server on the target system, create a file called dhcpd.conf and place it in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file is to have the following contents:

ddns-update-style none;
default-lease-time 600;
max-lease-time 7200;
authoritative;

subnet 192.168.200.0 netmask 255.255.255.0 {
  range 192.168.200.10 192.168.200.50;
  option broadcast-address 192.168.200.255;
  option routers 192.168.200.1;
  default-lease-time 600;
  max-lease-time 7200;
  option domain-name "local";
  option domain-name-servers 9.9.9.9, 1.1.1.1;
}

sysctl.conf

To allow packages to flow from one linux network interface to another, a file called sysctl.conf has to be created and placed in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file is to have the following contents:

net.ipv4.ip_forward = 1

S02procps

To activate the above configuration file (sysctl.conf) when the target OS boots, a startup/service file called S02procps is created and placed in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file will have the following contents:

#! /bin/sh
if [ "$1" == "start" ]; then
    sysctl -p
fi

S99firewall

To configure firewall settings when the target OS boots, a service will be created. The file will be called s99firewall and placed in buildroot-<VERSION_GOES_HERE>/board/raspberrypi/. The file will have the following contents:

#! /bin/sh
if [ "$1" == "start" ]; then
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    iptables -P FORWARD DROP
    iptables -A FORWARD -i eth0 -o wlan0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
    iptables -P INPUT DROP
    iptables -A INPUT -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A INPUT -i wlan0 -j ACCEPT
fi

Copying all files to the target system

To automatically copy all configuration files and services into the target system after it has been built, the following lines will be appended to buildroot-<VERSION_GOES_HERE>/board/raspberrypi/post-build.sh:

# copy configuration files
cp board/raspberrypi/interfaces ${TARGET_DIR}/etc/network/interfaces
cp board/raspberrypi/wpa_supplicant.conf ${TARGET_DIR}/etc/wpa_supplicant.conf
cp board/raspberrypi/dhcpd.conf ${TARGET_DIR}/etc/dhcp/dhcpd.conf
cp board/raspberrypi/sysctl.conf ${TARGET_DIR}/etc/sysctl.conf

# copy init scripts
cp board/raspberrypi/S02procps ${TARGET_DIR}/etc/init.d/S02procps
cp board/raspberrypi/S99firewall ${TARGET_DIR}/etc/init.d/S99firewall

# set permissions on the new init scripts
chmod 755 ${TARGET_DIR}/etc/init.d/S02procps
chmod 755 ${TARGET_DIR}/etc/init.d/S99firewall

# make the init scripts executable
chmod +x ${TARGET_DIR}/etc/init.d/S02procps
chmod +x ${TARGET_DIR}/etc/init.d/S99firewall

Rebuilding the OS

After all configurations are done, rebuild the system as explained in the previous post.

Testing

After the system.img file is flashed to an SD card, the SD card can be plugged into any Raspberry Pi 4.
If a monitor is connected to the HDMI0 port of the Raspberry Pi 4, the following logs can be seen:

Startup logs

The Raspberry Pi successfully connected to a lan network and then started it’s wireless access point. The network SSID should now be visible to client devices and connections can now be made.

The OS will fail to start the access point if it cannot connect to another LAN network via DHCP. If udhcpc fails after trying 99 times, the OS will not start a wireless network.

Sources