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

How do you configure IPTables so that it will only allow SSH in, and allow no other traffic in or out?

Any safety precautions anyone can recommend?

I have a server that I believe has been migrated away from GoDaddy successfully and I believe is no longer in use.

But I want to make sure just because ... you never know. :)

Note that this is a virtual dedicated server from GoDaddy... That means no backup and virtually no support.

share|improve this question
up vote 6 down vote accepted

You need just to set the default policy to DROP on the INPUT and OUTPUT chains.

To allow SSH in, you need the following commands:

$ sudo iptables -P INPUT DROP
$ sudo iptables -P OUTPUT DROP
$ sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
$ sudo iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED,RELATED -j ACCEPT

You can restrict the SSH access from specific IP using -s source_ip option.

share|improve this answer
--state RELATED on the last rule is unnecessary; --state ESTABLISHED is enough. You may also wish to allow DNS traffic, and probably should allow anything on the loopback interface, or all sorts of things may behave very oddly. – MadHatter Dec 21 '10 at 20:26
@MadHatter: Yes, you are right especially about the loopback stuff :) – Khaled Dec 21 '10 at 20:34
Thanks, would it be possible to get the entire file from you? ie, something I can copy and paste straight into /etc/sysconfig/iptables? I'm not experienced enough with this to trust my intuition to make the proper edits. – Disco Dec 21 '10 at 22:22
@Disco: I updated my answer – Khaled Dec 22 '10 at 10:10

Something like this:

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -j REJECT  # or iptables -P INPUT DROP

iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -j REJECT # or iptables -P OUTPUT DROP
share|improve this answer
I think you mean -i lo not -s lo; again, only ESTABLISHED is needed in the state rules, and there should probably be a --sport 22 in there, too. Why is everyone so keen to allow RELATED? – MadHatter Dec 21 '10 at 20:29
@MadHatter: About RELATED: It's actually useful for matching stuff that is non-TCP, like ping replies and DNS replies. At least, that's what I'd always assumed. – Steven Monday Dec 21 '10 at 20:34
My belief is that it will match neither of those. It would match, for example, an ICMP host-administratively-prohibited response, but that's about as helpful as it gets; and if not qualified, it will match any related traffic, not just traffic related to the previous line. – MadHatter Dec 21 '10 at 20:37
@MadHatter: I guess I'll have to run a few tests to see if you're right. Thanks for challenging my assumption. – Steven Monday Dec 21 '10 at 20:42
Yep, the ESTABLISHED state is all that's needed to match UDP DNS replies and ICMP echo-replies. – Steven Monday Dec 21 '10 at 21:03

This is very common scenario. You want to permit access to a remote machine only by SSH. You would like to block all incoming traffic to your system except ssh connection under Linux.

Add following rules to your iptables shell script:

/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT

/sbin/iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

First rule will accept incoming (INPUT) tcp connection on port 22 (ssh server) and second rule will send response of incoming ssh server to client (OUTPUT) from our ssh server source port 22.

However, iptables with kernel 2.4/2.6 provides very powerful facility to filter rule based upon different connection states such as established or new connection etc. Here is complete small script to do this task:


  • My system IP/set ip address of server


  • Flushing all rules

iptables -F

iptables -X

  • Setting default filter policy

iptables -P INPUT DROP

iptables -P OUTPUT DROP

iptables -P FORWARD DROP

  • Allow unlimited traffic on loopback

iptables -A INPUT -i lo -j ACCEPT

iptables -A OUTPUT -o lo -j ACCEPT

  • Allow incoming ssh only

iptables -A INPUT -p tcp -s 0/0 -d $SERVER_IP --sport 513:65535 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp -s $SERVER_IP -d 0/0 --sport 22 --dport 513:65535 -m state --state ESTABLISHED -j ACCEPT

  • make sure nothing comes or goes out of this box

iptables -A INPUT -j DROP

iptables -A OUTPUT -j DROP

This script is purely strict firewall. It only allows incoming ssh. No other incoming service or ping request or no outgoing service or request allowed. Incoming ssh connection can be either new or already established one and that is what specified by state rule '-m state --state NEW,ESTABLISHED'.

share|improve this answer
This is a copy paste from this webpage – max Jan 14 at 10:55

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.