CentOS服务器暴露在公网后,默认的22端口几乎每分钟都在遭受来自全球各地的自动化爆破尝试。很多运维人员以为改个端口、装个fail2ban就万事大吉,实际上暴力破解的对抗是一个多层叠加的工程,任何单点防护都可能在特定攻击手法下失效。下面直接进入配置层面,把每一层该做什么、怎么做、做到什么程度讲清楚。

第一步:先确认攻击面,别在盲目状态下防守

登录服务器后先执行 lastb 命令查看最近失败的登录记录。如果输出几十页甚至刷屏,说明你的机器已经被长期扫描和试探。再执行 grep "Failed password" /var/log/secure | wc -l 统计失败次数。这个数字能直观反映当前爆破压力。很多人跳过这一步直接上防护,结果连攻击来源是字典爆破还是分布式撞库都分不清。查看 /var/log/secure 中失败记录对应的源IP,如果IP集中在少数几个段,可以用防火墙直接封段;如果IP分散在全球各地,说明攻击者使用了僵尸网络,此时单纯封IP效果有限,必须配合密钥认证和端口敲门等机制。

修改SSH默认端口是基础但不是关键

编辑 /etc/ssh/sshd_config,将 Port 22 改为一个高位端口,例如 26482。同时确认 PasswordAuthentication 先保持 yes,因为后续要逐步过渡到密钥登录。改完执行 systemctl restart sshd 重启服务。注意,修改端口前务必先在防火墙放行新端口,否则重启后可能把自己锁在门外。CentOS 7/8 使用 firewalld 的话,执行 firewall-cmd --permanent --add-port=26482/tcp && firewall-cmd --reload。改端口能过滤掉大部分无差别扫描,但针对性攻击者通过端口扫描依然能找到新端口,所以这层只是降低噪音,不是安全核心。

禁用密码登录,强制使用密钥对

这是防暴力破解最有效的一层。攻击者爆破的本质是猜密码,一旦密码登录被禁用,即使他知道你的用户名和端口,没有私钥也无法进入。先在本地生成密钥对:ssh-keygen -t ed25519 -C "server-admin"。然后把公钥上传到服务器:ssh-copy-id -p 26482 user@服务器IP。确认能用密钥登录成功后,再修改 /etc/ssh/sshd_config,将 PasswordAuthentication 改为 no,同时将 ChallengeResponseAuthentication 设为 no,UsePAM 设为 no。重启 sshd 后,所有密码尝试都会直接拒绝。这里有一个容易被忽略的点:如果服务器上有多个管理员,必须确保每个人的公钥都已部署到位再禁用密码,否则会有人被锁在外面。

限制可登录用户和来源IP

在 sshd_config 中添加 AllowUsers 指令,只允许特定用户通过SSH登录。例如 AllowUsers admin@192.168.1.0/24 deploy@10.0.0.5。如果运维人员IP不固定,可以去掉来源限制,但至少限制用户范围。更严格的做法是配合防火墙只允许特定IP访问SSH端口。firewalld 可以用 rich rule 实现:firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.5" port protocol="tcp" port="26482" accept'。这样即使密码泄露或密钥被窃,攻击者从其他IP也无法连接。对于需要从任意地点访问的场景,可以考虑使用跳板机或临时开放机制,但不要长期对所有IP开放。

安装并精细配置fail2ban

fail2ban 的作用是在多次失败后自动封禁来源IP,属于动态防御层。CentOS 默认仓库可能没有 fail2ban,需要先安装 EPEL 仓库:yum install epel-release -y && yum install fail2ban -y。安装后不要直接启动,先创建 /etc/fail2ban/jail.local 配置文件,内容如下:

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
ignoreip = 127.0.0.1 你的办公网IP段

[sshd]
enabled = true
port = 26482
logpath = /var/log/secure
backend = systemd

这里 maxretry 设为 3 意味着 10 分钟内失败 3 次就封禁 1 小时。bantime 可以根据实际攻击强度调整,如果爆破非常频繁,可以设为 86400 甚至更长。ignoreip 一定要加上自己的常用IP,防止误封。启动服务:systemctl enable fail2ban && systemctl start fail2ban。查看封禁状态用 fail2ban-client status sshd。注意,fail2ban 依赖日志解析,如果修改了SSH日志级别或使用rsyslog转发,要确保日志格式能被识别。

