91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

使用fail2ban防御暴力破解的落地實踐

馬哥Linux運維 ? 來源:馬哥Linux運維 ? 2026-03-23 10:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

暴力破解(Brute Force Attack)是最原始也是最有效的攻擊手段之一。攻擊者通過自動化工具對 SSH、Web 登錄、數(shù)據(jù)庫等服務(wù)進行大量密碼嘗試,直到命中正確的憑據(jù)。根據(jù)公網(wǎng)蜜罐數(shù)據(jù)統(tǒng)計,一臺新上線的 Linux 服務(wù)器暴露 SSH 端口后,平均 5 分鐘內(nèi)就會收到第一次暴力破解嘗試,每天被掃描數(shù)千次是常態(tài)。

暴力破解攻擊的危害不僅在于密碼被破解本身:

危害類型 具體說明
憑據(jù)泄露 弱密碼被破解后攻擊者獲取系統(tǒng)權(quán)限
資源消耗 大量認證請求消耗 CPU 和內(nèi)存
日志膨脹 auth.log/secure 日志文件快速增長
影響正常訪問 連接數(shù)被惡意請求占滿
合規(guī)風(fēng)險 未防護暴力破解不符合等保要求

fail2ban 的工作原理

fail2ban 是一個入侵防御框架,核心機制是日志監(jiān)控 + 自動封禁:

日志文件        fail2ban          防火墻
(auth.log)       引擎
             |
 新日志行 ------> Filter(正則匹配)
             |
          匹配失敗特征?
           |    |
          是   否(忽略)
           |
         計數(shù)器 +1
           |
         超過閾值?
          |   |
         是   否(繼續(xù)計數(shù))
          |
       Action(執(zhí)行封禁) ------> iptables/nftables
          |           添加 DROP 規(guī)則
       記錄封禁日志
          |
       啟動解封定時器 ------> 到期自動解封

核心概念:

Filter:定義匹配規(guī)則的正則表達式,從日志中識別失敗的認證嘗試

Jail:一個監(jiān)控單元,包含 filter + action + 參數(shù)(閾值/時間窗/封禁時間)

Action:匹配后執(zhí)行的操作,通常是防火墻封禁

Ban/Unban:封禁和解封操作

1.2 與其他防御手段對比

工具 原理 優(yōu)勢 劣勢
fail2ban 日志正則匹配 通用性強,支持任意日志格式的服務(wù) 依賴日志實時寫入
DenyHosts 解析 /etc/hosts.deny 簡單輕量 僅支持 SSH,項目已不活躍
SSHGuard 日志解析 多協(xié)議支持,低資源占用 自定義規(guī)則不如 fail2ban 靈活
CrowdSec 日志分析 + 社區(qū)威脅情報 共享封禁列表,現(xiàn)代架構(gòu) 部署復(fù)雜,需要聯(lián)網(wǎng)同步
防火墻限速 連接頻率限制 不依賴日志 無法區(qū)分正常和惡意請求

fail2ban 在單機防護場景下是最成熟的選擇:配置靈活、文檔豐富、社區(qū)活躍、資源消耗低。對于大規(guī)模集群,可以考慮 CrowdSec 或 fail2ban + 集中式日志的組合方案。

1.3 適用場景

SSH 服務(wù)暴力破解防護

Nginx/Apache 的 HTTP Basic Auth 暴力破解防護

Web 應(yīng)用登錄接口的暴力破解防護

惡意掃描(路徑遍歷、漏洞探測)過濾

MySQL/PostgreSQL 遠程登錄保護

郵件服務(wù)(Postfix/Dovecot)暴力破解防護

自定義應(yīng)用日志的異常行為檢測

1.4 環(huán)境要求

組件 版本要求 說明
操作系統(tǒng) Ubuntu 24.04 LTS / Rocky Linux 9.5 內(nèi)核 6.12+
fail2ban 1.1.x 當(dāng)前穩(wěn)定版
Python 3.12+ fail2ban 運行依賴
iptables/nftables 系統(tǒng)自帶 封禁后端
firewalld 2.x(可選) Rocky Linux 默認
rsyslog/systemd-journald 系統(tǒng)自帶 日志來源

# Ubuntu 24.04 安裝
sudo apt update
sudo apt install -y fail2ban

# Rocky Linux 9.5 安裝(需要 EPEL 源)
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalld

# 檢查版本
fail2ban-client version
# Fail2Ban v1.1.0

# 檢查服務(wù)狀態(tài)
sudo systemctl status fail2ban

二、詳細步驟

2.1 配置文件結(jié)構(gòu)

fail2ban 的配置文件層級:

/etc/fail2ban/
├── fail2ban.conf     # 全局配置(日志級別、socket 路徑等)
├── fail2ban.local    # 全局配置覆蓋(自定義項寫在這里)
├── jail.conf       # 默認 jail 定義(不要直接修改)
├── jail.local      # jail 自定義配置(所有自定義都寫在這里)
├── jail.d/        # jail 片段配置目錄
│  └── defaults-debian.conf
├── filter.d/       # filter 正則定義
│  ├── sshd.conf
│  ├── nginx-http-auth.conf
│  └── ...
├── action.d/       # action 動作定義
│  ├── iptables-multiport.conf
│  ├── nftables-multiport.conf
│  ├── firewallcmd-rich-rules.conf
│  └── ...
└── paths-*.conf     # 不同發(fā)行版的路徑定義

