SSH 是 Linux 服务器最常用的远程管理入口,也是攻击者最常扫描和爆破的目标之一。只要服务器暴露在公网,几乎每天都会收到大量来自自动化脚本的 SSH 登录尝试。一旦某个账户使用弱密码,服务器就可能在短时间内被入侵,进而被植入挖矿程序、后门或勒索软件。
本文从 SSH 暴力破解的原理出发,介绍几种常见防护手段,并重点讲解如何使用 fail2ban 自动封禁恶意 IP,最后给出一份可直接落地的配置示例。
一、SSH 暴力破解是怎么发生的
SSH 默认监听 22 端口,攻击者通过扫描工具(如 Masscan、Nmap)快速发现开放 22 端口的主机,然后用字典对 root、admin、test 等常见用户名进行密码尝试。整个过程完全自动化,单台主机每秒可以尝试数十次。
常见的攻击特征包括:
- 短时间内大量
Failed password日志 - 尝试的用户名集中在 root、admin、oracle、postgres 等
- 来源 IP 分散,但行为模式高度一致
- 登录成功后立即执行下载脚本、添加公钥等操作
理解这些特征,有助于我们选择合适的防护策略。
二、基础防护:在 fail2ban 之前先做好这些
fail2ban 是动态封禁工具,但它不能替代基础安全配置。在部署 fail2ban 之前,建议先完成以下加固:
1. 禁止 root 直接登录
编辑 /etc/ssh/sshd_config:
PermitRootLogin no
改为使用普通用户登录后再 sudo,可以显著降低风险。
2. 使用密钥认证,关闭密码登录
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
密钥认证几乎无法被暴力破解,这是最有效的防护手段。如果必须保留密码登录,请确保密码足够复杂。
3. 修改默认端口
将 SSH 端口从 22 改为其他端口,例如 22022:
Port 22022
这不能阻止有针对性的攻击,但可以过滤掉绝大多数无差别扫描。
4. 限制登录来源
如果服务器只对固定 IP 开放,可以用防火墙限制:
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
或使用 AllowUsers、Match Address 等 sshd 配置进一步限制。
5. 部署公钥并定期审计
定期检查 ~/.ssh/authorized_keys 和 /var/log/auth.log,确认没有异常公钥和登录记录。
完成以上配置后,再引入 fail2ban,可以形成“静态加固 + 动态封禁”的双层防护。
三、fail2ban 的工作原理
fail2ban 通过读取日志文件,匹配预设的正则表达式,当某个 IP 在指定时间内失败次数超过阈值时,自动调用防火墙(iptables、nftables、firewalld)将其封禁一段时间。
核心概念:
- jail:一个监控单元,对应一组过滤规则和动作
- filter:定义日志匹配规则,位于
/etc/fail2ban/filter.d/ - action:封禁与解封动作,位于
/etc/fail2ban/action.d/ - findtime:统计时间窗口
- maxretry:窗口内允许的最大失败次数
- bantime:封禁时长
四、安装与配置 fail2ban
1. 安装
# Debian / Ubuntu
sudo apt update && sudo apt install fail2ban -y
# CentOS / RHEL
sudo yum install epel-release -y
sudo yum install fail2ban -y
2. 创建本地配置
不要直接修改 jail.conf,而是新建 jail.local:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo vim /etc/fail2ban/jail.local
3. 配置 sshd jail
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 203.0.113.10
[sshd]
enabled = true
port = 22022
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h
如果是 CentOS,日志路径通常为 /var/log/secure。
4. 启动并设置开机自启
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo systemctl status fail2ban
5. 查看状态与封禁记录
sudo fail2ban-client status
sudo fail2ban-client status sshd
输出中会显示当前封禁的 IP 列表。手动解封:
sudo fail2ban-client set sshd unbanip 198.51.100.7
五、进阶:自定义 filter 与邮件告警
如果使用非标准日志格式,可以自定义 filter。例如监控 Nginx 的 401 错误:
# /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*" 401
ignoreregex =
然后在 jail.local 中启用:
[nginx-auth]
enabled = true
port = http,https
filter = nginx-auth
logpath = /var/log/nginx/access.log
maxretry = 10
bantime = 1h
配置邮件告警,在 [DEFAULT] 中加入:
destemail = admin@example.com
sender = fail2ban@example.com
action = %(action_mwl)s
action_mwl 表示封禁时发送邮件并附带 whois 信息。
六、常见问题与注意事项
- 把自己封了怎么办:在
ignoreip中加入自己的固定 IP,或通过控制台登录后解封。 - 日志路径不对:不同发行版日志位置不同,Debian 系为
/var/log/auth.log,RHEL 系为/var/log/secure。 - 与 firewalld 冲突:使用 firewalld 时,将
banaction改为firewallcmd-ipset。 - fail2ban 不是万能药:它只能缓解暴力破解,无法防御密钥泄露、0day 漏洞等。仍需配合密钥认证、最小权限、定期更新等措施。
- 不要过度封禁:
bantime设置过长可能误伤正常用户,建议从 1 小时起步,根据实际情况调整。
七、总结
SSH 暴力破解是公网服务器面临的最常见威胁之一。防护思路可以概括为:
- 能不用密码就不用密码,优先密钥认证
- 能限制来源就限制来源,减少暴露面
- 用 fail2ban 做动态封禁,自动阻断持续尝试的 IP
- 定期审计日志和授权文件,及时发现异常
把这几步做好,服务器的 SSH 入口安全性会有质的提升。安全不是一次性的配置,而是持续的过程,建议把上述检查纳入日常运维清单,定期复查。
未经允许不得转载:任鹏个人博客 » Linux SSH 暴力破解防护与 fail2ban 实践


朋友圈点赞图在线生成源码