NoctisNode
← 指南安全2026-10-238 分钟

详解 SSH StrictModes、代理转发(ssh -A)与 ssh -a

如果家目录、~/.ssh 或 authorized_keys 可被他人写入,SSH StrictModes 会拒绝密钥登录;用 chmod 修复。不要在不可信主机上使用 ssh -A;ssh -a 可禁用代理转发。

简答:`StrictModes yes`(OpenSSH 默认值)会让 sshd 在接受密钥之前检查你的家目录、`~/.ssh` 和 `~/.ssh/authorized_keys` 的所有者和权限;如果其中任何一项可被组或其他用户写入,或归其他用户所有,就会以“Authentication refused: bad ownership or modes”拒绝登录。请修复权限,而不是关闭这项检查。使用 `ssh -A` 进行代理转发,会让远程主机在你连接期间使用你的本地密钥,因此不要在你不完全信任的主机上使用,改用 `ssh -J`(ProxyJump);小写的 `ssh -a` 则明确禁用代理转发。

本指南是 SSH 加固指南的补充,适用于 Debian 12/13、Ubuntu 24.04 以及 AlmaLinux 9、Rocky 9 等 RHEL 系系统。

SSH StrictModes 检查什么

StrictModes 是 `/etc/ssh/sshd_config` 中的服务器端设置。它的目的很简单:如果其他用户能写入你的 `authorized_keys`,他们就能添加自己的密钥并以你的身份登录。因此,除非整条路径都受到保护,否则 sshd 不会信任该文件。它会检查该文件及其上层目录,包括家目录。

用 `sshd -T | grep -i strictmodes` 确认实际生效的值。在 Ubuntu 24.04 和 Debian 13 上,还要检查 `/etc/ssh/sshd_config.d/` 中的附加配置文件。

路径StrictModes 的要求推荐权限
/home/alice归 alice 或 root 所有,组/其他用户不可写755、750 或 700
/home/alice/.ssh归 alice 或 root 所有,组/其他用户不可写700
/home/alice/.ssh/authorized_keys归 alice 或 root 所有,组/其他用户不可写600
/root 和 /root/.ssh(root 登录)归 root 所有,组/其他用户不可写700

修复“Authentication refused: bad ownership or modes”

客户端只会显示笼统的 `Permission denied (publickey)`。真正的原因在服务器日志中,日志会给出具体路径,例如 `Authentication refused: bad ownership or modes for directory /home/alice` 或 `... for file /home/alice/.ssh/authorized_keys`。请通过 VPS 控制台或另一个会话进行修复。

  1. 01.查看日志:Debian 和 Ubuntu 上用 `journalctl -u ssh -n 50`,AlmaLinux 和 Rocky 上用 `journalctl -u sshd -n 50`。
  2. 02.修复用户 SSH 目录的所有者:`chown -R alice:alice /home/alice/.ssh`。
  3. 03.修复权限:`chmod 700 /home/alice/.ssh` 和 `chmod 600 /home/alice/.ssh/authorized_keys`。
  4. 04.去掉家目录的组和其他用户写权限:`chmod go-w /home/alice`。
  5. 05.在 SELinux 系统(AlmaLinux、Rocky、Fedora)上恢复标签:`restorecon -Rv /home/alice/.ssh`。
  6. 06.保持现有会话不断开,在新终端中用 `ssh -v alice@server` 测试。
# all-in-one, run as root on the server
chown -R alice:alice /home/alice/.ssh
chmod go-w /home/alice
chmod 700 /home/alice/.ssh
chmod 600 /home/alice/.ssh/authorized_keys
namei -l /home/alice/.ssh/authorized_keys   # shows owner and mode of every path component

Note · 不要为了消除错误而设置 `StrictModes no`。这会移除一项真正的保护,掩盖而不是修复错误配置。

StrictModes 与 StrictHostKeyChecking 的区别

搜索“ssh strictmode”的人常常把两个毫不相干的选项混为一谈。`StrictModes` 位于服务器上的 `sshd_config` 中,负责检查文件权限。`StrictHostKeyChecking` 位于客户端的 `ssh_config` 或 `~/.ssh/config` 中,控制服务器主机密钥未知或已变化时的行为。客户端也有自己的权限检查:如果私钥可被其他用户读取,它会拒绝使用,并给出私钥文件未受保护的警告;`chmod 600 ~/.ssh/id_ed25519` 即可修复。

