这是一份经过修改和完善的文档,已添加关于 换行符(CRLF vs LF) 的处理建议以及 公钥部署位置 的重要说明。


Windows SSH 报错 “UNPROTECTED PRIVATE KEY FILE”?一招彻底解决权限与格式问题

在使用 Windows 进行开发或运维时,通过 SSH 连接远程服务器是家常便饭。然而,当你兴致勃勃地输入命令,准备建立安全隧道或登录服务器时,却可能被这样一段红色的警告信息拦在门外:

1
2
3
4
5
6
7
8
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'D:\\ownner\\ssh\\windows-hx.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "D:\\ownner\\ssh\\windows-hx.pem": bad permissions
stone@59.110.44.222: Permission denied (publickey).

特别是当错误提示中提到 NT AUTHORITY\Authenticated Users 时,很多从 Linux 转过来的朋友会感到困惑:“我在 Linux 上只要 chmod 600 就行了,Windows 上该怎么办?”

此外,即使权限设置正确,有时仍会报 bad permissions 或连接失败,这往往是因为 文件换行符格式公钥部署位置 不对导致的。

今天这篇博客就来详细拆解这个问题,并提供一套标准的“手术刀”式解决方案。


🚨 为什么会出现这个错误?

SSH 协议的核心是安全。私钥(.pemid_rsa 文件)是你身份的终极证明。如果这个文件可以被系统中的其他用户(甚至是经过身份验证的任意用户)读取,或者文件格式不符合 OpenSSH 的严格标准,你的服务器就面临着巨大的安全风险或连接失败。

OpenSSH 客户端在 Windows 上运行时会严格检查:

  1. ACL(访问控制列表):Windows NTFS 文件系统的权限条目。
  2. 文件格式:包括换行符(Line Endings)是否符合 Unix/Linux 标准。

默认情况下,Windows 中新建或复制的文件往往会继承父文件夹的权限(允许 Authenticated Users 读取),且文本编辑器可能默认保存为 Windows 格式的换行符(CRLF)。SSH 客户端检测到这些“不安全”或“不兼容”的因素后,会直接忽略该密钥并拒绝连接。


🛠️ 解决方案:使用 icacls 重塑权限 & 修复格式

在 Windows 上,我们需要结合 icacls 工具控制权限,并注意 换行符公钥位置

第一步:以管理员身份打开终端

为了确保有足够权限修改文件的安全描述符,请务必:

  1. 右键点击“开始”菜单。
  2. 选择 Windows PowerShell (管理员)终端 (管理员) / 命令提示符 (管理员)

第二步:执行权限修复命令

假设你的私钥路径是 D:\ownner\ssh\windows-hx.pem(请根据实际情况替换路径),依次执行以下三条命令:

1
2
3
4
5
6
7
8
# 1. 重置文件的所有权限为默认继承状态(清除现有的混乱权限)
icacls "D:\ownner\ssh\windows-hx.pem" /reset

# 2. 仅授予当前登录用户读取权限 (R),并移除该用户原有的其他权限
icacls "D:\ownner\ssh\windows-hx.pem" /grant:r "$($env:USERNAME):(R)"

# 3. 禁用权限继承,防止父文件夹再次把奇怪的用户组加进来
icacls "D:\ownner\ssh\windows-hx.pem" /inheritance:r

💡 懒人一键版
如果你想一步到位,可以直接复制下面这行命令执行:

1
icacls "D:\ownner\ssh\windows-hx.pem" /reset && icacls "D:\ownner\ssh\windows-hx.pem" /grant:r "$($env:USERNAME):(R)" && icacls "D:\ownner\ssh\windows-hx.pem" /inheritance:r

第三步:验证结果(可选)

执行完上述命令后,你可以运行以下命令查看当前的权限设置:

1
icacls "D:\ownner\ssh\windows-hx.pem"

成功的标志:输出列表中应该只包含你的用户名(例如 DESKTOP-ABC\YourName)和系统账户(NT AUTHORITY\SYSTEM),绝对不应该再出现 Authenticated UsersEveryone 或其他无关的用户组。


⚠️ 关键注意事项:换行符与公钥部署

