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.


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 '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
  • 2
    ps. establish connection will be force closed after first command – user956584 Nov 26 '16 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 '17 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 '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
  • 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 '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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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