返回

解决 Windows OpenSSH 1067 错误:启动失败分步指南

windows

Windows 下 net start opensshd 报错 1067?别慌,看这里!

刚装好 OpenSSH 服务器,或者跑得好好的突然就不行了,想用 net start opensshd 启动服务,结果命令行啪地一下甩给你一个错误,是不是挺让人头疼的?

问题来了:net start opensshd 失败,提示 “错误 1067”

你在 Windows 的命令提示符(CMD)里信心满满地敲下 net start opensshd,期望看到服务成功启动的提示。但现实是骨感的,屏幕上显示:

The OpenSSH Server service is starting.
The OpenSSH Server service could not be started.

A system error has occurred.

System error 1067 has occurred.

The process terminated unexpectedly.

简而言之,系统告诉你:OpenSSH 服务器启动失败,进程意外终止了,错误代码 1067。 这就像是汽车点火,引擎咳了两声就熄火了,肯定哪里不对劲。

为啥会出现 1067 错误?扒一扒原因

错误 1067,“进程意外终止”,是个比较通用的错误代码。用在 OpenSSH 服务上,意味着 sshd.exe 这个主进程在尝试启动过程中,遇到了让它无法继续运行下去的问题,只好提前结束。具体是啥问题呢?可能的原因五花八门,常见的有这么几类:

  1. 配置文件 (sshd_config) 写错了: 语法错误、参数值无效、路径指向不存在的文件等。这是最常见的原因之一。配置文件就是 sshd 服务的行为指南,指南写错了,它自然就懵了。
  2. 关键文件或目录权限不足: sshd 服务运行时需要读取配置文件、主机密钥文件,可能还需要写入日志文件。如果运行服务的账户(通常是 NT AUTHORITY\SYSTEMNT Service\sshd)没权限访问这些地方,启动就会失败。
  3. 主机密钥文件丢失或损坏: SSH 服务器需要用主机密钥来向客户端证明自己的身份。如果这些密钥文件(比如 ssh_host_rsa_key, ssh_host_ed25519_key 等)找不到了或者内容坏了,服务就起不来。
  4. 端口被占用: OpenSSH 服务器默认监听 22 端口。要是这个端口已经被别的程序占用了,sshd 就无法绑定监听,自然启动失败。
  5. 依赖问题或安装损坏: 虽然不常见,但 OpenSSH 的安装可能不完整,或者某些系统依赖出了问题。
  6. 服务账户问题: 服务配置使用的登录账户可能存在问题(密码更改、账户禁用等),但这对于使用默认系统账户的 OpenSSH Server 比较少见。

知道了大概方向,咱们就可以着手排查了。

解决之道:挨个排查,总有一款适合你

别急,一个个来。咱们按照可能性从高到低的顺序,把上面的原因捋一遍。

方案一:检查 sshd_config 配置文件

这是最常见的“肇事者”。sshd 对配置文件的语法要求比较严格。

原理和作用:
sshd_config 文件定义了 SSH 服务器的所有行为,包括监听端口、允许的认证方法、用户访问控制、日志级别等等。哪怕是一个多余的空格、一个拼写错误的指令,都可能导致 sshd 进程解析失败而退出。

操作步骤:

  1. 找到配置文件: OpenSSH 服务器的配置文件通常位于 C:\ProgramData\ssh\sshd_config。注意 ProgramData 是个隐藏目录,你可能需要在文件资源管理器里设置显示隐藏文件和文件夹,或者直接在地址栏输入路径。

  2. 使用 sshd 自带工具检查语法: OpenSSH 提供了一个方便的命令来测试配置文件的语法是否正确。打开 PowerShell 或者 CMD(最好是以管理员身份),执行以下命令:

    # 切换到 sshd 所在的目录,通常 OpenSSH 安装后会将其路径加入系统 PATH
    # 如果找不到 sshd 命令,请先 cd 到 OpenSSH 的安装目录,通常是 C:\Windows\System32\OpenSSH\
    
    sshd -t
    
    • 如果配置文件 没问题 ,你会看到类似 syntax is ok 的输出(可能没有任何输出,也代表没问题)。
    • 如果配置文件 有错误 ,它会明确指出哪一行的哪个指令有问题,比如:
      C:\\ProgramData\\ssh\\sshd_config: line 15: Bad configuration option: misspelledoption
      C:\\ProgramData\\ssh\\sshd_config: terminating, 1 bad configuration options
      
      这种情况下,你需要:
      • 用文本编辑器(比如 Notepad++ 或 VS Code,避免使用 Windows 自带的记事本 ,它可能会破坏文件编码或换行符)打开 C:\ProgramData\ssh\sshd_config 文件。
      • 找到报错提示的行号,仔细检查拼写、参数值是否符合规范。常见的错误包括:
        • 指令拼写错误(例如,把 Port 写成 portt)。
        • 路径错误(例如,HostKey 指向了一个不存在的密钥文件)。
        • 参数值无效(例如,给 LogLevel 设置了一个不支持的级别)。
        • 某行开头多了或少了空格。
      • 修改后保存文件。
      • 再次运行 sshd -t 直到没有任何错误提示。

