chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

使用fail2ban防御暴力破解的落地實(shí)踐

馬哥Linux運(yùn)維 ? 來(lái)源:馬哥Linux運(yùn)維 ? 2026-03-23 10:27 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、概述

1.1 背景介紹

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

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

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

fail2ban 的工作原理

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

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

核心概念:

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

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

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

Ban/Unban:封禁和解封操作

1.2 與其他防御手段對(duì)比

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

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

1.3 適用場(chǎng)景

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

Nginx/Apache 的 HTTP Basic Auth 暴力破解防護(hù)

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

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

MySQL/PostgreSQL 遠(yuǎn)程登錄保護(hù)

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

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

1.4 環(huán)境要求

組件 版本要求 說(shuō)明
操作系統(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 運(yùn)行依賴
iptables/nftables 系統(tǒng)自帶 封禁后端
firewalld 2.x(可選) Rocky Linux 默認(rèn)
rsyslog/systemd-journald 系統(tǒng)自帶 日志來(lái)源

# 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

二、詳細(xì)步驟

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

fail2ban 的配置文件層級(jí):

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

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

2.2 基礎(chǔ)配置

創(chuàng)建 jail.local

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

啟動(dòng)服務(wù)

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

# 啟動(dòng)并設(shè)置開(kāi)機(jī)自啟
sudo systemctlenable--now fail2ban

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

2.3 SSH 防護(hù)配置

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

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

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

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

增強(qiáng)的 SSH 防護(hù)配置

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

maxretry = 3
findtime = 300
bantime = 3600

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

驗(yàn)證 SSH 防護(hù)是否生效

# 查看 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 防護(hù)配置

HTTP Basic Auth 暴力破解防護(hù)

# /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 惡意掃描防護(hù)

fail2ban 默認(rèn)不包含通用的 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 攻擊防護(hù)

# 創(chuàng)建 CC 攻擊檢測(cè) 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 正則編寫(xiě)

編寫(xiě)自定義 filter 是 fail2ban 最核心的技能。

正則編寫(xiě)規(guī)則

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

測(cè)試 filter 是否生效

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

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

# 測(cè)試單行日志
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 暴力破解防護(hù)

假設(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

編寫(xiě) 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ù)防護(hù)配置

MySQL 遠(yuǎn)程登錄防護(hù)

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

FTP 防護(hù)(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 防護(hù)

[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)動(dòng)

firewalld 聯(lián)動(dòng)(Rocky Linux)

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

驗(yàn)證:

# 查看 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)動(dòng)

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

驗(yàn)證:

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

2.8 啟動(dòng)和驗(yàn)證

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

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

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

# 手動(dòng)封禁測(cè)試
sudo fail2ban-clientsetsshd banip 1.2.3.4

# 手動(dòng)解封
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]
# ========================
# 全局默認(rèn)參數(shù)
# ========================

# 封禁時(shí)間 1 小時(shí)
bantime = 3600

# 檢測(cè)窗口 10 分鐘
findtime = 600

# 失敗閾值 5 次
maxretry = 5

# 白名單(內(nèi)網(wǎng) + 跳板機(jī) 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 防護(hù)
# ========================
[sshd]
enabled = true
port = ssh
filter = sshd[mode=aggressive]
maxretry = 3
findtime = 300
bantime = 3600

# ========================
# Nginx 防護(hù)
# ========================
[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)計(jì))

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

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

# 統(tǒng)計(jì)攻擊來(lái)源 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. 確認(rèn) fail2ban 已配置并運(yùn)行
sudo fail2ban-client status sshd

# 3. 查看封禁效果(運(yùn)行 24 小時(shí)后)
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)計(jì)每日封禁 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 惡意掃描過(guò)濾

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

# 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. 確認(rèn) nginx-badbots filter 匹配效果
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-badbots.conf
# Results
# =======
# Failregex: 3247 total
# ...

# 3. 啟用后驗(yàn)證
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)用