内核层面限制连接速率

fail2ban 是在用户态处理,攻击者如果使用慢速爆破或分布式IP,可能绕过封禁阈值。此时可以在内核层面用 iptables 的 limit 模块限制SSH端口的连接频率。CentOS 7 默认使用 firewalld,但底层仍然是 iptables。可以直接添加规则:

iptables -A INPUT -p tcp --dport 26482 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 26482 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 -j DROP

这两条规则的意思是:60秒内同一个IP新建SSH连接超过5次就丢弃后续请求。注意保存规则:service iptables save 或使用 iptables-save > /etc/sysconfig/iptables。如果服务器重启,需要确保规则被重新加载。这个限制对正常运维影响很小,但对自动化爆破工具非常有效,因为爆破工具通常会在短时间内发起大量连接尝试。

部署端口敲门机制作为隐藏防线

对于安全性要求极高的服务器,可以考虑 knockd 实现端口敲门。原理是:SSH端口默认关闭,只有按照特定顺序访问几个指定端口后,防火墙才临时放行SSH端口。安装:yum install knock-server -y。配置 /etc/knockd.conf:

[options]
UseSyslog

[openSSH]
sequence = 7000,8000,9000
seq_timeout = 10
command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 26482 -j ACCEPT
tcpflags = syn

[closeSSH]
sequence = 9000,8000,7000
seq_timeout = 10
command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 26482 -j ACCEPT
tcpflags = syn

使用时先访问 7000、8000、9000 端口,然后10秒内连接SSH端口即可。关闭时反向敲门。这种方式能彻底隐藏SSH服务,即使攻击者扫描端口也发现不了开放状态。缺点是每次连接都要敲门,对自动化运维脚本不友好,适合作为堡垒机或核心服务器的额外保护。

日志监控与告警不能缺失

所有防护措施部署后,如果没有监控,攻击者可能在突破某层后长期潜伏。建议配置 logwatch 或自写脚本定期分析 /var/log/secure。更实时的方法是使用 rsyslog 将日志发送到集中日志服务器,配合简单的关键字告警。例如在 /etc/rsyslog.conf 中添加:

*.info;mail.none;authpriv.none;cron.none /var/log/messages
authpriv.* /var/log/secure

然后通过 crontab 每5分钟执行一次脚本,检查最近5分钟内 Failed password 次数是否超过阈值,超过则发送邮件或调用企业微信机器人告警。脚本示例:

#!/bin/bash
COUNT=$(grep "Failed password" /var/log/secure | awk -v d="$(date '+%b %e %H')" '$0 ~ d' | wc -l)
if [ $COUNT -gt 20 ]; then
    echo "SSH爆破告警:最近5分钟失败次数 $COUNT" | mail -s "安全告警" admin@example.com
fi

这个脚本简单但有效,能让你在攻击发生时第一时间知道,而不是事后才发现。

定期审计与更新系统补丁

暴力破解往往利用已知漏洞配合弱口令进行。CentOS 7 已经停止维护,如果还在使用,强烈建议迁移到 CentOS Stream 或 Rocky Linux。对于仍在运行的 CentOS 7 系统,至少要做到 yum update -y 定期更新。同时检查 /etc/passwd 中是否存在异常用户,grep -E ":/bin/(ba)?sh" /etc/passwd 列出所有可登录用户,确认每个用户都是必要的。检查 /root/.ssh/authorized_keys 和每个用户的 authorized_keys 文件,删除不认识的公钥。很多服务器被攻破后,攻击者会留下自己的公钥作为后门,这个检查必须定期做。

总结配置优先级

如果只能做一件事,那就是禁用密码登录改用密钥。如果做两件事,加上限制来源IP。如果做三件事,再部署fail2ban。这三层组合已经能抵御绝大多数暴力破解。端口敲门和内核限速属于进阶手段,适合安全要求更高的场景。日志监控和定期审计则是持续运营的保障,没有监控的防护等于没有防护。所有配置修改前务必备份原文件,修改后保持当前SSH会话不断开,新开一个会话测试能否正常登录,确认无误后再关闭旧会话。服务器安全是一个持续对抗的过程,攻击手法不断演变,运维策略也要随之调整。