SSH 免密登录突然失效?从密钥到 authorized_keys 权限的完整排查
昨天还能直接 ssh web01 上去,今天却要输密码,甚至报 Permission denied (publickey)。免密登录的链路其实很短,一旦出问题,按「客户端有没有送出钥匙 → 服务端认不认这把钥匙 → 认了之后权限放不放行」三步走,基本都能定位。
一、免密登录到底发生了什么
客户端本地有一对密钥:私钥留在 ~/.ssh/id_ed25519,公钥交给服务器,追加到目标用户的 ~/.ssh/authorized_keys。登录时服务器发一段随机数据,客户端用私钥签名后回传,服务器用公钥验签,通过即放行——全程没有密码在网络里传输。
所以「免密」失败只有三种可能:私钥没被用上、公钥没在服务器上,或者服务器因为权限与安全策略拒绝使用这把公钥。
二、三步标准配置
第一步,生成密钥(一路回车,口令可留空):
ssh-keygen -t ed25519 -C "me@example.com"
第二步,把公钥送到服务器(自动追加,权限由 ssh-copy-id 处理):
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@web01
第三步,验证:
ssh -o PasswordAuthentication=no deploy@web01 'echo ok'
第三步加上 PasswordAuthentication=no 很重要:它禁止回退到密码,能立刻暴露免密是否真正生效,而不是被密码兜住之后误以为配好了。
三、四个真实踩过的坑
坑 1,authorized_keys 权限过宽。这是最常见的原因。sshd 有一条硬性要求:家目录不能被组或其他用户写,~/.ssh 建议 700,authorized_keys 必须 600。多人共管机器时有人 chmod -R 777,免密立刻全线失效,而报错只有一句 Permission denied,看不出原因。修复方式:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod go-w ~
坑 2,家目录位于 NFS 或权限被父目录拖累。即便 ~/.ssh 本身没问题,只要 /home 或用户家目录对其他人可写,sshd 同样拒绝。用 namei -l ~/.ssh/authorized_keys 一次看清从根到文件的每一级权限。
坑 3,SELinux 上下文错乱。在 RHEL 与 CentOS 上把密钥文件从别处 cp 过来,权限对了但上下文还是 user_home_t,sshd 依然读不到。执行 restorecon -Rv ~/.ssh 恢复默认上下文,或看 ausearch -m avc -ts recent 有没有拒绝记录。
坑 4,多把私钥时 ssh 只试默认那把。手里有代码托管平台的 key、公司跳板机的 key,客户端默认只送 ~/.ssh/id_rsa。需要在 ~/.ssh/config 里明确指定:
Host web01
HostName 10.0.0.11
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
IdentitiesOnly yes 能避免客户端把 agent 里所有钥匙挨个试一遍,触发服务器的 MaxAuthTries 限制。
四、一条命令定位卡在哪一步
ssh -vvv deploy@web01 2>&1 | grep -E "Offering|Authentications|denied|Accepted"
如果输出里没有 Offering public key,说明客户端没送钥匙,检查 IdentityFile 和 agent 是否加载;如果有 Offering 但紧接 Authentications that can continue publickey,说明服务器不认这把钥匙,比对公钥内容是否真的写进了 authorized_keys(ssh-keygen -lf 看指纹最快)。服务端日志 journalctl -u sshd -n 50 会明确写出 Authentication refused bad ownership or modes for file,直接指向权限问题。
另一个高频细节:公钥必须整行粘贴,ssh-ed25519 开头的整行中间不能断行,Windows 记事本存的 CRLF 也会让整行失效,用 dos2unix 或 sed 清理一下即可。
小结
免密登录不是配一次就永远好的配置,它依赖一串权限和上下文都正确的路径。排查时先看客户端有没有送出钥匙,再看服务端日志说了什么,最后用 namei -l 和 restorecon 兜住权限与上下文这两类隐形问题。把 PasswordAuthentication=no 当成验收标准,能省掉很多看起来配好了但其实没生效的返工。
- 点赞
- 收藏
- 关注作者
评论(0)