FAQ-13:SSH 密钥认证失败(Permission denied publickey)

预计阅读时间:18 分钟

📖 目录

问题速查表

问题解决章节
客户端私钥与服务器公钥不匹配第一步:确认正在使用的密钥文件、第二步:确认公钥已正确部署到服务器
~/.ssh 或 authorized_keys 权限过松第三步:检查文件和目录权限、修复权限问题
sshd 配置限制了密钥认证第四步:检查 SSH 服务端配置、修复 sshd 配置
SELinux 安全上下文错误第六步:检查 SELinux(CentOS/RHEL)
公钥内容复制时格式错误原因分析
需要重新生成并部署密钥生成新的密钥对并部署

Permission denied (publickey) 是 SSH 连接中最常见的认证失败错误。当你尝试通过 SSH 连接到远程服务器时,如果服务器拒绝了你的公钥认证,就会看到这个错误。它是系统管理员和开发者日常工作中最频繁遇到的 SSH 问题之一。

SSH 密钥认证的核心机制是:客户端用私钥对一段数据进行签名,服务器用对应的公钥验证签名。如果服务器的 authorized_keys 文件中没有与客户端私钥匹配的公钥条目,认证就会失败。导致不匹配的原因多种多样:密钥文件错误、权限问题、配置限制、文件格式错误等。

理解 SSH 密钥认证的工作原理是排查的基础。SSH 协议在认证阶段会依次尝试所有可用的密钥类型,直到找到匹配的密钥或耗尽所有候选。使用 ssh -v 可以看到这个完整的尝试过程,这是排查问题的第一步。

原因分析

密钥文件不匹配是最常见的原因。客户端尝试使用的私钥与服务器 authorized_keys 中存储的公钥不是一对。这可能是因为你有多个密钥对,ssh 客户端默认选择了错误的密钥。

文件和目录权限错误是 SSH 安全机制的一部分。SSH 服务器对 ~/.ssh 目录和 authorized_keys 文件的权限有严格要求。如果权限设置过松(如 group 或 other 有写权限),SSH 会拒绝使用该密钥进行认证,以防止其他用户篡改授权列表。

SSH 服务端配置限制也会导致认证失败。/etc/ssh/sshd_config 中的 PubkeyAuthenticationAuthorizedKeysFilePermitRootLogin 等配置项都可能阻止密钥认证。

SELinux 安全上下文在 CentOS/RHEL 系统上可能导致 ~/.ssh 目录或 authorized_keys 文件的安全上下文不正确,即使权限数字正确也会被拒绝。

公钥格式错误在部署密钥时偶尔发生。复制公钥内容时可能引入了多余的换行、空格或字符,导致服务器无法正确解析。

多用户环境下的 HOME 目录权限也需要注意。如果用户的 HOME 目录(如 /home/username)对 group 或 other 有写权限,SSH 同样会拒绝认证。

排查决策树

publickey 认证失败的原因集中在五个层面,按下面的决策树从客户端到服务端逐层排查,不要一开始就去改 sshd 配置:

Permission denied (publickey)
│
├─ ① 客户端侧:确认用的是哪把密钥
│    │    ssh -v user@host 2>&1 | grep "Offering public key"
│    │    ├─ 尝试的不是预期密钥 → 用 -i 指定,或在 ~/.ssh/config
│    │    │    配 IdentityFile + IdentitiesOnly yes
│    │    └─ 密钥正确 → 进入 ②
│
├─ ② 服务器侧:公钥是否在 authorized_keys 中
│    │    cat ~/.ssh/authorized_keys 与本地 .pub 逐字符比对
│    │    ├─ 缺失 / 复制时换行损坏 → ssh-copy-id 重新部署
│    │    └─ 公钥在 → 进入 ③
│
├─ ③ 权限检查(最常见误配点)
│    │    基线:~ 755、~/.ssh 700、authorized_keys 600
│    │    ├─ 权限过松 → 服务端日志报 bad ownership or modes
│    │    │    → chmod 修复(见解决方案)
│    │    └─ 权限正确 → 进入 ④
│
├─ ④ sshd 配置检查
│    │    grep PubkeyAuthentication / AuthorizedKeysFile / StrictModes
│    │    ├─ 被禁用或被 sshd_config.d/ 覆盖 → 修正并重启 sshd
│    │    └─ 配置正常 → 进入 ⑤
│
└─ ⑤ SELinux(CentOS/RHEL)
     │    ls -Z ~/.ssh/authorized_keys 应为 ssh_home_t
     ├─ 上下文错误 → restorecon -Rv ~/.ssh
     └─ 正常 → 回到 ②,用 ssh -vvv 抓完整认证过程日志

