遇到 SSH 连接报"Permission denied (publickey)",通常是因为客户端私钥权限不对、密钥路径未指定,或服务端公钥配置有误,优先检查本地密钥权限和连接命令。
先说结论:这不是网络不通,而是身份验证环节被拒绝,重点排查密钥文件权限和匹配关系。
- 先确认本地私钥权限是否为 600
- 先处理服务端 authorized_keys 文件权限
- 再验证连接日志输出
命令速用版
如果急于恢复连接,可先尝试以下命令检查本地环境和指定密钥连接:
# 【本地执行】查看详细连接日志
ssh -v user@host
# 【本地执行】修复本地 SSH 目录及私钥权限(防止目录不存在报错)
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
# 【本地执行】指定密钥连接
ssh -i ~/.ssh/your_key user@host为什么会这样
SSH 协议在设计上将安全性置于便利性之上。当服务端返回"publickey"拒绝时,意味着 TCP 连接已建立,但认证阶段失败。常见原因包括客户端私钥文件权限过宽(如 755),导致 SSH 客户端主动拒绝加载;或者服务端家目录权限过松(如 777),触发 OpenSSH 的安全保护机制而中止认证。此外,密钥文件名非默认且未指定路径,也会导致客户端找不到正确的凭证。
分步处理
1. 生成密钥对(若无可用密钥)
如果本地没有合适的密钥对,需先生成。推荐使用 ed25519 算法:
# 【本地执行】生成密钥对
ssh-keygen -t ed25519 -C "your_email@example.com"
# 按提示操作,默认路径为 ~/.ssh/id_ed255192. 检查客户端私钥权限
SSH 客户端要求私钥文件权限必须严格限制。执行以下命令修复权限:
# 【本地执行】
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
# 若使用 ed25519,则 chmod 600 ~/.ssh/id_ed25519如果私钥文件名不是默认的 id_rsa 或 id_ed25519,连接时必须使用 -i 参数指定路径,或配置 ~/.ssh/config 文件。
3. 部署公钥到服务端
推荐使用 ssh-copy-id 自动部署,避免手动复制出错:
# 【本地执行】自动复制公钥
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host若无法使用 ssh-copy-id,需手动登录服务器(通过控制台或其他方式),确认公钥已正确写入 ~/.ssh/authorized_keys 文件。
4. 检查服务端公钥部署权限
检查该文件及目录权限:
# 【服务端执行】
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys5. 检查家目录权限
若用户家目录权限被设为 777,OpenSSH 会主动拒绝认证。需将其改为 755(普通用户)或 700(root):
# 【服务端执行】
chmod 755 /home/username
chown username:username /home/username6. 检查服务端配置
查看/etc/ssh/sshd_config,确认以下配置项启用:
# 【服务端执行】查看配置
sudo cat /etc/ssh/sshd_config | grep -E "PubkeyAuthentication|AuthorizedKeysFile"若需修改配置,务必先备份,防止配置错误导致无法远程连接:
# 【服务端执行】备份配置
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# 修改后测试配置无误再重启
sudo sshd -t
sudo systemctl restart sshd怎么验证是否生效
使用-v 参数查看详细连接日志,观察密钥加载情况:
# 【本地执行】
ssh -vvv user@host在输出中寻找"Offering public key"或"Authentication succeeded"字样。若仍失败,查看服务端日志(需 root 权限):
# 【服务端执行】
sudo tail -20 /var/log/auth.log
# 或 CentOS/RHEL 系统
sudo tail -20 /var/log/secure重点关注是否有"Authentication refused: bad ownership or modes"提示,这通常指向权限问题。
常见坑
1. 家目录权限过松:递归 chmod 777 操作常误伤家目录,导致 SSH 无法读取密钥文件。
2. 密钥文件名非默认:SSH 默认只加载 id_rsa 等标准名,自定义名称需显式指定或配置 Config。
3. 私钥加密未解锁:若私钥设有 passphrase 但未通过 ssh-agent 加载,可能导致静默跳过。
4. 混淆密码与密钥:服务端若禁用密码登录(PasswordAuthentication no),则必须使用密钥,无法 fallback 到密码。
5. SELinux 限制:某些系统开启 SELinux 可能阻止 SSH 读取家目录文件,可尝试临时 setenforce 0 排查。