使用 iptables 限制黑客猜密码

一般使用Linux做服务器都会开SSH服务用于管理,但世界上总有些无聊加无赖的黑客挂上字典暴力猜解你的密码,看着日志中不断增加的稀奇古怪的用户名,我不由的对这些不知疲倦的菜鸟起了敬佩之心。

 

好了,不想跟小菜玩了,今天介绍如何使用iptables的recent模块来防止暴力破解密码。

SSH服务默认端口是22,不过既然是你自己管理,大可改个端口,比如,本例中将SSH端口改成44322,一般只知用工具的菜鸟黑客都只会扫1000以下的端口,但一台计算机拥有65536个端口,随便把你的端口改到哪个犄角旮旯,就可以大幅度增加攻击者的成本。

下面的代码是直接修改/etc/sysconfig/iptables文件,当然也可以用脚本,脚本只要在每句前面加iptables就行了。

 

1
2
3
4
5
6
7
8
9
10
11
12
#SSH Login log  注:先记录都是谁要登录我的SSH服务,可以使用tail /var/log/iptables -n 100 | grep "SSH Login"查看最近谁在登录,iptables是日志文件名,日志名需要你自己在syslog中设置
-A INPUT -p tcp --dport 44322 --tcp-flags ALL SYN -m state --state NEW -j LOG --log-prefix "[SSH Login]:"  --log-level debug
#1 Hour allow 5 SSH Login  注:每3600秒(每小时)只限5次连接我的SSH服务,可以自己改时间和次数,在这里你可以用-j DROP来代替-j REJECT,-j REJECT --reject-with tcp-reset是对客户端明确的返回一个重置TCP连接的包,告诉对方我关闭连接了,如果你觉得不需要对攻击者这么好心,就用-j DROP直接丢弃包,让对方傻傻的等回包去。
-A INPUT -p tcp --dport 44322 --tcp-flags ALL SYN -m state --state NEW -m recent --name SSH-SYN --update --seconds 3600 --hitcount 5 --rttl -j REJECT --reject-with tcp-reset
-A INPUT -p tcp --dport 44322 --tcp-flags ALL SYN -m state --state NEW -m recent --name SSH-SYN -- set  -j ACCEPT
#SSH Service back data filter  注:过滤建立TCP连接后收到的数据包
-A INPUT -p tcp --dport 44322 --tcp-flags ALL ACK -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 44322 --tcp-flags ALL ACK,PSH -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 44322 --tcp-flags ALL ACK,FIN -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 44322 --tcp-flags ALL RST -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 44322 --tcp-flags ALL ACK,RST -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 44322 --tcp-flags ALL ACK,URG -m state --state ESTABLISHED -j ACCEPT

 这里使用了iptables的连接跟踪功能,就是-m state --state,因为TCP连接的第一个包只能是SYN包,所以第2、4、5行只允许SYN包进入,这样就防止了其他类型的包来搅局。第4、5行也能防止不伪造源IP地址的SYN FLood攻击。7至12行表示过滤TCP连接已建立后的包的类型,注意--tcp-flags ALL后面是正常的包,比如根本不能出现SYN/FIN包、FIN/RST包、SYN/FIN/PSH包、SYN/FIN/RST包、SYN/FIN/RST/PSH包,一旦出现这样的包说明你被攻击了。

 

这里要注意的一点就是,如果服务器管理员在一小时内成功登录了5次之后,他也不能登录了。因为iptables计算的是每小时内建立SSH连接的次数,不管你是猜密码还是正常登录。所以管理员最好做好配置计划。

 

本代码经iptables 1.3.5,ipt_recent 0.3.1测试。

 

上面的iptables代码你可以免费用于任何途径,但如果你发现了错误或不足之处或你完善了它,请写信告诉我  zhangyuan5558@yahoo.com.cn。






使用 iptables 限制黑客猜密码续—深入 recent 模块

《使用iptables限制黑客猜密码》中介绍了如何使用iptables的recent模块限制一段时间内的连接数。查阅网上文章,发现不同的文章有不同的recent命令,而且每位作者都言之凿凿说他的命令可以用。这些recent的命令大体有如下不同:1、set句在前,update(或rcheck)句在后,2、update(或rcheck)句在前,set句在后,3、set句带或不带-j ACCEPT。基本是上面这三项的排列组合。我用来用去不觉得很好用,这一篇就再深入一下。

先从一个案例开始:

案例:对连接到本机的SSH连接进行限制,每个IP每小时只限连接5次。

命令:

1
2
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL -- set  -j ACCEPT

模拟一下某个电脑连接本机SSH服务的数据包流程,假设以下数据包是在一小时内到达本机的:

1、当这个电脑的第1个SSH包到达本机,规则1检查SSHPOOL列表中这个源IP是否有hitcount,因为是第一个包,显而易见,列表是0,规则1判定这个数据包不必执行DROP,并且也不处理这个数据包,将数据包转给下条规则。

