Build a Linux Gateway Router VM Using Ubuntu 24.04 and nftables
In previous articles, of this DevOps Home lab Series, we created multiple VMs and configured Static IP addresses so they can communicate reliably within our lab network.
However, in real-production environments, services are very rarely exposed directly to the internet.
Instead, traffic typically flows through an intermediate system such as a gateway or router, which controls how these internal machines will access the external network.
In this article, we will build a Linux Gateway Router VM that connects our internal lab network to the outside network.
Why not iptables?
Historically, Linux systems used iptables to configure firewalls and NAT rules.
Many production environments still use iptables today, especially in older infrastructure.
However, modern Linux distributions such as Ubuntu 22.04 and Ubuntu 24.04 now use nftables as the default packet filtering framework.
In fact, many systems that appear to use iptables today are actually using iptables-nft, which translates iptables commands into nftables rules internally.
Compared to iptables,nftables offers:
Cleaner and more consistent syntax
Better performance with large rule sets
Unified IPv4 and IPv6 support
Improved maintainability
For this reason, in this homelab we will use nftables, which represents the modern Linux firewall system.
Network Design
The Gateway VM will have two network interfaces
Interface 1: External Network
Connected to
NAT (vnet8)Receives IP from DHCP in range
172.18.18.0/24
Interface 2: Internal NetworkConnected to
devops network (vnet2)Static IP:
172.29.10.254/24
All the machine in the internal devops network will use:172.29.10.254 as their default gateway
Step 1: Create The Gateway VM
Create a new VM with following configurations
Name: ubuntu24gw
CPU: 1 processors, 2 cores
Memory: 1 GB (2 GB Recommended)
Disk: 10 GB (20 GB Recommended)
Network Adapters: Two network adapters are required.
Keep default adapter to
NATAfter creating the VM add a second adapter via
VM > Setting > Add... > Network Adapterand selectCustom > devops(host-only)
Step 2: Configure Static IP For Internal Interface
Refer to the previous post, and setup static IP 172.29.10.254/24 on 2nd interface
TIP: Instead of creating new YAML as shown in previous article, you may directly modify
50-cloud-init.yaml
Edit
/etc/netplan/50-cloud-init.yamland enter the following content and ensure the interface names match with actual interface names which can be seen usingip anetwork: version: 2 ethernets: ens33: dhcp4: true ens34: addresses: - 172.29.10.254/24Run
sudo netplan tryand check if you can ping172.29.10.254from host or any other VM. It may take about 20 to 40 seconds for the first successful pingOnce sure apply the settings using
sudo netplan apply
Step 3: Enable IP Forwarding
For any Linux system to work as a router, IP Forwarding must be enabled
- We can enable it temporarily:
sudo sysctl -w net.ipv4.ip_forward=1
To make changes permanent, edit
/etc/sysctl.confand edit the following linenet.ipv4.ip_forward=1And apply the changes using
sudo sysctl -p
Step 4: Install nftables
Ubuntu server version > 22 are shipped with nftables by default. But if not you can install and enable it by following commands:
sudo apt-get update
sudo apt-get -y install nftables
sudo systemctl enable nftables
sudo systemctl start nftables
Step 5: Configure NAT (Masquerading)
Masquerading changes the source IP address of outgoing packets from a private IP to a public IP , so that internal devices can communicate with external networks, like the Internet, while hiding their private IP addresses
Edit nftables configuration file
sudo nano /etc/nftables.confAdd below contents inside it
flush ruleset
table ip nat {
chain postrouting {
type nat hook postrouting priority 100;
oifname "ens33" masquerade
}
}
table ip filter {
chain forward {
type filter hook forward priority 0;
policy accept;
}
}
- The above configuration does following things:
- Removes default configuration
- Enables *NAT Masquerading*
- Allows traffic forwarding between interfaces
- Restart nftables to apply the configuration
```sh
sudo systemctl restart nftables
```
- Verify the rules:
```sh
sudo nft list ruleset
NOTE:
In this lab we allow all forwarded traffic usingpolicy acceptfor simplicity
In real production environments, firewall policies usually default toDROPand only explicitly allowed traffic is permitted
Step 6: Updating VMs Network and Verifying
Finally, ensure that all machines on internal network has their default gateway set to : 172.29.10.254 and then try to ping www.google.com
If everything is configured correctly, the ping should succeed. Meaning machines on internal network can access the internet.
What's Next?
In the next article, we will set up our host machine as an Ansible control node using WSL2.
This controller will be responsible for managing and automating the configuration of all servers inside our DevOps homelab.
With this final step, we will complete the core architecture of our DevOps homelab environment.
Series Roadmap
Building a Gateway VM for Multi-VM Lab Architecture ✅
Setting Up an Ansible Control Node Using WSL2 and Final Lab Architecture Overview

