Linux 服务器配置 Fail2Ban 防暴力破解:SSH 安全加固实战

摘要:服务器上线后,每天都有大量自动化脚本尝试暴力破解 SSH 密码,有时每小时攻击次数超过数千次。Fail2Ban 是目前最成熟的自动封禁方案,能实时监控日志、自动封禁恶意 IP,还能防护 Nginx、WordPress 登录等多种攻击。本文从安装到精细调优,带你完整配置一套生产级防暴力破解体系。

先看数据:你的服务器每天遭受多少攻击?

服务器上线后先执行以下命令,看看过去 24 小时有多少次 SSH 攻击:

# Ubuntu/Debian 查看 SSH 失败登录次数
grep "Failed password" /var/log/auth.log | wc -l

# 查看攻击来源 IP Top 10
grep "Failed password" /var/log/auth.log \
  | awk '{print $11}' | sort | uniq -c | sort -rn | head -10

# CentOS/RHEL 用以下命令
grep "Failed password" /var/log/secure | wc -l
grep "Failed password" /var/log/secure \
  | awk '{print $11}' | sort | uniq -c | sort -rn | head -10
⚠️ 触目惊心:一台刚上线的公网服务器,通常在 24 小时内就会遭受数百到数万次 SSH 暴力破解尝试。这些来自全球的自动化攻击脚本 7×24 小时不间断扫描,只要密码稍弱就可能被攻破。

1 安装 Fail2Ban

# Ubuntu/Debian
apt update && apt install -y fail2ban

# CentOS/RHEL 7
yum install -y epel-release && yum install -y fail2ban

# CentOS/RHEL 8+
dnf install -y epel-release && dnf install -y fail2ban

# 启动并设置开机自启
systemctl enable --now fail2ban

# 验证运行状态
systemctl status fail2ban
fail2ban-client version
💡 配置原则:Fail2Ban 有两个配置文件:jail.conf(默认配置,不要直接修改)和 jail.local(用户自定义,优先级更高)。所有自定义配置都写在 jail.local,这样升级 Fail2Ban 后不会覆盖你的配置。

2 配置 SSH 防护(jail.local)

# 创建自定义配置文件
nano /etc/fail2ban/jail.local

粘贴以下完整配置(根据注释说明按需调整):

[DEFAULT]
# ── 全局基础设置 ──────────────────────────────

# 白名单:这些 IP 永远不会被封禁(用空格或逗号分隔)
# 强烈建议把你的固定办公 IP 加进来,防止误封自己
ignoreip = 127.0.0.1/8 ::1

# 封禁时长(秒):-1 表示永久封禁,推荐生产环境用 86400(1天)
bantime  = 86400

# 检测时间窗口(秒):在此时间内达到 maxretry 次则封禁
findtime = 600

# 最大失败次数:600 秒内失败 5 次即封禁
maxretry = 5

# 封禁动作:iptables-multiport 支持同时封禁多个端口
banaction = iptables-multiport

# 后端日志检测方式:systemd(推荐)或 auto
backend = systemd


[sshd]
# ── SSH 防护配置 ──────────────────────────────
enabled  = true
port     = ssh
# 如果你修改了 SSH 端口,将 ssh 改为实际端口号,如:
# port   = 2222
logpath  = %(sshd_log)s
backend  = %(sshd_backend)s
maxretry = 3        # SSH 只允许失败 3 次(比全局更严格)
bantime  = 86400    # 封禁 24 小时
findtime = 300      # 5 分钟内
# 重启 Fail2Ban 使配置生效
systemctl restart fail2ban

# 查看 SSH jail 状态
fail2ban-client status sshd
⚠️ 操作前务必确认:在配置 ignoreip 时,将你当前使用的 IP 加入白名单。如果不确定自己的 IP,执行 curl ifconfig.me 查看。否则一旦测试封禁,你可能把自己锁在外面。

3 验证 Fail2Ban 正常工作

# 查看所有已启用的 jail 列表
fail2ban-client status

# 查看 SSH jail 详细状态(含已封禁 IP 列表)
fail2ban-client status sshd

# 实时监控 Fail2Ban 日志
tail -f /var/log/fail2ban.log

# 手动测试:查看某个 IP 是否被封禁
fail2ban-client get sshd banip 1.2.3.4

# 手动封禁一个 IP(测试用)
fail2ban-client set sshd banip 1.2.3.4

# 手动解封一个 IP
fail2ban-client set sshd unbanip 1.2.3.4

# 查看 iptables 中的封禁规则
iptables -L f2b-sshd -n --line-numbers

