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.

2 Answers 2


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 -i lo -j ACCEPT
$ sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
$ sudo iptables -A OUTPUT -o lo -j ACCEPT
$ sudo iptables -A OUTPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

The last two commands allow loopback traffic as this is required by some applications to function correctly. You can restrict the SSH access from specific IP using -s source_ip option.

Executing the commands in order as shown above will cause your current SSH session to hang. This is because iptables commands take effect immediately. You need to execute them in a shell script to avoid losing the ability to connect to your machine when executing them remotely.

  • 4
    --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, 2010 at 20:26
  • @MadHatter: Yes, you are right especially about the loopback stuff :)
    – Khaled
    Dec 21, 2010 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, 2010 at 22:22
  • 2
    ps. establish connection will be force closed after first command
    – user956584
    Nov 26, 2016 at 0:49
  • 3
    You should really change the order of these commands. The Policy lines should appear as the last ones. Anyone just copypasting this into an ssh session will be HUPed and shut out immediately
    – AndreasT
    Apr 30, 2017 at 22:59

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
  • 1
    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, 2010 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. Dec 21, 2010 at 20:34
  • 2
    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, 2010 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. Dec 21, 2010 at 20:42
  • Yep, the ESTABLISHED state is all that's needed to match UDP DNS replies and ICMP echo-replies. Dec 21, 2010 at 21:03

You must log in to answer this question.

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