Archive for October, 2006

Fun with netfilter/iptables and the recent module

If you are anything like me you hate your logfiles filling up with ssh denied message from script-kiddies trying to guess passwords. Wouldn’t your life be just a bit easier if the connection would just get rejected when they attempted to do so?
Let’s get some netfilter-magic in here to rescue us. Some excerpts from my /etc/sysconfig/iptables1:


*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:VUURMUUR - [0:0]
:SSHD - [0:0]
:SSHD-REJECT - [0:0]

First we declare some new chains. VUURMUUR is where all the normal firewall stuff happens. SSHD to do the accounting and SSHD-REJECT to do the blacklisting.


-A INPUT -j VUURMUUR
-A FORWARD -j VUURMUUR
-A VUURMUUR -p tcp --dport 22 -m state --state NEW -j SSHD

Now we send all incoming and forward traffic to the VUURMUUR chain, then we add our new SSHD chain as the target for all NEW connections to port 22 (ssh). If we didn’t specify the NEW state here all our connections would die after the first few packets…


-A VUURMUUR -m state --state ESTABLISHED,RELATED -j ACCEPT
...
-A VUURMUUR -j REJECT --reject-with icmp-host-prohibited

This is where your `normal’ rules would go. Using REJECT as target on a final rule for all traffic you didn’t explicitly ACCEPT is always nice, as this will inform the other end of a closed port instead of letting them timeout on dropped packets.


-A SSHD -m recent --set --name SSHD --rsource

The first thing we do in our SSHD chain is add/increase a packet-counter for the source of our new connection using the recent module and SSHD as a name for our counter.


-A SSHD -m recent --rcheck --seconds 60 --hitcount 4 --name SSHD --rsource -j SSHD-REJECT

Now we check if we’ve had four or more new connections from the same host in the past minute. If so we’ll jump to the SSHD-REJECT chain.


-A SSHD-REJECT -m recent --set --name SSHD-REJECT --rsource

In the SSHD-REJECT chain we only add our source-ip (and timestamp) to a second counter: SSHD-REJECT


-A SSHD -m limit --limit 5/hour -m recent --rcheck --seconds 3600 --hitcount 1 --name SSHD-REJECT --rsource -j LOG --log-prefix SSH-BLACKLIST:
-A SSHD -m recent --rcheck --seconds 3600 --hitcount 1 --name SSHD-REJECT --rsource -j REJECT --reject-with icmp-port-unreachable

Now we check if this host has been put in our SSHD-REJECT counter in the past hour (3600 seconds). If so we log a message to syslog (but limited to a maximum of 5 messages per hour) and we reject the connection.


-A SSHD -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
COMMIT

And finally we accept the connection.

More information about the iptables recent module can be found at snowman.net
More information about netfilter/iptables can be found at netfilter.org

1: This is where “service iptables save” will store your firewall config on RHEL/Fedora systems. If you’re using Debian or Ubuntu you can put all of this in your own firewall-script by doing the chain-creation with “iptables -N <chainname>” and prefixing the rest of the lines with “iptables”