朕喜技术(ZhenxiJS)
2026.09.07
1 分钟阅读

SSH 免密登录失败:authorized_keys 权限过宽导致 StrictModes 拒绝密钥认证

日期:2026-09-07 | 技术栈:OpenSSH, sshd, StrictModes, authorized_keys, Docker, Linux 权限管理 | 关键词:ssh 免密登录失败, Permission denied publickey, bad ownership or modes for file authorized_keys, StrictModes, ~/.ssh 权限 777, authorized_keys 666, ssh 密钥认证不生效, chmod 700 chmod 600

一、问题背景

部署服务器时,为了能让 CI/CD 脚本免密 SSH 登录执行命令,按标准流程配置了 SSH 密钥认证:

  1. 用 ssh-keygen 生成了密钥对
  2. 把公钥追加到目标用户的 ~/.ssh/authorized_keys
  3. 公钥内容和格式都正确

结果执行 ssh devuser@server 仍然被要求输入密码,免密登录完全不生效。使用 ssh -v 调试只看到 Offering public key 后被拒。密码登录正常,公钥明明在 authorized_keys 里却无法使用——到底是怎么回事?

关键报错:sshd 服务端日志显示 Authentication refused: bad ownership or modes for file /home/devuser/.ssh/authorized_keys

二、复现步骤

# 1. 构建并启动问题环境(Docker 内运行 sshd)
cd scenario/2026-09-07-0002/
docker compose up -d --build

# 2. 运行复现脚本
docker compose exec app bash /reproduce.sh

复现输出

【1】检查 ~/.ssh 目录和 authorized_keys 的权限:
drwxrwxrwx 1 devuser devuser 37 /home/devuser/.ssh           ← 777 过宽
-rw-rw-rw- 1 devuser devuser 102 /home/devuser/.ssh/authorized_keys  ← 666 过宽

【2】尝试 SSH 免密登录(应失败):
devuser@localhost: Permission denied (publickey,password).
退出码: 255

sshd 日志(服务端关键报错)

Authentication refused: bad ownership or modes for file /home/devuser/.ssh/authorized_keys

三、根本原因

OpenSSH StrictModes 机制

sshd 默认开启 StrictModes yes(sshd_config 中未显式配置时就是默认值)。它会在使用 authorized_keys 进行公钥认证前,严格检查三个路径的所有权和权限:

路径正确权限违反后果
用户家目录 ~不能 group/others 可写拒绝认证
~/.ssh/700 (drwx------)拒绝认证
~/.ssh/authorized_keys600 (-rw-------)拒绝认证

核心规则:文件/目录不能被 group 或 others(其他用户) 写入。防止恶意用户替换别人的 authorized_keys 来实现越权登录。

本案例的问题

~/.ssh 被设为 777(任何人可写),authorized_keys 被设为 666(任何人可写)。sshd 的 safe_path() 安全检查直接判定文件不安全,拒绝使用该 key,即使公钥内容完全正确。密码登录不受此影响,所以"密码能登、免密不能登"。

代码验证

sshd -T | grep strictmodes
# strictmodes yes

四、解决办法

修复命令

chmod 700 /home/devuser/.ssh
chmod 600 /home/devuser/.ssh/authorized_keys

完整修复验证

docker compose exec app bash -c '
chmod 700 /home/devuser/.ssh
chmod 600 /home/devuser/.ssh/authorized_keys
ssh -i /root/.ssh/client_key -o StrictHostKeyChecking=no \
    -o BatchMode=yes devuser@localhost "echo SSH_SUCCESS"
'

修复后输出

SSH_SUCCESS
退出码: 0

五、验证结果

修复后 SSH 免密登录立即成功。以下是我做的完整边界测试:

~/.sshauthorized_keys家目录结果
700600755✅ 通过
700666755❌ 拒绝
777600755❌ 拒绝
700600777❌ 拒绝
700600755✅ 通过
755644755✅ 通过
775600755✅ 通过
700660755✅ 通过

核心发现:

  • others(世界)可写 才会触发拒绝
  • group 可写时若 group 内只有用户自己则可通过
  • 家目录 world 可写(777)也会被拒
  • 最佳实践仍推荐 700/600(最安全)

六、经验与避坑

1. SSH 免密登录不生效的排查顺序

① 检查公钥是否正确 → ② 检查权限(家目录/.ssh/authorized_keys)→ ③ 查看 sshd 日志
# 三步排查
ls -la ~/.ssh/
stat -c "%a %U:%G %n" ~ ~/.ssh ~/.ssh/authorized_keys
journalctl -u sshd -n 20 | tail  # 或 docker compose logs app

2. 关键报错速查

报错含义
Permission denied (publickey)key 认证失败
bad ownership or modes for file ...权限或所有权不合法
Offering public key 但无后续服务端拒绝了 key
Permission denied (publickey,password)密码认证也被要求(BatchMode 下直接失败)

3. 预防:创建用户配置密钥认证的标准流程

# 1. 创建用户
useradd -m devuser
echo 'devuser:pass1234' | chpasswd

# 2. 创建 ~/.ssh 设权限
mkdir -p /home/devuser/.ssh
chmod 700 /home/devuser/.ssh
chown -R devuser:devuser /home/devuser/.ssh

# 3. 安装公钥设权限
cp key.pub /home/devuser/.ssh/authorized_keys
chmod 600 /home/devuser/.ssh/authorized_keys
chown devuser:devuser /home/devuser/.ssh/authorized_keys

顺序很重要:先 chmod 700 再放文件,最后统一 chmod 600 并确认 owner 正确。

4. 其他常见坑

  • owner 不对:authorized_keys 的 owner 必须是登录用户或 root(chown user:user)
  • SELinux 上下文:restorecon -R ~/.ssh 修复 SELinux 标签
  • sshd_config:若 AuthorizedKeysFile 被改到非标准路径,检查新路径的权限
  • StrictModes 可以临时设为 no 调试(但生产环境绝不要这样做)
  • sshd 需要重启:修改 sshd_config 后 systemctl restart sshd 才生效(改文件权限不需要重启)

5. 可复现命令速查

cd scenario/2026-09-07-0002/
docker compose up -d --build
docker compose exec app bash /reproduce.sh   # 复现问题
docker compose exec app bash /check.sh       # 排查权限
docker compose logs app                      # 查看 sshd 报错
docker compose exec app bash -c "chmod 700 /home/devuser/.ssh && chmod 600 /home/devuser/.ssh/authorized_keys"  # 修复
docker compose exec app bash -c "ssh -i /root/.ssh/client_key -o StrictHostKeyChecking=no -o BatchMode=yes devuser@localhost 'echo 成功'"  # 验证

版权声明

本文为博主原创文章,遵循 CC BY-NC-SA 4.0 许可协议。 转载请注明出处:http://localhost/blogs/2026-09-07-0000-ssh-strictmodes-authorized-keys

分享这篇文章