核心原則:永遠不要修改.conf文件,所有自定義配置寫在.local文件中。fail2ban 會先讀取.conf,再用.local覆蓋。

2.2 基礎(chǔ)配置

創(chuàng)建 jail.local

sudo cat > /etc/fail2ban/jail.local <

啟動服務(wù)

# 檢查配置語法
sudo fail2ban-client -t
# OK: configuration test is successful

# 啟動并設(shè)置開機自啟
sudo systemctlenable--now fail2ban

# 查看運行狀態(tài)
sudo fail2ban-client status
# Status
# |- Number of jail:   1
# `- Jail list:  sshd

2.3 SSH 防護配置

SSH 暴力破解是最常見的攻擊類型。fail2ban 內(nèi)置的 sshd filter 覆蓋了大部分場景。

# 查看 sshd filter 內(nèi)置的匹配規(guī)則
cat /etc/fail2ban/filter.d/sshd.conf

sshd filter 能匹配的日志模式包括:

日志模式 含義
Failed password for from 密碼認證失敗
Failed publickey for from 公鑰認證失敗
Invalid user from 不存在的用戶名
Connection closed by authenticating user 認證過程中斷開
maximum authentication attempts exceeded 超過最大認證次數(shù)

增強的 SSH 防護配置

# /etc/fail2ban/jail.local 中的 [sshd] 部分
[sshd]
enabled = true
port = ssh
filter = sshd[mode=aggressive]
# aggressive 模式包含更多匹配規(guī)則,會匹配 "Invalid user" 等

maxretry = 3
findtime = 300
bantime = 3600

# 如果 SSH 使用非標(biāo)準端口
# port = 2222

驗證 SSH 防護是否生效

# 查看 sshd jail 狀態(tài)
sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# | |- Currently failed: 2
# | |- Total failed:   47
# | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
# `- Actions
#  |- Currently banned: 3
#  |- Total banned:   15
#  `- Banned IP list:  103.xx.xx.92 45.xx.xx.201 185.xx.xx.33

# 查看 iptables 中的封禁規(guī)則
sudo iptables -L f2b-sshd -n -v
# Chain f2b-sshd (1 references)
# pkts bytes target prot opt in  out source     destination
#  234 14040 REJECT all -- *  *  103.xx.xx.92  0.0.0.0/0
#  156 9360 REJECT all -- *  *  45.xx.xx.201  0.0.0.0/0

2.4 Nginx 防護配置

HTTP Basic Auth 暴力破解防護

# /etc/fail2ban/jail.local 追加

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
findtime = 300
bantime = 3600

Nginx 惡意掃描防護

fail2ban 默認不包含通用的 Nginx 惡意掃描 filter,需要自定義:

# 創(chuàng)建自定義 filter
sudo cat > /etc/fail2ban/filter.d/nginx-badbots.conf < .*"(GET|POST|HEAD) .*(.php|.asp|.aspx|.jsp|.cgi|.env|wp-login|wp-admin|phpmyadmin|.git|.svn|config.|.bak|.sql|shell|eval|base64).*"(400|403|404|444)
      ^ .*"(GET|POST) /"[0-9]+ [0-9]+"-"".*(?:masscan|zgrab|python-requests|Go-http-client|Scrapy|curl/|wget/).*"

ignoreregex =
EOF
# /etc/fail2ban/jail.local 追加