排查步骤

第一步:确认正在使用的密钥文件

# 使用 verbose 模式查看认证过程
ssh -v user@host 2>&1 | grep "Offering public key"
# 输出示例:
# debug1: Offering public key: /home/user/.ssh/id_rsa RSA
# debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519

# 确认这是你期望使用的密钥文件
# 注意 "Accepted" 和 "Offering" 的区别

第二步:确认公钥已正确部署到服务器

# 在服务器上查看 authorized_keys
cat ~/.ssh/authorized_keys

# 对比本地公钥内容
cat ~/.ssh/id_rsa.pub

# 部署公钥(如果还没部署)
ssh-copy-id user@host

# 手动部署公钥
cat ~/.ssh/id_rsa.pub | ssh user@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

第三步:检查文件和目录权限

SSH 对权限要求非常严格,以下是正确的权限设置:

# 服务端检查
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~  # HOME 目录权限

# 客户端检查
chmod 600 ~/.ssh/id_rsa      # 私钥
chmod 644 ~/.ssh/id_rsa.pub  # 公钥
chmod 700 ~/.ssh

# 一键修复脚本
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_* 2>/dev/null
chmod 644 ~/.ssh/*.pub 2>/dev/null
chmod 600 ~/.ssh/authorized_keys 2>/dev/null
chmod 600 ~/.ssh/config 2>/dev/null

第四步:检查 SSH 服务端配置

# 检查关键配置项
grep -E "^PubkeyAuthentication|^AuthorizedKeysFile|^PermitRootLogin|^PasswordAuthentication|^StrictModes" /etc/ssh/sshd_config

# 确保以下配置正确
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
# PasswordAuthentication no  # 如果设为 no 且密钥认证也失败,会完全无法登录

# 检查 /etc/ssh/sshd_config.d/ 下的覆盖配置(Debian/Ubuntu)
ls /etc/ssh/sshd_config.d/
cat /etc/ssh/sshd_config.d/*.conf

第五步:查看详细日志

# 在服务端查看 SSH 日志
sudo journalctl -u sshd -n 50 --no-pager

# 或
sudo tail -50 /var/log/auth.log

# 使用更详细的客户端日志(三重 -v)
ssh -vvv user@host 2>&1 | grep -E "debug1.*key|debug1.*public|debug1.*Accepted|Authentication refused"

第六步:检查 SELinux(CentOS/RHEL)

# 查看 SELinux 状态
getenforce

# 修复 .ssh 目录的安全上下文
restorecon -Rv ~/.ssh

# 或手动设置
chcon -R -t ssh_home_t ~/.ssh

解决方案

生成新的密钥对并部署

# 生成 Ed25519 密钥(推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"

# 生成 RSA 4096 位密钥(兼容性更好)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 部署到服务器
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

# 验证连接
ssh -i ~/.ssh/id_ed25519 user@host

修复权限问题

# 服务端执行
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~

# CentOS/RHEL 额外步骤
restorecon -Rv ~/.ssh

配置 SSH 客户端使用指定密钥

# 编辑 ~/.ssh/config
Host myserver
    HostName 192.168.1.100
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes  # 只使用指定的密钥

# 或在命令行指定
ssh -i ~/.ssh/id_ed25519 user@host

修复 sshd 配置

# 编辑 /etc/ssh/sshd_config
sudo vim /etc/ssh/sshd_config

# 确保以下配置
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

# 重启 SSH 服务
sudo systemctl restart sshd

常见错误总结

错误日志原因解决方案
Authentication refused: bad ownership or modes for directory~/.ssh 或 HOME 目录权限过松chmod 700 ~/.ssh && chmod 755 ~
No supported authentication methods available服务器禁用了公钥认证设置 PubkeyAuthentication yes
Failed publickey for user公钥内容不匹配重新部署公钥到 authorized_keys
Connection closed by remote hostSSH 配置错误或服务崩溃检查 sshd_config 和服务状态
Key rejected by serverSELinux 安全上下文错误restorecon -Rv ~/.ssh

真实案例

案例 A:~/.ssh 目录权限 777,公钥被 sshd 直接忽略

现象:运维在刚配置好的 CentOS 服务器上测试密钥登录,反复失败:

$ ssh deploy@192.168.1.50
deploy@192.168.1.50: Permission denied (publickey)

排查过程:看服务端日志,第一行就给出了明确线索:

$ sudo tail -5 /var/log/secure
Apr 12 09:31:22 srv50 sshd[2318]: Authentication refused: bad ownership or modes for directory /home/deploy/.ssh
Apr 12 09:31:22 srv50 sshd[2318]: Failed publickey for deploy from 192.168.1.20 port 54321 ssh2

$ ls -ld ~/.ssh ~/.ssh/authorized_keys
drwxrwxrwx 2 deploy deploy 4096 Apr 12 09:00 /home/deploy/.ssh
-rw------- 1 deploy deploy  389 Apr 12 09:00 /home/deploy/.ssh/authorized_keys

根因.ssh 目录权限是 777(group 和 other 都有写权限)。sshd 的 StrictModes 机制认为该目录可能被其他用户篡改,直接拒绝使用其中的 authorized_keys,日志中的 bad ownership or modes 就是它的"指纹"。

修复

$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
$ ls -ld ~/.ssh ~/.ssh/authorized_keys
drwx------ 2 deploy deploy 4096 Apr 12 09:10 /home/deploy/.ssh
-rw------- 1 deploy deploy  389 Apr 12 09:10 /home/deploy/.ssh/authorized_keys

验证

$ ssh deploy@192.168.1.50       # 直接登录成功
Last login: ...
$ sudo tail -2 /var/log/secure
Apr 12 09:31:55 srv50 sshd[2450]: Accepted publickey for deploy from 192.168.1.20 port 54601 ssh2: ED25519 SHA256:...

教训:创建 .ssh 目录后顺手 chmod 700,千万不要用 chmod -R 777 图省事。

案例 B:SELinux 上下文错误导致密钥被拒,restorecon 一键修复

现象:RHEL 8 服务器上,管理员用 rsync 从旧服务器迁移了 /home/user/.ssh 目录,之后密钥登录一直失败:

$ ssh user@192.168.1.60
user@192.168.1.60: Permission denied (publickey)

$ sudo journalctl -u sshd -n 10 --no-pager
sshd[3102]: Failed publickey for user from 192.168.1.20 port 33451 ssh2

排查过程:authorized_keys 内容、权限数字全部正常,怀疑 SELinux。检查安全上下文:

$ getenforce
Enforcing
$ ls -Z ~/.ssh/authorized_keys
unconfined_u:object_r:user_home_t:s0 /home/user/.ssh/authorized_keys
# 正确应为 ssh_home_t

$ sudo ausearch -m avc -ts recent | grep sshd
type=AVC msg=audit(...): avc: denied { read } for pid=3102 comm="sshd"
  name="authorized_keys" dev="sda1" ino=... tcontext=user_home_t tclass=file

根因:rsync 迁移的文件带上了错误的安全上下文 user_home_t(应为 ssh_home_t),SELinux 在 Enforcing 模式下拒绝 sshd 读取 authorized_keys,权限数字再正确也没用。

修复

$ restorecon -Rv ~/.ssh
Relabeled /home/user/.ssh from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:ssh_home_t:s0
Relabeled /home/user/.ssh/authorized_keys from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:ssh_home_t:s0

验证

$ ssh user@192.168.1.60
Last login: ...
$ ls -Z ~/.ssh/authorized_keys
unconfined_u:object_r:ssh_home_t:s0 /home/user/.ssh/authorized_keys

经验:在 SELinux 系统上用 rsync/scp 迁移 .ssh 目录后,先执行一次 restorecon -Rv ~/.ssh,可以避开绝大多数上下文类故障。

案例 C:sshd_config 禁用密码登录后密钥登录也失败

现象:运维修改 /etc/ssh/sshd_config 禁用密码登录(PasswordAuthentication no),重启 sshd 后所有用户(包括密钥登录)都无法连接。

# 服务端日志
$ sudo journalctl -u sshd -n 10 --no-pager
sshd[4567]: Failed publickey for root from 192.168.1.20 port 54321 ssh2
sshd[4567]: Connection closed by authenticating user root 192.168.1.20 port 54321 [preauth]

# 检查 sshd_config
$ grep -E "^(PubkeyAuthentication|PasswordAuthentication)" /etc/ssh/sshd_config
PubkeyAuthentication no         # ← 问题在这里
PasswordAuthentication no

根因:运维在修改配置时误将 PubkeyAuthentication 也设为 no,导致公钥认证被禁用。密码和密钥登录同时被禁,所有用户无法连接。

修复PubkeyAuthentication yes,然后 sudo systemctl restart sshd。修改 SSH 配置前务必备份:cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

案例 D:多密钥配置导致 ssh 客户端选错密钥

现象:用户有多个 SSH 密钥(工作、个人、服务器),连接某台服务器时报 publickey 拒绝,但用 -i 指定密钥后正常:

# 默认连接失败
$ ssh deploy@server.example.com
deploy@server.example.com: Permission denied (publickey)

# 指定密钥后成功
$ ssh -i ~/.ssh/work_key deploy@server.example.com
Last login: ...

# 查看 ssh 尝试了哪些密钥
$ ssh -v deploy@server.example.com 2>&1 | grep "Offering public key"
debug1: Offering public key: /home/user/.ssh/id_rsa RSA
debug1: Offering public key: /home/user/.ssh/id_ed25519 ED25519
debug1: Offering public key: /home/user/.ssh/personal_key RSA
# 三个密钥都被尝试,但都不匹配

排查过程

# 查看服务器上允许的公钥
$ ssh deploy@server.example.com "cat ~/.ssh/authorized_keys"
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... work-key-comment

# 只有工作密钥在服务器上,但 ssh 默认尝试了其他两个密钥

根因:SSH 客户端默认会尝试 ~/.ssh/ 下的所有密钥。当密钥数量多且服务器只接受特定密钥时,容易出现选错密钥的问题。

修复:配置 ~/.ssh/config 为每个主机指定密钥:

# ~/.ssh/config
Host server.example.com
    User deploy
    IdentityFile ~/.ssh/work_key
    IdentitiesOnly yes  # 只使用指定的密钥,不尝试其他

Host github.com
    IdentityFile ~/.ssh/personal_key
    IdentitiesOnly yes

预防:为每个服务器/服务配置 ~/.ssh/config,明确指定密钥。使用 IdentitiesOnly yes 避免尝试所有密钥。

案例 E:authorized_keys 文件被追加了多余内容

现象:运维手动编辑 authorized_keys 文件后,密钥登录失败:

# 查看 authorized_keys 内容
$ cat ~/.ssh/authorized_keys
# 这是我的工作密钥
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... work-key
# 注意这里有个空行
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... personal-key
# 末尾有多余的换行符

排查过程

# 检查文件格式
$ cat -A ~/.ssh/authorized_keys
# 这是我的工作密钥$
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... work-key$
$
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... personal-key$
$
$

# 查看文件行数
$ wc -l ~/.ssh/authorized_keys
6

根因:authorized_keys 文件中有注释行、空行和多余换行符。虽然 SSH 应该能处理这些格式问题,但某些版本的 sshd 对格式要求更严格。

修复

# 清理文件,只保留有效的公钥行
$ grep -E "^ssh-" ~/.ssh/authorized_keys > /tmp/keys_clean
$ mv /tmp/keys_clean ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

# 验证格式
$ cat -A ~/.ssh/authorized_keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... work-key$
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... personal-key$

预防:使用 ssh-copy-id 部署公钥,避免手动编辑。如需手动编辑,保持每行一个公钥,不要添加注释或空行。

案例 F:HOME 目录权限过松导致整个 SSH 认证链失败

现象:用户执行了 chmod -R 777 ~ 后,SSH 密钥登录完全失败,即使修复了 .ssh 目录权限也无效:

# 修复 .ssh 目录权限后仍然失败
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
$ ls -ld ~ ~/.ssh ~/.ssh/authorized_keys
drwxrwxrwx 15 user user 4096 Apr 15 10:00 /home/user    # HOME 目录仍然是 777
drwx------  2 user user 4096 Apr 15 10:05 /home/user/.ssh
-rw-------  1 user user  389 Apr 15 10:05 /home/user/.ssh/authorized_keys

$ ssh user@server
user@server: Permission denied (publickey)

排查过程

# 查看 sshd 日志
$ sudo journalctl -u sshd | grep "bad ownership"
sshd: Authentication refused: bad ownership or modes for home directory /home/user

根因:SSH 的 StrictModes 不仅检查 .ssh 目录权限,还会检查 HOME 目录权限。HOME 目录对 group 或 other 有写权限时,sshd 会拒绝使用该用户的密钥认证。

修复

# 修复 HOME 目录权限
$ chmod 755 ~
$ ls -ld ~
drwxr-xr-x 15 user user 4096 Apr 15 10:10 /home/user

# 验证连接
$ ssh user@server
Last login: ...

预防chmod -R 777 ~ 是极其危险的操作,永远不要使用。修改权限时使用精确的权限设置,避免递归修改。

预防措施

  • 使用 ssh-copy-id 部署公钥,避免手动复制导致的内容错误
  • 为不同服务器使用不同密钥对,并在 ~/.ssh/config 中配置 IdentityFile
  • 使用 ssh-agent 管理密钥,避免重复输入私钥密码
  • 定期检查服务器的 SSH 配置和权限,尤其是在系统更新后
  • 迁移 .ssh 目录(rsync/scp)后立即执行 restorecon -Rv ~/.ssh(SELinux 系统)
  • 建立密钥轮换计划:每 6-12 个月轮换一次密钥,定期清理 authorized_keys 中的废弃条目

进阶排查技巧

使用 ssh -vvv 获取详细调试信息

三重 -v 选项可以输出 SSH 连接的完整调试信息:

# 获取完整的认证过程日志
ssh -vvv user@host 2>&1 > /tmp/ssh-debug.log

# 关键信息提取
grep -E "debug1: Offering|debug1: Accepted|debug1: Trying|Authentication refused" /tmp/ssh-debug.log

使用 ssh-keygen 验证密钥对匹配

# 从私钥导出公钥进行比对
ssh-keygen -y -f ~/.ssh/id_ed25519

# 与服务器上的公钥比对
ssh user@host "cat ~/.ssh/authorized_keys"

使用 sshd -T 测试配置

# 测试 sshd 配置文件语法
sudo sshd -t

# 查看 sshd 运行时配置(合并所有配置文件)
sudo sshd -T | grep -E "pubkeyauthentication|authorizedkeysfile|strictmodes"

批量检查服务器 SSH 配置

# 从跳板机批量检查多台服务器的 SSH 配置
for host in server{1..10}; do
    echo "=== $host ==="
    ssh user@$host "grep -E '^(PubkeyAuthentication|PasswordAuthentication|PermitRootLogin)' /etc/ssh/sshd_config"
done

常见误区与陷阱

  • 不要使用 chmod -R 777 ~:这会破坏 SSH 的安全检查,导致密钥认证失败
  • 不要在 authorized_keys 中添加注释或空行:虽然 SSH 支持注释,但可能导致解析问题
  • 不要忽略 sshd_config.d/ 目录:Debian/Ubuntu 的 SSH 配置可能被该目录下的文件覆盖
  • 不要使用 RSA 1024 位密钥:安全性不足,建议使用 Ed25519 或 RSA 4096 位
  • 不要在多个服务器间复制同一个密钥对:一个密钥泄露会影响所有服务器

故障复现与验证清单

修复 SSH 密钥认证问题后,使用以下清单验证:

# 1. 验证密钥权限
ls -la ~/.ssh/
# ~/.ssh 目录:700
# 私钥:600
# 公钥:644
# authorized_keys:600

# 2. 验证 HOME 目录权限
ls -ld ~
# 应为 755 或 700

# 3. 验证公钥部署
ssh user@host "cat ~/.ssh/authorized_keys" | grep "your-key-comment"

# 4. 验证 sshd 配置
sudo sshd -T | grep -E "pubkeyauthentication|authorizedkeysfile"

# 5. 验证 SELinux 上下文(CentOS/RHEL)
ls -Z ~/.ssh/authorized_keys
# 应为 ssh_home_t

SSH 权限基线速查表:

对象权限说明
/home/user(HOME 目录)755 或 700组/其他不能有写权限
~/.ssh700仅属主可访问
~/.ssh/authorized_keys600仅属主可读写
~/.ssh/id_ed25519(私钥)600过松 ssh 会拒绝使用
~/.ssh/id_ed25519.pub(公钥)644公钥可公开
~/.ssh/config600可能含敏感参数

最佳实践

  • 使用 Ed25519 密钥:相比 RSA,Ed25519 密钥更短、更快、更安全,是当前推荐的密钥类型
  • 禁用密码登录:部署好密钥认证后,立即禁用 PasswordAuthentication,大幅提升服务器安全性
  • 使用 ssh-agent:避免每次连接都输入私钥密码,提升使用体验。运行 ssh-add ~/.ssh/id_ed25519 将密钥加入 agent
  • 维护密钥清单:记录每台服务器使用的密钥对和部署时间,便于后续管理和轮换
  • 使用 config 文件~/.ssh/config 可以为不同服务器配置不同的密钥、用户名、端口,避免每次手动指定

延伸阅读

附录:SSH 密钥管理命令速查表

任务命令说明
生成密钥对ssh-keygen -t ed25519推荐使用 Ed25519
部署公钥到服务器ssh-copy-id user@host自动处理权限和格式
查看公钥指纹ssh-keygen -lf ~/.ssh/id_ed25519.pub验证公钥内容
测试密钥认证ssh -v -i 密钥文件 user@host查看详细认证过程
查看 ssh-agent 中的密钥ssh-add -l列出已加载的密钥
添加密钥到 agentssh-add ~/.ssh/id_ed25519加载私钥到内存
查看 authorized_keyscat ~/.ssh/authorized_keys检查已部署的公钥
修复权限chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys设置正确权限

附录:SSH 配置文件示例

# ~/.ssh/config
# 为不同服务器配置不同的密钥和参数

# 生产服务器
Host prod-server
    HostName 192.168.1.100
    User deploy
    Port 22
    IdentityFile ~/.ssh/prod_key
    IdentitiesOnly yes
    ServerAliveInterval 60
    ServerAliveCountMax 3

# 开发服务器(通过跳板机)
Host dev-server
    HostName 10.0.0.50
    User developer
    IdentityFile ~/.ssh/dev_key
    ProxyJump jump-server

# 跳板机
Host jump-server
    HostName 203.0.113.50
    User admin
    IdentityFile ~/.ssh/jump_key
    Port 2222

# GitHub
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/github_key
    IdentitiesOnly yes

附录:SSH 安全加固清单

  • 禁用密码认证:PasswordAuthentication no
  • 禁用 root 登录:PermitRootLogin no
  • 使用非标准端口(可选,但能减少自动扫描攻击)
  • 限制允许登录的用户:AllowUsers deploy admin
  • 使用 Fail2ban 防止暴力破解
  • 定期轮换密钥(每 6-12 个月)
  • 清理 authorized_keys 中的废弃条目
  • 监控 SSH 登录日志:journalctl -u sshd

附录:SSH 调试日志解读

# 使用 ssh -vvv 获取完整调试信息
ssh -vvv user@host 2>&1 | tee /tmp/ssh-debug.log

# 关键日志解读:
# debug1: Offering public key: /home/user/.ssh/id_rsa RSA    # 客户端尝试的密钥
# debug1: Server accepts key: /home/user/.ssh/id_rsa RSA     # 服务器接受密钥
# debug1: Authentication succeeded (publickey).              # 认证成功
# Authentication refused: bad ownership or modes             # 权限错误
# debug1: Trying private key: /home/user/.ssh/id_ed25519     # 尝试私钥
#debug1: No more authentication methods to try.              # 所有方法失败

附录:SSH 密钥类型对比

密钥类型长度安全性性能推荐场景
Ed25519256 位首选,适用于所有场景
RSA 40964096 位较慢兼容旧系统
RSA 20482048 位中等不推荐,安全性不足
ECDSA256/384/521 位可用于兼容性要求高的场景
DSA1024 位已弃用,不要使用

案例 G:AuthorizedKeysCommand 配置错误导致密钥认证失败

现象:企业环境中使用 AuthorizedKeysCommand 从 LDAP 获取公钥,配置后 SSH 密钥登录失败:

# 服务端日志
$ sudo journalctl -u sshd -n 10 --no-pager
sshd[5678]: AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys failed, status 1
sshd[5678]: Failed publickey for user from 192.168.1.20 port 54321 ssh2

排查过程

# 检查 sshd 配置
$ grep -E "^(AuthorizedKeysCommand|AuthorizedKeysCommandUser)" /etc/ssh/sshd_config
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser nobody

# 手动执行命令测试
$ sudo -u nobody /usr/bin/sss_ssh_authorizedkeys user
# 无输出或报错

# 检查 SSSD 状态
$ systemctl status sssd
● sssd.service - System Security Services Daemon
   Active: inactive (dead)

根因:AuthorizedKeysCommand 依赖 SSSD 服务从 LDAP 获取公钥,但 SSSD 未运行导致命令执行失败。sshd 在 AuthorizedKeysCommand 失败时会跳过该认证方式,如果本地 authorized_keys 中也没有匹配的公钥,认证就会失败。

修复

# 启动 SSSD 服务
sudo systemctl start sssd
sudo systemctl enable sssd

# 验证命令可用
sudo -u nobody /usr/bin/sss_ssh_authorizedkeys user

# 测试 SSH 连接
ssh user@host

预防:配置 AuthorizedKeysCommand 后立即测试命令可用性。确保依赖的服务(如 SSSD)已正确配置并设置开机自启。

案例 H:/root HOME 目录权限导致 root 用户 SSH 登录失败

现象:root 用户 SSH 密钥登录失败,但其他用户正常:

# 连接失败
$ ssh root@192.168.1.50
root@192.168.1.50: Permission denied (publickey)

# 检查 root 的 .ssh 目录
$ ls -ld /root /root/.ssh /root/.ssh/authorized_keys
drwx------ 15 root root 4096 Apr 15 10:00 /root
drwx------  2 root root 4096 Apr 15 10:05 /root/.ssh
-rw-------  1 root root  389 Apr 15 10:05 /root/.ssh/authorized_keys

# 权限看起来正确,但检查 HOME 目录
$ ls -ld /root
drwxr-x--- 15 root root 4096 Apr 15 10:00 /root
# 注意:group 有 rx 权限

根因:SSH 的 StrictModes 检查 HOME 目录权限时,如果 group 有写权限会拒绝认证。某些系统上 /root 目录的 group 权限设置不正确。

修复

# 修复 HOME 目录权限
$ chmod 700 /root
$ ls -ld /root
drwx------ 15 root root 4096 Apr 15 10:10 /root

# 验证连接
$ ssh root@192.168.1.50
Last login: ...

预防:root 用户的 HOME 目录权限应严格设置为 700。定期检查关键用户的目录权限,尤其是在系统迁移或备份恢复后。

↑ 回到顶部