場(chǎng)景: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. 測(cè)試 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}, 累計(jì)封禁${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)計(jì)(最近 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

四、最佳實(shí)踐和注意事項(xiàng)

4.1 最佳實(shí)踐

白名單管理

# /etc/fail2ban/jail.local 的 [DEFAULT] 部分
[DEFAULT]
# 白名單:絕不封禁的 IP
# 包含:本機(jī)、內(nèi)網(wǎng)、跳板機(jī)、監(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    # 跳板機(jī) IP
     203.0.113.51    # 監(jiān)控服務(wù)器 IP

注意事項(xiàng):

白名單一定要包含所有合法的運(yùn)維入口 IP,否則運(yùn)維人員輸錯(cuò)密碼也會(huì)被封

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

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

白名單支持 CIDR 表示法

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

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

# 倍增因子
bantime.factor = 2

# 最大封禁時(shí)間 7 天
bantime.maxtime = 604800

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

遞增封禁效果示例:

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

與 CrowdSec 混合部署

fail2ban 負(fù)責(zé)本地日志檢測(cè),CrowdSec 提供社區(qū)威脅情報(bào)補(bǔ)充:

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

# CrowdSec 會(huì)自動(dòng)共享封禁列表,補(bǔ)充 fail2ban 的本地檢測(cè)
# 兩者并存不沖突,分別使用不同的 iptables 鏈

4.2 注意事項(xiàng)

常見(jiàn)錯(cuò)誤

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

性能注意事項(xiàng)

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

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

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

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

兼容性問(wèn)題

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

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

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

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

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

5.1 故障排查

fail2ban 日志

# 查看 fail2ban 運(yùn)行日志
sudo tail -f /var/log/fail2ban.log

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

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

# 過(guò)濾錯(cuò)誤
sudo grep"ERROR|WARNING"/var/log/fail2ban.log | tail -20

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

常見(jiàn)問(wèn)題排查

問(wèn)題 1:fail2ban 無(wú)法匹配日志

# 檢查日志文件權(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,確認(rèn) journald 正在記錄
sudo journalctl -u sshd -n 5

問(wèn)題 2:封禁后 IP 仍可訪問(wèn)

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

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

# 如果使用 Docker,檢查 DOCKER 鏈?zhǔn)欠窭@過(guò)了 INPUT 鏈
sudo iptables -L FORWARD -n -v

問(wèn)題 3:重啟后封禁記錄丟失

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

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

調(diào)試模式

# 前臺(tái)運(yùn)行 fail2ban,查看詳細(xì)輸出
sudo fail2ban-client stop
sudo fail2ban-server -xf --loglevel DEBUG

# 查看某個(gè) filter 的實(shí)時(shí)匹配
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 }}/小時(shí)"
    description:"jail{{ $labels.jail }}的封禁速率超過(guò) 50/小時(shí),可能遭受大規(guī)模攻擊"

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

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

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

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

# 每小時(shí)失敗嘗試速率
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ù)庫(kù)
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ù)庫(kù)(保留封禁記錄)
sudo systemctl stop fail2ban
sudo cp /opt/backup/fail2ban/fail2ban_db_20260313.sqlite3 /var/lib/fail2ban/fail2ban.sqlite3
sudo systemctl start fail2ban

# 驗(yàn)證
sudo fail2ban-client status

六、總結(jié)

6.1 技術(shù)要點(diǎn)回顧

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

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

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

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

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

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

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

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

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

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

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

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

6.3 參考資料

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

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

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

Linux iptables 手冊(cè): man iptables(8)

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

附錄

A. 命令速查表

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

# 配置管理
sudo fail2ban-client -t      # 語(yǔ)法檢查
sudo fail2ban-client reload    # 重新加載配置
sudo fail2ban-client reload sshd  # 重新加載單個(gè) jail

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

# 封禁/解封
sudo fail2ban-clientsetsshd banip 1.2.3.4  # 手動(dòng)封禁
sudo fail2ban-clientsetsshd unbanip 1.2.3.4 # 手動(dòng)解封
sudo fail2ban-client unban --all        # 解封所有

# 調(diào)試
sudo fail2ban-regex   # 測(cè)試 filter
sudo fail2ban-clientsetsshd loglevel DEBUG # 開(kāi)啟調(diào)試

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

參數(shù) 默認(rèn)值 說(shuō)明
bantime 600 封禁持續(xù)時(shí)間(秒)
findtime 600 檢測(cè)時(shí)間窗口(秒)
maxretry 5 觸發(fā)封禁的失敗次數(shù)
ignoreip 127.0.0.1/8 白名單 IP/CIDR
backend auto 日志后端(systemd/polling/inotify)
banaction iptables-multiport 封禁動(dòng)作
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 - 最大封禁時(shí)間

C. 術(shù)語(yǔ)表

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


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

    關(guān)注

    88

    文章

    11781

    瀏覽量

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

    關(guān)注

    14

    文章

    10299

    瀏覽量

    91587

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

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

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

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

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

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

    labview密碼破解

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

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

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

    何為暴力破解

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

    labview的VI加密暴力破解工具

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

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

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

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

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

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

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

    IP知識(shí)百科之暴力破解

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

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

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

    暴力破解壓縮包密碼

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

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

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

    會(huì)用kali破解wifi嗎?

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

    R5300 G4服務(wù)器的BMC進(jìn)行滲透測(cè)試案例

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

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

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