[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 60
bantime = 86400

Nginx CC 攻擊防護

# 創(chuàng)建 CC 攻擊檢測 filter
sudo cat > /etc/fail2ban/filter.d/nginx-cc.conf < .*"(GET|POST|PUT|DELETE) .*"(429|503) .*$
      limiting requests, excess: .* by zone .*, client: 

ignoreregex =
EOF
# /etc/fail2ban/jail.local 追加

[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
logpath = /var/log/nginx/error.log
     /var/log/nginx/access.log
maxretry = 30
findtime = 60
bantime = 600

2.5 自定義 filter 正則編寫

編寫自定義 filter 是 fail2ban 最核心的技能。

正則編寫規(guī)則

# fail2ban filter 正則語法
#  - 特殊標(biāo)記,匹配 IP 地址并作為封禁目標(biāo)
# ^   - 行首(fail2ban 自動處理時間戳前綴)
# .*   - 任意字符
# 其他  - 標(biāo)準 Python 正則語法

測試 filter 是否生效

# 測試 filter 規(guī)則是否匹配日志
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 測試自定義 filter
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-badbots.conf

# 測試單行日志
echo'103.1.2.3 - - [13/Mar/202600:00 +0800] "GET /wp-login.php HTTP/1.1" 404 0'| 
 sudo fail2ban-regex - /etc/fail2ban/filter.d/nginx-badbots.conf

# 輸出示例
# Results
# =======
# Failregex: 1 total
# Ignoreregex: 0 total
# Date template hits: ...
# Lines: 1 lines, 0 ignored, 1 matched, 0 missed

自定義 API 暴力破解防護

假設(shè)應(yīng)用日志格式如下:

2026-03-13 1045 [WARN] Login failedforuser admin from 103.1.2.3
2026-03-13 1046 [WARN] Login failedforuser admin from 103.1.2.3

編寫 filter:

sudo cat > /etc/fail2ban/filter.d/myapp-login.conf <s*$

ignoreregex =

datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S
EOF

配置 jail:

# /etc/fail2ban/jail.local 追加

[myapp-login]
enabled = true
port = 8080
filter = myapp-login
logpath = /var/log/myapp/application.log
maxretry = 5
findtime = 300
bantime = 1800

2.6 多服務(wù)防護配置

MySQL 遠程登錄防護

[mysqld-auth]
enabled = true
port = 3306
filter = mysqld-auth
logpath = /var/log/mysql/error.log
maxretry = 5
findtime = 600
bantime = 3600

FTP 防護(vsftpd)

[vsftpd]
enabled = true
port = ftp,ftp-data,ftps,ftps-data
filter = vsftpd
logpath = /var/log/vsftpd.log
maxretry = 5
findtime = 600
bantime = 3600

Postfix SMTP 防護

[postfix]
enabled = true
port = smtp,465,submission
filter = postfix[mode=auth]
logpath = /var/log/mail.log
maxretry = 5
findtime = 300
bantime = 3600

2.7 與 firewalld/nftables 聯(lián)動

firewalld 聯(lián)動(Rocky Linux)

# /etc/fail2ban/jail.local 的 [DEFAULT] 部分
[DEFAULT]
banaction = firewallcmd-rich-rules
banaction_allports = firewallcmd-rich-rules

驗證:

# 查看 firewalld 中的 fail2ban 規(guī)則
sudo firewall-cmd --list-rich-rules
# rule family="ipv4" source address="103.xx.xx.92" reject type="icmp-port-unreachable"

nftables 聯(lián)動

# /etc/fail2ban/jail.local 的 [DEFAULT] 部分
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports

驗證:

# 查看 nftables 中的 fail2ban 規(guī)則
sudo nft listsetinet f2b-table addr-set-sshd

2.8 啟動和驗證

# 重新加載配置
sudo fail2ban-client reload

# 查看所有活躍的 jail
sudo fail2ban-client status

# 查看特定 jail 的詳細狀態(tài)
sudo fail2ban-client status sshd

# 手動封禁測試
sudo fail2ban-clientsetsshd banip 1.2.3.4

# 手動解封
sudo fail2ban-clientsetsshd unbanip 1.2.3.4

# 查看 fail2ban 日志
sudo tail -f /var/log/fail2ban.log

三、示例代碼和配置

3.1 完整的 jail.local 配置示例

# /etc/fail2ban/jail.local
# fail2ban 完整配置模板

[DEFAULT]
# ========================
# 全局默認參數(shù)
# ========================

# 封禁時間 1 小時
bantime = 3600

# 檢測窗口 10 分鐘
findtime = 600

# 失敗閾值 5 次
maxretry = 5

# 白名單(內(nèi)網(wǎng) + 跳板機 IP)
ignoreip = 127.0.0.1/8 ::1
     10.0.0.0/8
     172.16.0.0/12
     192.168.0.0/16

# 遞增封禁
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800
bantime.overalljails = true

# 封禁后端(Ubuntu)
banaction = iptables-multiport
banaction_allports = iptables-allports

# 日志后端
backend = systemd

# ========================
# SSH 防護
# ========================
[sshd]
enabled = true
port = ssh
filter = sshd[mode=aggressive]
maxretry = 3
findtime = 300
bantime = 3600

# ========================
# Nginx 防護
# ========================
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
findtime = 300
bantime = 3600

[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 60
bantime = 86400

[nginx-cc]
enabled = true
port = http,https
filter = nginx-cc
logpath = /var/log/nginx/error.log
maxretry = 30
findtime = 60
bantime = 600

# ========================
# 其他服務(wù)
# ========================
[mysqld-auth]
enabled = false
port = 3306
filter = mysqld-auth
logpath = /var/log/mysql/error.log
maxretry = 5

[postfix]
enabled = false
port = smtp,465,submission
filter = postfix[mode=auth]
logpath = /var/log/mail.log
maxretry = 5

3.2 案例 1:SSH 暴力破解防御(封禁統(tǒng)計)

場景:一臺公網(wǎng)服務(wù)器遭受持續(xù)的 SSH 暴力破解,需要配置 fail2ban 并統(tǒng)計封禁效果。

# 1. 先看看攻擊有多嚴重
sudo journalctl -u sshd --since"1 hour ago"| grep"Failed password"| wc -l
# 2847

# 統(tǒng)計攻擊來源 IP TOP 10
sudo journalctl -u sshd --since"1 hour ago"| 
 grep"Failed password"| 
 grep -oP'from K[0-9.]+'| 
 sort | uniq -c | sort -rn | head -10
#   423 103.xx.xx.92
#   389 45.xx.xx.201
#   312 185.xx.xx.33
#   287 91.xx.xx.156
#   ...

# 2. 確認 fail2ban 已配置并運行
sudo fail2ban-client status sshd

# 3. 查看封禁效果(運行 24 小時后)
sudo fail2ban-client status sshd
# Status for the jail: sshd
# |- Filter
# | |- Currently failed: 1
# | |- Total failed:   4823
# | `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
# `- Actions
#  |- Currently banned: 47
#  |- Total banned:   312
#  `- Banned IP list:  103.xx.xx.92 45.xx.xx.201 ...

# 4. 統(tǒng)計每日封禁 IP 數(shù)量
sudo grep"Ban "/var/log/fail2ban.log | 
 awk'{print $1}'| sort | uniq -c
#  312 2026-03-13
#  287 2026-03-14

3.3 案例 2:Nginx 惡意掃描過濾

場景:Nginx 日志中發(fā)現(xiàn)大量 404/403 請求,都是漏洞掃描器的探測行為。

# 1. 分析惡意掃描模式
sudo grep" 404 "/var/log/nginx/access.log | 
 awk'{print $7}'| sort | uniq -c | sort -rn | head -20
#   847 /wp-login.php
#   623 /wp-admin/
#   412 /phpmyadmin/
#   389 /.env
#   356 /.git/config
#   298 /config.php.bak
#   ...

# 2. 確認 nginx-badbots filter 匹配效果
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-badbots.conf
# Results
# =======
# Failregex: 3247 total
# ...

# 3. 啟用后驗證
sudo fail2ban-client status nginx-badbots
# Status for the jail: nginx-badbots
# |- Filter
# | |- Currently failed: 5
# | |- Total failed:   3247
# | `- File list:    /var/log/nginx/access.log
# `- Actions
#  |- Currently banned: 23
#  |- Total banned:   89

3.4 案例 3:自定義規(guī)則防御 API 暴力調(diào)用

場景:API 網(wǎng)關(guān)日志發(fā)現(xiàn)有 IP 在暴力嘗試登錄接口。

應(yīng)用日志格式:

2026-03-13 1045.123 WARN [auth-service] - Authentication failed: user=admin, ip=103.1.2.3, reason=bad_password
2026-03-13 1046.456 WARN [auth-service] - Authentication failed: user=test, ip=103.1.2.3, reason=user_not_found
# 1. 創(chuàng)建自定義 filter
sudo cat > /etc/fail2ban/filter.d/api-auth.conf <.*$

ignoreregex =

datepattern = ^%%Y-%%m-%%d %%H:%%M:%%S
EOF

# 2. 測試 filter
sudo fail2ban-regex /var/log/myapp/auth.log /etc/fail2ban/filter.d/api-auth.conf

# 3. 添加 jail 配置
sudo cat >> /etc/fail2ban/jail.local <

3.5 fail2ban 管理腳本

#!/bin/bash
# f2b_manage.sh - fail2ban 日常管理腳本
# 用法: ./f2b_manage.sh [status|banned|unban|stats|top]

RED='?33[0;31m'
GREEN='?33[0;32m'
YELLOW='?33[1;33m'
NC='?33[0m'

case"${1:-status}"in
  status)
   echo"===== fail2ban 服務(wù)狀態(tài) ====="
    sudo fail2ban-client status
   echo""
   echo"===== 各 Jail 封禁數(shù) ====="
   forjailin$(sudo fail2ban-client status | grep"Jail list"| sed's/.*://;s/,//g');do
      banned=$(sudo fail2ban-client status"$jail"| grep"Currently banned"| awk'{print $NF}')
      total=$(sudo fail2ban-client status"$jail"| grep"Total banned"| awk'{print $NF}')
     echo-e" ${jail}: 當(dāng)前封禁${RED}${banned}${NC}, 累計封禁${total}"
   done
    ;;

  banned)
   echo"===== 當(dāng)前封禁 IP 列表 ====="
   forjailin$(sudo fail2ban-client status | grep"Jail list"| sed's/.*://;s/,//g');do
     echo-e"
${YELLOW}[${jail}]${NC}"
      sudo fail2ban-client status"$jail"| grep"Banned IP"| sed's/.*list:/ /'
   done
    ;;

  unban)
    IP="${2:?用法: $0 unban }"
   echo"解封 IP:${IP}"
   forjailin$(sudo fail2ban-client status | grep"Jail list"| sed's/.*://;s/,//g');do
      sudo fail2ban-clientset"$jail"unbanip"$IP"2>/dev/null && 
       echo-e" ${GREEN}已從${jail}解封${NC}"||true
   done
    ;;

  stats)
   echo"===== 封禁統(tǒng)計(最近 7 天) ====="
    sudo grep"Ban "/var/log/fail2ban.log | 
      awk'{print $1, $6}'| 
      sort | 
      awk'{date=$1; jail=$2; count[date" "jail]++} END {for (k in count) print k, count[k]}'| 
      sort
    ;;

  top)
   echo"===== 被封禁最多的 IP TOP 20 ====="
    sudo grep"Ban "/var/log/fail2ban.log | 
      awk'{print $NF}'| 
      sort | uniq -c | sort -rn | head -20
    ;;

  *)
   echo"用法:$0[status|banned|unban |stats|top]"
   exit1
    ;;
