Or, you could use a simple iptables module called "ipt_recent". I added this function to my /etc/shorewall/start script. Whitelisted IP addresses are found in /etc/shorewall/ssh-bruteforce-whitelist. FWDSSH_PORT=2345 SSH_PORT=22 ssh_bruteforce() { # Prime the whitelist iptables -N SSH_WHITELIST echo " SSH Bruteforce whitelist chain created." >&2 sed -e '/^#/ D' /etc/shorewall/ssh-bruteforce-whitelist | \ while read CIDR; do iptables -A SSH_WHITELIST -s $CIDR -m recent --remove --name SSH \ -j ACCEPT echo " Added $CIDR to whitelist.">&2 done # Start following state iptables -N SSH_BRUTEFORCE echo " Creating SSH_BRUTEFORCE chain" >&2 iptables -A SSH_BRUTEFORCE -m recent --set --name SSH iptables -A SSH_BRUTEFORCE -j SSH_WHITELIST iptables -A SSH_BRUTEFORCE -m recent --update --seconds 60 --hitcount 4 \ --rttl --name SSH \ -j LOG --log-prefix "SSH_BRUTE_FORCE " iptables -A SSH_BRUTEFORCE -m recent --update --seconds 60 --hitcount 4 \ --rttl --name SSH \ -j DROP echo " Added rules to SSH_BRUTEFORCE chain" >&2 iptables -I net2fw 2 -p tcp \ -m multiport --destination-ports $SSH_PORT,$FWDSSH_PORT \ -m state --state NEW \ -j SSH_BRUTEFORCE echo " Added SSH_BRUTEFORCE chain to net2fw" >&2 } ssh_bruteforce Logs look like this: Jan 25 15:50:01 skuld kernel: SSH_BRUTE_FORCE IN=eth0 OUT= MAC=00:11:2f:9e:c9:1e:00:14:bf:18:80:c0:08:00 SRC=163.21.251.8 DST=192.168.1.10 LEN=60 TOS=0x00 PREC=0x00 TTL=47 ID=22053 DF PROTO=TCP SPT=59345 DPT=22 WINDOW=5840 RES=0x00 SYN URGP=0 After four hits to the same port by the same IP address, it's added to the black list for 60 seconds. I could extend that if I wanted, but I find that 60 seconds is sufficiently long to discourage most worm/bots. -- Chad Walstrom <chewie at wookimus.net> http://www.wookimus.net/ assert(expired(knowledge)); /* core dump */