SSH Dictionary Attack Prevention with iptables

来源:互联网 发布:淘宝的的中草药被硫熏 编辑:程序博客网 时间:2024/06/18 05:54

SSH Dictionary Attack Prevention with iptables
Post by scotty — Wed Apr 19 16:14:00 EST 2006 in linux
Last week (9-15 April). 8,750 failed SSH login attempt, averaging almost one per minute, trying out all kinds of possible user names and left tons of junk in my message log. The recent SSH brute-force attacks (actually it’s not that recent) are rather annoying, and this article at Whitedust.com has useful information on how to prevent this kind of attacks.

For me I have always used AllowUsers directive in /etc/ssh/sshd_config to limit the users that can login. In my setup, I have

AllowUsers root@home-IP my-regular-login
It allows root ssh login, but only from my home ADSL connection with static IP address so I can automate backups. Then it also includes a user ID that I regularly use to log into this VPS. If I need to do some system administration, I’ll use either su or sudo once I am inside.

However I found it is also ideal to slow down the attack when the infested host started to brute force the SSH authentication. There are many scripts/user-land daemons that perform monitoring and blocking. However in a resource limited VPS, I prefer to use something that has less demand in memory/CPU usage. IPTables recent module provides a kernel level solution with little overhead.

This is what I have in my iptables rules:

iptables -N SSH_CHECK
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK
iptables -A SSH_CHECK -m recent --set --name SSH
iptables -A SSH_CHECK -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
What it does is:

Create a new chain SSH_CHECK, and all incoming SSH connection (TCP port 22) will go into this chain to test the condition.
Condition is, for any source IP address there cannot be more than 3 SSH connection attempts within a 60 seconds window.
If condition has been met, then all packets from that source IP address will be dropped.
That source IP can only connect again if condition is cleared again, i.e. there has been 60 seconds of quiet time.
I found it quite effectively and dramatically reduce bot attacks on SSH port. Still, it is important to remove shell access from users that no longer require it, and choose sensible random password that is difficult to guess.

2 comments
Hi,
the rules above did not work for me, they would immediately cut off ssh access. This did work..

-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp –dport 22 -m recent –update –hitcount 4 –seconds 60 –name SSHIN -j DROP
-A INPUT -p tcp -m tcp –dport 22 -m recent –set –name SSHIN -j ACCEPT

jope this helps someone :)

Comment by linux_terror — Mon Jul 10 4:51:07 EST 2006 | #
After playing around a bit more I introduced a pretty handy logging chain for auditing, This following is working great for me…
add your 2 new chains..

:SSH_DROP - [0:0]
:LOG_ACCEPT - [0:0]

and add in your rules..

-A INPUT -p tcp -m tcp -m recent –dport 22 -j SSH_DROP –update –hitcount 4 –seconds 60 –name SSHIN
-A INPUT -p tcp -m tcp -m recent –dport 22 -j LOG_ACCEPT –set –name SSHIN
-A LOG_ACCEPT -j LOG –log-prefix “[IPTABLES ACCEPT] : ” –log-tcp-options –log-ip-options
-A LOG_ACCEPT -j ACCEPT
-A SSH_DROP -j LOG –log-prefix “[SSH_BRUTE_FORCE] : ” –log-tcp-options –log-ip-options
-A SSH_DROP -j DROP

this gives output like the following in your syslog or whereever you have your firewall logs going.

Jul 9 15:08:14 server kernel: [SSH_BRUTE_FORCE] : IN=eth0 OUT= MAC=00:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:00 SRC=xx.xx.xx.xx DST=xx.xx.xx.xx LEN=60 TOS=0×00 PREC=0×20 TTL=51 ID=64078 DF PROTO=TCP SPT=58251 DPT=22 WINDOW=5840 RES=0×00 SYN URGP=0 OPT (020405B40402080A05D9C8990000000001030302)