使用 ssh -A 进行代理转发的风险

`ssh -A`(或 `ForwardAgent yes`)会在远程主机上创建一个由 `$SSH_AUTH_SOCK` 引用的套接字,把签名请求转发回你本机的 ssh-agent。你的私钥永远不会离开本机,但在你连接期间,任何能访问该套接字的人都可以使用你的密钥。在远程主机上,这包括 root 以及以你的用户身份运行的任何进程。

如果服务器已被入侵或由他人管理,攻击者可以悄无声息地登录你的密钥能打开的所有其他主机,包括 Git 托管平台和生产服务器。这就是 OpenSSH 客户端默认 `ForwardAgent no` 的原因。

  • ▹绝不要把代理转发到共享主机、第三方主机或刚重装且尚未加固的主机。
  • ▹如果必须转发,使用 `ssh-add -c`,让每次使用密钥都需要本地确认。
  • ▹OpenSSH 8.9 及更高版本支持用 `ssh-add -h` 设置目标约束,限制被转发的密钥可用于哪些主机。
  • ▹在服务器端,`sshd_config` 中的 `AllowAgentForwarding no` 可以禁用它,不过拥有 shell 访问权限的用户仍可自行搭建转发器。

跳板机优先使用 ProxyJump(ssh -J)

大多数代理转发是为了经由跳板机访问内部机器。`ssh -J` 可以做到这一点而不暴露你的代理:跳板机只转发加密的 TCP 流,对内部主机的认证从你的笔记本端到端完成。对于只能通过私有网络访问的服务器,WireGuard 隧道是另一种选择;参见 WireGuard VPN 指南或 WireGuard 网状网络指南,keepalive 和 PSK 设置请参阅这篇 WireGuard 调优指南。

在 NoctisNode VPS 上,你可以通过 SSH 获得 KVM 机器的完整 root 权限,因此一台小型 Wisp 套餐就能充当专用跳板机,不运行任何其他服务;参见 VPS 套餐。

# one-off
ssh -J [email protected] [email protected]

# ~/.ssh/config
Host bastion
    HostName bastion.example.com
    User alice
    ForwardAgent no

Host db1
    HostName 10.88.0.3
    User alice
    ProxyJump bastion

ssh -a(小写)的作用

小写的 `ssh -a` 会为该连接禁用代理转发,与 `-A` 相反。当你的 `~/.ssh/config` 为通配主机启用了 `ForwardAgent`,而你想确保某个特定连接不转发时,它很有用,例如 `ssh -a admin@untrusted-host`。不要把它与 `ssh-agent -a`(设置代理套接字路径)或 `ssh-add`(向代理加载密钥)混淆。

常见问题

Qsshd_config 中的 StrictModes 有什么作用?

A它让 sshd 检查用户的家目录、~/.ssh 和 authorized_keys 是否归该用户或 root 所有,且组和其他用户不可写。如果检查失败,密钥认证会被拒绝。

Q如何修复 Authentication refused: bad ownership or modes?

A运行 `chmod go-w ~`、`chmod 700 ~/.ssh` 和 `chmod 600 ~/.ssh/authorized_keys`,并确保这些文件归该用户所有。服务器日志会指出出错的具体路径。

Qssh -A 代理转发安全吗?

A只在你完全信任的主机上安全。在你连接期间,远程主机上的 root 或被入侵的账户可以利用你转发的代理以你的身份登录其他地方;请改用 `ssh -J`。

Qssh -A 和 ssh -a 有什么区别?

A大写 `-A` 启用将 ssh-agent 转发到远程主机。小写 `-a` 为该连接禁用代理转发,覆盖配置中的任何 `ForwardAgent yes`。

Q我应该设置 StrictModes no 吗?

A不应该。禁用它会导致即使其他用户能修改你的 authorized_keys 也允许登录,这是一个真正的安全漏洞;请改为修复所有者和权限。

详解 SSH StrictModes、代理转发(ssh -A)与 ssh -a · NoctisNode