[Network] Fail2ban 指南 – 搭配Nginx (DDoS、Request Limit)

Outline

Fail2ban – Manuals


架構

Fail2ban是依照設定檔執行過濾,原始設定檔路徑:

/etc/fail2ban/jail.conf

如要修改新增可以複製建立成local的設定檔名稱,如有此檔會以此檔優先:

/etc/fail2ban/jail.local
/etc/fail2ban/jail.d/*

Ubuntu Fail2ban 0.9 版本中可以找到預設的/etc/fail2ban/jail.d/defaults-debian.conf,內容是對[sshd]enabled = true
所以安裝好後預設即會開啟SSH保護(預設port為22)

[過濾器名稱]會對應到/etc/fail2ban/filter.d/過濾器名稱.conf

參數解析

官方文件 – Options

port: 實施IP禁止的port,可以設定單一, 複數或範圍
maxretry: 命中規則次數,為觸發動作的門檻次數
findtime: 搜尋指定Log紀錄的範圍秒數
bantime: IP被禁止的秒數

以SSH過濾器為例,預設共用的maxretry5,SSH規則上帳號與密碼的錯誤Log會分開,意即如果是帳號錯誤又打密碼登入,這樣嘗試三次就會被鎖了(2×3 > 5)。

sshd為範例:

[sshd]

#mode   = normal
#port    = ssh
#port    = ssh,80,443
port    = 1000:65535
logpath = %(sshd_log)s
backend = %(sshd_backend)s

#enabled = true (Already enabled in jail.d/defaults-debian.conf)
#maxretry = 5
#findtime = 600
#bantime = 5m

port設定的ssh等服務變數不會隨sshd服務的port改變而一起變動。


Nginx防禦設定方針

看想要哪種方式讓Fail2ban判斷:

Access log

設定爬Nginx access.logfindtimemaxretry純對應RPS

  1. 建立一個Fail2ban的Filter用於爬Nginx access log,舉例為/etc/fail2ban/filter.d/nginx-access-limit.conf

    [Definition]
    failregex = ^<HOST> - - .*\"(GET|POST).*
    ignoreregex =
  2. 添加此Filter設定至/etc/fail2ban/jail.local

    [nginx-access-limit]
    
    enabled = true
    filter = nginx-access-limit
    action = iptables-multiport[name=nginx-access-limit, port="http,https", protocol=tcp]
    logpath = /var/log/nginx/access.log
    findtime = 5
    bantime = 900
    maxretry = 100

設定後重啟Fail2ban即可,RPS完全依照Filter的findtimemaxretry調節。

Error log by llimit_req_zone

設定爬Nginx error.log,亦即須搭配設定Ngnix limit_req_zone (failregex = limiting requests, excess:.* by zone.*client: <HOST>)

  1. 設定Nginx http_limit_req以便提供error.log對應資料給Fail2ban

  2. 建立一個Fail2ban的Filter用於Nginx req limit,舉例為/etc/fail2ban/filter.d/nginx-req-limit.conf

    # Fail2Ban configuration file
    #
    # supports: ngx_http_limit_req_module module 
    
    [Definition]
    failregex = limiting requests, excess:.* by zone.*client: <HOST>
    ignoreregex =
  3. 添加此Filter設定至/etc/fail2ban/jail.local

    [nginx-req-limit]
    
    enabled = true
    filter = nginx-req-limit
    action = iptables-multiport[name=nginx-req-limit, port="http,https", protocol=tcp]
    logpath = /var/log/nginx/*error.log
    findtime = 60
    bantime = 900
    maxretry = 10

設定後重啟Fail2ban即可,此設定的RPS調整實際上主要在Nginx http_limit_req,Fail2ban只是純粹吃其excess出來的error log資料做黑名單。

針對Fail2ban的黑名單門檻,就看在多少區間(findtime)內excess幾次(maxretry)。

[Web] Nginx limit_req 指南 – ngx_http_limit_req_module


進階

Fail2ban log

Log位置:/var/log/fail2ban.log

確認IPTABLES禁止IP狀態

$ sudo iptables -S
$ sudo iptables -L

移除IPTABLES禁止的IP

0.10.0版本後可以支援unban指令:

unban --all                              unbans all IP addresses (in all
                                         jails and database)
unban <IP> ... <IP>                      unbans <IP> (in all jails and
                                         database)

$ fail2ban-client unban --all

舊版通用逐筆移除IP指令:

$ fail2ban-client set {filter-name} unbanip {ip-address}

依照error log範例,假如nginx-req-limit過濾器禁止了192.168.10.123,則使用unbanip cmd action:

$ fail2ban-client set nginx-req-limit unbanip 192.168.10.123

設定Email Notifications

  1. 將設定檔預設的action更換為action_mw:
action = %(action_mw)s
  1. 設定設定檔中的Email資料:
destemail = to@todomain.local
sender = admin@admin.local

Reference

GitHub – fail2ban/fail2ban

Leave a Reply

Your email address will not be published. Required fields are marked *