Setting Up a Linux Machine as a Router for Your Home Network

I’m trying to set up an old PC running Ubuntu Server as a router for my home network. I’ve got two network cards installed: one connected to the modem, the other to a switch. The idea is to share the internet connection with my other devices, including a desktop running Windows 10.

I’ve read about using iptables for NAT and dnsmasq for DHCP/DNS, but the actual configuration is a bit overwhelming. I’ve tried following some guides, but I keep running into issues with the firewall rules or the DHCP server not assigning addresses.

Can someone walk me through the basic steps? Specifically:

What I need

  • A clear explanation of how to configure iptables for masquerading (NAT).
  • How to set up dnsmasq to serve DHCP and DNS to the LAN side.
  • Any essential tweaks like IP forwarding and persistent rules.

My current setup

  • WAN interface: enp0s3 (connected to modem, gets IP via DHCP from ISP).
  • LAN interface: enp0s8 (static IP 192.168.1.1/24).
  • Clients: Windows 10 desktop, a few other devices.

I’ve enabled IP forwarding (sysctl net.ipv4.ip_forward=1) and installed dnsmasq, but I’m not sure if my iptables rules are correct. Here’s what I tried:

sudo iptables -t nat -A POSTROUTING -o enp0s3 -j MASQUERADE
sudo iptables -A FORWARD -i enp0s3 -o enp0s8 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT

But clients can’t reach the internet. Ping to 8.8.8.8 fails from a client. dnsmasq seems to be running but maybe it’s not handing out the correct gateway?

Any help would be appreciated. I’m new to this and probably missing something obvious.

Topic Summary: Configure Ubuntu Server as a home router with iptables NAT and dnsmasq DHCP/DNS. Diagnose common misconfigurations and explore modern alternatives like nftables.

:open_book: Topic Overview (Wikipedia):

iptables is a user-space utility program that allows a system administrator to configure the IP packet filter rules of the Linux kernel firewall, implemented as different Netfilter modules. The filters are organized in a set of tables, which contain chains of rules for how to treat network traffic packets. Different kernel modules and programs are used for different protocols; iptables applies to IPv4, ip6tables to IPv6, arptables to ARP, and ebtables to Ethernet frames.
Read more on Wikipedia

:books: Official Documentation & Reference Links:

---
title: Linux Router Setup Process
---
flowchart TD
  Step1[Install Ubuntu Server]
  Step2[Configure Network Interfaces]
  Step3[Enable IP Forwarding]
  Step4[Configure iptables NAT]
  Step5[Install & Configure dnsmasq]
  Step6[Test Connectivity]
  Step1 --> Step2
  Step2 --> Step3
  Step3 --> Step4
  Step4 --> Step5
  Step5 --> Step6

Your iptables rules look correct at a glance, but there are a few common culprits that can break connectivity. Let’s step through the whole setup systematically.

Diagnosing the Issue

First, verify that IP forwarding is actually enabled. Run sysctl net.ipv4.ip_forward – it should return 1. If not, make sure you’ve edited /etc/sysctl.conf to set net.ipv4.ip_forward=1 permanently and rebooted or applied with sysctl -p.

Next, check your FORWARD chain default policy. By default, iptables often has a policy of DROP for the FORWARD chain. Even though you added ACCEPT rules, if the default is DROP, packets hitting the chain before your rules might still be dropped. Change the default policy to ACCEPT temporarily for testing: sudo iptables -P FORWARD ACCEPT. If that works, you can refine later.

Also, ensure that the WAN interface (enp0s3) has internet access. From the Ubuntu router itself, can you ping 8.8.8.8? If not, the issue is upstream.

dnsmasq Configuration

dnsmasq is often the source of DHCP problems. A minimal working configuration for your LAN interface would look like this:

interface=enp0s8
bind-interfaces
dhcp-range=192.168.1.50,192.168.1.150,12h
dhcp-option=3,192.168.1.1
dhcp-option=6,192.168.1.1

This tells dnsmasq to listen on the LAN interface, hand out IPs in that range, and advertise the router’s LAN IP as both gateway and DNS. Restart dnsmasq after saving.

Persistence

Your iptables rules will vanish on reboot. To make them permanent, you can install iptables-persistent or save the rules manually:

sudo netfilter-persistent save

Modern Alternatives

While a manual iptables setup is educational, you might consider these modern approaches:

  • nftables: The successor to iptables, with simpler syntax and better performance. On Ubuntu 20.04+, nftables is the default. A basic NAT ruleset:
table ip nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        oifname "enp0s3" masquerade
    }
}
table ip filter {
    chain forward {
        type filter hook forward priority filter; policy drop;
        iifname "enp0s8" oifname "enp0s3" accept
        iifname "enp0s3" oifname "enp0s8" ct state related,established accept
    }
}
  • systemd-networkd: Can handle bridging and routing with simple config files, reducing the need for iptables altogether.
  • Dedicated firewall distros: For production home networks, consider OPNsense or pfSense – they package firewall, DHCP, DNS, and VPN into a web interface.

Why Clients Fail to Reach the Internet

If dnsmasq hands out IPs but clients can’t ping external IPs, the issue is likely one of these:

  1. FORWARD chain default DROP – as mentioned.
  2. WAN interface not getting default route – check ip route show on the Ubuntu router. Should have a default via your ISP’s gateway.
  3. Client gateway not set to 192.168.1.1 – verify on the client with ipconfig (Windows) or ip route.
  4. ISP modem doing double NAT – if your modem is already a router, the Ubuntu machine is behind it, and you need to either put the modem in bridge mode or use a different subnet.

Final Thoughts

Setting up a Linux router is a fantastic way to learn networking deeply. Once you get past the initial hurdles, you’ll appreciate the control and flexibility. For a home network, you might also look into ad-blocking via Pi-hole running on the same machine, or VPN server for remote access. But get the basics stable first.

Test step by step: confirm WAN connectivity on the router, then check client can ping the router’s LAN IP, then ping 8.8.8.8, then check DNS resolution. That’ll pinpoint exactly where the chain breaks.