Electrical-Forenics Home ray@RayFranco.com                       601.529.7473
   © Dr. Ray Franco, PhD, PE  -  208 Fairways Dr., Vicksburg, MS 39183

Updated on Dec 6, 2024

Linux (Debian) Router

To turn a Raspberry Pi 5B into a router, I followed the excellent article: Setting up a Linux Server as a Router [1] . Also, helpful was Set Static IP Address [2] .

Packet Forwarding

By default, Linux does not forward packets. That is, by default, if a computer (host) receives a packet that is not addressed to it, it simply ignores (drops) the packet.

Hence, the first step in using a computer as router, is to get it to forward packets to the next computer or router.

To enable packet forwarding, you have to modify the /etc/sysctl.conf file:

sudo vi /etc/sysctl.conf

Add the following line:

net.ipv4.ip_forward=1

and optionally:

net.ipv6.ip_forward=1

To check that packet forwarding is enabled:

cat /proc/sys/net/ipv4/ip_forward

References

  1. Wikipedia - Packet Forwarding
  2. What is Packet Forwarding? - Includes the Next Hop Method

Router Addresses

For a computer to forward a packet, it has to have somewhere to forward it to. That is, the computer has to have a least a second network interface (Ethernet/Wireless).

One of the network interfaces will receive it's ip address from an upstream router. This address can be static or dynamic. The upstream router will also automaticlly assign a gateway and domain name server.

The ip addresses of the other network interfaces have to be manually set. How you do this, depends on the network manager, you are using. Debian has several network managers, and they can be running at the same time, as long as a particular network interface is only controlled by one network manager. In the referenced article, the author chooses, to assign ip addresses by modifying the /etc/network/interfaces files. This is probably the easiest and most straight forward way to do this.

The referenced article [1] assumes that the computer has 3 Ethernet interfaces, eth0, eth1, and eth2. It also assumes that eth0 has already been assigned an ip address from an upstream router or computer. The author assigns ip address 192.168.200.254 to eth1 and ip address 192.168.100.254 to eth2.

The computer that I wanted to turn into a router was a Raspberry Pi 5B. It only has one built-in Ethernet interface - eth0. For my second Ethernet interace, I used a Benfei USB 3.0 to Ethernet adapter - eth1. I did not implement the third Ethernet interface - eth2.

To assign the ip address, I added the following to /etc/network/interfaces:

sudo vi /etc/network/interfaces

I added the following:

auto eth1
iface eth1 inet static
  address 192.168.200.254
  netmask 255.255.255.0

This is old school. As of Raspberry Pi OS 12 (Bookworm), the NetworkManager is default package for managing network interfaces. To do this with the NetworkManager see references [5,6].

Client Addresses

The referenced article assumes two client machines. The first is running Linux, and its Ethernet interface (eth0) is connected to Ethernet interface eth1 on the routing computer. The ip address on the Linux client is assigned 192.168.200.15. The ip address on the Windows client is 192.168.100.10. However, the author does not show how to set up either client, and this was my achilles' heel. On the Linux client, in addition to assigning an ip address, you must assign a gateway back to the routing computer.

My code for this was:

sudo vi /etc/network/interfaces

and, add the following:

auto eth0
iface eth0 inet static
  address 192.168.200.15
  netmask 255.255.255.0
  gateway 192.168.200.254

Without setting the client's gateway, I could ping 192.168.200.15 from the routing computer, but I could not ping the routing computer from the client computer - ditto for SSHing and the Internet.

To see the gateways, run:

ip route

This is old school. As of Raspberry Pi OS 12 (Bookworm), the NetworkManager is default package for managing network interfaces. To do this with the NetworkManager see references [5,6].

Diagram with Code


        Upstream Router
        Assigns IP address
        192.168.50.45
        and gateway
               |  
               |
               |
               |               ------------------------
               |               |                      |
               |               |                      |
       ---------------------------------              |
      |      eth0            eth1       |             |
      | 192.168.50.45   192.168.200.254 |             |
      |                                 |             |
      |    Enable Packet Forwarding:    |             |
      |    sudo /etc/network/interfaces |             |
      |    net.ipv4.ip_forward=1        |             |
      |    net.ipv6.ip_forward=1        |             |
      |                                 |             |
      |      /etc/network/interfaces    |             |
      |      auto eth1                  |             |
      |      iface eth1 inet static     |             |
      |         address 102.168.200.254 |             |
      |         netmask 255.255.255.0   |             |
       ---------------------------------              |
                                                      |
                                       ----------------------------
                                      |             eth0           | 
                                      |        192.168.200.15      |
                                      |                            |
                                      | /etc/network/interfaces    |
                                      | auto eth0                  |
                                      | iface eth0 inet static     |
                                      |    address 192.168.200.15  |
                                      |    netmask 255.255.255.0   |
                                      |    gateway 192.168.200.254 |
                                       ----------------------------
          
      

