使用 iptables 限制***猜密码续—深入 recent 模块
使用 iptables 限制***猜密碼續(xù)—深入 recent 模塊
作者:高張遠(yuǎn)矚(HiLoveS)
博客:http://www.cnblogs.com/hiloves/
轉(zhuǎn)載請保留該信息
在《使用iptables限制***猜密碼》中介紹了如何使用iptables的recent模塊限制一段時間內(nèi)的連接數(shù)。查閱網(wǎng)上文章,發(fā)現(xiàn)不同的文章有不同的recent命令,而且每位作者都言之鑿鑿說他的命令可以用。這些recent的命令大體有如下不同:1、set句在前,update(或rcheck)句在后,2、update(或rcheck)句在前,set句在后,3、set句帶或不帶-j ACCEPT。基本是上面這三項的排列組合。我用來用去不覺得很好用,這一篇就再深入一下。
先從一個案例開始:
案例:對連接到本機(jī)的SSH連接進(jìn)行限制,每個IP每小時只限連接5次。
命令:
?| 12 | -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 | 
模擬一下某個電腦連接本機(jī)SSH服務(wù)的數(shù)據(jù)包流程,假設(shè)以下數(shù)據(jù)包是在一小時內(nèi)到達(dá)本機(jī)的:
1、當(dāng)這個電腦的第1個SSH包到達(dá)本機(jī),規(guī)則1檢查SSHPOOL列表中這個源IP是否有hitcount,因為是第一個包,顯而易見,列表是0,規(guī)則1判定這個數(shù)據(jù)包不必執(zhí)行DROP,并且也不處理這個數(shù)據(jù)包,將數(shù)據(jù)包轉(zhuǎn)給下條規(guī)則。
2、規(guī)則2將這個數(shù)據(jù)包計入SSHPOOL列表,就是做+1,因為規(guī)則中有-j ACCEPT,規(guī)則2放行這個包。
3、第1個數(shù)據(jù)包進(jìn)入本機(jī),不用再在iptables里轉(zhuǎn)了。
4、當(dāng)?shù)?個SSH包到達(dá)本機(jī),規(guī)則1檢查SSHPOOL列表的hitcount,發(fā)現(xiàn)是1沒有超過5,于是判定不執(zhí)行DROP并轉(zhuǎn)給下條規(guī)則處理。
5、規(guī)則2在SSHPOOL中+1,并放行,第2個數(shù)據(jù)包進(jìn)入本機(jī)。
6、第3、4、5個包同上。
7、第6個包到達(dá)本機(jī),規(guī)則1檢查SSHPOOL列表中的hitcount,發(fā)現(xiàn)是5了已經(jīng)連接5次了,于是規(guī)則2執(zhí)行DROP,不必再轉(zhuǎn)給下條規(guī)則了丟棄該包。
8、第7、8…個包同上。
實際上recent的處理更為復(fù)雜,這里只是粗淺的描述一下,set也并非簡單的做+1。詳細(xì)的列表在/proc/net/xt_recent/目錄下,用cat查看即可。
從上面的流程可以看出,--set的功能在于計錄數(shù)據(jù)包,將源IP加入列表。--rcheck(update)的功能在于判定數(shù)據(jù)包在seconds和hitcount條件下是否要DROP。
我在CU論壇上看到另一個版本的命令,作者保證是從服務(wù)器上復(fù)制下來的,肯定能用:
?| 12 | -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 | 
但在我的服務(wù)器上這兩行命令就是不能用,所有的SSH包都被丟棄了。最后問題找到了,這兩行命令僅能工作在INPUT鏈的默認(rèn)策略為ACCEPT的情況下,而我的INPUT鏈的默認(rèn)策略為DROP。這個命令與我的命令的區(qū)別在于:set句在前,且set句不帶-j ACCEPT。這導(dǎo)致數(shù)據(jù)包的流程也不同。
1、第1個數(shù)據(jù)包到達(dá)規(guī)則1后馬上計入SSHPOOL列表,并且規(guī)則1因為沒有-j ACCEPT,直接將數(shù)據(jù)包轉(zhuǎn)給下條規(guī)則。規(guī)則2拿到這個數(shù)據(jù)包后檢查SSHPOOL列表,發(fā)現(xiàn)是1,也不處理這個包,轉(zhuǎn)給下條規(guī)則。如果后續(xù)的規(guī)則都沒有再處理這個數(shù)據(jù)包,則最后由INPUT鏈的默認(rèn)策略ACCEPT處理。由于我的策略是DROP,所以丟棄該包,于是這兩行命令在我的服務(wù)器上不能用。
2、這里有個問題,由于set句在前,數(shù)據(jù)包進(jìn)入是先計入列表,再判定是否合法。這導(dǎo)致第5個包到達(dá)后,先在列表中+1,結(jié)果是5,再由規(guī)則2判定,發(fā)現(xiàn)是5,結(jié)果丟棄該包,最后真正ACCEPT的只有4個包。本人認(rèn)為這樣寫的代碼不符合正常的思維邏輯。而且這樣寫只能正常工作于默認(rèn)策略是ACCEPT的情況,所以本人不建議用這個版本的命令,我的版本ACCEPT、DROP策略都能用。
從上面可以看出,如果大家在網(wǎng)上看到不同的recent模塊的命令,記得一定要先問問作者INPUT鏈的默認(rèn)策略是什么。
最后,rcheck和update的區(qū)別:
rcheck從第1個包開始計算時間,update是在rcheck的基礎(chǔ)上增加了從最近的DROP包開始計算阻斷時間,具有準(zhǔn)許時間和阻斷時間,幫助中說update會更新last-seen時間戳。
放在案例中,rcheck是接收到第1個數(shù)據(jù)包時開始計時,一個小時內(nèi)僅限5次連接,后續(xù)的包丟棄,直到一小時過后又可以繼續(xù)連接。update則是接收到第1個數(shù)據(jù)包時計算準(zhǔn)許時間,在一個小時的準(zhǔn)許時間內(nèi)僅限5次連接,當(dāng)有包被丟棄時,從最近的丟棄包開始計算阻斷時間,在一個小時的阻斷時間內(nèi)沒有接收到包,才可以繼續(xù)連接。所以rcheck類似令牌桶,一小時給你5次,用完了抱歉等下個小時吧。update類似網(wǎng)銀,連續(xù)輸錯5次密碼,停止一小時,只不過update更嚴(yán)格,阻斷時間是從最近的一次輸錯時間開始算,比如輸錯了5次,過了半個小時又輸錯一次,這時阻斷時間不是剩半小時,而是從第6次重新計算,剩一小時。這個區(qū)別我不太會表述,大家自己做做測試就明白了。
給大家一個測試用的命令,自行替換rcheck、update,然后ping一下就明白了:
?| 12 | -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情況是一樣的,因為是無狀態(tài)的,不同于TCP,iptables可以靠SYN等flags確定state,而iptables是基于ICMP包/UDP包到達(dá)服務(wù)器的間隔時間來確定state的。像我在做上面測試的時候,使用ping 192.168.1.1 -t時,除了第一個ICMP包state是NEW,后續(xù)的包state都是ESTABLISHED,結(jié)果因為前面有一句
?| 1 | -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT | 
結(jié)果ping一直是通的,搞了半天才弄明白。
限制DNS設(shè)置:
-A INPUT -p udp --dport 53 -m state --state NEW -m recent --name DNSPOOL --rcheck --seconds 600 --hitcount 10 -j DROP
-A INPUT -p udp --dport 53 -m state --state NEW -m recent --name DNSPOOL --set -j ACCEPT
轉(zhuǎn)載于:https://blog.51cto.com/bristol/1302416
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的使用 iptables 限制***猜密码续—深入 recent 模块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: Windows系统查看端口占用
 - 下一篇: javascript 函数声明与函数表达