正常的 Fail2Ban 日志输出示例:

2026-03-11 14:23:01 INFO    [sshd] Found 185.234.xx.xx - 2026-03-11 14:23:01
2026-03-11 14:23:05 INFO    [sshd] Found 185.234.xx.xx - 2026-03-11 14:23:05
2026-03-11 14:23:09 INFO    [sshd] Found 185.234.xx.xx - 2026-03-11 14:23:09
2026-03-11 14:23:09 NOTICE  [sshd] Ban 185.234.xx.xx
✅ 看到 Ban 字样说明封禁机制正常工作。

4 防护 Nginx 和 WordPress 登录

Fail2Ban 不只能防护 SSH,还能防护 Nginx 暴力请求和 WordPress 登录爆破。在 jail.local 末尾追加以下配置:

nano /etc/fail2ban/jail.local

追加以下内容:

[nginx-http-auth]
# ── Nginx 基础认证暴力破解防护 ─────────────────
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
maxretry = 5
bantime  = 3600


[nginx-botsearch]
# ── 防护恶意扫描器(扫描 wp-admin、phpMyAdmin 等)──
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 2
bantime  = 86400
filter   = nginx-botsearch


[wordpress-auth]
# ── WordPress 登录暴力破解防护 ──────────────────
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 5
bantime  = 86400
findtime = 300
filter   = wordpress-auth

创建 WordPress 登录过滤规则文件:

nano /etc/fail2ban/filter.d/wordpress-auth.conf
[Definition]
failregex = ^ .* "POST /wp-login.php
            ^ .* "POST /xmlrpc.php
ignoreregex =

创建恶意扫描器过滤规则:

nano /etc/fail2ban/filter.d/nginx-botsearch.conf
[Definition]
failregex = ^ .* "(GET|POST) /(wp-admin|phpmyadmin|pma|admin|administrator|wp-login\.php|xmlrpc\.php|\.env|\.git|config\.php)
ignoreregex =
# 测试过滤规则是否正确匹配日志
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-auth.conf

# 重启 Fail2Ban 加载新配置
systemctl restart fail2ban

# 验证新 jail 已启用
fail2ban-client status
效果:配置完成后,任何 IP 在 5 分钟内超过 5 次尝试登录 WordPress 后台,将被自动封禁 24 小时,完全阻断暴力破解攻击。

5 配置邮件告警

当有 IP 被封禁时自动发送邮件通知,第一时间掌握攻击态势:

# 安装邮件发送工具
apt install -y mailutils   # Ubuntu/Debian
yum install -y mailx       # CentOS

jail.local[DEFAULT] 部分添加邮件配置:

[DEFAULT]
# ... 原有配置保留 ...

# 邮件告警配置
destemail = admin@yourdomain.com    # 收件人邮箱
sender    = fail2ban@yourdomain.com # 发件人
mta       = sendmail                # 发送方式

# 封禁时发送邮件(含 WHOIS 信息)
action = %(action_mwl)s
💡 action 说明:%(action_)s 只封禁不发邮件;%(action_mw)s 封禁并发送含 WHOIS 的邮件;%(action_mwl)s 封禁并发送含 WHOIS 和相关日志行的邮件(信息最全,推荐)。

6 SSH 安全加固进阶配置

Fail2Ban 是事后封禁,以下措施从根本上减少攻击面:

① 修改 SSH 默认端口(最立竿见影)

nano /etc/ssh/sshd_config

# 将 Port 22 改为高位随机端口(1024-65535 之间)
Port 22345   # 替换为你选择的端口

# 重启 SSH(确保新端口连接成功后再关闭旧连接)
systemctl restart sshd

# 记得在云平台安全组中放行新端口!
# 同时更新 Fail2Ban 中的 SSH 端口配置
# jail.local 中 [sshd] 的 port = 22345

② 禁用 root 密码登录,改用密钥认证

nano /etc/ssh/sshd_config

# 修改以下配置项
PermitRootLogin prohibit-password   # root 只能用密钥登录
PasswordAuthentication no           # 完全禁用密码认证
PubkeyAuthentication yes            # 启用密钥认证
AuthorizedKeysFile .ssh/authorized_keys

systemctl restart sshd
⚠️ 操作顺序:必须先把你的公钥添加到 ~/.ssh/authorized_keys,验证密钥登录成功后,再禁用密码认证。否则会把自己锁在外面。

在本地生成并上传 SSH 密钥:

# 在本地电脑执行(Mac/Linux)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 将公钥上传到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub root@你的服务器IP

