跳转至

Fail2ban 入侵防御

一句话概述:Fail2ban 监控日志文件,发现有人暴力破解密码(比如 SSH 登录连续失败),自动用 iptables/nftables 封禁该 IP,是 Linux 服务器安全的必装工具。

核心知识点

概念白话解释
暴力破解攻击者用程序自动尝试大量密码组合
Jail"监狱",一组过滤规则 + 封禁动作的配置
Filter过滤器,定义用什么正则表达式匹配日志中的失败尝试
Action动作,匹配到后做什么(封 IP、发邮件)
Ban Time封禁时长
Max Retry最大尝试次数,超过就封
Find Time在多长时间内累计失败次数

安装配置

# Ubuntu/Debian
sudo apt update
sudo apt install fail2ban  # 安装

# CentOS/RHEL
sudo yum install epel-release
sudo yum install fail2ban

# 启动
sudo systemctl start fail2ban  # 启动
sudo systemctl enable fail2ban  # 开机自启

配置文件

# 不要直接改 /etc/fail2ban/jail.conf
# 创建本地配置(优先级更高)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local  # 复制为本地配置
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600  # 封禁时间 1 小时(秒)
findtime = 600  # 10 分钟内
maxretry = 5  # 失败 5 次就封
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24  # 白名单(不封这些 IP)
banaction = iptables-multiport  # 用 iptables 封禁
# banaction = nftables-multiport  # 或用 nftables

# 邮件通知(可选)
# destemail = admin@example.com
# sender = fail2ban@example.com
# mta = sendmail
# action = %(action_mwl)s  # 封禁+邮件+日志

# ===== SSH 保护(最重要!) =====
[sshd]
enabled = true  # 启用 SSH 保护
port = ssh  # 端口(如果改了 SSH 端口,这里也要改,如 port = 2222)
logpath = /var/log/auth.log  # 日志路径(CentOS 用 /var/log/secure)
maxretry = 3  # SSH 只允许失败 3 次
bantime = 86400  # 封 24 小时

# ===== Nginx 保护 =====
[nginx-http-auth]
enabled = true  # 启用 Nginx 基本认证保护
logpath = /var/log/nginx/error.log

[nginx-botsearch]
enabled = true  # 封禁扫描机器人
logpath = /var/log/nginx/access.log

# ===== Nginx 限速 =====
[nginx-limit-req]
enabled = true  # 启用 Nginx 限速保护
logpath = /var/log/nginx/error.log

基本使用

# 查看状态
sudo fail2ban-client status  # 查看所有 jail 状态
sudo fail2ban-client status sshd  # 查看 SSH jail 详情(包括已封 IP)

# 手动封禁/解封
sudo fail2ban-client set sshd banip 1.2.3.4  # 手动封禁某 IP
sudo fail2ban-client set sshd unbanip 1.2.3.4  # 解封某 IP

# 重载配置
sudo fail2ban-client reload  # 修改配置后重新加载

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

高级用法

递增封禁时间

# /etc/fail2ban/jail.local
[DEFAULT]
bantime.increment = true  # 启用递增封禁
bantime.factor = 2  # 每次翻倍
bantime.maxtime = 604800  # 最长封 7 天
# 第1次 1h → 第2次 2h → 第3次 4h → ... → 最长 7 天

自定义过滤器

# /etc/fail2ban/filter.d/my-app.conf
[Definition]
failregex = ^<HOST> - .* "POST /api/login" 401  # 正则匹配登录失败
ignoreregex =  # 忽略的模式
# /etc/fail2ban/jail.local
[my-app]
enabled = true
filter = my-app
logpath = /var/log/my-app/access.log
maxretry = 5
bantime = 3600

永久封禁

[recidive]  # 惯犯检测
enabled = true
logpath = /var/log/fail2ban.log  # 监控 fail2ban 自己的日志
bantime = -1  # -1 = 永久封禁
findtime = 86400  # 24小时内
maxretry = 3  # 被封 3 次就永久封

常见报错

报错信息原因解决方案
No file(s) found for glob日志文件不存在检查 logpath 路径
Unable to find a corresponding IP日志格式不匹配检查 filter 的正则表达式
封了自己的 IP测试时登录失败次数太多ignoreip 白名单
重启后封禁丢失默认不持久化配置 dbfile 持久化
fail2ban 没启动配置文件有错sudo fail2ban-client -t 测试配置

速查表

# 常用命令
sudo fail2ban-client status              # 总状态
sudo fail2ban-client status sshd          # SSH 状态
sudo fail2ban-client set sshd banip <IP>  # 封 IP
sudo fail2ban-client set sshd unbanip <IP>  # 解封
sudo fail2ban-client reload               # 重载配置
sudo fail2ban-client -t                   # 测试配置
sudo fail2ban-client get sshd banned      # 列出所有被封 IP

# 日志查看
sudo tail -f /var/log/fail2ban.log   # fail2ban 日志
sudo grep "Ban" /var/log/fail2ban.log  # 查看所有封禁记录

# 推荐安全配置
# SSH: maxretry=3, bantime=86400
# Nginx: maxretry=5, bantime=3600
# 白名单你自己的 IP
# 启用递增封禁

参考:Fail2ban 官网 | GitHub | Wiki