Convert a Linux machine into a Router
Ever wanted to build a router? Ever wondered how router works internally? If any of the question is "YES", then this blog is for you (🫵).

Search for a command to run...
Ever wanted to build a router? Ever wondered how router works internally? If any of the question is "YES", then this blog is for you (🫵).

No comments yet. Be the first to comment.
Security dashboards are lying to you. That critical CVE flagged in your dependency scan? Odds are, your application never touches the vulnerable code path. The result is alert fatigue, wasted engineer

Harbor is an enterprise-class private container registry with advanced features like RBAC, replication, vulnerability scanning, and more. In this guide, we'll set up Harbor on a Ubuntu machine, secure it with Let's Encrypt certificates, and use Cloud...

Introduction This document provides a step-by-step guide to installing and configuring the AWS CLI and Pulumi on Ubuntu 24.04. Prerequisites Ubuntu 24.04 installed and configured. A user account with sudo privileges. An active AWS account. 1. In...

What motivated me to do this? While reading the book Container Security, a strange question popped into my head. Since everything inside a container is essentially a process running on the host machine's Linux kernel, what about creating nested conta...

Introduction This document outlines the procedures for creating AWS Access Keys for both IAM users and IAM Identity Center (Federated) Users. These credentials are used for programmatic access to AWS services, enabling applications and tools to inter...

I've used VMware workstation for virtualization. You can use Virtual Box and follow this steps. Just interface name will be different.
Also, ubuntu server 22.04 iso is used for creating 3 virtual machines - client, router, server.
vmnet8: NAT - 192.168.22.0/24 - DHCP (for internet connection)
vmnet2: Host-only - 10.10.1.0/24
vmnet3: Host-only - 10.10.2.0/24
Create a VM using ubuntu server 22.04 iso image.
It will use the following configurations:
RAM: 2048 MB
Processors: 1
Network Adapter 1 → vmnet8
Network Adapter 2 → vmnet2
Network Adapter 3 → vmnet3
Setup the configuration of these 3 interface in /etc/netplan/*.yaml file.
network:
ethernets:
ens33:
dhcp4: true
ens36:
addresses: [10.10.1.1/24]
ens37:
addresses: [10.10.2.1/24]
version: 2
The above configuration:
Enables the DHCP protocol on ens33 interface. IP and gateway address will be set dynamically.
Sets IP address of ens36 interface.
Sets IP address of ens37 interface.
Change permission: sudo chmod 600 *.yaml
Apply the change: sudo netplan apply
Stop and remove UFW firewall.
sudo systemctl stop ufw
sudo apt purge ufw
Clone the router VM. Go to settings and delete adapter 1, 3.
Configure the interface using netplan. in /etc/netplan/*.yaml file.
network:
ethernets:
ens36:
addresses: [10.10.1.10/24]
routes:
- to: default
via: 10.10.1.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
version: 2
The above configuration:
Sets device IP address (10.10.1.10) and Netmask (/24).
Sets any destination IP address route except this network will go to specific gateway (10.10.1.1).
Apply the change: sudo netplan apply
Clone the router VM. Go to settings and delete adapter 1, 2.
Configure the interface in /etc/netplan/*.yaml file.
network:
ethernets:
ens37:
addresses: [10.10.2.20/24]
routes:
- to: default
via: 10.10.2.1
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
version: 2
Apply the change: sudo netplan apply
Now both client and server can communicate with the router.
Client (or Server) VM can't ping the Router VM?
Ping client (or server) from the router.
This will invoke the ARP request to get the MAC address of client (or server).
Router need to forward packet from one interface to another. Thant's why we need to enable packet forwarding.
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
From the configured infrastructure, we know that two host-only network is in 10.10.1.0/24 & 10.10.2.0/24 range. Devices connected in these network is configured with 10.10.1.1 & 10.10.2.1 IP address respectively as Gateway IP.
(we don't need to configure MAC address manually. All interface will get the MAC address through ARP broadcast, if they don't have it in cache.)
The router has three network interfaces; ens36 & ens37 for two different host-only network and ens33 for internet-facing connection.
Now your packet from client (or server) can go to routers appropriate interface. If the packet goes from one network to another, the gateway would not recognize the source IP. It will send ARP request to the network to get MAC address of the source IP. If it doesn't get response, it will drop it.
So, to send the packet of different network, we are going to change the source IP address with interfaces own IP address.
We will run the following two rules in router VM to do IP Masquerading when the packet is coming form 10.10.1.0/24 and 10.10.2.0/24 network.
sudo iptables -t nat -s 10.10.1.0/24 -A POSTROUTING -j MASQUERADE
sudo iptables -t nat -s 10.10.2.0/24 -A POSTROUTING -j MASQUERADE
Now, say a device in local network with IP address 10.10.1.10 wants to access a website on the internet. When the device sends a packet to the gateway, the iptables rule kicks in.
The source IP address (10.10.1.10) of the outgoing packet is dynamically replaced with the routers private IP address of the ens33 interface.
This is called IP Masquerading. In this process, nothing is changed except the source IP.
I have used tcpdump to check the source and destination IP address of a packet in every interface.
The following table shows when a packet is going form client machine to server machine:
| Client Interface | Router Interface | Server Interface |
| ens36: 10.10.1.10 > 10.10.2.20 | ens36: 10.10.1.10 > 10.10.2.20 ens33: - ens37: 10.10.2.1 > 10.10.2.20 | ens37: 10.10.2.1 > 10.10.2.20 |
The following table shows when a packet is going from server machine to internet:
| Server Interface | Router Interface | Client Interface |
| ens37: 10.10.2.20 > 1.1.1.1 | ens36: - ens33: 192.168.22.132 > 1.1.1.1 ens37: 10.10.2.20 > 1.1.1.1 | ens36: - |
When a packet comes, linux kernel checks the routing table to determine the appropriate interface for the packet.
If the packet was destined for the internet, the routing table directs the packet to the ens33 interface. After going to that interface, in POSTROUTING chain, the source IP is changed to current interface's IP.
If the packet was destined for the server VM, the routing table would direct the packet to ens37 interface. Similar to above, the source IP would change.