适用场景
本教程适用于所有面向公网开放 SSH 服务的 Linux 服务器管理员。SSH 暴力破解(Brute Force Attack)是最常见且持续的自动化攻击之一,攻击者利用字典或枚举方式不断尝试用户名和密码组合,试图获得服务器控制权。Fail2ban 通过监控日志文件中的失败登录模式,动态配置 iptables 或 nftables 封锁恶意 IP,是保护服务器安全的第一道实用防线。
前置条件
- Linux 服务器(Debian/Ubuntu 或 CentOS/RHEL),拥有 root 或 sudo 权限
- SSH 服务已启用(默认端口 22 或自定义端口)
- 安装了 Python 3(Fail2ban 依赖)
- iptables 或 nftables 防火墙已启用
- 建议先配置 SSH 密钥登录,Fail2ban 作为补充防御
原理说明
Fail2ban 的核心工作机制是一个”日志监控 → 规则匹配 → 动态封禁”的闭环:
- 日志监控(Filter):Fail2ban 实时监控指定日志文件(如
/var/log/auth.log),使用正则表达式匹配登录失败模式 - 规则匹配:管理员设定阈值——在指定时间窗口内(如 10 分钟)允许的最大失败次数(如 5 次),超过即触发封禁
- 动态封禁(Action):触发后自动执行 iptables 规则,在指定时间(如 1 小时)内拒绝该 IP 的所有 SSH 连接请求
- 解封恢复:封禁时间到期后自动移除规则,恢复正常访问
操作步骤
步骤 1:安装 Fail2ban
# Debian/Ubuntu
sudo apt update
sudo apt install fail2ban -y
# CentOS/RHEL
sudo yum install epel-release -y
sudo yum install fail2ban -y
步骤 2:确认 SSH 日志路径
# Debian/Ubuntu 默认路径
ls -la /var/log/auth.log
# CentOS/RHEL 默认路径
ls -la /var/log/secure
步骤 3:创建本地配置文件
不要直接编辑 jail.conf(它会被更新覆盖),而是在 jail.local 中写入自定义配置:
sudo tee /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
# 封禁时间:3600 秒(1 小时)
bantime = 3600
# 时间窗口:600 秒(10 分钟)
findtime = 600
# 阈值:10 分钟内最多 5 次失败
maxretry = 5
# 发送邮件通知(可选,需安装 sendmail)
# destemail = admin@example.com
# action = %(action_mwl)s
[sshd]
enabled = true
# 日志路径自动检测
logpath = %(sshd_log)s
# SSH 端口
port = ssh
# 白名单(永不封禁的 IP)
# ignoreip = 127.0.0.1/8 192.168.1.0/24
EOF
步骤 4:启动并启用 Fail2ban 服务
# 重启以加载新配置
sudo systemctl restart fail2ban
# 设置为开机自启
sudo systemctl enable fail2ban
# 检查运行状态
sudo systemctl status fail2ban
步骤 5:查看封禁状态与统计
# 查看所有监狱状态
sudo fail2ban-client status
# 查看 SSH 监狱详情(被封 IP 列表)
sudo fail2ban-client status sshd
# 查看近期日志
sudo tail -f /var/log/fail2ban.log
配置验证
验证 1:模拟暴力破解
从另一台机器使用错误密码测试(注意:不要对自己正在使用的 IP 测试):
# 从测试机器反复使用错误密码登录
ssh testuser@你的服务器IP
# 重复 6 次后,正常 SSH 应被拒绝
# 观察 fail2ban 日志
sudo tail -20 /var/log/fail2ban.log
# 应看到类似:INFO [sshd] Ban xx.xx.xx.xx
验证 2:检查 iptables 规则
# 确认 Fail2ban 已添加规则链
sudo iptables -L -n | grep -A 20 "f2b-sshd"
# 输出示例:
# Chain f2b-sshd (1 references)
# target prot opt source destination
# REJECT all -- xx.xx.xx.xx 0.0.0.0/0
# RETURN all -- 0.0.0.0/0 0.0.0.0/0
验证 3:手动解封测试 IP
# 解封指定 IP
sudo fail2ban-client set sshd unbanip xx.xx.xx.xx
# 查看更新后的封禁列表
sudo fail2ban-client status sshd
常见问题(FAQ)
Q1:Fail2ban 误封了自己的 IP 怎么办?
首先使用 fail2ban-client set sshd unbanip 你的IP 立即解封。然后在 jail.local 的 [DEFAULT] 部分添加白名单:ignoreip = 127.0.0.1/8 你的固定公网IP,重启 Fail2ban 生效。如果你没有固定 IP,可将 maxretry 提高到 10-15 次,减少误封概率。
Q2:Fail2ban 不工作,日志中没有任何封禁记录?
常见原因和排查步骤:① 确认服务已启动:systemctl status fail2ban;② 检查 SSH 日志路径是否正确:fail2ban-client get sshd logpath,如果返回 /var/log/secure 但你的系统用 auth.log,需要在 jail.local 中手动指定 logpath = /var/log/auth.log;③ 确认 fail2ban 用户有日志文件读取权限;④ 在 fail2ban.conf 中将 loglevel = INFO 改为 DEBUG 查看详细日志。
总结
Fail2ban 是一种轻量级、高效的 SSH 暴力破解防御方案,通过分析日志动态封禁恶意 IP,大幅提升服务器安全水平。本文介绍了从安装、配置到验证的完整流程。推荐结合 SSH 密钥认证(禁用密码登录)、修改默认 SSH 端口、使用 Port Knocking 等策略构成纵深防御体系。建议每周检查一次 fail2ban 封禁统计,持续监控异常峰值。