I am just getting started with iptables and stumbled across something I don't really understand.

FYI, I followed the instructions of Ubuntu wiki's IptablesHowTo.

The nat and mangle tables are empty, I'm only working with the filter table right now.

The problem

If I add the following iptables rules:

iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -j DROP

... then I still have access to my machine via ssh, however all iptables commands take about a minute or two to run. It's not a DNS problem, -n doesn't change it.

The solution

If I flush the table and add these three rules instead, everything is working fine:

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -j DROP

Can someone explain to me, why the first rule has such a great impact on iptables? I understand that it allows established sessions to receive traffic, but why do I need it if ssh is open?

  • In some cases, sudo does DNS lookups and if these are blocked, the command will be slow. Are all your other iptables commands prefixed with sudo?
    – Ladadadada
    Dec 28, 2013 at 11:50
  • Run sudo strace … (from a root shell) to see what it's blocking on. Dec 28, 2013 at 23:19

2 Answers 2


It's performing a DNS lookup and since the response is blocked, it takes a while to time out.

Try doing iptables -n ... to prevent DNS lookup.

The conntrack allows connections to be received on the ephemeral port that was created for responses to requests that was initiated by your machine (in this case the DNS request). Without allowing ESTABLISHED or RELATED connections, even responses to your requests are blocked.

EG: If you attempt to go to a website, even though you would be able to send the request for the website, the website's response would be blocked.



iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -j DROP

your machine will drop each incoming packet unless it comes from the SSH port. It's a good idea if you want that machine to comunicate only via SSH. Otherwise you need to add

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

that will make you sure you're going to connect to some web server rather than getting connected from somebody.

  • While good advice in general, this doesn't answer the question that was actually being asked. Dec 28, 2013 at 13:02
  • @Shadur conntrack makes the difference. This opposes drop all.
    – Nils
    Dec 28, 2013 at 14:13
  • If you send a generic request to a web server through a machine like in this case, this last one will show nothing since the firewall doesn't allow sending packets to a machine with an established connection.
    – edmz
    Dec 28, 2013 at 14:28
  • But even if I would only allow ssh using just the first two commands, why do iptables commands take so much longer than with the conntrack rule... And does the conntrack rule mean that I could connect to a webserver? Wouldn't that make the drop rule useless?
    – mohrphium
    Dec 28, 2013 at 22:14
  • No, it would not. With -m conntrack you can have another "chance" that the packets get accepted before they are going to be dropped for sure. On the client machine, you need to have iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT if you want to see some answer. On the server side, just allow SSH incoming connection and drop everything else (if the server acts only as an SSH one). Hope everything is clear.
    – edmz
    Dec 29, 2013 at 13:26

You must log in to answer this question.

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