在日常运维和开发中,反复输入服务器密码不仅繁琐,在自动化脚本场景下更是直接不可用。本文介绍如何配置 SSH 公钥免密登录,以及配置后仍然提示输密的常见排查思路。
一、免密登录的原理
SSH 免密登录基于非对称加密:客户端生成一对密钥(私钥留在本地,公钥上传到服务器)。连接时,服务器用公钥发起一个加密挑战,客户端用私钥应答,验签通过即放行,全程不需要传输密码。
- 私钥:保存在客户端
~/.ssh/id_ed25519(或id_rsa),绝不能泄露 - 公钥:上传到服务器的
~/.ssh/authorized_keys,一行一个公钥
二、配置步骤
1. 生成密钥对(客户端执行)
ssh-keygen -t ed25519 -C "yebin@workstation"
# 旧系统不支持 ed25519 时可用:
ssh-keygen -t rsa -b 4096 -C "yebin@workstation"
一路回车即可。建议设置一个私钥口令(passphrase),配合 ssh-agent 使用既安全又方便。生成的文件在 ~/.ssh/ 目录下:
id_ed25519 # 私钥
id_ed25519.pub # 公钥
2. 上传公钥到服务器
最简单的方式是用 ssh-copy-id(最后一次输密码):
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
如果客户端没有该命令(例如 Windows),手动追加也可以:
# Windows PowerShell
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
3. 验证
ssh [email protected] # 应该直接登录,不再提示密码
三、配置免密后仍然要输密码?排查清单
这是实际使用中最高频的问题,按概率从高到低排查:
1. 权限问题(占 80%)
SSH 对权限要求非常严格,权限过宽会直接拒绝公钥认证:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~ # home 目录不能是 777
2. SELinux 上下文错误(CentOS 常见)
restorecon -Rv ~/.ssh
3. sshd 配置未开启公钥认证
检查 /etc/ssh/sshd_config:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
修改后重载:systemctl reload sshd
4. 服务器 home 目录属主不对
如果 authorized_keys 的属主或属组不是登录用户,sshd 会忽略它:
chown -R $USER:$USER ~/.ssh
5. 查看详细日志定位问题
# 客户端开调试
ssh -vvv [email protected]
# 服务器端实时看日志
tail -f /var/log/secure # CentOS
tail -f /var/log/auth.log # Ubuntu/Debian
日志里出现 Authentication refused: bad ownership or modes,基本就是权限问题。
四、进阶:ssh config 多服务器管理
服务器多了以后,推荐用 ~/.ssh/config 统一管理:
Host web1
HostName 192.168.1.10
User root
Port 22
IdentityFile ~/.ssh/id_ed25519
Host db1
HostName 192.168.1.20
User root
Port 2222
IdentityFile ~/.ssh/id_ed25519
之后直接 ssh web1 即可登录,scp、rsync 等工具也自动复用这套配置。
五、安全建议
- 确认免密登录稳定后,可关闭密码登录:
sshd_config中设置PasswordAuthentication no,防止暴力破解 - 私钥务必设置 passphrase,或至少限制文件权限为 600
- 定期清理
authorized_keys中不再使用的公钥 - 有条件的话搭配 fail2ban 进一步加固
掌握 SSH 免密登录是自动化运维的第一步,配合 crontab、rsync、ansible 等工具就能实现无人值守的脚本化操作。

发表评论 取消回复