Linux – iptables: Allow only HTTP access for web browsing

firewalliptableslinux

Have a linux box, want it locked down but just be able to surf internet on it. Why is this script blocking http too?

#!/bin/sh
#
#
iptables -F

#
#Set default policies for INPUT, FORWARD and OUTPUT chains
#
iptables -P INPUT DROP                
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

#
# Allow TCP connections on tcp port 80
#
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

#
# Set access for localhost
#
iptables -A INPUT -i lo -j ACCEPT


#
# List rules
#
iptables -L -v

Best Answer

Because the rule

iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

with a DROP policy on the OUTPUT chain requires two things which are highly relevant here:

  1. The connection must already have been established
  2. The source port must be 80/tcp

Source ports below 1024 are privileged, and generally aren't used for outgoing connections even when the socket owning process is running as root. You are more likely to see a high source port number going out, well above 30000 seems to be common.

There is also no way to establish a connection, since the only outgoing traffic that is allowed must be related to an already established connection.

Hence, in practice, nothing can match this rule.

Try instead:

iptables -A OUTPUT -o eth0 -p tcp --dport 80 -j ACCEPT

which should allow any outbound connections to destination TCP port 80 where the traffic is routed through eth0, which is much more in line with what you want.

And then as has been pointed out, don't forget about HTTPS, DNS, ...

Related Question