# 验证密钥登录成功后再禁用密码

③ 限制 SSH 登录用户

nano /etc/ssh/sshd_config

# 只允许指定用户 SSH 登录
AllowUsers deploy admin   # 只有这两个用户可以 SSH

# 或者只允许指定用户组
AllowGroups sshusers

systemctl restart sshd

④ 配置 SSH 连接超时和登录限制

nano /etc/ssh/sshd_config

LoginGraceTime 30          # 登录超时 30 秒
MaxAuthTries 3             # 最多允许 3 次认证尝试
MaxSessions 5              # 最多 5 个并发 SSH 会话
ClientAliveInterval 300    # 5 分钟发送一次保活包
ClientAliveCountMax 2      # 连续 2 次无响应则断开

systemctl restart sshd

Fail2Ban 常用命令速查

操作命令
查看服务状态systemctl status fail2ban
查看所有 jail 列表fail2ban-client status
查看 SSH jail 状态fail2ban-client status sshd
手动封禁 IPfail2ban-client set sshd banip 1.2.3.4
手动解封 IPfail2ban-client set sshd unbanip 1.2.3.4
解封所有 IPfail2ban-client unban --all
重载配置fail2ban-client reload
测试过滤规则fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
实时查看日志tail -f /var/log/fail2ban.log
查看封禁历史grep "Ban " /var/log/fail2ban.log | wc -l
查看今日封禁 IPgrep "Ban " /var/log/fail2ban.log | grep $(date +%Y-%m-%d)
查看 iptables 封禁规则iptables -L f2b-sshd -n

SSH 安全加固完整 Checklist

优先级安全措施难度效果
🔴 必做安装并启用 Fail2Ban自动封禁暴力破解 IP
🔴 必做使用强密码(16位以上+特殊字符)防止简单密码被破解
🔴 必做云平台安全组限制 SSH 来源 IP从网络层封堵攻击
🟡 推荐修改 SSH 默认端口(22 → 高位端口)减少 90% 自动化扫描
🟡 推荐禁用密码登录,改用 SSH 密钥彻底杜绝密码暴破
🟡 推荐禁用 root 直接登录减少高权限账号暴露
🟡 推荐AllowUsers 限制可登录用户最小权限原则
🟢 进阶配置 Fail2Ban 邮件告警实时掌握攻击动态
🟢 进阶配置 Nginx/WordPress 登录防护防护 Web 应用暴力破解
🟢 进阶定期审查 /var/log/auth.log发现异常登录行为

常见问题解答(FAQ)

Q1:Fail2Ban 会影响服务器性能吗?

影响极小。Fail2Ban 基于日志文件监控,CPU 和内存占用通常在 10–30MB 以内,对服务器性能几乎没有影响。封禁动作通过 iptables 在内核层实现,封禁后被封 IP 的数据包直接被丢弃,反而减少了应用层的处理压力。

Q2:我把自己的 IP 封禁了,怎么解封?

通过云平台的 VNC 控制台登录服务器,执行 fail2ban-client set sshd unbanip 你的IP 解封。解封后立即将该 IP 加入 jail.localignoreip 白名单,重启 Fail2Ban 防止再次误封。后浪云用户可登录 my.idc.net 通过 VNC 控制台紧急操作。

Q3:Fail2Ban 和云平台安全组有什么区别?应该用哪个?

两者互补,建议同时使用。云平台安全组在网络层拦截(流量到达服务器之前就被丢弃),性能最好但规则是静态的,需要手动维护;Fail2Ban 在系统层动态响应,能根据攻击行为自动更新封禁规则。最佳实践:安全组白名单限制 SSH 只允许你的固定 IP 访问,Fail2Ban 作为第二道防线处理其他端口的攻击。

Q4:修改 SSH 端口后,Fail2Ban 需要同步更新吗?

需要。在 jail.local[sshd] 部分将 port = ssh 改为实际端口号(如 port = 22345),然后执行 systemctl restart fail2ban。否则 Fail2Ban 封禁的仍是 22 端口,对新端口的攻击无法防护。

Q5:后浪云服务器推荐的完整安全配置是什么?

推荐组合方案:云平台安全组只开放 80、443 和自定义 SSH 端口(限制来源 IP)+ Fail2Ban 自动封禁 + SSH 密钥登录(禁用密码)+ 修改 SSH 默认端口。这四层防护叠加后,绝大多数自动化攻击都会在第一层(安全组)被拦截,极大降低服务器被入侵风险。后浪云香港服务器控制面板支持可视化安全组配置,操作简单直观。

THE END