很多时候权限修好了依然报错,请重点检查以下两点:

1. 修复换行符问题 (CRLF ➔ LF)

Windows 系统默认使用 CRLF (\r\n) 作为换行符,而 Linux/Unix 系统和 OpenSSH 严格要求私钥文件使用 LF (\n) 换行符。如果私钥文件中包含 CR (\r) 字符,OpenSSH 会认为文件已损坏或权限异常,从而拒绝加载。

解决方法(使用 VS Code):

  1. VS Code 打开你的 .pem 私钥文件。
  2. 查看右下角的状态栏,如果显示 CRLF,请点击它。
  3. 在弹出的菜单中选择 LF
  4. 保存文件 (Ctrl + S)。

注意:此操作必须针对 私钥文件 (.pem, id_rsa)。公钥文件通常也建议保持 LF 格式以避免潜在问题。

2. 确认公钥部署位置 (Authorized Keys)

确保你的 公钥 内容已经正确添加到了远程服务器的 ~/.ssh/authorized_keys 文件中。

  • 普通用户登录:如果你是用普通用户(如 stone)登录,公钥必须添加到该用户目录下的 ~/.ssh/authorized_keys
    • 路径示例:/home/stone/.ssh/authorized_keys
  • 阿里云/云服务器特殊情况
    • 某些云厂商(如阿里云)的镜像默认配置可能将 PermitRootLogin 开启,或者习惯将公钥直接放入 root 用户的 authorized_keys 中。
    • 如果你是用非 root 用户登录但连接失败,请登录服务器检查:
      1. 当前用户的 ~/.ssh/authorized_keys 是否存在且包含公钥。
      2. 该文件的权限是否正确(应为 600644,属主必须是当前用户)。
      3. 如果不确定,可以尝试将公钥同时也添加到 /root/.ssh/authorized_keys(仅限测试环境,生产环境请遵循最小权限原则),或者确认你登录的用户名是否与公钥部署的用户一致。

检查命令(在服务器上执行):

1
2
3
4
5
# 查看当前用户 authorized_keys 权限
ls -l ~/.ssh/authorized_keys
# 如果权限不对,修复它
chmod 600 ~/.ssh/authorized_keys
chown $USER:$USER ~/.ssh/authorized_keys

🚀 重新连接

权限修复、换行符转换及公钥确认完成后,再次运行你的 SSH 命令。

注意:在你的原始报错中,命令似乎缺少了指定密钥的参数 -i。虽然某些配置下 SSH 会自动尝试默认密钥,但显式指定是最稳妥的做法。

正确的命令格式如下:

1
ssh -i "D:\ownner\ssh\windows-hx.pem" -N -L 18789:127.0.0.1:18789 stone@59.110.44.222
  • -i: 指定私钥文件路径。
  • -N: 不执行远程命令(常用于端口转发)。
  • -L: 本地端口转发配置。

现在,你应该能顺利看到连接成功的提示,而不再被 WARNING: UNPROTECTED PRIVATE KEY FILE! 阻拦。


💡 额外小贴士

  1. 关于路径中的空格:如果你的文件路径中包含空格(例如 D:\My Keys\key.pem),请务必在命令中给路径加上双引号,如上例所示。
  2. WSL 用户注意:如果你是在 WSL (Windows Subsystem for Linux) 中操作位于 Windows 盘符(/mnt/d/...)下的文件,chmod 命令可能无法正确修改 NTFS 权限。在这种情况下,依然建议回到 Windows 的 PowerShell 中使用 icacls 进行处理,并在 Windows 编辑器中修正换行符。
  3. 安全第一:永远不要为了图省事而试图关闭 SSH 的权限检查(如使用 StrictModes no),这会极大地降低你的系统安全性。

结语

Windows 下的权限管理逻辑与 Linux 有所不同,初次遇到 bad permissions 确实容易让人摸不着头脑。但只要掌握了 icacls 这个强大的工具,并注意 换行符格式公钥部署位置 这两个隐形杀手,你就能轻松驾驭 Windows 下的 SSH 密钥管理。

希望这篇教程能帮你节省排查问题的时间!如果你在操作中遇到其他问题,欢迎在评论区留言交流。