Skip to content


A quick iptables mini-guide

I’ve always had trouble dealing with iptables. So instead of trying to do some extensive configuration, I figured I’d start small by temporarily configuring a few things and wrapping them up in a post here.

Before going further, a small note about IPv6: iptables only deals with IPv4 traffic. For IPv6, you’ll have to use ip6tables. I didn’t really look at it much for the moment, but the commands seems pretty similar.

First, the command to list all rules:
iptables -n -L
NB: the -n is an extra option to avoid doing reverse DNS lookups (they can take a while, so you may want to avoid them when you have more than a few rules).

If you want, for instance, to list only the input rules, then it’s like:
iptables -n -L INPUT

For a more verbose output (notably, with packets and bytes count):
iptables -nv -L INPUT

Now before you start messing around, you may want to backup your current configuration:
iptables-save > myIptablesBackup.txt
To restore it later:
iptables-restore < myIptablesBackup.txt
NB: restoring a backup will first flush the configuration, then apply the backup. If you want to avoid the flush, specify -n (aka --noflush). But if you don't flush when restoring, the restored configuration will be added to the current one, even if this results in duplicates.

To block all traffic from a specific IP:
iptables -A INPUT -s 91.121.23.114 -j DROP
(NB: this example IP is one currently really performing server scans, notably looking for poorly secured phpMyAdmin installation)

To block all traffic from an IP range:
iptables -A INPUT -s 91.121.23.0/24 -j DROP
(NB: this one, although inspired from the above-mentioned IP, is NOT a real problematic IP range)

Now, to be a bit more subtle, you may want to block only a specific protocol and port. For this you use respectively the parameters -p and --dport. For instance, to block TCP on port 80:
iptables -A INPUT -s 91.121.23.114 p tcp --dport 80 -j DROP
It is to be noted that --dport doesn’t seem to work when specified without a protocol. My limited knowledge in networking doesn’t allow me to understand the rationale behind this, I suppose some protocols don’t use ports?

To delete a specific rule, for instance the third input rule:
iptables -D INPUT 3

To delete all input rules (NB: if you use fail2ban, you’ll notice that fail2ban adds an entry to the INPUT chain. I’m not sure of what it does, but I don’t think it’s a good idea to remove it… so just make sure you backed up your configuration first):
iptables -F INPUT

To delete all rules (NB: same remark as above):
iptables -F

A more restrictive configuration could be to deny all traffic but some specific one. Note that this has to be carefully planned, so that:

  • you don’t lock yourself out (hint: beware if you have a dynamic IP… the best idea IMO is to let your SSH port open to all – although you may want to move it to something else than port 22 – and then use fail2ban to protect it)
  • you don’t lock your legit visitors / customers out (usually that’s the part you don’t forget. Not too hard too, usually you just need to let them go to port 80)
  • you don’t break normal interactions between your servers (like, your Apache server connecting to your SQL server, or your main server connecting to your backup server)
  • you don’t kick your server monitoring tools, or your hosting company’s server monitoring tools (usually they have some, to detect when your server is down so they send a tech to reboot/fix it)
  • you don’t lock out your disaster recovery tools (virtual KVM and such)

Once you’ve carefully thought about what needs to be allowed, the syntax to explicitly allow traffic is just the same as the syntax to drop, except that you replace “DROP” with “ACCEPT”. For instance:
-A INPUT -p tcp --dport 22 --source [your IP] -j ACCEPT
And then when you’ve put all your ACCEPT rules, finish with a:
-A INPUT -i eth0 -j REJECT or
-A INPUT -i eth0 -j DROP
NB: it might be a good idea to remain interface-specific (thus the -i eth0), I’m not too sure what happens if you block the local loopback. To find out your interface names, just use ifconfig.
My second source (unfortunately in French) contains a complete example configuration, but remember that some settings are “hosting company-specific”.

Sources:

Bonus: blocking some spammers from my postfix relay

Not sure if this is the most appropriate way to deal with those, but that’s pretty efficient 😉
iptables -A INPUT -s 180.241.244.156 -j DROP
iptables -A INPUT -s 46.134.253.175 -j DROP
iptables -A INPUT -s 91.185.252.14 -j DROP
iptables -A INPUT -s 72.55.148.21 -j DROP
iptables -A INPUT -s 93.48.97.149 -j DROP
iptables -A INPUT -s 176.9.35.83 -j DROP
iptables -A INPUT -s 64.26.174.67 -j DROP
iptables -A INPUT -s 108.170.42.155 -j DROP
iptables -A INPUT -s 95.9.249.219 -j DROP
iptables -A INPUT -s 186.61.2.80 -j DROP
iptables -A INPUT -s 95.232.147.85 -j DROP
iptables -A INPUT -s 200.62.249.86 -j DROP

Bonus 2: some quick rules to protect my postfix server from unwanted relay requests

iptables -A INPUT -p tcp --dport 25 -j DROP
iptables -A INPUT -p udp --dport 25 -j DROP

Bonus 3: how to apply those rules at boot time

Create a script custIptables looking like:
#!/bin/sh
# chkconfig: 3 21 91
# description: Firewall

IPT=/sbin/iptables

$IPT -A INPUT -p tcp --dport 25 -j DROP
$IPT -A INPUT -p udp --dport 25 -j DROP

exit 0
Then use Webmin to have it run at start up: in Webmin menu, go to “Bootup and Shutdown” then “Create a new bootup and shutdown action”, then fill the form. You can leave the shutdown action blank in this case.

Posted in Linux, security, servers.


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.

Sorry about the CAPTCHA that requires JS. If you really don't want to enable JS and still want to comment, you can send me your comment via e-mail and I'll post it for you.

Please solve the CAPTCHA below in order to fight spamWordPress CAPTCHA