Network Filter Table (nft) Code

The easy part of this was the nft code for masquerading:


#!/usr/bin/nft -f

flush ruleset

table inet router {

   chain prerouting {
       type nat hook prerouting priority filter; policy accept;
   }

   chain input  {
       type filter hook input priority filter; policy accept;
   }

   chain forward {
       type filter hook forward priority filter; policy accept;
   }

   chain output {
       type filter hook output  priority filter; policy accept;
   }

   chain postrouting  {
       type nat  hook postrouting priority filter; policy accept;
        masquerade
   }
}
          

The primary advantage of a Linux Router is to do filtering with nftables, and this code does not do any filtering.

References

  1. nftables multi network (home) router primer
  2. Classic perimetral firewall example
  3. What Is a Demilitarized Zone (DMZ)? Definition, Examples, Working, and Importance in 2022
  4. DMZ (computing)

                         Internet
                           / \
                            |
                            |     
                            |              
      -----------------------------------------------
      |                    bond0                    |
      |                  nic_inet                   |
      |                                             |
      |              Linx Router/Firewall           |
      |                                             |
      |    nic_DMZ                        nic_LAN   |
      |     bond1                          bond2    |
       ----------------------------------------------    
              |                              |
              |                              |
 ============ | ===========      =========== | ============
 ||           |          ||      ||          |           ||
 ||       ----------     ||      ||      ----------      ||
 ||       | Swtich |     ||      ||      | Switch |      ||
 ||       ----------     ||      ||      ----------      ||
 ||           |          ||      ||          |           ||
 ||     --------------   ||      ||    --------------    ||    
 ||     |  Server    |   ||      ||    | Workstation |   ||  
 ||     |  10.0.1.2  |   ||      ||    |  10.0.2.2   |   || 
 ||     --------------   ||      ||    --------------    || 
 ||                      ||      ||                      ||
 || 10.0.1.x  DMZ Zone   ||      ||   10.0.2.x    LAN    ||
 ==========================      ==========================                         
                               
                             
          
      

Benchmarks - Linux Router - Raspberry Pi 5B

