在找到 policyd-weight 之後,立刻給它裝上去,原本還寄望可以解決大量 SMTP 連線 的問題,想不到… 完全不是我想的那麼一回事,即使 policyd-weight 可以幫忙擋下一些 SMTP 連線,但是數量太多的 SMTP 連線 ,佔滿了我的 mail server , 無奈我的機器是 P3 500,只有 128MB 的 Ram, smtpd 開到20個(原本是15個)就會吃掉系統資源,開始影響 pop3 與 ssh 的連線。
這時我開始往 iptables 的方向找出路,希望能在更底層就把這些不必要的連線切斷,讓 postfix 做它該做的事。
在網路上找一找後,發現還真的有人寫出這些東西,我找到了 2 個看來比較多人用的,一個是 DenyHosts ,一個是 fail2ban 。
What is DenyHosts?
DenyHosts is a script intended to be run by Linux system administrators to help thwart SSH server attacks (also known as dictionary based attacks and brute force attacks).
Fail2ban :
Fail2ban scans log files like /var/log/pwdfail or /var/log/apache/error_log and bans IP that makes too many password failures. It updates firewall rules to reject the IP address.
大致了解了一下後,我選擇了 fail2ban ,因為 DenyHosts 是要透過 TCP Wrapper 運作,所以我還得先把 postfix 設定成 inetd 模式… XD ,除了 qmail 的 daemontools ,沒看過人家的這樣跑的… 我想一般的 inetd 會撐不住吧… 而且另一個重點在於… 這樣的管理方式… 還是會佔到 TCP sessions …
我選用的是 fail2ban ,它可以用 iptables 擋,這可直接省下 tcp sessions 的資源,另外,要是不想用 iptables ,它也能改用 TCP Wrapper 來擋。
稍微比較一下 TCP Wrapper 與 iptables 的阻擋方式,2個都會佔系統資源,TCP Wrapper是吃軟體資源,連帶核心的處理量也會增加,但是 iptables 僅僅吃 核心 的資源,上層的軟體完全不受影響,這個樣子,我個人認為會是比較好的。
好啦~ 我的是 Debian etch , 直接下 aptitude install fail2ban 就會安裝行了。
我的 Debian etch 少裝了 libnet-dns-perl,所以一開始 fail2ban 無法執行,補一下 aptitude install libnet-dns-perl 就 ok 了。(我愛 apt ,愛死 apt 了~ ^_^ )
裝完後,到 /etc/fail2ban ,看一下預設的 config 檔 /etc/fail2ban/jail.conf ,裏頭有提到
# To avoid merges during upgrades DO NOT MODIFY THIS FILE我就建了 /etc/fail2ban/jail.local 檔,內容是直接由 jail.conf 拷背過來,然後關閉 ssh 的監視,並開啟我要的 postfix。
# and rather provide your changes in /etc/fail2ban/jail.local
/etc/fail2ban/jail.local 裏可以指定我們要監視的 log 檔。
# cat /etc/fail2ban/jail.local
[ssh]
enabled = false
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 6
[postfix]
enabled = true
port = smtp
filter = postfix
logpath = /var/log/mail.log
ignoreip = 127.0.0.1 192.168.0.0/23 192.168.100.0/24
bantime = 10800
findtime = 300
maxretry = 1
/etc/fail2ban/filter.d/postfix.conf 則是指定了監視 postfix 的 log 檔時,要檢查哪內容的 regex 語法。
# cat /etc/fail2ban/filter.d/postfix.conf
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = reject: RCPT from (.*)\[
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
預設的監視句子只有一種 reject: RCPT from (.*)\[
450 4.7.1 Client host rejected: cannot find your hostname 450 4.1.1 : Recipient address rejected: undeliverable address: unknown user: "ant" 450 4.1.8 <7csg@gcn.net.tw>: Sender address rejected: Domain not found 550 5.1.1 : Recipient address rejected: User unknown in local recipient table 554 5.7.1 Service unavailable (RBL) ; Client host [70.121.10.64] blocked using zen.spamhaus.org; http://www.spamhaus.org/query/bl?ip=70.121.10.64
# cat /etc/fail2ban/filter.d/postfix.conf
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = reject: RCPT from (.*)\[
reject: RCPT from (.*)\[
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
改完後然執行 /etc/init.d/fail2ban start 啟用 fail2ban 。
開啟 fail2ban 的 log 檔 (/var/log/fail2ban.log) 卻發現有錯誤訊息…
這就怪了,我明明有設 failregex 呀,還設了很多,怎麼會這樣。上 google 網路上找了很久,似乎其他人都沒有這個問題,最後在這一篇寫的很不錯的教學文章裏有看到
- Unable to compile regular expression
- ERROR No failregex is set (這個還一大堆,並且非常、非常快速的在增加中)
Preventing Brute Force Attacks With Fail2ban On Debian Etch :
I've added a failregex line to some services because the regular expressions in the appropriate filter files in the /etc/fail2ban/filter.d directory do not work for Debian Etch. The failregex line overrides the filter rule in the appropriate file in /etc/fail2ban/filter.d.雖然這位作者提到是 Debian etch 的問題,但是經過我的測試後發現,這個問題已經修正了,我遇到的問題,是我改過的 failregex 的語法 : 它不能分行!! (剛剛重看該文件,發現… 我的 Debian etch 裏裝的是 0.7.5 版,人家 configuration 的網頁上有說,要用 0.7.6 版以上才行… :-p 真是不好意思了, 原來是我的版本太舊才不行的, 不是不能分行的錯)
所以依據 mail log ,我又改了我的 failregex … (下面這個是最終版)
# cat /etc/fail2ban/filter.d/postfix.conf
[Definition]
# Option: failregex
# Notes.: regex to match the password failures messages in the logfile. The
# host must be matched by a group named "host". The tag "" can
# be used for standard IP/hostname matching.
# Values: TEXT
#
failregex = reject: RCPT from (.*)\[\]: ... (4.7.1|4.1.1|4.1.8|5.1.1)
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
我要擋下所有產生 4.7.1 , 4.1.1 , 4.1.8 , 5.1.1 的可惡連線,記得每次改完設定檔,都要 /etc/init.d/fail2ban restart 哦。
現在開始監看 fail2ban 的 log 檔,就有如下的 IP 被擋的紀錄了…
# tail -f /var/log/fail2ban.log
2007-11-22 02:52:36,340 fail2ban.actions: WARNING [postfix] Ban 193.246.249.140
2007-11-22 02:52:36,958 fail2ban.actions: WARNING [postfix] Ban 213.42.186.228
2007-11-22 02:52:38,417 fail2ban.actions: WARNING [postfix] Ban 209.196.11.149
2007-11-22 02:52:39,558 fail2ban.actions: WARNING [postfix] Ban 216.111.202.180
要查目前的 iptables 的 rules 是阻擋了哪些 ip,可以用
# iptales -L -n
(-n 是不解析 ip,也可以省略。)
要查看目前有多少個 ip 被擋下來,可以用
# iptables -L -n | grep ':25' | wc -l
3584
(嘿 目前擋了 3584 個ip...)
下面這個是官方指令,剛不小心重啟了 fail2ban ,所以重啟後的現在只有 2029 個ip被擋。
# fail2ban-client status postfix
Status for the jail: postfix
|- filter
| |- Currently failed: 0
| `- Total failed: 2167
`- action
|- Currently banned: 1066
`- Total banned: 2029
fail2ban 對我來說,有個缺點,就是每次執行 restart 或 reload 時,iptables 裏被 ban 掉的 ip ,全部都會清除重來… 這讓我很困擾。
最後紀錄一下參考網站:
Fail2ban 官方站 :
http://www.fail2ban.org/wiki/
Preventing Brute Force Attacks With Fail2ban On Debian Etch :
這篇非常非常的有參考價值,而且是必看,因為我這邊只是隨意筆記一下。
Fail2ban HOWTOs http://www.fail2ban.org/wiki/index.php/HOWTOs :
這裏有很多 fail2ban 與其他 AP 交互應用的 HOWTO
1 則留言:
在 cron 裡面,使用 iptables-save 把 iptables 規則存成清單
0 0 * * * iptables-save > /root/list
再在 rc.local 裡面,把清單規則設回去
iptables-restore < /root/list
張貼留言