ssh安全加固需四步:改非标端口(如2222)并关闭22端口;禁用密码认证,强制密钥登录;配置allowusers白名单限制登录用户;设置clientaliveinterval 300与clientalivecountmax 2清理僵死连接。

SSH 服务默认端口暴露在公网就是风险源
22 端口被暴力扫描是常态,不是“可能”,而是“一定”——只要你的服务器有公网 IP 且 sshd 监听 0.0.0.0:22,每天都会收几百到几千次密码爆破。这不是小概率事件,是基础设施层面的默认攻击面。
改端口不能防高级攻击,但能过滤掉 95% 以上的自动化脚本。别信“改了端口就不安全”的说法,它不解决根本问题,但确实大幅降低噪音和误报干扰。
-
Port改成非标准值(比如2222或22022),必须在/etc/ssh/sshd_config中显式设置,不能只靠防火墙 redirect - 改完后运行
sudo systemctl restart sshd,再用sudo ss -tlnp | grep :2222确认监听生效 - 防火墙(如
ufw)要同步放行新端口,同时 立刻关闭旧端口 22 的入向规则,否则等于没改 - 客户端连接时必须显式指定端口:
ssh -p 2222 user@host,别漏-p
密码登录开着等于给机器人发钥匙
哪怕你密码很复杂,只要允许密码认证,sshd 就得接收并校验每一次尝试——这本身就在消耗资源、留下日志噪音,还可能被撞库或重放利用。密钥登录才是 linux SSH 的事实标准。
禁用密码不是为了“更酷”,是为了让登录行为可追溯、不可批量、失败成本高。
- 确认
/etc/ssh/sshd_config中PasswordAuthentication no和PubkeyAuthentication yes都已启用 - 改配置前,先用新密钥登录成功一次——别在唯一会话里改完就重启,否则可能锁死
- 私钥务必设
umask 077,文件权限必须是600,否则ssh客户端会直接拒绝加载 - 如果用了
ssh-agent,记得ssh-add ~/.ssh/id_rsa后再测试,否则本地也连不上
AllowUsers 比防火墙规则更早拦住非法用户
防火墙只能按 IP 或端口过滤,而 AllowUsers 是 SSH 协议层的第一道身份闸门——它在认证前就拒绝非名单用户的连接请求,不分配 session、不记录 auth 日志、不触发 PAM。
它比 DenyUsers 更安全,因为白名单天然防漏,黑名单永远追着新账号跑。
- 在
/etc/ssh/sshd_config中写死允许登录的用户,例如:AllowUsers deploy@192.168.1.* admin@2001:db8::/64 - 支持用户名 + 可选 IP 段组合,IP 部分留空表示任意来源(不推荐),建议绑定可信出口 IP 或 IPv6 前缀
- 多个用户用空格分隔,不要换行,否则第二行会被忽略
- 修改后必须
sudo sshd -t测试配置语法,再sudo systemctl reload sshd(reload 比 restart 更稳妥)
ClientAliveInterval 不是保活,是主动断开僵死连接
很多人以为这个参数是为了防止终端断开,其实它的核心作用是清理那些没真正退出、却不再响应的 SSH 连接——比如网络中断后客户端没发 FIN,或者用户关了笔记本但没登出,这些连接会一直占着 sshd 子进程和内存。
不设的话,几十个僵尸连接就能拖慢新连接建立,甚至触发系统级连接数限制。
- 推荐配对使用:
ClientAliveInterval 300(每 5 分钟发一次探针) +ClientAliveCountMax 2(连续两次无响应就断开) - 注意:这个机制只对已认证成功的连接生效,不影响登录过程中的握手阶段
- 如果用了跳板机或中间代理,确保探针包能双向穿透,否则可能误杀正常连接
- 配合
netstat -tnp | grep :22观察 ESTABLISHED 连接数变化,验证是否真正在回收
最常被跳过的其实是配置重载后的连通性验证——改完 sshd_config,光看 systemctl status sshd 没用,得从另一台机器上真实走一遍登录流程,包括密钥、端口、用户白名单三者同时满足。少一个环节,就等于开了个暗门。