Configuring a Raspberry Pi 4 as a router
Recently, I ran into a situation that I needed to move my whole computer setup to another room. The only issue with this was that I have an IP phone that needs to be connected through an ethernet cable to connect to the Internet. This will have been fine if I were to run a cable all the way from one end of the apartment to the other end of the apartment, but I'm not a fan of having cables all over the floor or also couldn't run it. So, this got me thinking about setting up a router/firewall in a small computer that will allow me to connect the IP phone.
The purpose of this is to setup a simple, but efficient, router using the Raspberry Pi 4 B using Ubuntu Server 20.04 LTS for the OS. This guide is part of a series of posts. The end result of each post is to have a fully working project independently from the other projects.
Getting Started
There are few things that are required before we start:- Raspberry Pi 4 B (Raspberry Pi 2 or 3 will also work)
- SD card with Ubuntu Server 20.04 LTS (Ubuntu Server 18 will also work) - Install Ubuntu Server on the Raspberry Pi.
- Raspberry Pi 4 B case
- And sure, an internet connection
Network configuration
Once Ubuntu serve is configured and up and running, the first thing that needs to be done is to make sure the OS is up to date. Run the following commands to update and upgrade Ubuntu's packages:
sudo apt update -y && sudo apt upgrade -y
Once Ubuntu has been updated, the next step is to configure its network and interfaces. There are a few things we need to configure before we start getting our hands dirty. First, one interface needs to be configured to function as our WAN and the other to function as the LAN. The following setup will be used to define the WAN and the LAN:
- WAN port is wth0
- LAN port is eth0
We need to configure the network settings using Netplan. Open the netplan configuration file by running the following command:
sudo nano /etc/netplan/00-installer-config.yaml
Note: The Netplan configuration file might have a different name in your system. In this case, it is 00-installer-config.yml.
Both of the interfaces are being set as statics. This is how it should look like (WiFi's SSID and password need to be changed):
network:
wifis:
wlan0:
access-points:
"SSID_Name_goes_here":
password: "wi-fi_assword_goes_here"
dhcp4: no
dhcp6: no
optional: true
addresses: [10.0.0.50/8]
gateway4: 10.0.0.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
ethernets:
eth0:
dhcp4: no
dhcp6: no
addresses: [192.168.2.1/24]
gateway4: 192.168.2.1
nameservers:
addresses: [1.1.1.1, 8.8.8.8]
optional: true
version: 2
After configuring Netplan, apply the changes by running:
sudo netplan --debug apply
DNS Configuration
The next step is to configure the DNS. This will tell the system where to look for DNS requests. Type the following into the terminal:
sudo nano /etc/resolv.conf
In my case, I setup the DNS with the following configuration:
nameserver 8.8.8.8 # Primary DNS Server
nameserver 1.1.1.1 # Secondary DNS Server
DHCP server configuration
The next step is to setup our DHCP server which will configure any device or computer that is connected to the LAN port (Raspberry Pi's ethernet interface) an IP address. Side note, if you need to connect multiple computers to the LAN port, I would recommend to use a switch. First thing first, the necessary packages need to be installed for the DHCP server. Installing DHCP server packages:
sudo apt-get install isc-dhcp-server -y
Once the dhcp server has been installed, next the interface that will function as the DHCP server needs to be configured by adding the LAN interface in the isc-dhcp-server's configuration file. Enter the following in the line that start with INTERFACESv4="eth0" in the /etc/default/isc-dhcp-server file, as follow:
sudo nano /etc/default/isc-dhcp-server
The next step is to setup the /etc/dhcp/dhcpd.conf file with the right values for the dhcp server by running the following command:
sudo nano /etc/dhcp/dhcpd.conf
The final result should look like as follow (eth0's MAC address needs to be changed to your eth0's MAC address):
#option domain-name "example.org";
option domain-name-servers 8.8.8.8, 1.1.1.1;
ddns-update-style none;
#log-facility local7;
subnet 192.168.2.0 netmask 255.255.255.0 {
authoritative;
interface eth0;
range 192.168.2.100 192.168.2.200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.2.255;
option routers 192.168.2.1;
default-lease-time 600
max-lease-time 7200;
}
host server {
hardware ethernet [Change_to_eth0_MAC_Address];
fixed-address 192.168.2.1;
}
Once the /etc/dhcp/dhcpd.conf has been configured, then the isc-dhcp-server service needs to be enabled and restarted as follow:
sudo systemctl enable isc-dhcp-server
And then run the following to restart it:
sudo systemctl restart isc-dhcp-server
After restarting the isc-dhcp-server services, then it is time to check its status:
sudo systemctl status isc-dhcp-server
This should give us a good indication if the DHCP server is running or not and/or if it encountered any issues.
Firewall Configuration
Before start configuring the firewall, there a few things that need to be setup.
The next step is to configure the firewall. Even though, I'm not connecting the Raspberry Pi router directly to the Internet, I still want to implement a firewall to block unwanted traffic and also to have NAT capability.
By default, Ubuntu Server comes with UFW already setup. As we will be using iptables to configure the firewall, we don't need it. Instead of uninstalling it, it is best to disable and stop it by running the following commands:
sudo ufw disable
And then:
sudo systemctl stop ufw
The next step is to first allow traffic to be forwarded between the WAN interface and the LAN interface. This can be accomplished by editing the sysctl.conf file located
at the /etc/ directory. Open the file and uncomment the line that start with net.ipv4.ip_forward=1
by running:
sudo nano /etc/sysctl.conf
Then apply the changes with:
sudo sysctl -p
Instead of configuring the firewall by entering one rule at the terminal line by line, we are going to save all the rules that we need to a file and then use this file to load the rules into iptables. We can do this in different ways; however, the most convenient way is to have the iptables-persistent package loads iptables rules every time the system boot. Run the following command to install the iptables-persistent package:
sudo apt install iptables-persistent
During the installation, you will get a prompt asking if you to save the current IPv4 rules configuration, select "Yes". Then select "No" for IPv6 rules configuration. If you didn't select "Yes" during the installation, that is fine, by running the following command, you will get the same prompt:
sudo dpkg-reconfigure iptables-persistent
After the installation, the new iptables directory will be created inside the /etc directory. This should have the rules.v4 file which where we are going to put the iptables configuration. Run the following command to edit the /etc/iptables/rules.v4 file:
sudo nano /etc/iptables/rules.v4
Then enter the following iptables configuration. Note: the only three iptables chains that need to be configured for this setup are the INPUT, FORWARD, and OUTPUT chains.
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wlan0 -j MASQUERADE
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# wlan0 is the WAN
# eth0 is the LAN
# Accept ssh connection into the router (add this one if you need it):
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i wlan0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Drop invalid traffic:
-A INPUT -m conntrack --ctstate INVALID -j DROP
# Drop all other inbound traffic
-A INPUT -j DROP
# FORWARD
-A FORWARD -i eth0 -o wlan0 -j ACCEPT
-A FORWARD -i wlan0 -o eth0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# drop all other forwarded traffic
-A FORWARD -j DROP
COMMIT
Once the configuration is saved, reboot the system. You can verify that the configuration is active by running after the reboot:
sudo iptables -L
Now it is time to test the whole setup. Connect a computer to the Raspberry Pi's ethernet port and then try to access the internet.