🔑 为什么 SSH 要记住服务器指纹:known_hosts 不是多余的麻烦

很多人第一次用 SSH 连服务器,都会看到那句有点吓人的提示:The authenticity of host ... can't be established。看起来像是系统在找你麻烦,其实它做的是一件很硬核但很朴素的事:防止你连上的根本不是那台服务器。

SSH 不是只负责“加密”,它还要先确认“对面是谁”。如果没有这一步,中间有人冒充服务器,你照样会把密码、命令、文件都交出去。于是 SSH 设计了 host key,也就是服务器自己的长期身份公钥。你第一次连接时,客户端还不认识它,所以会把这个指纹展示给你;一旦你确认并接受,它就被记到 ~/.ssh/known_hosts 里。下一次再连,SSH 会先检查:这台机器现在给出的指纹,和上次记住的是不是同一个。

这就是 known_hosts 的意义。它不是地址簿,而是“我以前见过这个人,而且我记得他的脸”。如果某天同一个域名、同一个 IP,突然拿出一把不同的 host key,SSH 就会直接报警。很多新手这时会觉得“删掉 known_hosts 再连不就好了”,这动作能解决表面错误,但也顺手把安全检查废了。更糟的是,你会分不清到底是服务器真的重装了,还是有人在中间拦你。

这里的设计很有意思:SSH 不相信网络路径,只相信上一次确认过的身份。网络里的 IP 可以变,DNS 可以改,路由可以绕,但只要 host key 没变,客户端就知道自己还在和原来的那台机器说话。也正因为这样,云服务器重建、容器宿主替换、负载切换时,最容易踩的坑就是“主机变了,但你还拿旧指纹去比”,于是出现经典的 REMOTE HOST IDENTIFICATION HAS CHANGED!。这不一定代表被攻击,但它一定代表“身份发生了变化,先别装作没看见”。

真正靠谱的做法不是无脑删记录,而是先确认这次变化是不是合理的。比如服务器是否刚被重装,是否换了实例,是否确实更新了 host key。确认无误后,再用 ssh-keygen -R 主机名或IP 删除旧记录,重新接受新的指纹。顺序不能反,不然你是在把报警器当噪音关掉。

🧪 课后一题:如果你连 server.example.com 时,SSH 提示 host key 变了,但运维同事说“昨天刚把这台机器重装了”,这时候最正确的动作是什么?

💡 易混淆点:known_hosts 记录的是“服务器身份”,不是“你自己的登录密钥”;它和 authorized_keys 不是一回事,前者防你连错人,后者决定你能不能登录。
#CS