fail2banAlmaLinux (RHEL系) 的默认仓库中没有 fail2ban 包,它需要通过 EPEL (Extra Packages for Enterprise Linux) 这个第三方仓库来安装。
bashsudo dnf install epel-release -y
系统会提示确认导入EPEL的GPG密钥,输入 y 即可。
bashsudo dnf install fail2ban -y
fail2banFail2ban 的配置遵循“覆盖”原则,所以绝对不要修改主配置文件 jail.conf,而应在 jail.local 中进行所有自定义。
bashsudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
txt[DEFAULT] # --- 全局默认设置 --- # 这些设置将应用于所有未明确覆盖它们的 "Jail" (监狱)。 # 忽略的 IP 地址,这些 IP 永远不会被封禁。 # 127.0.0.1/8 是本机回环地址,::1 是 IPv6 的本机回环地址。建议将您自己的固定 IP 也加入此列表。 ignoreip = 127.0.0.1/8 ::1 你的可信ip_1 你的可信ip_2 # 默认封禁时长。单位可以是 s(秒), m(分钟), h(小时), d(天), w(周)。这里是 1 天。 bantime = 1d # 查找时间窗口。Fail2ban 会在此时间段内统计客户端的失败次数。这里是 10 分钟。 findtime = 10m # 最大重试次数。在 `findtime` 时间窗口内,如果失败次数达到此值,客户端 IP 将被封禁。这里是 5 次。 # 结合上面的 findtime,意味着“10分钟内失败5次”。 maxretry = 5 # 触发封禁时执行的动作。%(action_)s 是一个变量,通常指向默认的封禁动作(如 iptables-multiport)。 action = %(action_)s # 对于 Debian 或 Ubuntu 并且你希望它和 UFW 集成 请删除 banaction = ufw 的注释 # banaction = ufw # ================================================================================= # JAILS (监狱) - 职责明确,策略清晰 # 每个 [section] 都是一个独立的 "监狱",用于监控一种特定的服务或攻击行为。 # ================================================================================= # --- 基础安全 (SSH) --- [sshd] # 是否启用此监狱。true 为启用,false 为禁用。 enabled = true # SSH 服务的端口号。 【重要】请务必修改为您服务器上实际的 SSH 端口! port = 22 # 覆盖默认的 maxretry。SSH 是核心服务,策略更严格,3次失败就封禁。 maxretry = 3 # 覆盖默认的 bantime。对于攻击 SSH 的 IP,封禁更长时间,这里是 1 周。 bantime = 1w # --- Nginx 核心防护:恶意扫描器 --- # 监控并阻止常见的目录扫描、漏洞扫描工具。 [nginx-pro-scanner] enabled = true # 监控的端口,http (80) 和 https (443)。 port = http,https # 使用的过滤器规则文件名 (位于 /etc/fail2ban/filter.d/nginx-pro-scanner.conf)。【注意】此为自定义过滤器。 filter = nginx-pro-scanner # 监控的 Nginx 日志文件路径。【重要】此路径通常用于宝塔面板,请根据您的实际情况修改。 logpath = /www/wwwlogs/*.log # --- Nginx 核心防护:恶意机器人与脚本 --- # 监控并阻止已知的恶意 User-Agent 或爬虫。 [nginx-badbots] enabled = true port = http,https # 使用的过滤器规则文件名 (位于 /etc/fail2ban/filter.d/nginx-badbots.conf)。【注意】此为自定义过滤器。 filter = nginx-badbots logpath = /www/wwwlogs/*.log # 策略非常严格,只要匹配到 1 次就封禁。 maxretry = 1 # 时间窗口缩短到 1 分钟,反应更迅速。 findtime = 1m # 封禁 1 周。 bantime = 1w # --- Nginx 核心防护:SQL注入 & XSS 攻击尝试 --- # 监控 URL 或请求体中包含的典型 SQLi 和 XSS 攻击代码。 [nginx-sqli-xss] enabled = true port = http,https # 使用的过滤器规则文件名 (位于 /etc/fail2ban/filter.d/nginx-sqli-xss.conf)。【注意】此为自定义过滤器。 filter = nginx-sqli-xss logpath = /www/wwwlogs/*.log # 策略严格,5 分钟内尝试 2 次就封禁。 maxretry = 2 findtime = 5m # 封禁 1 周。 bantime = 1w # --- Nginx 辅助防护:畸形请求 (4xx 错误) --- # 监控产生大量 4xx 客户端错误(如 404 Not Found, 403 Forbidden)的 IP。 [nginx-4xx-errors] enabled = true port = http,https # 使用的过滤器规则文件名 (位于 /etc/fail2ban/filter.d/nginx-4xx-errors.conf)。【注意】此为自定义过滤器。 filter = nginx-4xx-errors logpath = /www/wwwlogs/*.log # 策略相对宽松,允许一定程度的错误,防止误封正常用户。5 分钟内 15 次 4xx 错误才封禁。 maxretry = 15 findtime = 5m # 封禁时间较短,6 小时,因为误封的可能性相对较高。 bantime = 6h # --- Nginx 辅助防护:HTTP Basic Auth 爆破 --- # 监控 Nginx 的 HTTP 基本认证失败日志。 [nginx-http-auth] enabled = true # 【最终修正】为保证服务稳定启动,只监控最核心且确定存在的 nginx_error.log。 # HTTP 认证失败通常记录在错误日志中,而不是访问日志。 logpath = /www/wwwlogs/nginx_error.log # 3 次认证失败就封禁。 maxretry = 3 # 封禁 1 周。 bantime = 1w # --- 累犯加重处罚规则 (Recidive) --- # 这是一个特殊的“元监狱”,它不监控服务日志,而是监控 Fail2ban 自己的日志。 # 用来惩罚那些在短时间内被多次封禁的“惯犯” IP。 [recidive] enabled = true # 监控 Fail2ban 自己的日志文件。路径在各系统上可能不同,但 /var/log/fail2ban.log 是最常见的。 logpath = /var/log/fail2ban.log # 执行更严厉的封禁动作,通常是封禁所有端口 (allports),而不仅仅是触发的那个端口。 action = %(banaction_allports)s # 时间窗口为 1 天。 findtime = 1d # 如果一个 IP 在 1 天内被其他任何监狱封禁了 3 次... maxretry = 3 # ...那么它将被这个监狱处以更长的封禁时间:2 周,并且是所有端口。 bantime = 2w
/etc/fail2ban/filter.d/nginx-pro-scanner.conf,并复制粘贴下列内容:txt[Definition] # 匹配各种恶意扫描行为,状态码可以是 3xx, 4xx failregex = ^<HOST> .* "(GET|POST) .*/\.(git|env|svn|htpasswd|sql|bak|conf|ini|rar|zip|tgz|gz|bz2)[^"]*" (30|40)\d .* ^<HOST> .* "(GET|POST) .*/(phpmyadmin|pma|admin|db|mysql|websql|backup|dump)[^"]*" (30|40)\d .* ^<HOST> .* "(GET|POST) .*/(wp-admin|wp-login|wp-content|wp-includes|wordpress|wp)[^"]*" (30|40)\d .* ^<HOST> .* "(GET|POST) /xmlrpc\.php" (30|40)\d .* ^<HOST> .* "(GET|POST) /vendor/phpunit/phpunit/src/Util/PHP/eval-stdin\.php" (30|40)\d .* ^<HOST> .* "GET .*\?phpinfo=.*" .* ^<HOST> .* "GET .*/(console|invokefunction|api/jsonws/invoke)" .* ignoreregex =
/etc/fail2ban/filter.d/nginx-badbots.conf,并复制粘贴下列内容:text[Definition] # User-Agent 黑名单,不区分大小写 (?i) # 包含常见扫描工具、脚本语言、某些过于激进的爬虫 failregex = (?i)^<HOST> .* ".*(Go-http-client|AhrefsBot|SemrushBot|MegaIndex|BLEXBot|DotBot|Nmap|masscan|zgrab|sqlmap|nikto|python-requests|curl|wget|scan|spider|bot|crawler).*"$ ^<HOST> .* "-" "-"$ # 忽略主流搜索引擎爬虫,防止误伤 ignoreregex = (?i).*(googlebot|bingbot|baidu|slurp|duckduckbot|applebot|yandex|facebookexternalhit)
/etc/fail2ban/filter.d/nginx-sqli-xss.conf,并复制粘贴下列内容:txt[Definition] # 解码后的URL中包含SQL注入或XSS攻击的典型关键字 # (?i) 不区分大小写,\s 代表空格 failregex = (?i)^<HOST> .* ".*(union\s*select|select.*from|insert\s*into|<\s*script>|%%3Cscript%%3E|<\s*img|onmouseover|javascript:).*" .* ignoreregex =
/etc/fail2ban/filter.d/nginx-4xx-errors.conf,并复制粘贴下列内容:txt[Definition] # 捕获返回 4xx 客户端错误的请求,例如 400, 403, 404, 405 等 failregex = ^<HOST> -.*- .* 4\d\d .* # 忽略对 favicon.ico 和 robots.txt 的 404 请求,这些很常见 ignoreregex = .*(GET|HEAD) /(favicon.ico|robots.txt) .*
配置完成后,必须重启服务才能让新配置生效。
bash# 启动并设置开机自启
sudo systemctl enable --now fail2ban
# 重启服务以加载 jail.local 中的新配置
sudo systemctl restart fail2ban
# 查看 Fail2ban 整体状态,验证规则是否加载成功
sudo fail2ban-client status
# 停止服务
sudo systemctl stop fail2ban
成功标志:在输出的 Jail list 中,能看到您在 jail.local 里启用了 enabled = true 的所有规则名称,例如 sshd, nginx-bad-requests 等。
常见问题:如果发现某个自定义的 Jail (如 nginx-bad-requests) 没有出现在列表中,通常是因为缺少 filter 定义。请返回 jail.local 文件,在该 Jail 段落中添加一行 filter = nginx-botsearch。
bash# 查看 SSH 服务的封禁列表
sudo fail2ban-client status sshd
# 查看核心漏洞扫描(最常用)
sudo fail2ban-client status nginx-pro-scanner
# 查看恶意机器人封禁列表
sudo fail2ban-client status nginx-badbots
# 查看 SQL 注入 / XSS 攻击尝试
sudo fail2ban-client status nginx-sqli-xss
# 查看“骚扰型”扫描
sudo fail2ban-client status nginx-4xx-errors
注:在输出结果中查找 Banned IP list,后面就是被封禁的IP地址。
bash# 使用一行命令遍历并显示所有已启用规则的状态
sudo fail2ban-client status | grep "Jail list:" | sed -e 's/.*Jail list:[ \t]*//' -e 's/,//g' | xargs -n1 sudo fail2ban-client status
bash# 命令格式: sudo fail2ban-client set <规则名> unbanip <要解封的IP>
# 示例:解封被 sshd 规则封禁的IP 123.123.123.123
sudo fail2ban-client set sshd unbanip 123.123.123.123
bash# 临时停止服务,所有封禁会立即解除
sudo systemctl stop fail2ban
# 启动服务
sudo systemctl start fail2ban
本文作者:哈希喵
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!