There is only one Ethernet cable going from my desk into the floor. Hence, all of the hosts on my desk (HP EliteDesk and Raspberry Pi's) go through an Ethernet switch, and everything in my office goes to a second Ethernet Switch. Thus, traffic between any host on my desk and the Synology 220 (network attaches storage - nas) must pass through two Ethernet switches.

The diagram below depicts my test setup. The HP Elite Desk is running Windows 11. A Raspberry Pi 5B only has one native Ethernet port. For the second Ethernet Port, a Benfei USB 3.0 to Ethernet adapter was used ( Amazon #10 ).



               Internet
                  |
                  |  192.168.50.xxx
                  |
             /----------\
             | Ethernet |
             | Switch   |
             \----------/
               |     |
               |     |
         -------     ------
         |                |
         |                |
    /----------\     /----------\
    | Synology |     |   Desk   |
    | Network  |     | Ethernet |
    | Attached |     | Switch   |
    | Storage  |     \----------/
    \----------/      |       |                   192.168.200.xxx
        NAS           |       -------         ---------------------
                      |             |         |                   |
                      |       /--------------------\              |
                      |       | Ethernet   USB 3.0 |              |
                      |       |                    |      /-----------------\
                      |       |    Linux Router    |      |    USB 3.0      |
                      |       | Raspberry Pi 5B    |      | Benfie          |
                      |       | NVMe Gen 3 x 1     |      | USB to Ethernet |
                      |       \--------------------/      | Adapter         |
                      |                                   |   Ethernet      |
                      |                                   \-----------------/       
                      |                                           |
                      |                                           |
                      |                                  /-------------------\
                      |                                  | Ethernet  USB 3.0 |
             /----------------\                          |                   |
             | HP Elite Desk  |                          | Raspberry Pi 5B   |
             | Gen 6          |                          | NVMe Gen 2 x 1    |
             | NVME Gen 3 x 4 |                          | or SD Card        |
             \----------------/                          \-------------------/       
               Windows - Host                                Linux - Host
          

The table below is for transfer a single 7.5GB file, "Subject-Contactor-CT_Scan.zip" from and to the Synology NAT (network attached storage).

Ethernet Transfer Speed of a 7.5GB file.
From To Seconds  Router
HP Elite Desk Gen 6 Synology 220 69 none
Synology 220 HP Elite Desk G6 69 none
       
RPi-5 with NVMe Gen 2 Synology 220 74 RPi-5
Synology 220 RPi-5 with NVMe Gen 3 69 RPi-5
       
RPi-5 with SD Card Synology 220 84 RPi-5
Synology 220 RPi-5 with sd Card 94 Rpi-5

Thus, the Raspberry Pi 5B with a Benfie USB-to-Ethernet adapter is plenty fast enough for a 1 Gbps Ethernet network.

Closing Thoughts

It looks like most Linux distros are using or switching to the "Network Manager" as their default network manager. The above code does not use the "Network Manager" to assign static IP address or the default gateway. I need to learn, how to do this with the "Network Manager".

Nordvpn NFT

Nordvpn has its own nftables. Unfortunately, Nordvpn will flush the nft rules in /etc/nftables.conf and install its own rules. This occurs even if Nordvpn is not connected.

However, after booting, you can install your own nft rules: with the command:

sudo nft -f /etc/nftables.conf

If you now execute:

sudo nft list ruleset

It will only list your ruleset and not Nordvpn's. However, Nordvpn is still working. In fact all host connected to this Linux router are going through Nordvpn.

If you want to have the list ruleset show both sets of rules, disconnect Nordvpn and then run your script or /etc/nftables.conf and afterwards reconnect to Nordvpn.

You can then disconnect and reconnect to Nordvpn, and both sets of rules will be active. Now all host connected to this Linux router, will go through Nordvpn. To the outside world, all host connected to this Linux router will all have the same IP address.

One way to accomplish this, is to not enable autoconnect on Nordvpn, and to use an on reboot cron job to load your nft ruleset and then connect to Nordvpn

References:

  1. Setting up a Linux Server as a Router
  2. Set Static IP Address
  3. YouTube - Tall Paul Tech - NAT is Not a Firewall
  4. VLANs - Raspberry Pi as a Router Using a Single Network Interface
  5. Jeff Geerling - Set a static IP address with nmtui on Raspberry Pi OS 12 'Bookworm'
  6. How to use the command 'nmtui' (with examples)
  7. Raspberry Pi Forums - How to setup static IP address on Raspberry Pi OS 64bit bookworm

Extra Networking References:

  1. YouTube - Practical Networks - Networking Fundamentals - Lesson 1a
  2. YouTube - Practical Networks - Networking Fundamentals - Lesson 1b
  3. YouTube - Practical Networks - Networking Fundamentals - Lesson 2a
  4. YouTube - Practical Networks - Networking Fundamentals - Lesson 2b
  5. YouTube - Practical Networks - Lesson 3 - OSI Model Part 1
  6. YouTube - Practical Networks - Lesson 3 - OSI Model Part 2
  7. YouTube - Practical Networks - Networking Fundamentals - Lesson 4 Part 1 - Switches
  8. YouTube - Practical Networks - Networking Fundamentals - Lesson 4 Part 2 - Switches
  9. YouTube - Practical Networks - Everything Routers do - Part 1 - Networking Fundamentals - Lesson 5
  10. YouTube - Practical Networks - Everything Routers do - Part 2 - How Routers forward Packets - Networking Fundamentals - Lesson 5
  11. YouTube - Practical Networks - Lesson 5 - Part 3 - Router Hierarchies and Route Summarization
  12. YouTube - Practical Networks - Lesson 6 - Network Protocols
  13. YouTube - Practical Networks - Lesson 7 - How Data Moves Through the Internet
  14. YouTube - Practical Networks - Network Protocols - ARP, FTP, SMTP, HTTP, SSL, TLS, HTTPS, DNS, DHCP - Networking Fundamentals - L6
  15. YouTube - Cisco - What is LAN | What is VLAN - Difference Explained