esac

四、最佳實踐和注意事項

4.1 最佳實踐

白名單管理

# /etc/fail2ban/jail.local 的 [DEFAULT] 部分
[DEFAULT]
# 白名單:絕不封禁的 IP
# 包含:本機、內(nèi)網(wǎng)、跳板機、監(jiān)控服務(wù)器
ignoreip = 127.0.0.1/8 ::1
     10.0.0.0/8
     172.16.0.0/12
     192.168.0.0/16
     203.0.113.50    # 跳板機 IP
     203.0.113.51    # 監(jiān)控服務(wù)器 IP

注意事項:

白名單一定要包含所有合法的運維入口 IP,否則運維人員輸錯密碼也會被封

如果使用跳板機,跳板機 IP 必須在白名單中

監(jiān)控系統(tǒng)的探測 IP 也要加入白名單

白名單支持 CIDR 表示法

封禁策略梯度設(shè)計

[DEFAULT]
# 遞增封禁:每次被封,時間翻倍
bantime.increment = true

# 倍增因子
bantime.factor = 2

# 最大封禁時間 7 天
bantime.maxtime = 604800

# 跨 jail 累計(同一 IP 在不同 jail 的違規(guī)都計入)
bantime.overalljails = true

遞增封禁效果示例:

被封次數(shù) 封禁時間 累計
第 1 次 1 小時 1 小時
第 2 次 2 小時 3 小時
第 3 次 4 小時 7 小時
第 4 次 8 小時 15 小時
第 5 次 16 小時 31 小時
第 6 次+ 7 天(上限) -