安全建议:

  • 修改 sshd_config 时要特别小心。比如 PasswordAuthentication yes 允许密码登录,方便但风险较高;推荐使用密钥认证 (PubkeyAuthentication yes) 并禁用密码登录 (PasswordAuthentication no)。
  • 确保 PermitRootLogin 设置为 no(在 Windows 上通常不是问题,因为没有真正的 root 用户,但保持良好习惯)。
  • 限制允许登录的用户或组,使用 AllowUsers, AllowGroups, DenyUsers, DenyGroups 指令。

进阶使用技巧:

  • 如果你想看更详细的检查过程,可以使用 -T 选项,它会进行扩展测试并打印出生效的配置:
    sshd -T
    
  • 在排查复杂问题时,可以临时提高日志级别,比如在 sshd_config 中设置 LogLevel DEBUGDEBUG3,这会产生大量日志,有助于分析问题,但记得问题解决后调回 INFOVERBOSE

配置文件没问题后,再次尝试 net start opensshd。如果还不行,继续看下一个方案。

方案二:检查关键文件和目录权限

sshd 服务进程需要特定的权限来访问它的家目录 (%ProgramData%\ssh) 以及里面的配置文件和主机密钥。

原理和作用:
Windows 的 NTFS 文件系统有精细的权限控制。如果 sshd 服务运行的账户(默认是 SYSTEM,或者在较新版本中可能是专门的 NT Service\sshd 账户)没有读取 %ProgramData%\ssh\sshd_config 和主机密钥文件 (ssh_host_*_key) 的权限,它就无法正确初始化,导致启动失败。写入日志文件也需要相应权限。

操作步骤:

  1. 确认服务运行账户: 打开服务管理器 (services.msc),找到 "OpenSSH SSH Server" 服务,右键点击“属性”,切换到“登录”选项卡。记下“此账户”的值,通常是“本地系统帐户”(NT AUTHORITY\SYSTEM) 或 NT SERVICE\SSHD
  2. 检查 %ProgramData%\ssh 目录权限:
    • 右键点击 C:\ProgramData\ssh 目录,选择“属性”。
    • 切换到“安全”选项卡,点击“高级”。
    • 检查列表中的主体(Principal)。确保以下用户/组拥有必要的权限:
      • SYSTEM: 应具有完全控制 (Full control) 或至少读取和执行 (Read & execute) 的权限。
      • Administrators: 通常也具有完全控制权限。
      • 如果服务以 NT Service\sshd 运行:确保 NT Service\sshd 用户拥有对该目录的读取和执行权限,并且对主机私钥文件 (ssh_host_*_key) 具有读取权限(非常重要!),对日志文件(如果配置了)具有写入权限。
  3. 检查主机私钥文件权限 (ssh_host_*_key): 这些文件包含敏感信息,权限需要特别严格。
    • 通常,只有 SYSTEMAdministrators 组应该拥有读取权限。并且,尤其重要,运行服务的账户(SYSTEMNT Service\sshd)必须要有读取权限。 不应该给普通用户或其他不相关的账户任何权限。

    • 可以使用 PowerShell 的 Repair-SshdHostKeyPermission 命令来修复主机密钥文件的权限:

      # 以管理员身份运行 PowerShell
      cd C:\ProgramData\ssh
      Repair-SshdHostKeyPermission -FilePath .\ssh_host_rsa_key
      Repair-SshdHostKeyPermission -FilePath .\ssh_host_ecdsa_key
      Repair-SshdHostKeyPermission -FilePath .\ssh_host_ed25519_key 
      # 如果还有其他类型的密钥文件,也一并修复
      

      这个命令会尝试将文件的所有权设置为 SYSTEM,并只给 SYSTEMAdministrators 读取权限。

    • 或者,你也可以手动通过文件属性的“安全”选项卡进行调整。点击“高级”,可能需要先更改“所有者”为 SYSTEM,然后移除不必要的继承权限,再精确添加 SYSTEM 的读取权限。

