Table of Contents
- Prerequisites
- Understanding iptables Basics
- Planning Your Firewall Rules
- Setting Up the Firewall: Step-by-Step
- Saving and Restoring Rules
- Testing Your Firewall
- Troubleshooting Common Issues
- Advanced Configurations
- Conclusion
- References
Prerequisites
Before diving in, ensure you have the following:
- A Linux Machine: Any Linux distribution (e.g., Ubuntu Server, Debian, CentOS) will work. A low-power device like a Raspberry Pi, old laptop, or mini-PC is ideal (it will act as your firewall/gateway).
- Two Network Interfaces: One for the WAN (connects to your modem/ISP) and one for the LAN (connects to your home network switch). Most modern machines have Ethernet ports; use USB-Ethernet adapters if needed.
- Basic Linux Knowledge: Familiarity with the command line (e.g.,
ssh,sudo, editing files withnano/vim). - Root Access: You’ll need
sudoprivileges to modify iptables rules. - Network Information: Know your LAN subnet (e.g.,
192.168.1.0/24), WAN interface (e.g.,eth0), and LAN interface (e.g.,eth1).
Understanding iptables Basics
Iptables is a user-space utility for configuring Linux kernel firewall rules. It filters traffic based on tables, chains, and rules:
-
Tables: Collections of chains. The most common are:
filter: Default table for packet filtering (INPUT, OUTPUT, FORWARD chains).nat: For network address translation (e.g., masquerading for LAN internet access).mangle: For modifying packet headers (rarely used in home setups).
-
Chains: Predefined sequences of rules that packets traverse:
INPUT: Packets destined for the firewall itself.OUTPUT: Packets originating from the firewall.FORWARD: Packets passing through the firewall (e.g., from LAN to WAN).
-
Rules: Conditions that packets must match. If a packet matches, an action is taken:
ACCEPT: Allow the packet.DROP: Silently discard the packet (no response sent).REJECT: Discard the packet and send an error response (e.g., “Connection refused”).
Planning Your Firewall Rules
A secure firewall starts with a clear policy. For home use, we recommend a “deny-by-default” approach: block all traffic unless explicitly allowed. Ask:
- Which services do I need to expose to the internet? (e.g., none—most home users don’t need public servers.)
- Which devices need to communicate with each other on the LAN? (e.g., laptops, smart TVs, printers.)
- What outbound traffic should be allowed? (e.g., web browsing, streaming, gaming.)
Example Network Topology:
[Modem/ISP] ←→ [Linux Firewall (WAN: eth0)] ←→ [LAN Switch (eth1)] ←→ [Home Devices: Laptops, Phones, IoT]
Setting Up the Firewall: Step-by-Step
Let’s configure iptables from scratch. Replace eth0 (WAN) and eth1 (LAN) with your actual interface names (check with ip addr).
Step 1: Flush Existing Rules
Start with a clean slate by flushing all existing rules and deleting custom chains:
sudo iptables -F # Flush filter table
sudo iptables -t nat -F # Flush nat table
sudo iptables -X # Delete custom chains
sudo iptables -t nat -X
Step 2: Set Default Policies
Default policies define what happens to packets that don’t match any rule. For security:
- Block all unsolicited inbound traffic (
INPUT). - Block forwarded traffic unless explicitly allowed (
FORWARD). - Allow all outbound traffic from the firewall itself (
OUTPUT).
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
Step 3: Allow Loopback Traffic
The loopback interface (lo) is critical for internal system communication (e.g., between services on the firewall). Allow it:
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
Step 4: Allow Established/Related Connections
If the firewall initiates a connection (e.g., you browse a website), allow responses to that connection:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
conntrack: Tracks connection states (ESTABLISHED = active connection, RELATED = new connection related to an existing one).
Step 5: Allow Inbound Traffic from the LAN
Permit traffic from your home network (LAN) to the firewall (e.g., SSH for management, file sharing):
Example 1: Allow SSH Access from LAN
Restrict SSH (port 22) to your LAN subnet (e.g., 192.168.1.0/24):
sudo iptables -A INPUT -i eth1 -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
Example 2: Allow HTTP/HTTPS for a Home Server
If running a web server (e.g., Pi-hole, Plex) on the firewall, allow LAN access to ports 80 (HTTP) and 443 (HTTPS):
sudo iptables -A INPUT -i eth1 -s 192.168.1.0/24 -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -i eth1 -s 192.168.1.0/24 -p tcp --dport 443 -j ACCEPT
Example 3: Allow ICMP (Ping) from LAN
Let LAN devices ping the firewall for troubleshooting:
sudo iptables -A INPUT -i eth1 -s 192.168.1.0/24 -p icmp --icmp-type echo-request -j ACCEPT
Step 6: Block Unwanted Inbound Traffic
Block traffic from known malicious IPs or restrict dangerous protocols (e.g., UDP ports used for DDoS):
# Block a specific malicious IP (replace with actual IP)
sudo iptables -A INPUT -s 1.2.3.4 -j DROP
# Block inbound UDP ports except those explicitly allowed (optional)
sudo iptables -A INPUT -p udp -j DROP
Step 7: Configure Outbound Traffic
By default, we allowed all outbound traffic from the firewall (OUTPUT policy = ACCEPT). To restrict outbound traffic (e.g., block the firewall from accessing risky sites):
# Block outbound traffic to a malicious IP
sudo iptables -A OUTPUT -d 5.6.7.8 -j DROP
# Restrict outbound SSH from the firewall (only allow to LAN)
sudo iptables -A OUTPUT -p tcp --dport 22 ! -d 192.168.1.0/24 -j DROP
Step 8: Set Up NAT for LAN Internet Access
To let LAN devices access the internet, enable masquerading (NAT) on the WAN interface. This replaces LAN private IPs with the firewall’s public WAN IP:
# Enable IP forwarding (required for NAT)
sudo sysctl -w net.ipv4.ip_forward=1
# Make it persistent (survive reboot)
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
# Add masquerading rule in the nat table
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Now, allow forwarded traffic from LAN to WAN (and vice versa for responses):
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT # LAN → WAN
sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # WAN → LAN (responses)
Saving and Restoring Rules
Iptables rules are temporary—they vanish after a reboot. To save them permanently:
On Debian/Ubuntu:
Use the iptables-persistent package:
sudo apt install iptables-persistent # Install
sudo netfilter-persistent save # Save rules to /etc/iptables/rules.v4
sudo netfilter-persistent reload # Restore rules (e.g., after editing)
On RHEL/CentOS:
Save rules to /etc/sysconfig/iptables:
sudo iptables-save > /etc/sysconfig/iptables
# Restore on boot (enabled by default with iptables.service)
sudo systemctl enable iptables
Testing Your Firewall
Verify your rules work as expected with these steps:
-
List Rules: Check active rules with:
sudo iptables -L -v # -v = verbose (shows packet counts) sudo iptables -t nat -L # Check NAT rules -
Test LAN Access:
- From a LAN device, ping the firewall:
ping 192.168.1.1(replace with firewall’s LAN IP). - SSH into the firewall:
ssh [email protected].
- From a LAN device, ping the firewall:
-
Test Internet Access:
- From a LAN device, browse a website (e.g.,
google.com). If it fails, check NAT rules.
- From a LAN device, browse a website (e.g.,
-
Test Inbound Blocking:
- From outside your LAN (e.g., a phone on mobile data), scan the firewall’s public IP with
nmap <public-ip>. No ports should be open unless explicitly allowed.
- From outside your LAN (e.g., a phone on mobile data), scan the firewall’s public IP with
Troubleshooting Common Issues
- Locked Out of SSH: If you accidentally block SSH, connect via a physical console and flush rules (
sudo iptables -F). - LAN Devices Can’t Access Internet: Ensure
net.ipv4.ip_forward=1is set, and NAT masquerading is enabled (iptables -t nat -L). - Rules Not Saving: Verify
iptables-persistentis installed (Debian/Ubuntu) or rules are saved to/etc/sysconfig/iptables(RHEL/CentOS).
Advanced Configurations
Port Forwarding
To expose a LAN service to the internet (e.g., a home web server at 192.168.1.100:80):
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
sudo iptables -A FORWARD -i eth0 -p tcp --dport 80 -d 192.168.1.100 -j ACCEPT
Limit SSH Brute-Forces
Use the recent module to block repeated SSH login attempts:
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --rcheck --seconds 60 --hitcount 5 -j DROP
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh_brute --set -j ACCEPT
- Blocks IPs with 5+ SSH attempts in 60 seconds.
Conclusion
Building a home firewall with iptables gives you granular control over your network security. By following this guide, you’ve created a robust barrier against threats while allowing essential traffic. Remember to update rules regularly (e.g., block new malicious IPs) and test changes in a safe environment.
For even more simplicity, consider frontends like ufw (Uncomplicated Firewall) or firewalld, but iptables remains the gold standard for flexibility.