與 CrowdSec 混合部署

fail2ban 負責(zé)本地日志檢測,CrowdSec 提供社區(qū)威脅情報補充:

# 安裝 CrowdSec
curl -s https://install.crowdsec.net | sudo bash
sudo apt install -y crowdsec crowdsec-firewall-bouncer-iptables

# CrowdSec 會自動共享封禁列表,補充 fail2ban 的本地檢測
# 兩者并存不沖突,分別使用不同的 iptables 鏈

4.2 注意事項

常見錯誤

錯誤現(xiàn)象 原因分析 解決方案
fail2ban 啟動失敗 jail.local 語法錯誤 fail2ban-client -t 檢查語法
filter 不匹配日志 正則表達式錯誤 fail2ban-regex 測試
封禁后仍可訪問 iptables 規(guī)則順序問題 檢查規(guī)則鏈優(yōu)先級
誤封合法 IP 白名單配置不完整 完善 ignoreip
日志時間不匹配 時區(qū)或日期格式問題 檢查 datepattern
jail 顯示 0 failed backend 配置不對 切換 backend 為 systemd 或 polling
Docker 容器內(nèi)日志 fail2ban 無法讀取容器日志 將日志掛載到宿主機
重啟后封禁丟失 默認不持久化封禁 啟用 dbpurgeage 或增大 bantime

性能注意事項

# fail2ban 的資源消耗主要在日志匹配
# 每個 jail 都會啟動一個線程監(jiān)控日志文件

# 查看 fail2ban 內(nèi)存使用
ps aux | grep fail2ban | grep -v grep

# 如果日志文件非常大,建議:
# 1. 使用 logrotate 定期切割日志
# 2. 減少 findtime 縮小掃描范圍
# 3. 優(yōu)化正則表達式(避免過于寬泛的 .*)

# 查看 fail2ban 數(shù)據(jù)庫大小
ls -lh /var/lib/fail2ban/fail2ban.sqlite3

兼容性問題

fail2ban 1.1.x 需要 Python 3.8+,Ubuntu 24.04 和 Rocky Linux 9.5 均滿足

如果系統(tǒng)同時運行 firewalld 和 iptables,注意 banaction 的選擇

Docker 環(huán)境中,fail2ban 需要在宿主機上運行,監(jiān)控宿主機上的日志文件

使用 systemd journal 作為 backend 時,確保日志持久化(Storage=persistent)

五、故障排查和監(jiān)控

5.1 故障排查

fail2ban 日志

# 查看 fail2ban 運行日志
sudo tail -f /var/log/fail2ban.log

# 過濾封禁事件
sudo grep"Ban"/var/log/fail2ban.log | tail -20

# 過濾解封事件
sudo grep"Unban"/var/log/fail2ban.log | tail -20

# 過濾錯誤
sudo grep"ERROR|WARNING"/var/log/fail2ban.log | tail -20

# 查看 fail2ban 服務(wù)日志
sudo journalctl -u fail2ban -n 50 --no-pager

常見問題排查

問題 1:fail2ban 無法匹配日志

# 檢查日志文件權(quán)限
ls -la /var/log/auth.log
# fail2ban 需要讀取權(quán)限

# 檢查日志格式是否匹配 filter
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched

# 檢查 backend 設(shè)置
# 如果使用 systemd,確認 journald 正在記錄
sudo journalctl -u sshd -n 5

問題 2:封禁后 IP 仍可訪問

# 檢查 iptables 規(guī)則是否存在
sudo iptables -L f2b-sshd -n -v

# 檢查規(guī)則順序(fail2ban 的規(guī)則是否在 ACCEPT 之前)
sudo iptables -L INPUT -n -v --line-numbers

# 如果使用 Docker,檢查 DOCKER 鏈是否繞過了 INPUT 鏈
sudo iptables -L FORWARD -n -v

問題 3:重啟后封禁記錄丟失

# fail2ban 使用 SQLite 數(shù)據(jù)庫存儲封禁記錄
# 檢查數(shù)據(jù)庫是否正常
sudo fail2ban-client get sshd bantime

