可以直接在/etc/ssh/sshd_config里收紧登录策略:把MaxAuthTries改成3,限制认证尝试次数;将PermitRootLogin设为no,禁止root直接登录;把PasswordAuthentication设为no,关闭密码登录(前提是先把公钥认证配置好);再通过AllowUsers明确指定允许登录的用户。修改完成后,执行systemctl restart sshd使配置生效,同时务必保留一个已登录的终端作为备用,以免新配置导致自己被锁在系统外。

怎么改 sshd_config 里的登录限制参数
直接改 /etc/ssh/sshd_config 是最基础也最关键的一步,但改错会导致 SSH 无法连接,必须逐项确认。
MaxAuthTries控制单次连接最多尝试几次密码,默认是 6,建议设为3:找这行#MaxAuthTries 6,去掉注释并改成MaxAuthTries 3PermitRootLogin决定 root 能不能直连,禁用就写no;如果只允许密钥登录,写without-password(注意不是prohibit-password,后者在 CentOS 7 里不识别)PasswordAuthentication关密码登录必须设为no,但前提是已配好公钥,否则会彻底锁死AllowUsers或DenyUsers按用户名过滤,比如只允许admin和deploy登录:写成AllowUsers admin deploy
改完必须执行 systemctl restart sshd,且建议先开一个已登录的终端备用——别关,防止配置错误连不上。
为什么 /etc/hosts.allow 和 /etc/hosts.deny 要一起用
这两个文件是 TCP Wrappers 层的访问控制,优先级高于防火墙,但容易被忽略或顺序写反。
- 先写
/etc/hosts.deny:固定写sshd: ALL,表示默认全部拒绝 - 再写
/etc/hosts.allow:只放开可信 IP,例如sshd: 192.168.1.100: allow或sshd: 203.0.113.0/24: allow - 顺序不能颠倒——
hosts.allow优先匹配,匹配成功就放行,不再看hosts.deny;所以“全拒”必须放在 deny 文件里,allow 文件只写白名单 - 注意:如果用了
AllowUsers,IP 白名单和用户白名单是“且”关系,两者都得满足
防火墙和 SELinux 对新端口的影响
改了 SSH 端口(比如从 22 改成 2222),光改配置不够,系统层还有两道关卡要过。
- firewalld 必须显式放行新端口:
firewall-cmd --permanent --add-port=2222/tcp,然后firewall-cmd --reload - SELinux 默认只认 22 端口,不放行会静默拒绝连接。装
policycoreutils-python后运行:semanage port -a -t ssh_port_t -p tcp 2222 - 验证是否生效:
semanage port -l | grep ssh应该能看到2222在输出里 - 如果懒得调 SELinux,临时方案是
setsebool -P ssh_port_t 1,但不如加端口规则稳妥
登录失败后自动封 IP 的脚本为什么总漏掉攻击源
常见脚本从 /var/log/secure 解析 Failed password 日志来封 IP,但实际漏封有三个硬伤:
- 日志格式随 OpenSSH 版本变:CentOS 7.6+ 的日志字段位置可能偏移,
$(NF-3)取 IP 容易取错,建议用awk '/Failed.*from/ {print $11}'(字段数更稳定) - 没排除内网扫描或误操作:脚本应过滤掉
127.0.0.1、192.168.、10.等私有地址段 /etc/hosts.deny不支持 CIDR,只能封单 IP;想封段得靠iptables或fail2ban,原生脚本做不到- crontab 每天跑一次太慢,真实攻击往往几分钟内扫完——建议用
fail2ban实时监控,它才是生产环境标配
真正要落地,别自己拼脚本,fail2ban 配 sshd jail 几行配置就能跑,比手动解析日志可靠得多。