SSH 加固不是关掉密码那么简单:一条不会把自己锁在门外的路径

从密钥、来源限制、配置验证到救援通道,系统化加固 SSH。

分享
SSH 加固不是关掉密码那么简单:一条不会把自己锁在门外的路径
SSH 是服务器的总门钥匙。换一把更复杂的钥匙有用,但更重要的是谁能靠近门、钥匙丢了怎么办。

很多 SSH 教程只有三句话:改端口、禁用 root、关闭密码登录。方向不算错,但照抄最危险的地方在于,它没有告诉你变更顺序,也没有告诉你如何证明新配置真的可用。远程服务器只有一条管理通道时,一次拼写错误就可能把安全加固变成自我拒绝服务。

可靠的 SSH 加固应该同时解决四件事:身份是否足够强、入口是否足够窄、异常是否可观察、失败时是否有恢复路径。它更像更换飞机引擎,而不是换门锁:必须边验证边切换,不能先拆旧的再祈祷新的能启动。

密钥认证解决了什么,又没有解决什么

公钥认证避免服务器保存可被撞库的登录密码,也让客户端可以使用硬件密钥或带口令的私钥。但私钥文件一旦被复制,攻击者仍可能冒充你。客户端磁盘加密、私钥口令、代理转发控制和密钥轮换同样重要。不要把同一把私钥复制到所有电脑,更不要把它塞进同步盘。

服务器端的 authorized_keys 也可以收窄能力,例如限制来源地址、禁止端口转发或为自动化密钥指定固定命令。人类管理员的密钥和备份脚本的密钥不应该拥有同样权限。前者需要交互终端,后者通常只需要写入某个目录。

安全的变更顺序

先在第二个终端保持现有 SSH 会话,不要退出;再添加新密钥并验证新会话;随后使用 sudo sshd -t 检查语法;确认云控制台或救援模式可用后,最后才关闭密码登录。Ubuntu 建议把自定义项放进 /etc/ssh/sshd_config.d/,比直接反复编辑主文件更容易审计和回滚。

验证不应只看服务状态。要从另一台设备真正发起登录,确认目标用户、sudo、文件传输和必要的端口转发都能工作。配置文件通过语法检查,只能证明句子通顺,不能证明整条运维链路可用。

网络层先替 SSH 减压

改端口可以减少自动扫描产生的日志,却不会改变服务本身的安全等级。更有效的是在云防火墙或 UFW 中把 SSH 来源限制到固定公网 IP、办公网段或 VPN。Ubuntu 的 UFW 支持按来源和端口放行,例如只允许某个 /32 地址访问 22 端口。来源地址经常变化时,可以保留一个经过强认证的跳板入口,而不是重新开放全网。

Fail2ban 属于减速带,不是城墙。它能根据连续失败暂时封禁来源,对付低速撞库很有用,但无法替代密钥认证,也可能被分布式来源绕过。日志告警应关注成功登录的新来源、短时间大量用户枚举以及非预期时段的 sudo,而不只是失败次数。

root、sudo 与自动化账号

禁用 root 直接登录的价值,是把身份认证和提权分成两个事件,日志也更清楚。但如果普通用户拥有免密执行任意 sudo 命令,边界仍然很薄。自动化任务应该使用专门账号和精确 sudo 规则,不要为了让脚本少报一个错误就给它完整 root。

AI 运维工具尤其需要单独账号。让模型通过 SSH 连接生产服务器时,默认只给读取状态的命令;涉及删除、重启、修改防火墙和用户管理时,要求人工确认。提示词不是权限系统,真正的边界必须落实在 Unix 用户、sudoers 和网络策略上。

准备一条不会日常暴露的救援通道

云厂商控制台、串口终端、救援镜像或预先验证的第二管理员密钥,至少要有一种。救援通道平时不必方便,但必须知道在哪里、如何认证、恢复需要多久。把步骤写进离线文档,因为真正失联时你可能无法再打开服务器里的笔记。

每次 SSH 加固后记录有效配置:sshd -T 展示的是合并后的结果,比只查看某个配置文件更可靠。保留变更前备份和时间戳,也能在日志中把登录行为与配置变更对齐。

可以直接照着做的检查清单

  • 为每台管理设备使用独立、带口令或硬件保护的密钥。
  • 先验证第二个新会话,再关闭密码或 root 登录。
  • 执行 sshd -t 与 sshd -T,分别检查语法和最终生效值。
  • 在云防火墙或 UFW 收窄 SSH 来源,而不是只改端口。
  • 把人工管理员、备份脚本和 AI 运维工具拆成不同账号。
  • 确认云控制台或救援模式可用,并保存离线恢复步骤。

延伸阅读

最好的 SSH 配置不是看起来最严厉的那份,而是每条限制都经过验证、每次登录都可追溯、每个故障都有退路。