# 確保 dbpurgeage 設(shè)置足夠長
# /etc/fail2ban/fail2ban.local
# [Definition]
# dbpurgeage = 86400

調(diào)試模式

# 前臺運行 fail2ban,查看詳細輸出
sudo fail2ban-client stop
sudo fail2ban-server -xf --loglevel DEBUG

# 查看某個 filter 的實時匹配
sudo fail2ban-clientsetsshd loglevel DEBUG
sudo tail -f /var/log/fail2ban.log | grep sshd

5.2 性能監(jiān)控

fail2ban 指標(biāo)導(dǎo)出到 Prometheus

使用 fail2ban-prometheus-exporter 或自定義腳本:

#!/bin/bash
# f2b_exporter.sh - fail2ban 指標(biāo)導(dǎo)出腳本
# 配合 node_exporter 的 textfile collector 使用

METRICS_DIR="/var/lib/prometheus/node-exporter"
METRICS_FILE="${METRICS_DIR}/fail2ban.prom"
TEMP_FILE=$(mktemp)

mkdir -p"$METRICS_DIR"

# 獲取所有 jail 的指標(biāo)
forjailin$(sudo fail2ban-client status 2>/dev/null | grep"Jail list"| sed's/.*://;s/,//g');do
  status=$(sudo fail2ban-client status"$jail"2>/dev/null)

  currently_failed=$(echo"$status"| grep"Currently failed"| awk'{print $NF}')
  total_failed=$(echo"$status"| grep"Total failed"| awk'{print $NF}')
  currently_banned=$(echo"$status"| grep"Currently banned"| awk'{print $NF}')
  total_banned=$(echo"$status"| grep"Total banned"| awk'{print $NF}')

  cat >>"$TEMP_FILE"<< EOF
fail2ban_currently_failed{jail="${jail}"}?${currently_failed:-0}
fail2ban_total_failed{jail="${jail}"}?${total_failed:-0}
fail2ban_currently_banned{jail="${jail}"}?${currently_banned:-0}
fail2ban_total_banned{jail="${jail}"}?${total_banned:-0}
EOF
done

# 原子替換
mv?"$TEMP_FILE"?"$METRICS_FILE"
chmod 644?"$METRICS_FILE"

將腳本加入 crontab:

# 每分鐘采集一次
* * * * * /opt/scripts/f2b_exporter.sh

Prometheus 告警規(guī)則

# fail2ban_alerts.yml
groups:
-name:fail2ban
 rules:
  -alert:Fail2banJailDown
   expr:absent(fail2ban_currently_banned)
   for:5m
   labels:
    severity:critical
   annotations:
    summary:"fail2ban 指標(biāo)消失,服務(wù)可能已停止"

  -alert:Fail2banHighBanRate
   expr:rate(fail2ban_total_banned{jail="sshd"}[1h])>50
   for:10m
   labels:
    severity:warning
   annotations:
    summary:"SSH 封禁頻率異常高:{{ $value }}/小時"
    description:"jail{{ $labels.jail }}的封禁速率超過 50/小時,可能遭受大規(guī)模攻擊"

  -alert:Fail2banManyCurrentlyBanned
   expr:fail2ban_currently_banned>200
   for:5m
   labels:
    severity:warning
   annotations:
    summary:"當(dāng)前封禁 IP 數(shù)量過多:{{ $value }}"

Grafana 面板關(guān)鍵查詢

# 當(dāng)前封禁數(shù)
fail2ban_currently_banned

# 每小時封禁速率
rate(fail2ban_total_banned[1h]) * 3600

# 每小時失敗嘗試速率
rate(fail2ban_total_failed[1h]) * 3600

# 各 jail 封禁占比
fail2ban_currently_banned / ignoring(jail) group_left sum(fail2ban_currently_banned)

5.3 備份與恢復(fù)

配置備份

#!/bin/bash
# 備份 fail2ban 完整配置
BACKUP_DIR="/opt/backup/fail2ban"
DATE=$(date +%Y%m%d)

mkdir -p"$BACKUP_DIR"

