Trying to allow incoming ssh traffic on port 22. Default behavior is to DROP all incoming traffic.

I came across 2 articles on how to allow traffic. However, they are different.

## open port ssh tcp port 22 ##
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s -m state --state NEW -p tcp --dport 22 -j ACCEPT


# Allow all incoming SSH
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

It appears that the 1st one allows all traffic and then specifes a specific network. Seems like those are mutually exclusive?

What are the differences between these 2 and which one should I use?

  • 2
    it's not really a problem if iptables rules are mutually exclusive. Since iptables works chain based, the first rule that matches a packet will be applied, if a later rule would match the same packet it's simply ignored/not even checked. – mauro.stettler Aug 23 '13 at 1:13
  • 1
    I think the first one is for use on a Linux firewall/router, not on the SSH host. And the second is for use on the SSH host. I can't tell if you are configuring a gateway or the SSH server. – Dru Aug 23 '13 at 4:49
  • Webserver with SSH access – csi Aug 23 '13 at 16:22
up vote 16 down vote accepted

Both of those sets of rules have problems, and I wouldn't use either of them as-is.

In the first set, the first rule allows new incoming traffic to destination port 22 from anywhere. This isn't a problem.

The first problem is that the second rule allows new incoming traffic to destination port 22 from a specific subnet. This is completely redundant since the first rule has allowed traffic from anywhere.

My guess is that you read some tutorial which used these rules as (mutually exclusive) examples, advising you to select one or the other, but not both.

The second problem is that another rule is required before this rule to make the firewall fully stateful, and that rule is missing here. Without this rule, only the SYN packet would be allowed, and the connection would never complete.


The second set of rules has a similar problem. I don't know who originally wrote this ruleset, but it's been widely copied all over the Internet. It seems to have been written by someone who was unfamiliar with stateful firewalls in general, or iptables in particular.

In this ruleset, the input rule allows new and established incoming traffic to destination port 22 from anywhere. Then, the output rule allows established traffic from source port 22 to anywhere. This is essentially a mirror of the first rule and something like it is required if your default policy on outgoing traffic is to drop or reject it.

The problem is that these outbound rules become redundant very fast, which leads to performance issues as well as comprehension problems for any humans who have to read the rules later. If you are dropping outgoing traffic, only one rule is needed for established outgoing traffic (matching allowed incoming traffic) on any port, regardless of how many incoming ports you allow.


For a host firewall where the default input policy is to deny trafic and the default output policy is to permit traffic, most all of your rules will be in the INPUT table. It's sufficient to have the stateful rule and then rules to open ports for any incoming traffic you need.

For example, to allow ssh and http connections:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

If you're also denying output traffic by default, then you need to allow the return traffic for these allowed inbound connections as well.


And that is a firewall that's about as simple and effective as iptables can be.

  • 2
    Excellent, thorough answer. – Joel E Salas Aug 23 '13 at 1:38
  • Wish I could upvote this answer 2x. – csi Sep 6 '13 at 17:49
  • @MichaelHampton As a general rule of thumb, should we decline Output traffic by default? Simple webserver with outbound mail and mysql database – csi Sep 6 '13 at 17:58
  • @ChristopherIckes It depends on your security policy and your goals. It's not generally harmful, so long as you actually allow necessary outbound traffic for your applications. – Michael Hampton Sep 6 '13 at 18:03

The top one seems a little confused about what it's trying to do, it only seems to be allowing ssh packets in if iptables hasn't seen traffic in both directions, very strange.

The bottom one is much more sensible but the 2nd line is redundant unless you have a policy of other than ACCEPT on your OUTPUT chain. (iptables -L and look for "Chain OUTPUT (policy XXXXXX)").

You probably just want the first line of the bottom set.

line 1 of First Set will allow INBOUND port 22 traffic if connection = NEW CONNECTION. Line 2 of First set seems to be not necessary due to only allows port 22 traffic for a set network range also must be a new connections. Howver the previous rule on line 2 has already allowed the traffic through.
This seem wrong or incomplete

2nd set line 1, Allow INBOUND traffic on the0 if port = 22 and is new or established connections Line 2, Alllow OUTBOUND traffic if device = eth0 & port = 22 & connection is established

This will allow SSH connections to this host and will also allow outgoing SSH.

2 nd set is your better option

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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