代码示例 (使用 icacls 查看权限):

:: 以管理员身份运行 CMD
icacls "C:\ProgramData\ssh"
icacls "C:\ProgramData\ssh\sshd_config"
icacls "C:\ProgramData\ssh\ssh_host_rsa_key" 
:: 对每个密钥文件执行一次

输出会显示每个用户/组的权限。

安全建议:

  • 坚持 最小权限原则 。不要为了省事就给 Everyone 或者普通用户赋予对 %ProgramData%\ssh 目录及其内容的过多权限,特别是写入权限和对私钥的读取权限。
  • 如果服务是以 NT Service\sshd 运行,这个账户的权限更受限,务必确保它能读取所需文件。

权限修复后,再次尝试 net start opensshd

方案三:重新生成主机密钥

密钥文件丢失或损坏也会导致 1067 错误。

原理和作用:
主机密钥 (ssh_host_*_key) 是服务器的身份标识。客户端第一次连接时会记录服务器的公钥。如果服务器启动时找不到这些密钥,或者密钥格式不对、损坏了,它就无法承担服务器的角色。

操作步骤:

  1. 备份现有密钥(如果存在且你还想保留):C:\ProgramData\ssh 目录下的 ssh_host_*_keyssh_host_*_key.pub 文件复制到别处。如果它们确实损坏了,备份也没用,但以防万一。

  2. 删除旧密钥文件: 删除 C:\ProgramData\ssh 目录里所有以 ssh_host_ 开头的文件。

  3. 生成新的主机密钥: 最稳妥的方式通常是利用 OpenSSH 安装包自带的修复或设置脚本,但如果找不到,可以用 ssh-keygen 命令手动生成。需要以管理员身份运行 PowerShell 或 CMD

    # 切换到 OpenSSH 安装目录,确保 ssh-keygen 可用
    # 通常在 C:\Windows\System32\OpenSSH\
    
    # 切换到配置目录
    cd "C:\ProgramData\ssh"
    
    # 生成 RSA 密钥 (如果需要兼容旧客户端)
    ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N "" 
    
    # 生成 ECDSA 密钥
    ssh-keygen -t ecdsa -f ssh_host_ecdsa_key -N ""
    
    # 生成 Ed25519 密钥 (推荐,性能和安全性较好)
    ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N ""
    
    • -t 指定密钥类型。
    • -b 指定 RSA 密钥长度(建议 3072 或 4096)。
    • -f 指定输出文件名。
    • -N "" 表示设置空密码(主机密钥通常不需要密码)。
  4. 修复新密钥的权限: 新生成的文件权限可能不正确,务必 执行上一个方案中提到的权限修复步骤:

    # 以管理员身份运行 PowerShell
    Repair-SshdHostKeyPermission -FilePath .\ssh_host_rsa_key
    Repair-SshdHostKeyPermission -FilePath .\ssh_host_ecdsa_key
    Repair-SshdHostKeyPermission -FilePath .\ssh_host_ed25519_key
    

安全建议:

  • 客户端影响: 重新生成主机密钥后,所有之前连接过这台服务器的客户端在下次连接时,会收到 “主机密钥已更改” (HOST KEY VERIFICATION FAILED) 的警告。这是正常的安全机制,提示用户服务器身份可能发生了变化(可能是被攻击,也可能是管理员像现在这样合法更换了密钥)。用户需要从客户端的 known_hosts 文件中删除旧的服务器记录,然后重新连接并接受新的主机密钥。务必告知用户这个情况。
  • 保护好你的主机私钥文件 (ssh_host_*_key),它们的权限设置至关重要。

生成新密钥并修复权限后,再试一次 net start opensshd

