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

Outline


Intro

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,可以設定單一, 複數或範圍 (例如1000:65535)
maxretry: 命中規則次數,為觸發動作的門檻次數
findtime: 搜尋指定Log紀錄的範圍秒數
bantime: IP被禁止的秒數
bantime.increment: 開啟累犯加重阻擋設定,建議設定於[sshd]服務底下

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

[DEFAULT]參數為範例,/etc/fail2ban/jail.conf

[DEFAULT]

...

# "bantime" is the number of seconds that a host is banned.
bantime  = 10m

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

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


SSH 設定方針

Ubuntu Fail2ban 0.9 版本預設即有開啟 SSH,可以參考 /etc/fail2ban/jail.d/defaults-debian.conf:

[sshd]
enabled = true

而參數可以參考原始設定檔 /etc/fail2ban/jail.conf:

[sshd]                                                                               

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:       
# normal (default), ddos, extra or aggressive (combines all).                        
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details. 
#mode   = normal                                                                     
port    = ssh                                                                        
logpath = %(sshd_log)s                                                               
backend = %(sshd_backend)s

# Enable recidive jail to increase the ban time for repeat offenders. 
# bantime.increment = true

[sshd]未定義的參數都會參照[DEFAULT]


Nginx 防禦設定方針

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

Access log

設定爬Nginx access.logfindtimemaxretry純對應RPS

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

    [Definition]
    failregex = ^ - - .*\"(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 limit_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: 
    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  ...                       unbans  (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. 將設定檔(如/etc/fail2ban/jail.local)預設的action更換為action_mw:

    action = %(action_mw)s
  2. 指定設定檔中的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 *