Windows OpenSSH 服务 1067 错误的排查与修复

问题

Windows 上用 net start sshd 启动 OpenSSH Server,每次都是 1067 错误,服务根本无法启动。

排查过程

首先试了各种常规操作——重启服务、删除重建、检查配置语法,都不行。然后用 sshd -d 调试模式看日志,才知道问题:

debug3: Bad owner on C:/ProgramData/ssh/ssh_host_rsa_key
debug1: hostkeys_setup: convert ssh_host_rsa_key

Bad owner——sshd 检查 host key 文件的所有者,要求必须是 SYSTEM

根因

Windows OpenSSH 的 host key 文件用 ssh-keygen -A 生成时,如果以用户身份运行(而非 SYSTEM),生成的文件所有者就是当前用户。而 sshd 服务以 SYSTEM 身份运行,会检查 host key 的所有者是不是 SYSTEM,不是就拒绝启动。

很多人以为是文件权限问题(icacls 设置不对),但这里的问题是文件所有者Owner)不对,icacls 修权限是没用的。

修复

1. 把 host key 所有权交给 SYSTEM

cd C:\ProgramData\ssh
takeown /F ssh_host_rsa_key /A SYSTEM
takeown /F ssh_host_ecdsa_key /A SYSTEM
takeown /F ssh_host_ed25519_key /A SYSTEM

takeown /A SYSTEM 用 Administrators 组权限把文件所有权转给 SYSTEM。用 icacls /setowner 也可以达到同样效果。

2. 配置关闭严格模式(可选)

C:\ProgramData\ssh\sshd_config 里加上:

StrictModes no

这个不是必须的,但如果你之前用 icacls 修改过权限导致乱了,StrictModes no 可以跳过权限校验,避免连环报错。

3. 启动服务

net start sshd

如果能正常跳到「OpenSSH SSH Server 服务正在启动……」并且没有报错回退,就搞定了。

验证

ssh localhost
whoami
# 输出应该是你的 Windows 用户名

为什么会这样

ssh-keygen -A 这个命令的行为很坑——你用管理员 PowerShell 跑,它生成的文件所有者是你自己(DESKTOP-XXX\YourUsername),而不是 SYSTEM。而 sshd 服务启动时检查 owner,发现不是 SYSTEM,直接 1067 退出。

网上搜这个错误,大部分回答都在讲文件权限(icaclsStrictModes),很少有人提到 owner 问题。因为 Linux 上根本没有这个烦恼——Linux 的 root 运行 ssh-keygen -A,owner 自然是 root,sshd 也是 root 启动,完美匹配。

Windows 的特殊之处在于:管理员不等于 SYSTEM。管理员运行的程序生成的文件,所有者是管理员自己,而服务以 SYSTEM 运行,文件所有者不一致就报错。

另一种修复思路

如果不方便用 takeown,可以:

  • sc.exe 创建自定义服务,以 SYSTEM 身份运行 ssh-keygen -A
  • 或者直接删掉旧的 key 文件,用 psexec -s 提权到 SYSTEM 再生成
  • 这两种更麻烦,takeown 是最直接的办法。

    总结

    | 症状 | sshd 服务 1067 错误 |
    |------|---------------------|
    | 日志线索 | Bad owner on ... ssh_host_rsa_key |
    | 根因 | 文件所有者为当前用户,不是 SYSTEM |
    | 修复 | takeown /F 文件 /A SYSTEM |
    | 预防 | 用 SYSTEM 身份执行 ssh-keygen -A |

    记录下来,以后重装系统或者配置新机器少踩一个坑。