前言
我在阿里雲搭建的自用 dnsmasq 服務器,用來做免污染的 DNS,最近由於公開了IP,果然就遭到了攻擊——其實是被用於 DNS 放大攻擊。
由於 dnsmasq 本身就沒有設計為對外提供 DNS 服務,所以它對於安全方面的配置文件不是很多(根本沒有!),但它的解析策略又很方便配置(比如中國DNS解析白名單等),所以我在原本的基礎上,再加了一個 Bind9 作為前端來做安全。
那麼,今天我們就一起來看看到底如何給 Bind9 做安全配置。
Bind9 自身安全配置
Bind9 本身支持很多安全策略,我們把它做好,就已經能夠讓 DNS 十分健壯:
編輯
/等等/捆綁/命名.CONF.選項
,我們添加自定義策略:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
options { directory "/var/cache/bind"; version "None of your business"; // If there is a firewall between you and nameservers you want // to talk to, you may need to fix the firewall to allow multiple // ports to talk. See http://www.kb.cert.org/vuls/id/800113 // If your ISP provided one or more IP addresses for stable // nameservers, you probably want to use them as forwarders. // Uncomment the following block, and insert the addresses replacing // the all-0's placeholder. forwarders { 127.0.0.1 port 5352; }; //======================================================================== // If BIND logs error messages about the root key being expired, // you will need to update your keys. See https://www.isc.org/bind-keys //======================================================================== // dnssec-validation auto; // recursion no; auth-nxdomain no; # conform to RFC1035 //listen-on-v6 { any; }; forward only; allow-query {any;}; allow-query-cache {any;}; dnssec-enable no; dnssec-validation no; rate-limit { ipv4-prefix-length 32; window 10; responses-per-second 25; errors-per-second 5; nxdomains-per-second 5; slip 2; }; }; |
詳細解釋:
1 |
version "None of your business"; |
隱藏掉 Bind9 的版本信息,避免黑客針對你的 Bind9 版本漏洞進行攻擊。
1 2 3 |
forwarders { 127.0.0.1 port 5352; }; |
這句是開啟 Bind9 解析轉發,就像 dnsmasq 一樣,讓 Bind9 能夠向上獲取解析而不是自身去從根解析,就可以避免污染了(我這裡解析到了本地的 dnsmasq 上)
1 2 3 |
forward only; allow-query {any;}; allow-query-cache {any;}; |
只允許轉發,禁用根解析,同時開啟外部解析和緩存。
1 2 |
dnssec-enable no; dnssec-validation no; |
關閉安全配置,因為我要向上轉發到dnsmasq,而前者的應答是非權威應答,所以要讓 Bind9 接受非權威應答,就要關閉它。你不這樣用的話就不必關。
在查詢一個域名時,可能會看到有“非權威應答”的提示,該提示表示你所查詢的域名不使用你當前所用的DNS查詢服務器上。
1 2 3 4 5 6 7 8 |
rate-limit { ipv4-prefix-length 32; window 10; responses-per-second 25; errors-per-second 5; nxdomains-per-second 5; slip 2; }; |
為每個 IP 進行限速,如果請求超過每秒 25 個,就不再響應直接丟包。
效果
這樣一來,你應該就能在
/是/日誌/系統日誌
裡看到大量的超限 drop 記錄了,不過,即使如此,vps的流量依舊如流水一般遠去,所以,我們還需要使用第三方的工具來處理這些 IP。
記得重啟服務
服務 BIND9 重新開始
使用 Fail2ban 自動屏蔽黑客 IP
沒錯, 如果你讀過我的 購買了VPS之後你應該做足的安全措施 這篇文章,那你的 vps 上應該已經安裝了這個工具,它默認就已經能夠很好的運行了,但要給 Bind9 使用,我們還要繼續定制一番。
定制 Bind9 以兼容 Fail2ban
Bind9 默認並不會單獨生成日誌的,我們需要把出錯的日誌輸出以便 Fail2ban 能夠記錄,所以編輯
/等等/捆綁/命名.CONF
,在文件末尾另起一行插入如下語句:
1 2 3 4 5 6 7 8 9 10 |
logging { channel query_log { file "security.log" versions 3 size 30m; severity info; print-time yes; }; category default { query_log; }; }; |
這是重定向 Bind9 的默認日誌到
/是/高速緩存/捆綁/安全.日誌
大小保持30M
這時候如果你用
尾巴 -F /是/高速緩存/捆綁/安全.日誌
來查看,就會看到一大堆類似這樣的記錄了:
1 2 3 4 5 6 7 8 9 10 11 12 |
23-Apr-2016 18:44:08.560 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.589 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.607 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.695 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.696 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.752 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.844 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:08.950 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:09.009 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:09.015 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:09.112 client 94.254.209.48#80 (nhl.msk.su): rate limit drop response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) 23-Apr-2016 18:44:09.117 client 94.254.209.48#80 (nhl.msk.su): rate limit slip response to 94.254.209.48/32 for nhl.msk.su IN ANY (0000640d) |
顯然,現在有人在利用我的 DNS 進行反射攻擊,接下來我們配置 Fail2ban 來幹掉這些 IP。
讓 Fail2ban 對 Bind9 生效
其實 Fail2ban 原生支持 Bind9 的,甚至其列表裡就已經內置——不過那個策略與我們的期望不甚相符,還得自己改改。
編輯過濾配置
編輯
/等等/的fail2ban/監獄.CONF
文件,在裡邊找到關於 Bind9 的配置部分,默認如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# These jails block attacks against named (bind9). By default, logging is off # with bind9 installation. You will need something like this: # # logging { # channel security_file { # file "/var/log/named/security.log" versions 3 size 30m; # severity dynamic; # print-time yes; # }; # category security { # security_file; # }; # }; # # in your named.conf to provide proper logging # !!! WARNING !!! # Since UDP is connection-less protocol, spoofing of IP and imitation # of illegal actions is way too simple. Thus enabling of this filter # might provide an easy way for implementing a DoS against a chosen # victim. See # http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html # Please DO NOT USE this jail unless you know what you are doing. #[named-refused-udp] …… [named-refused-tcp] …… |
我們給它改改,udp 和 tcp 都啟用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[named-refused-udp] enabled = true port = domain,953 protocol = udp filter = named-refused logpath = /var/cache/bind/security.log findtime = 1 maxretry = 5 action = iptables-multiport[name=Named, port=53, protocol=udp] [named-refused-tcp] enabled = true port = domain,953 protocol = tcp filter = named-refused logpath = /var/cache/bind/security.log findtime = 1 maxretry = 5 action = iptables-multiport[name=Named, port=53, protocol=tcp] |
這裡的意思是一旦在1秒內發現5次記錄,就會把對應的 IP 給加入黑名單,時間則是默認的3600秒。不過不要擔心,這個記錄是 drop 記錄,不是正常的 query 記錄。
修改過濾規則
接下來我們改一下默認規則,默認的規則是探測被攻擊——而我們是要探測被用於攻擊……編輯
/等等/的fail2ban/過濾.ð/命名-拒絕.CONF
文件,找到如下幾行:
1 2 3 |
failregex = ^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$ ^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: zone transfer '\S+/AXFR/\w+' denied\s*$ ^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$ |
改為:
1 |
failregex = <HOST>#\S+( \([\S.]+\))?\: rate limit drop |
重啟服務
使用命令
服務 的fail2ban 重新開始
來重啟服務,這時候使用命令可查看其狀態:
1 2 3 4 5 6 7 8 9 10 |
:~# fail2ban-client status named-refused-udp Status for the jail: named-refused-udp |- filter | |- File list: /var/cache/bind/security.log | |- Currently failed: 0 | - Total failed: 9 - action |- Currently banned: 1 | - IP list: 94.254.209.48 - Total banned: 1 |
你看,已經抓到一個了。
總結
總之,一番折騰下來,我們得到瞭如下收穫:Bind9 能夠對單個 IP 的每秒請求進行限制(隨後你可以根據需求進行修改),一旦某IP再一秒內對服務器請求次數超過限制,則會被記錄並丟棄請求,如果超過的次數超過五次,那麼就會被拉入黑名單被防火牆拒絕(對方顯示目標地址不可達)。
關於UDP的一點討論
如你所見,在 Fail2ban 配置文件當中也寫明了對 UDP 的策略很有危險,因為黑客可以很容易偽造不同的地址,這樣可能會被用來利用你的規則惡意屏蔽某些 IP ,如果你的服務器出現這個情況,你就需要關掉針對 UDP 的策略了。
擴展閱讀
本文由 落格博客 原創撰寫:落格博客 » 使用 fail2ban 防止 Bind9 被用於 DNS 放大攻擊
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/1681.html
I need help ! I try to use fail2ban with bind9 but when i check fail2ban’s status i get errors ! some one can help me with how to do! Thanks
你好, 感謝您的出版物. 我可以建議發布 dnsmasq 檔案配置嗎,因為這個 dns 解析器被用於您的文章開發的邏輯中 ?
希望能幫助你.
問候?
—–
貨運代理 {
127.0.0.1 港口 5352;
};
訊息轉發解析開啟Bind9,就像 dnsmasq 一樣,讓Bind9能夠起床而不是自行解析root,你可以避免被污染 (我這裡是解析本地的dnsmasq)
感謝您寫了一篇有用的博客. 我按照你的配置並配置了我的伺服器.
But failregex = #\S+( \([\S.]+\))?\: 速率限制下降與我不匹配. 我的日誌檔案產生日誌. 是否 # 評論該行後 “^\s*\S+\s+named(?:\[\d+\])?: [^:]+: 限速下降” ? 之後顏色也變了 #.
我的 Fail2ban 版本是 1.0.2.
輸出
fail2ban-regex /var/cache/bind/security.log /etc/fail2ban/filter.d/named-refused.conf
運行測試
=============
使用failregex過濾文件 : 命名拒絕, 基於: /等/fail2ban
使用日誌文件 : /var /緩存/綁定/ security.log
使用編碼 : UTF-8
結果
=======
普雷格克斯: 1 全部的
| ^\s*(?:\S + (?:(?:\[\d+\])?:\s+\(?命名(?:-\瓦特+)?(?:\(\S+\))?\)?:?|\(?命名(?:-\瓦特+)?(?:\(\S+\))?\)?:?(?:\[\d+\])?:)\s+)?(?:(?!錯誤|信息)[\w-]+: )?(?:(?:錯誤|信息):\s*)?客戶(?: @\S*)? (?:\[?(?:(?:::F{4,6}:)?(?P(?:\ð{1,3}\.){3}\ð{1,3})|(?P(?:[0-9a-fA-F]{1,4}::?|::){1,7}(?:[0-9a-fA-F]{1,4}|(?<=:):)))\]?|(?P[\w\-.^_]*\W¯¯))#\S +(?: \([\S.]+\))?: (?P.+)\小號(?:被拒絕|\(NOTAUTH ))\s * $
-
Failregex: 0 total
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [253912] {^LN-BEG}Day(?P[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
–
線路: 253912 線, 0 被忽略, 0 匹配的, 253912 錯過了
[加工於 9.25 秒]
錯過線路(小號): 太多無法列印. 使用 –print-all-missed 列印全部 253912 線
我缺少什麼 ?
我會說… 首先嘗試重新啟動fail2ban. 您的更改似乎沒有生效, 失敗正規表示式: 0 全部的, 它應該是 1, 否則正規表示式未載入.
如果服務重啟不起作用, 那麼我建議檢查路徑/文件名,看看是否有任何拼寫錯誤或其他內容, 或甚至在 prefreregex 周圍閒逛,然後看看更改是否生效.
只是為了確保其他人不會犯此錯誤.
在TCP監獄下:
[命名拒絕TCP]
…
更改為:
動作= iptables-多端口[name =已命名, 端口= 53, 協議= udp]
這個:
動作= iptables-多端口[name =已命名, 端口= 53, 協議= TCP] << 這個
坦克人, 更新.
站長好,我的dns服務器收到的攻擊日誌如下:
202.9.120.7#13620 (aaa.com): 視圖G-1: 限速下降SERVFAIL錯誤響應 202.9.120.7/32
可能是由於啟用了view?在使用您教程裡的正則表達式failregex = #S+( \([\S.]+\))?\: rate limit drop時無法匹配,請問我這種日誌,如何修改正則表達式,使其能匹配日誌?盼求回复,謝謝!
如果是靜態的,那就 failregex =#\S +( \([\S.]+\))?\: 視圖G-1: 限速下降 #\S +( \([\S.]+\))?\: \W¯¯{4} \W- d: 限速下降
如果那個也是動態的,那就:failregex =
我使用您提到的兩個正則式,都不行。是不是什麼地方漏寫了什麼?
日誌中一條為
120.9.20.2#52774 (Chef.vpn.qianxin.com): 查看cnc用戶: 限速下降
我文中的例子是 “#80 (nhl.msk.su): 限速下降”, 你的日誌是 “#52774 (Chef.vpn.qianxin.com): 查看cnc用戶: 限速下降”,比我的多了“ view cnc-user:“ 這麼個字段,如果它是固定的,那就把正则改成“#\S+( \([\S.]+\))?\: view cnc-user\: rate limit drop“ 試試,如果是變化的,干脆变成 “#\S+( \([\S.]+\))?\:.+\: rate limit drop“ 得了。
簡單來說就是你的日誌格式和我的不一致~
這是很有趣的, 你是一個非常熟練的博客. 我加入你的飼料和期待性尋求更多的夢幻後. 也, 我在社交網絡分享您的網站!
阿里雲太貴啦,學生版一個月要十塊錢呢,你弄個騰訊雲,一個月一塊錢哦~~也是學生版呢!
聽說了,他們推出的時候我早就已經買了,另外聽說騰訊雲挺坑的啊。
就看著便宜,反正我也是用來搭ss,因為學校訪問外網有時太坑,順便弄個UDP53的OpenVPN,你懂的!