2、规则2将这个数据包计入SSHPOOL列表,就是做+1,因为规则中有-j ACCEPT,规则2放行这个包。

3、第1个数据包进入本机,不用再在iptables里转了。

4、当第2个SSH包到达本机,规则1检查SSHPOOL列表的hitcount,发现是1没有超过5,于是判定不执行DROP并转给下条规则处理。

5、规则2在SSHPOOL中+1,并放行,第2个数据包进入本机。

6、第3、4、5个包同上。

7、第6个包到达本机,规则1检查SSHPOOL列表中的hitcount,发现是5了已经连接5次了,于是规则2执行DROP,不必再转给下条规则了丢弃该包。

8、第7、8…个包同上。

实际上recent的处理更为复杂,这里只是粗浅的描述一下,set也并非简单的做+1。详细的列表在/proc/net/xt_recent/目录下,用cat查看即可。

从上面的流程可以看出,--set的功能在于计录数据包,将源IP加入列表。--rcheck(update)的功能在于判定数据包在seconds和hitcount条件下是否要DROP。

 

我在CU论坛上看到另一个版本的命令,作者保证是从服务器上复制下来的,肯定能用:

1
2
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL -- set
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP

但在我的服务器上这两行命令就是不能用,所有的SSH包都被丢弃了。最后问题找到了,这两行命令仅能工作在INPUT链的默认策略为ACCEPT的情况下,而我的INPUT链的默认策略为DROP。这个命令与我的命令的区别在于:set句在前,且set句不带-j ACCEPT。这导致数据包的流程也不同。

1、第1个数据包到达规则1后马上计入SSHPOOL列表,并且规则1因为没有-j ACCEPT,直接将数据包转给下条规则。规则2拿到这个数据包后检查SSHPOOL列表,发现是1,也不处理这个包,转给下条规则。如果后续的规则都没有再处理这个数据包,则最后由INPUT链的默认策略ACCEPT处理。由于我的策略是DROP,所以丢弃该包,于是这两行命令在我的服务器上不能用。

2、这里有个问题,由于set句在前,数据包进入是先计入列表,再判定是否合法。这导致第5个包到达后,先在列表中+1,结果是5,再由规则2判定,发现是5,结果丢弃该包,最后真正ACCEPT的只有4个包。本人认为这样写的代码不符合正常的思维逻辑。而且这样写只能正常工作于默认策略是ACCEPT的情况,所以本人不建议用这个版本的命令,我的版本ACCEPT、DROP策略都能用。

从上面可以看出,如果大家在网上看到不同的recent模块的命令,记得一定要先问问作者INPUT链的默认策略是什么。

 

最后,rcheck和update的区别:

rcheck从第1个包开始计算时间,update是在rcheck的基础上增加了从最近的DROP包开始计算阻断时间,具有准许时间和阻断时间,帮助中说update会更新last-seen时间戳。

放在案例中,rcheck是接收到第1个数据包时开始计时,一个小时内仅限5次连接,后续的包丢弃,直到一小时过后又可以继续连接。update则是接收到第1个数据包时计算准许时间,在一个小时的准许时间内仅限5次连接,当有包被丢弃时,从最近的丢弃包开始计算阻断时间,在一个小时的阻断时间内没有接收到包,才可以继续连接。所以rcheck类似令牌桶,一小时给你5次,用完了抱歉等下个小时吧。update类似网银,连续输错5次密码,停止一小时,只不过update更严格,阻断时间是从最近的一次输错时间开始算,比如输错了5次,过了半个小时又输错一次,这时阻断时间不是剩半小时,而是从第6次重新计算,剩一小时。这个区别我不太会表述,大家自己做做测试就明白了。

给大家一个测试用的命令,自行替换rcheck、update,然后ping一下就明白了:

1
2
-A INPUT -p icmp -m recent --name PINGPOOL --rcheck --seconds 30 --hitcount 5 -j DROP
-A INPUT -p icmp -m recent --name PINGPOOL -- set  -j ACCEPT

 

最最后,再啰索一句

ICMP包和UDP包在iptables中的state情况是一样的,因为是无状态的,不同于TCP,iptables可以靠SYN等flags确定state,而iptables是基于ICMP包/UDP包到达服务器的间隔时间来确定state的。像我在做上面测试的时候,使用ping 192.168.1.1 -t时,除了第一个ICMP包state是NEW,后续的包state都是ESTABLISHED,结果因为前面有一句

1
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

结果ping一直是通的,搞了半天才弄明白。


博主,感谢你分析与分享。
7、第6个包到达本机,规则1检查SSHPOOL列表中的hitcount,发现是5了已经连接5次了,于是规则2执行DROP,不必再转给下条规则了丢弃该包。
这个是不是应该还是执行规则1中的DROP。因为规则2没有DROP。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值