前阵子帮朋友调一台群晖,折腾完发现他还在用密码登录每一台服务器,我当时就有点绷不住。做运维或者自己玩服务器的人,SSH免密登录算是基本功中的基本功,可偏偏有太多人卡在“明明配了密钥还是不生效”这一步上。这篇东西不打算写成官方文档的复读机,就按我自己这几年从Windows、macOS、Linux到各种网络设备上折腾SSH免密的真实经历,把原理、配置、坑全部摊开讲一遍。不管是刚接触SSH的新人,还是已经被“Permission denied”折磨了一下午的老哥,应该都能在这里找到对应的解法。
1. 免密登录的底层逻辑:搞清楚密钥对是怎么“对上暗号”的
1.1 非对称加密在SSH里到底做了什么
SSH免密登录的核心不是“不需要密码”,而是把“人知道的密码”换成了“机器持有的密钥”。这里面用的是非对称加密体系,也就是一对钥匙:私钥和公钥。私钥留在你自己的客户端机器上,权限必须收紧,谁拿到它谁就能冒充你;公钥则是可以公开分发的东西,你把它放到目标服务器的 ~/.ssh/authorized_keys 文件里,服务器就认这把公钥了。
整个认证过程可以简化成三步:客户端发起连接时出示自己的身份信息,服务器从 authorized_keys 里找到对应的公钥,生成一个随机挑战值发给客户端;客户端用私钥对挑战值签名后返回;服务器用公钥验证签名。签名验证通过,连接直接建立,全程不需要输入密码。
这个机制的好处很明显——私钥不出本地机器,网络上传输的只有挑战值和签名,即使有人抓包也拿不到能用于冒充你的材料。相比之下,密码认证每次都要把密码送到服务器端比对,虽然SSH协议本身做了加密传输,但密码本身依然是一个“可被猜测、可被爆破”的弱点。我之前遇到过一台暴露在公网上的测试机,一天之内被尝试登录几千次,开了免密并关闭密码认证之后,日志立刻安静了。
1.2 为什么说免密不是“取消认证”,而是“更换认证方式”
很多人问我:免密登录是不是不安全?我的回答通常是:如果你把私钥管理好,免密登录比密码登录安全得多。真正要注意的,是别把私钥当成无所谓的东西随手乱放。私钥文件默认权限是600,也就是只有属主可读写,这个权限如果被改大了,SSH客户端会直接拒绝使用该私钥,这是保护机制在起作用。
另外要区分两种情况:一种是本机到本机的免密,比如用 ssh localhost 测试;另一种是跨机器的免密,比如从你笔记本SSH到云服务器。前者通常是为了在脚本里执行本地命令时不被打断,后者才是日常运维里最常见的场景。理解了“客户端持私钥、服务端存公钥”这个基本模型,所有配置思路都会变得非常清晰。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 密钥生成与格式兼容:全平台实操细节
2.1 Linux和macOS下的密钥生成标准流程
在Linux或macOS的终端里生成密钥,我习惯用 ed25519 算法而不是老牌的 rsa。原因很简单:ed25519密钥更短、生成速度更快、安全性也足够,而且现代OpenSSH版本全都支持。命令如下:
bash复制ssh-keygen -t ed25519 -C "your_email_or_comment" -f ~/.ssh/id_ed25519
-C 参数是给密钥加一个备注,通常写自己的邮箱或者机器名,方便以后在 authorized_keys 文件里认出这是谁的密钥。-f 指定生成路径,如果想用默认路径,直接回车就行。执行过程中会提示设置私钥的密码(passphrase),这一步我建议设置,哪怕只是一个简单口令。设了passphrase之后,私钥文件即使被人拷走,没有口令也无法使用。
生成完成后,~/.ssh 目录下会出现两个文件:id_ed25519 是私钥,id_ed25519.pub 是公钥。公钥内容是一行文本,格式是 ssh-ed25519 一大串字符 备注,这一整行内容就是要放到服务器上的东西。
2.2 Windows平台的密钥生成与PuTTY格式转换
Windows用户的情况稍微复杂一点。Win10及以上的系统自带了OpenSSH客户端,可以直接在PowerShell或CMD里使用 ssh-keygen 命令,用法和Linux完全一致。但还有不少老用户习惯用PuTTY,PuTTY的密钥格式自成一套(.ppk),不能直接拿来给OpenSSH用,反之亦然。
如果你在Windows上用 `ssh-key
