1. 为什么要折腾免密登录:从一次抓狂的批量操作说起
如果你只在两三台机器上偶尔敲敲命令,密码登录确实够用。但一旦你开始管理五台、十台甚至更多Linux服务器,或者在写脚本批量同步配置、定时拉取日志、自动发布代码,你会发现每次都要输密码这件事会把人逼疯。
我自己第一次被逼到去研究免密登录,是因为一个深夜的故障处理。当时线上有六台应用服务器,需要逐个登录查看日志定位问题,每台机器都要输一遍root密码,输到第四台的时候我已经开始怀疑人生。更致命的是,当时有个临时脚本需要从跳板机向三台机器分发配置文件,脚本本身写好只要一分钟,但我守在旁边一遍遍输密码花了快十分钟——而且因为其中一台机器密码输错了一次,整个流程被迫重跑。
这就是SSH免密登录的核心价值:让机器之间的信任关系代替人肉输密码,从而实现批量操作的自动化和无人值守。它解决的不只是“省事”的问题,而是让一些原本不可能手动完成的操作成为可能——比如凌晨两点的定时备份、CI/CD流水线里自动部署到生产服务器、大规模集群的初始化配置。
这篇文章我会用两台CentOS主机作为示例(其他发行版如Ubuntu、Debian操作几乎一致),完整走一遍从生成密钥、分发公钥、验证登录到排查常见问题的全过程。同时会把每一步背后的原理讲清楚,让你不只是“照着敲能通”,而是真正理解这套信任机制是怎么工作的。
适合谁看:刚开始接触Linux运维的同学、需要配置自动化脚本的开发者、以及那些已经照着网上教程配过但没成功或者配完还是一头雾水的朋友。即使你之前完全没接触过SSH密钥,跟着这篇文章一步步操作也能搞定。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 免密登录背后的信任逻辑:公钥加密与授权文件
很多人照着教程执行成功了,但不知道自己到底做了什么,后面一遇到变体场景就懵。所以动手之前,我们先花五分钟把原理理清楚。
2.1 密码认证和密钥认证的本质区别
传统的密码登录,是客户端把密码传给服务端,服务端验证密码对不对,对了就放行。这个过程有两个隐患:一是密码在网络传输过程中有被截获的风险(虽然SSH协议本身会加密传输通道,但密码认证仍然面临暴力破解的威胁);二是密码认证要求每次连接都必须有人参与——要么人手动输入,要么把密码硬编码到脚本里(这是极度危险的做法,脚本泄露等于服务器裸奔)。
密钥认证则完全换了一套逻辑。它基于非对称加密,核心是一对密钥:
- 私钥(private key):留在客户端,权限必须严格控制,相当于你的身份证原件。
- 公钥(public key):分发到所有你想免密登录的服务器上,相当于你提前在门卫处备案的“通行证样本”。
登录过程大致是这样:
- 客户端发起SSH连接,告诉服务端“我是某某用户,我带了密钥”。
- 服务端在自己的授权列表(authorized_keys文件)里查找是否有对应的公钥记录。
- 找到后,服务端生成一段随机数据,用你的公钥加密,发给客户端。
- 客户端用自己的私钥解密这段数据,再把结果回传给服务端。
- 服务端验证解密结果正确,确认“你确实持有与公钥配对的私钥”,放行登录。
整个过程私钥始终不出客户端本机,网络上传输的只是加密后的验证数据,即使被截获,没有私钥也无法伪造身份。这就是为什么密钥认证比密码认证更安全、更适合自动化场景。
2.2 授权文件 authorized_keys 和 known_hosts 的角色
这里有两个特别容易混淆的文件,一个是服务端的authorized_keys,一个是客户端的known_hosts,弄不清它们会导致很多奇怪的报错。
authorized_keys:存放在服务端用户家目录下的.ssh文件夹里,路径通常是~/.ssh/authorized_keys。这个文件里每行存放一个公钥,代表“允许哪个公钥对应的私钥登录当前用户”。比如你在主机B上把A机的公钥追加进了root用户的authorized_keys,那A机就可以免密登录B机的root用户。
known_hosts:存放在客户端用户家目录下,路径是~/.ssh/known_hosts。它记录的是你曾经连接过哪些服务器,以及那些服务器的主机指纹(host key)。它的作用是防止中间人攻击——如果有人冒充服务器,指纹对不上,SSH客户端就会警告你。当你第一次SSH连接一台新服务器时,终端会问你是否信任这个主机指纹,就是这个文件在起作用。
注意这个区别非常重要:authorized_keys决定“谁能进”,known_hosts决定“我认不认识这台机器”。前者是授权机制,后者是防伪机制。
2.3 权限为什么那么敏感
Linux下SSH对文件权限极其敏感,这是大多数免密配置失败的头号原因。核心权限要求如下:
| 路径或文件 | 要求权限 |
|---|---|
| 用户家目录(~) | 755或更严格(不能是777) |
| .ssh目录 | 700 |
| authorized_keys文件 | 600 |
| 私钥 | 600 |
| 公钥 | 644 |
这些权限要求不是SSH开发者闲得慌,而是实打实的安全底线。如果.ssh目录权限过宽(比如777),意味着系统上的其他用户也能进去篡改你的authorized_keys文件,往里面塞一个他们自己的公钥,那你的服务器等于对人家敞开大门。所以SSH在验证时会严格检查权限,一旦发现权限过宽,直接拒绝使用这个密钥,防止被攻击者利用。
我在实操中发现一个规律:权限问题导致的失败,报错信息往往很有迷惑性,不会直接说“权限不对”,而是说“Permission denied (publickey)”,排查起来很费劲。所以配置时最好一次性把权限设对,后面出的很多问题都能从源头避免。
3. 动手前的心跳检查:确认SSH服务、网络与基础环境
很多人配置免密失败,卡在的不是后面的密钥操作,而是最基础的环境检查没做。你想,如果A机连B机的SSH端口都连不通,后面生成再多密钥也是白搭。
3.1 确认两台机器的SSH服务状态
首先在目标机器(B机,即被登录方)上确认SSH服务是否正常运行:
bash复制systemctl status sshd
看到active (running)就说明服务正常。如果没在运行,启动并设置开机自启:
bash复制systemctl start
