6

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
3
  • You probably need to also include port 443 for HTTPS, unless you expect to only be browsing websites that do not require you to log in. Commented Jul 2, 2012 at 14:05
  • Oh yea and 53 for dns... i'm running it in virtualbox but even the above won't let me visit non-https pages. Commented Jul 2, 2012 at 14:16
  • You won't be able to visit http pages if you have DNS blocked, unless you're giving it an IP to go to. Also, this isn't "HTTP-only" access, it's "port 80-only" access. There's a subtle difference in there. Commented Jul 2, 2012 at 14:24

6 Answers 6

3

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, ...

2

Looking at these two rules you have

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

What you have is what you'd say to allow incoming, to a web server you run.

What you have is identical to what this webpage says For allowing incoming.. http://crm.vpscheap.net/knowledgebase.php?action=displayarticle&id=29

6. Allow Incoming HTTP and HTTPS

The following rules allow all incoming web traffic. i.e HTTP traffic to 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

But you want to allow outgoing, according to your question. You can consult that webpage again

Here is an example to allow outgoing.

iptables -A OUTPUT -o eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

It's clear on that webpage, it looks like you were consulting the wrong section.

So both the rules you had were wrong.

2
iptables -I  INPUT 1 -i lo -j ACCEPT
iptables -I  INPUT 2 -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I  INPUT 3 -j DROP
iptables -I  OUTPUT 1 -o lo -j ACCEPT
iptables -I  OUTPUT 2 -p tcp -m multiport --dports 80,443 -j ACCEPT 
iptables -I  OUTPUT 3 -j DROP
iptables -I  FORWARD 1  -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I  FORWARD 2 -j DROP

Lets not make our rules more complex than needed.

NEVER block the loopback adapter.

------INPUT

  1. DNS and web surfing and etc only generated traffic based on output, therefore is considered RELATED or ESTABLISHED.
  2. DROP everything else because it isn't needed.

-----OUTPUT

  1. Accept LO
  2. You want to only accept web traffic 80,443 are those ports DROP the leftovers

-----FORWARD

If you have 1 nic there shouldn't be much traffic here, but same thing applies if it isn't RELATED or ESTABLISHED we just don't want it.

1

If possible, try to flush ip tables and see if you actually can connect via http. (iptables -F)

Like Darth Android was saying, make sure you aren't trying to connect via https.

Also, do you have more than one ethernet interface? Or is your ethernet interface called something else besides eth0. a quick ifconfig will show you what your interface names are.

1
  • its eth0, i can't even visit a website when i paste the ip into my browser. Iptables -L -v shoes many packets being dropped on the output chain so somehow i dont have even port 80 open correctly. Commented Jul 2, 2012 at 14:31
0

You also need to allow ICMP in both directions or path MTU discovery and error recovery by trying a different IP address will be broken.

Generally you want to allow all ESTABLISHED and RELATED traffic.

0

Well if you using google dns like me, then it should be something like this:

sudo ip6tables -P INPUT DROP
sudo iptables -P INPUT ACCEPT
sudo iptables -F

sudo iptables -A INPUT -i lo -p udp -s 127.0.0.1 -d 127.0.1.1 --sport 40000:65535 --dport 53 -m limit --limit 50/s -j ACCEPT
sudo iptables -A INPUT -i lo -p udp -d 127.0.0.1 -s 127.0.1.1 --dport 40000:65535 --sport 53 -m limit --limit 50/s -j ACCEPT
sudo iptables -A INPUT -p udp -s 8.8.4.4 --sport 53 -m limit --limit 50/s -j ACCEPT
sudo iptables -A INPUT -p udp -s 8.8.8.8 --sport 53 -m limit --limit 50/s -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport --sports 443,80 -m state --state NEW,ESTABLISHED -m limit --limit 50/s -j ACCEPT
sudo iptables -P INPUT DROP
1
  • Welcome to SuperUser! It is recommended that you generalize your answers a bit more and give more details... Enjoy!
    – undo
    Commented Jan 7, 2016 at 16:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .