The method described in the previous section has a problem in that it permanently blocks access from any client when user mistypes their password several times. It is better to block access temporarily instead of permanently. The iptables module "recent" provides a way to do just that.
In this example, I only use the basic features of the "recent" module you can find more information about the available options for this module at the netfilter How-To page. http://netfilter.org/documentation/HOWTO/netfilter-extensions-HOWTO-3.shtml#ss3.16
To use this module, I create the following custom service object (see Section 5.3.6):
This module matches packets that have source address that is on the list of the module and was seen within the last 600 seconds. Now we can use this module in a rule:
These two rules translate into the following iptables script:
# Rule 0 (global) # echo "Rule 0 (global)" # $IPTABLES -N RULE_0 $IPTABLES -A INPUT -m recent --rcheck --seconds 600 -j RULE_0 $IPTABLES -A RULE_0 -j LOG --log-level info --log-prefix "RULE 0 -- DENY " $IPTABLES -A RULE_0 -j DROP # # Rule 1 (global) # echo "Rule 1 (global)" # $IPTABLES -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT #
Rule 0 blocks any packets that match module "recent," that is, that have source address that is on the module's list and were seen within last 10 minutes. Rule #1 simply permits SSH to the firewall. If everything goes well, no addresses should be on the module recent list, which means rule #0 does not match any packets and SSH access to the firewall is permitted by rule #1. However if any address is placed on the list of the module recent, rule #0 will block access to the firewall from that address for 10 min.
To place addresses of the attacking bots on the list I am using swatch just like in the previous chapter. The configuration file /root/.swatchrc looks like this:
# cat /root/.swatchrc watchfor /sshd\[\d+\]: Failed password for invalid user (\S+) from (\S+)/ echo bold exec "/root/swatch/block_ssh_scanner.sh $2" watchfor /sshd\[\d+\]: Failed password for (\S+) from (\S+)/ echo bold exec "/root/swatch/block_ssh_scanner.sh $2" watchfor /sshd\[\d+\]: Did not receive identification string from (\S+)/ echo bold exec "/root/swatch/block_ssh_scanner.sh $1" watchfor /sshd\[\d+\]: Invalid user (\S+) from (\S+)/ echo bold exec "/root/swatch/block_ssh_scanner.sh $2"
When swatch finds log entry that signals a potential SSH scan attack, it calls the script /root/swatch/block_ssh_scanner.sh:
#!/bin/sh addr=$1 ADDRDB="/root/swatch/ssh_scan_addresses" test -f $ADDRDB || touch $ADDRDB echo $addr >> $ADDRDB # take last 10 entries from the list, sort and count them, then # use addresses that appear 3 or more times. This means we'll block # clients that make 3 mistakes for a short interval of time. # tail -10 $ADDRDB | sort | uniq -c | awk '$1>3 { print $2;}' | while read a do echo "+$a" > /proc/net/xt_recent/DEFAULT done
This script finds addresses that tried wrong password or non-existent user accounts three or more times and adds them to the list "DEFAULT" of the module recent. If such address tries to connect to the firewall one more time, it will be blocked by the rule #0 in the policy. However if they try 10 minutes later, they will be allowed to connect. This means if I mistype my password three times and get blocked, I can still log in 10 minutes later.
Finally, to start swatch and bring this all in motion, I use the following command:
nohup /usr/bin/swatch --daemon --pid-file=$PID_FILE --tail-file=/var/log/auth.log \ --use-cpan-file-tail < /dev/null &
Swatch should monitor log file /var/log/auth.log on Debian and Ubuntu or /var/log/secure on RedHat, Fedora and other similar systems.
Copyright © 2000-2012 NetCitadel, Inc. All rights reserved.
Using free CSS Templates.