用 fail2ban 防止 BIND DNS 一直被 DDOS 攻擊
好久沒發文啦,來發個文記錄近期主機的攻防戰好了。最近有個困擾,就是有天我閒閒沒事看著弱點掃描的時候發現有奇妙的連線一直連到我的主機,最後看了 log 才知道一直有奇妙的俄羅斯 IP 一直連進來掃查詢我的 DNS 主機……。雖然透過 BIND (DNS Server 的一種) 內建的設定可以不讓它查詢,但是他好像不放棄地一直跟我作對,而且來自好幾百個不同的 IP?
好久沒發文啦,來發個文記錄近期主機的攻防戰好了。最近有個困擾,就是有天我閒閒沒事看著弱點掃描的時候發現有奇妙的連線一直連到我的主機,最後看了 log 才知道一直有奇妙的俄羅斯 IP 一直連進來掃查詢我的 DNS 主機……。雖然透過 BIND (DNS Server 的一種) 內建的設定可以不讓它查詢,但是他好像不放棄地一直跟我作對,而且來自好幾百個不同的 IP?
看上面的 log,誇張的時候一秒大概可以查詢個十幾次,主要查詢對象大概是:isc.org、cpsc.gov、hehehey.ru 這三個。
雖然把 bind 的 allow-recursion 都關掉了,但這樣也只能 denied 它,我還是得每天收個幾百 MB 的 denied log,的確不是一個解決辦法。
後來我試過,手動去爬這些 IP,然後透過 ufw 把它鎖起來,但它的 IP 好像很多,我鎖了幾百個 IP 它還是一直查詢我的 DNS。
最後我才找到這個工具:fail2ban,它可以防止一些常見的服務被攻擊,例如 SSH、Apache、FTP、postfix…等等,原理應該是去分析 log,然後把疑似攻擊的連線透過 iptables 封鎖。
安裝及設定 fail2ban
這裡以 debian 為例。直接透過 apt 來安裝即可。
apt-get install fail2ban
安裝好後打開 /etc/fail2ban/jail.conf
這個檔案,例如:
nano /etc/fail2ban/jail.conf
首先找到 [DEFAULT]
的部分,記得把內部 IP 都加到 ignoreip
裡面;bantime
表示要封鎖 600 秒;findtime
和 maxretry
表示 3600 秒內超過 3 次錯誤就封鎖。最後把 backend
改為 polling。
[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8 192.168.16.0/24
bantime = 3600
findtime = 600
maxretry = 3
# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto".
# yoh: For some reason Debian shipped python-gamin didn't work as expected
# This issue left ToDo, so polling is default backend for now
backend = polling
接著捲到最下面的 [named-refused-udp]
和 [named-refused-tcp]
,建議先照註解裡的說明設定好 bind 的紀錄檔,否則就把接下來的 logpath 改為 /var/log/syslog
。
把 [named-refused-udp]
和 [named-refused-tcp]
裡的 enabled 改為 true 表示開啟;action
如下設定,表示符合條件的要加入 iptables 封鎖(port 53、953);bantime
表示封鎖時間,31556926
指的是一年、-1 指的是永久封鎖。
[named-refused-udp]
enabled = true
port = domain,953
action = iptables-multiport[name=Named, port="domain,953", protocol=udp]
protocol = udp
filter = named-refused
logpath = /var/log/named/security.log
bantime = 31556926
[named-refused-tcp]
enabled = true
port = domain,953
action = iptables-multiport[name=Named, port="domain,953", protocol=tcp]
protocol = tcp
filter = named-refused
logpath = /var/log/named/security.log
bantime = 31556926
接著把 fail2ban 重啟
sudo service fail2ban reload
檢視封鎖紀錄
接著回去看 bind 的記錄檔應該好很多了,也可以從 fail2ban-client status 看看目前的狀況怎麼樣。
可以使用 fail2ban-client status named-refused-tcp
、fail2ban-client status named-refused-udp
、fail2ban-client status ssh
等指令查看不同服務的紀錄。
# fail2ban-client status named-refused-tcp
Status for the jail: named-refused-tcp
|- filter
| |- File list: /var/log/named/security.log
| |- Currently failed: 0
| `- Total failed: 3091
`- action
|- Currently banned: 4
| `- IP list: 2.5.81.189 222.209.56.106 221.231.6.169 201.210.53.57
`- Total banned: 4
好啦,目前看起來好多了,終於不用再看到一堆 log 了。