# 備份配置文件
tar czf"${BACKUP_DIR}/fail2ban_config_${DATE}.tar.gz"
  /etc/fail2ban/jail.local 
  /etc/fail2ban/jail.d/ 
  /etc/fail2ban/filter.d/*local* 
  /etc/fail2ban/action.d/*local* 
  2>/dev/null

# 備份數(shù)據(jù)庫
cp /var/lib/fail2ban/fail2ban.sqlite3"${BACKUP_DIR}/fail2ban_db_${DATE}.sqlite3"

# 保留 30 天
find"$BACKUP_DIR"-mtime +30 -delete

echo"fail2ban 配置已備份到${BACKUP_DIR}"

配置恢復(fù)

# 恢復(fù)配置
sudo tar xzf /opt/backup/fail2ban/fail2ban_config_20260313.tar.gz -C /

# 恢復(fù)數(shù)據(jù)庫(保留封禁記錄)
sudo systemctl stop fail2ban
sudo cp /opt/backup/fail2ban/fail2ban_db_20260313.sqlite3 /var/lib/fail2ban/fail2ban.sqlite3
sudo systemctl start fail2ban

# 驗證
sudo fail2ban-client status

六、總結(jié)

6.1 技術(shù)要點回顧

fail2ban 通過日志正則匹配 + 自動防火墻封禁實現(xiàn)入侵防御,核心是 Filter → Jail → Action 鏈路

所有自定義配置寫在.local文件中,不要修改.conf原始文件

SSH 防護使用內(nèi)置 sshd filter 的 aggressive 模式,覆蓋面最廣

Nginx 防護需要自定義 filter(惡意掃描、CC 攻擊),內(nèi)置的 nginx-http-auth 只覆蓋 Basic Auth

白名單(ignoreip)必須包含所有合法運維入口,避免誤封

遞增封禁策略(bantime.increment)對重復(fù)違規(guī)者逐步加重處罰

使用fail2ban-regex工具測試 filter 匹配效果,避免上線后才發(fā)現(xiàn)規(guī)則不生效

6.2 進階學(xué)習(xí)方向

CrowdSec 社區(qū)防御:基于社區(qū)威脅情報的協(xié)同防御,適合大規(guī)模部署

自定義 Action:封禁后自動發(fā)送通知(郵件/企微/釘釘),或?qū)懭?SIEM 系統(tǒng)

集中式日志 + fail2ban:使用 Filebeat/Fluentd 收集多臺服務(wù)器日志,在中心節(jié)點運行 fail2ban

WAF 集成:將 fail2ban 與 ModSecurity/Coraza WAF 結(jié)合,實現(xiàn)多層防御

6.3 參考資料

fail2ban 官方文檔: https://github.com/fail2ban/fail2ban/wiki

fail2ban filter 編寫指南: https://github.com/fail2ban/fail2ban/wiki/Developing-Filters

CrowdSec 官方文檔: https://docs.crowdsec.net/

Linux iptables 手冊: man iptables(8)

nftables wiki: https://wiki.nftables.org/

附錄

A. 命令速查表

# 服務(wù)管理
sudo systemctl start fail2ban   # 啟動
sudo systemctl stop fail2ban    # 停止
sudo systemctl restart fail2ban  # 重啟
sudo systemctl status fail2ban   # 狀態(tài)

# 配置管理
sudo fail2ban-client -t      # 語法檢查
sudo fail2ban-client reload    # 重新加載配置
sudo fail2ban-client reload sshd  # 重新加載單個 jail

# 狀態(tài)查看
sudo fail2ban-client status    # 總體狀態(tài)
sudo fail2ban-client status sshd  # 單個 jail 狀態(tài)
sudo fail2ban-client banned    # 所有封禁列表

# 封禁/解封
sudo fail2ban-clientsetsshd banip 1.2.3.4  # 手動封禁
sudo fail2ban-clientsetsshd unbanip 1.2.3.4 # 手動解封
sudo fail2ban-client unban --all        # 解封所有

# 調(diào)試
sudo fail2ban-regex   # 測試 filter
sudo fail2ban-clientsetsshd loglevel DEBUG # 開啟調(diào)試

B. 配置參數(shù)詳解

參數(shù) 默認值 說明
bantime 600 封禁持續(xù)時間(秒)
findtime 600 檢測時間窗口(秒)
maxretry 5 觸發(fā)封禁的失敗次數(shù)
ignoreip 127.0.0.1/8 白名單 IP/CIDR
backend auto 日志后端(systemd/polling/inotify)
banaction iptables-multiport 封禁動作
usedns warn DNS 解析策略(yes/no/warn/raw)
logencoding auto 日志文件編碼
enabled false 是否啟用 jail
port - 要封禁的端口
filter - 使用的 filter 名稱
logpath - 監(jiān)控的日志文件路徑
bantime.increment false 是否啟用遞增封禁
bantime.factor 1 遞增倍數(shù)
bantime.maxtime - 最大封禁時間

C. 術(shù)語表

術(shù)語 英文 解釋
暴力破解 Brute Force Attack 通過窮舉方式嘗試大量密碼組合的攻擊方法
字典攻擊 Dictionary Attack 使用預(yù)定義密碼列表進行暴力破解
撞庫 Credential Stuffing 使用泄露的賬號密碼在其他平臺嘗試登錄
封禁 Ban 將攻擊 IP 添加到防火墻黑名單,阻止其訪問
監(jiān)獄 Jail fail2ban 的監(jiān)控單元,包含 filter + action + 參數(shù)
過濾器 Filter 定義日志匹配規(guī)則的正則表達式模塊
動作 Action 匹配后執(zhí)行的操作(如添加防火墻規(guī)則)
遞增封禁 Incremental Ban 對重復(fù)違規(guī)者逐次增加封禁時間
蜜罐 Honeypot 故意暴露的假目標(biāo),用于誘捕和分析攻擊者
CC 攻擊 Challenge Collapsar 通過大量合法 HTTP 請求耗盡服務(wù)器資源的攻擊


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    88

    文章

    11782

    瀏覽量

    219235
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    14

    文章

    10303

    瀏覽量

    91597

原文標(biāo)題:用 fail2ban 防御暴力破解的落地實踐

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    LabView密碼破解暴力模式小程序

    LabView密碼破解暴力模式小程序,得重新去下載破解密碼的字典
    發(fā)表于 12-18 10:33

    labview密碼破解

    求助,軟件是去年改過的不知道誰設(shè)置了密碼,都說不知道。暴力破解字典實在太大。速度太慢,故求幫助~~PS :網(wǎng)上說的MD5破解,試了下也沒成。大神們,求交流~~
    發(fā)表于 01-19 23:37

    labview如何寫暴力破解密碼 密碼4位數(shù) 由1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ 如何每次讀取一個數(shù)進行測試完成后進行下一個測試

    labview如何寫暴力破解密碼 密碼4位數(shù) 由1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ 如何每次讀取一個數(shù)進行測試完成后進行下一個測試
    發(fā)表于 02-17 09:46

    何為暴力破解

    ps:代碼復(fù)制黏貼即可,有什么問題下方留言,博主會及時回復(fù) !工具:1:筆記本2:USB無線網(wǎng)卡(必備)3:kali系統(tǒng)4:靠譜字典暴力破解法:何為暴力破解呢,其實就是一個一個密碼試,直到正確的密碼
    發(fā)表于 07-15 09:46

    labview的VI加密暴力破解工具

    VI加密破解工具,有需要可以聯(lián)系我發(fā)送wx:***,破解內(nèi)容僅用于學(xué)習(xí),勿用于商用。
    發(fā)表于 09-03 08:53

    為什么不能隨便暴力破解比特幣私鑰

    試圖用暴力破解私鑰有點像試圖數(shù)到無限大:越早開始,就越不可能到達那里。盡管幾乎不可能做到,但對許多人來說,使用暴力破解一個比特幣私鑰仍然是一個耐人尋味的想法。 永不消逝的夢想
    發(fā)表于 10-30 11:23 ?9315次閱讀

    暴力破解比特幣私鑰可能會實現(xiàn)嗎

    試圖用暴力破解私鑰有點像試圖數(shù)到無限大:越早開始,就越不可能到達那里。盡管幾乎不可能做到,但對許多人來說,使用暴力破解一個比特幣私鑰仍然是一個耐人尋味的想法。 永不消逝的夢想
    發(fā)表于 10-31 09:35 ?4326次閱讀

    字符串硬核暴力破解法講解

    1 暴力破解法 在主串A中查找模式串B的出現(xiàn)位置,其中如果A的長度是n,B的長度是m,則n 》 m。當(dāng)我們暴力匹配時,在主串A中匹配起始位置分別是 0、1、2….n-m 且長度為 m 的 n-m+1
    的頭像 發(fā)表于 04-04 11:50 ?3829次閱讀
    字符串硬核<b class='flag-5'>暴力破解</b>法講解

    IP知識百科之暴力破解

    暴力破解 暴力破解是一種針對于密碼的破譯方法,將密碼進行逐個推算直到找出真正的密碼為止。設(shè)置長而復(fù)雜的密碼、在不同的地方使用不同的密碼、避免使用個人信息作為密碼、定期修改密碼等是防御暴力破解
    的頭像 發(fā)表于 09-06 09:28 ?4996次閱讀

    如何通過Python腳本實現(xiàn)WIFI密碼的暴力破解

    前言 本文將記錄學(xué)習(xí)下如何通過 Python 腳本實現(xiàn) WIFI 密碼的暴力破解,從而實現(xiàn)免費蹭網(wǎng)。 無圖形界面 先來看看沒有圖形界面版的爆破腳本。 WIFI爆破 import pywififrom
    的頭像 發(fā)表于 09-10 17:09 ?2.6w次閱讀
    如何通過Python腳本實現(xiàn)WIFI密碼的<b class='flag-5'>暴力破解</b>

    暴力破解壓縮包密碼

    可以暴力破解壓縮包密碼
    發(fā)表于 08-08 14:23 ?10次下載

    通過Python腳本實現(xiàn)WIFI密碼的暴力破解

    本文將記錄學(xué)習(xí)下如何通過 Python 腳本實現(xiàn) WIFI 密碼的暴力破解。
    的頭像 發(fā)表于 09-19 09:55 ?7965次閱讀

    會用kali破解wifi嗎?

    準備好 [kali] 系統(tǒng),電腦可以鏈接無線 wifi!! 使用 Aircrack-ng 進行暴力破解,linux 上已經(jīng)安裝此工具!
    的頭像 發(fā)表于 12-05 11:54 ?2638次閱讀

    R5300 G4服務(wù)器的BMC進行滲透測試案例

    對R5300 G4服務(wù)器的BMC進行滲透測試,發(fā)現(xiàn)存在BMC被暴力破解密碼的安全問題:攻擊者通過使用字典進行暴力破解,破解成功后獲取密碼,登錄BMC Web門戶對服務(wù)器進行操控,影響服務(wù)器運行安全。
    發(fā)表于 06-25 12:29 ?1443次閱讀
    R5300 G4服務(wù)器的BMC進行滲透測試案例

    如何在服務(wù)器端自動ban掉掃描ssh的IP

    掃描,可以利用fail2ban這個框架來把頻繁掃描的源IP直接丟進黑名單。讓服務(wù)器在一定時間內(nèi)拒絕連接。 ? ? 1.安裝fail2ban: # Ubuntu sudo apt update sudo
    的頭像 發(fā)表于 11-06 11:53 ?1201次閱讀
    如何在服務(wù)器端自動<b class='flag-5'>ban</b>掉掃描ssh的IP