方案四:检查端口冲突

默认情况下,sshd 服务会监听 TCP 端口 22。如果这个端口已经被别的程序抢先占用了呢?

原理和作用:
一个网络端口同时只能被一个应用程序监听(技术上有些例外,但对 TCP 来说基本如此)。如果 22 端口已经被比如另一个 SSH 服务器实例、某个调试工具或者意外配置的服务占用了,sshd 就没法绑定到这个端口上,启动就会报错。

操作步骤:

  1. 检查端口占用情况: 打开管理员权限的 CMD 或 PowerShell,执行以下命令:

    :: 在 CMD 中
    netstat -ano | findstr ":22" 
    

    或者

    # 在 PowerShell 中
    Get-NetTCPConnection -LocalPort 22
    
    • 观察输出。如果看到有状态为 LISTENING 并且本地地址包含 :22 的条目,说明端口 22 确实被占用了。
    • 记下该条目对应的 PID (Process Identifier)。在 netstat 的输出中是最后一列的数字;在 Get-NetTCPConnection 的输出中是 OwningProcess 列的数字。
  2. 找出占用端口的进程:

    • 打开任务管理器(Ctrl+Shift+Esc)。
    • 切换到“详细信息”或“进程”选项卡。
    • 找到 PID 列(如果看不到,可以在表头右键选择显示 PID)。
    • 找到与你记下的 PID 匹配的进程。看看这个进程是什么程序。
  3. 解决冲突:

    • 如果占用端口的是不必要的程序: 直接在任务管理器里结束该进程,或者卸载/停止该程序。
    • 如果占用端口的是另一个有用的服务: 你有两个选择:
      • 更改那个服务的端口: 如果可以,修改那个服务,让它使用其他端口。
      • 更改 OpenSSH 服务器的端口: 这是更常见的做法。编辑 C:\ProgramData\ssh\sshd_config 文件,找到 Port 22 这一行(如果被注释掉了 #Port 22,就去掉 # 并修改),把它改成一个未被占用的端口,比如 Port 2222
        注意: 改了端口后,客户端连接时也需要指定新的端口号 (例如 ssh user@your_server -p 2222)。
  4. 更新防火墙规则: 如果你修改了 OpenSSH 的端口,别忘了更新 Windows 防火墙规则,允许新端口的入站连接。可以通过“高级安全 Windows Defender 防火墙”图形界面操作,或者使用 PowerShell 命令:

    # 先移除可能存在的旧规则(如果端口确实是22改过来的)
    # Remove-NetFirewallRule -DisplayName "OpenSSH SSH Server (sshd)"
    
    # 添加新规则(假设新端口是 2222)
    New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP-NewPort' -DisplayName 'OpenSSH Server (sshd - custom port)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 2222
    

安全建议:

  • 使用非标准端口 (不是 22) 可以在一定程度上减少被自动化扫描工具骚扰的频率,但不能替代真正的安全措施(如强密码/密钥、防火墙、禁用root登录等)。这属于“安全靠隐蔽”(security through obscurity),效果有限。
  • 确保防火墙规则只开放必要的端口。

处理完端口冲突后,尝试 net start opensshd

方案五:查看事件查看器和调试日志

如果以上方法都没解决问题,那么就需要更深入地挖掘错误信息了。

原理和作用:
Windows 事件查看器记录了系统和应用程序的重要事件,包括服务的启动失败信息。OpenSSH Server 自身也有日志记录机制,可以提供更详细的内部错误细节。

操作步骤:

  1. 检查 Windows 事件查看器:

    • Win + R,输入 eventvwr.msc 并回车,打开事件查看器。
    • 在左侧导航栏展开 "Windows 日志",分别检查 "应用程序" 和 "系统" 日志。
    • 在右侧面板,寻找来源为 sshd 或与 OpenSSH 相关的错误 (Error) 或警告 (Warning) 级别的事件,特别是在你尝试启动服务失败的时间点附近。
    • 双击事件,查看详细信息。这里可能包含比错误 1067 更具体的线索,比如缺少某个 DLL 文件、加载配置时的具体失败点等。
    • 另外,检查 "应用程序和服务日志" -> "OpenSSH"。这里有 AdminOperational 两个日志通道,里面可能有更直接的 OpenSSH 相关信息。
  2. 启用并检查 OpenSSH 调试日志:

    • 编辑 C:\ProgramData\ssh\sshd_config 文件。

    • 找到 LogLevel 指令。将其级别改为 DEBUG,或者更详细的 DEBUG1, DEBUG2, DEBUG3(级别越高,日志越详细)。例如:

      LogLevel DEBUG3
      
    • 保存文件。

    • 再次尝试 net start opensshd

    • 然后 立刻 回到事件查看器的 "应用程序和服务日志" -> "OpenSSH" -> "Operational" 通道,或者根据 sshd_configSyslogFacility 和可能的 LogFile 指令(如果配置了)去查找日志文件(默认可能还是输出到事件日志)。DEBUG 级别的日志会非常详细,记录 sshd 启动过程的每一步,仔细阅读其中的错误信息,往往能准确定位问题所在。

    • 或者 ,你可以在管理员 CMD 或 PowerShell 中手动以前台调试模式运行 sshd,这样日志会直接输出到控制台:

      # 确保没有 sshd 服务在运行 (net stop sshd)
      # 以前台、调试模式、指定配置文件运行
      sshd -d -e -f "C:\ProgramData\ssh\sshd_config"
      
      • -d 开启调试模式。
      • -e 将日志输出到标准错误 (stderr),也就是当前控制台窗口。
      • -f 指定配置文件路径。

      观察控制台输出的最后几行信息,通常就能看到导致进程终止的具体原因。按 Ctrl+C 停止手动运行的 sshd

进阶技巧:

  • 结合使用事件查看器和 sshd -d 命令通常是排查疑难杂症的最有效方式。
  • 分析 DEBUG 日志时,关注 fatal:, error:, Could not load host key:, Missing privilege 等。
  • 问题解决后,记得把 sshd_config 里的 LogLevel 调回 INFOVERBOSE,避免产生过多不必要的日志。

方案六:彻底重装 OpenSSH 服务器

如果以上所有方法都试过了,或者你怀疑 OpenSSH 的安装本身有问题,可以考虑彻底卸载重装。

原理和作用:
重装可以解决因文件损坏、配置混乱、注册表项错误等难以排查的问题,相当于恢复到初始状态。

操作步骤 (使用 PowerShell 管理员权限):

  1. 卸载 OpenSSH 服务器:

    # 停止服务 (如果还在尝试运行)
    Stop-Service sshd
    
    # 卸载 OpenSSH Server 功能 (根据你的 Windows 版本选择)
    # 方法一:适用于较新的 Windows 10 / Windows Server
    Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    
    # 方法二:适用于某些 Windows Server 版本
    # Uninstall-WindowsFeature OpenSSH.Server
    
    # 你可以用 Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Server*' 查看到底是哪个名字
    
  2. 清理残留文件 (可选但推荐): 卸载通常不会删除 %ProgramData%\ssh 目录。备份好你的 sshd_config 和自定义密钥(如果需要保留) ,然后可以手动删除这个目录:

    Remove-Item -Path "C:\ProgramData\ssh" -Recurse -Force
    
  3. 重启电脑 (推荐): 确保所有相关进程和服务都已完全停止和清理。

  4. 重新安装 OpenSSH 服务器:

    # 方法一:适用于较新的 Windows 10 / Windows Server
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    
    # 方法二:适用于某些 Windows Server 版本
    # Install-WindowsFeature OpenSSH.Server
    
  5. 配置防火墙规则: 安装后通常会自动添加防火墙规则,但检查一下总没错。如果没有,手动添加:

    New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 
    
  6. 启动服务并设置为自动启动:

    Start-Service sshd
    Set-Service -Name sshd -StartupType 'Automatic' 
    
  7. 恢复配置 (如果需要): 如果你之前备份了 sshd_config,可以将其恢复到 %ProgramData%\ssh 目录,然后 务必 再次用 sshd -t 检查配置有效性,并根据需要重新生成主机密钥、修复权限。

安全建议:

  • 重装后,相当于回到了默认设置。你需要重新进行所有必要的安全加固配置,比如修改端口(如果需要)、禁用密码认证、配置用户访问权限等。

完成重装后,再次尝试启动服务。这时候,Error 1067 应该已经被解决了。