Server Fault is a question and answer site for system and network administrators. 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 am trying to configure a testserver based on CentOS 6.4. I have changed the default SSH port to another port, 56988. Now I am trying to create a set of rules in order to:

  • Allow connections on 56988 with a maximum (to prevent bruteforce)
  • Accept incoming and outgoing connections on 80 and 443, limited to prevent DOS attacks
  • Block everything else

In order to accomplish this, I have written a small bash script:

iptables -F

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

iptables -A INPUT -p tcp --dport 56988 -m state --state NEW -m recent --set --name ssh -rsource
iptables -A INPUT -p tcp --dport 56988 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name ssh -j DROP
iptables -A OUTPUT -p tcp --sport 56988 -m state --state ESTABLISHED -j ACCEPT

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

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

iptables -A INPUT -p tcp --dports 80,443 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 50/second --limit-burst 50 -j ACCEPT

/etc/init.d/iptables save

Though after running this, I am being blocked out through SSH. What am I doing wrong with this configuration? Thanks in advance!

share|improve this question
You have no rule to "allow connections on 56988". Everything for that port falls off your input chain and is rejected by the DROP policy. Could it be that you just forgot to change those 22's to 56988? – Karma Fusebox Mar 26 '13 at 22:25
As an aside: the canonical way to go about iptables in RHEL/Centos is to save the rules in /etc/sysconfig/iptables rather than writing a script for it. – tink Mar 26 '13 at 22:49
Yes Karma, you're right. While testing I have changed these values, should be 56988. Though that has been tested too. – Aquillo Mar 27 '13 at 6:32
Well, I still don't see a rule to accept connections on port 56988. Somthing like: iptables -A INPUT -p tcp --dport 56988 -m state --state NEW -j ACCEPT – Laurentiu Roescu Mar 27 '13 at 7:11
up vote 3 down vote accepted

I'm glad to see you've clarified the issue with respect to port numbers. Now, all I'm doing is formalising the comments by Karma Fusebox and Laurentiu Roescu, because they've identified the actual problem: you're specifying which ssh packets to drop, but never which ones to accept. You need to insert a line as follows:

iptables -A INPUT -p tcp --dport 56988 -m state --state NEW -m recent --set --name ssh -rsource
iptables -A INPUT -p tcp --dport 56988 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name ssh -j DROP
###### new line is the next one #########
iptables -A INPUT -p tcp --dport 56988 -j ACCEPT
###### new line was the previous one ####
iptables -A OUTPUT -p tcp --sport 56988 -m state --state ESTABLISHED -j ACCEPT

Do you see why? Your INPUT chain has a bunch of logic about rate-limiting, and rejects any packets that exceed the rate limit - but it then never makes any provision for those NEW packets which don't fail the rate-limit test, so they pass through the entire chain and die on the policy (DROP).

I would have just upvoted vasco.debian's answer, but the position of this new line is important. Because iptables works on a first-dispositive-match-wins basis, the new line must come after the rate-limiting lines; otherwise all NEW packets will match this new line, and never get tested against the rate-limiting line first.

share|improve this answer
Great answer MadHatter, thank you! +1 for the clear explanation. – Aquillo Mar 27 '13 at 11:22

The obvious problem is that you opened port 22, but put ssh listening on port 56988. This is what you need to change.

share|improve this answer
My fault, this was a problem due to a testversion. I have changed it accordingly. Though, still being locked out. – Aquillo Mar 27 '13 at 6:33

Is sshd listening on port 56988? By default, SELinux prevents sshd from binding to non-standard port.

share|improve this answer
Yes, as posted in the first line of the question, I have changed /etc/ssh/sshd_config by editing the line #Port 22 to Port 56988. After that a restart of the service ofcourse. – Aquillo Mar 27 '13 at 6:51
Anyway, you can investigate the problem this way: flush iptables counters, then take a look at iptables counters while trying to connect from remote host. Thus you can see what rule exactly are applied to SSH packets. – Gevial Mar 27 '13 at 7:07

Try following.

/sbin/iptable -I INPUT -p tcp --dport 56988 -j ACCEPT

This will insert rule at the top of INPUT chain

share|improve this answer

Your Answer


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.