Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I thought the following was necessary was necessary for outgoing HTTP on a desktop (non-server):

iptables -A INPUT  -p tcp -m multiport --sports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

But, it turns out I need these two to make it work. I don't know why:

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

I know the last rule allows UDP to the lo interface.

But, I thought all I needed was outgoing TCP for NEW/ESTABLISHED connections + incoming TCP for ESTABLISHED connections. It seemed counter-intuitive to me (because I'm still learning).

share|improve this question
    
It seems that there must be other IPtables rules in place. It could be from a firewall or a captive portal system or a number of other things. – Shawn J. Goff Jun 29 '13 at 14:58

You obviously don't need lo for Internet access. But maybe you have a local DNS server (forwarder) running. DNS uses UDP, and web access requires DNS in addition to HTTP.

Your rules do not allow (related) ICMP responses BTW. That will probably lead to problems (unless you use lowered values for MSS/MTU). But you don't even allow outgoing ICMP so that path MTU discovery would't even work.

share|improve this answer

It will depend on whether or not the INPUT and/or OUTPUT chains are set to ACCEPT unmatched packets. If they are, you don't need any rules at all. If you haven't changed it this is probably the default.

Those last 2 rules allow any traffic from or to the lo interface (i.e. 127.0.0.1 / ::1), not just UDP. Unless you are connecting to a web server on the local desktop, they have no relevance to HTTP.

share|improve this answer
    
"Unless you are connecting to a web server on the local desktop...no relevance to HTTP": That's what I though too. The default policy is ACCEPT for all IN./FORW/OUT. The very last rules are -j DROP for IN./FORD/OUT. Nevertheless, there is something in the network or machine that is requires UDP packets sent to/from the loopback interface for internet access to work. I checked the logs: UDP to/from lo were dropped and that's when I could not access the internet. Internet access comes back by allowing tcp/udp/etc on the loopback interface. It's weird. – dgo.a Jun 29 '13 at 7:42

I can only make assumptions, because, you haven't listed your default policies. Found at the top of the output of iptables -S. I'll assume you're being restrictive and you have something like this.

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP

Great! Your machine is now completely invisible, blindfolded, bound and gagged with respect to IP packets. This is as almost as good as unplugging it from your Ethernet network.

So if you want to have hope in this cruel, dark world, you'll have to put some rules in place to accept some packets, maybe meet someone with a knife to cut your ropes with, but which packets are the right ones?

An output rule is needed to allow packets to reach ports the servers use for http/https traffic

-A OUTPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

An INPUT rule is needed to allow packets in to your browser from ports used for http/https traffic.

-A INPUT -p tcp -m multiport --sports 80,443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

So now you can ESTABLISH NEW http/https connections from your web browser, and receive information coming back through those ESTABLISHED connections.

What's the problem then? There is no way to get DNS information, you should be able to enter the ip address of websites you want to visit into your web browser, but that's not exactly what we want. DNS traffic is handled over port 53 with the UDP protocol.

-A OUTPUT -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

And to receive those handy replies, we'll need to cut some more holes in that blindfold.

-A INPUT -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Now there is some light, you can hear it, say if you make a dns query to one of google's servers

dig @8.8.8.8 slashdot.org

Such response! But maybe your browser still can't figure out where slashdot really is in the world. At least one distribution (Ubuntu) is setup to use an internal DNS proxy so you'll need to be able to talk to yourself (the rest of the world is boring anyway) by setting up rules to allow you to communicate as a server on port 53

-A OUTPUT -o lo -p udp --sport 53 -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -i lo -p udp --dport 53 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

Notice the subtle difference between these, "I'm my own server" rules, and the previous, "I just want to see the world rules". Also -o lo and -i lo indicate that this server will only serve this machine, a good measure to avoid being sucked into some complicated DNS bounce type attack.

You should now see that you're browser works again.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.