I have a Debian running device that needs to act as an internet-gateway. On top of that I want to provide a firewall that not only blocks inbound traffic, but also outbound traffic. And I figured iptables should be able to do the job.
The problem: I've configured NAT properly (I think?), but once I set the default policy to DROP and add rules to for instance allow HTTP traffic from inside the LAN, HTTP is not going through. So basically my rules don't seem to work.
Below is the initialization script that I use for iptables. The device has two NICs, respectively eth0 (the WAN interface) and eth1 (the LAN interface).
echo 1 > /proc/sys/net/ipv4/ip_forward # Flush tables iptables -F iptables -t nat -F # Set policies iptables -P INPUT DROP iptables -P OUTPUT DROP # NAT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT # Allow outbound HTTP from LAN? iptables -A FORWARD -i eth1 -o eth0 -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
Can anyone shed some light on this?
Solved: Mike suggested to use telnet and an IP instead of domain name to test HTTP traffic, and that led to two discoveries: DNS wasn't working properly and outbound filtering wasn't working either (I could telnet to port 8080).
So first of all I added rules to allow the LAN clients to use services of the gateway, DNS for instance. (And yes, don't worry, I'm going to narrow this down to offered services)
iptables -A INPUT -i eth1 -d 172.16.0.1 -j ACCEPT iptables -A OUTPUT -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
You'd think I'd be able to do DNS-requests now. And I actually could, but the requests were timing out because the gateway couldn't do DNS-requests itself. Rules for outbound DNS were added:
iptables -A OUTPUT -o eth0 -p tcp --dport 53 -j ACCEPT iptables -A OUTPUT -o eth0 -p udp --dport 53 -j ACCEPT
Finally I set default policy of the
FORWARD chain to
DROP. And we were back to square one.
I was about post an update when I saw Ram's reply that suggested I allow inbound traffic for existing connections. I also applied this principle on the
OUTPUT chain above.
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
So now it seems to be working exactly how I want it. Full script here. Thanks!