记一次 Mac SSH 免密登录 Windows 的踩坑与修复

记一次 Mac SSH 免密登录 Windows 的踩坑与修复

背景

日常开发中,我需要在 Mac 和 Windows 之间频繁传输文件、执行命令。虽然 Windows 10/11 已经原生支持 OpenSSH Server,但配置公钥认证时却遇到了不少坑------尤其是那令人头疼的 Permission denied (publickey,password,keyboard-interactive)

本文记录了从零开始配置、排查到最终解决的全过程,希望对遇到类似问题的朋友有所帮助。

环境

  • 客户端:macOS (OpenSSH_9.9)
  • 服务端:Windows 10 (OpenSSH_for_Windows_9.5)
  • 网络:同局域网,IP 地址可互通

第一步:在 Windows 上安装并启动 SSH 服务

以管理员身份打开 PowerShell,执行:

powershell 复制代码
# 安装 OpenSSH 服务器
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# 启动服务并设为开机自启
Start-Service sshd
Set-Service -Name sshd -StartupType 'Automatic'

# 放行防火墙
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22

验证安装:

powershell 复制代码
Get-Service sshd   # 状态应为 Running

第二步:密码登录测试

在 Mac 终端尝试用密码登录:

bash 复制代码
ssh ch122633@172.88.67.99

输入密码后成功进入 Windows 命令行,说明 SSH 服务本身没问题。

第三步:配置公钥认证(遇到问题)

在 Mac 上生成密钥对(如果还没有):

bash 复制代码
ssh-keygen -t rsa -b 4096

尝试将公钥复制到 Windows:

bash 复制代码
ssh-copy-id ch122633@172.88.67.99

虽然提示 Number of key(s) added: 1,但随后测试免密登录时却失败了:

bash 复制代码
ssh ch122633@172.88.67.99
# Permission denied (publickey,password,keyboard-interactive)

第四步:查看日志,定位根源

在 Windows 上开启 SSH 调试日志(以管理员身份运行):

powershell 复制代码
notepad C:\ProgramData\ssh\sshd_config

修改以下两行:

复制代码
SyslogFacility LOCAL0
LogLevel DEBUG3

重启服务:

powershell 复制代码
Restart-Service sshd

再次从 Mac 尝试登录,然后查看日志文件 C:\ProgramData\ssh\logs\sshd.log。关键错误信息如下:

复制代码
debug1: trying public key file C:\\Users\\ch122\\.ssh/authorized_keys
debug3: Failed to open file:C:/Users/ch122/.ssh/authorized_keys error:13
debug1: Could not open authorized keys 'C:\\Users\\ch122\\.ssh/authorized_keys': Permission denied
Failed publickey for ch122633 ...

error:13 即 Permission denied ------ Windows 上的 OpenSSH 服务进程无法读取 authorized_keys 文件,原因是文件或父目录权限过于宽松。

第五步:修复权限(核心步骤)

管理员身份 打开 PowerShell,执行以下命令(将 ch122633 替换为你的用户名):

powershell 复制代码
# 停止服务避免文件占用
Stop-Service sshd

# 进入用户目录
cd C:\Users\ch122

# 重置 .ssh 目录权限
icacls .ssh /reset /t
icacls .ssh /inheritance:r
icacls .ssh /grant "ch122633:(OI)(CI)F"
icacls .ssh /grant "SYSTEM:(OI)(CI)F"

# 确保 authorized_keys 文件存在
if (-not (Test-Path .\.ssh\authorized_keys)) {
    New-Item -Path .\.ssh\authorized_keys -ItemType File -Force
}

# 设置 authorized_keys 的精确权限
icacls .\.ssh\authorized_keys /reset
icacls .\.ssh\authorized_keys /inheritance:r
icacls .\.ssh\authorized_keys /grant "ch122633:F"
icacls .\.ssh\authorized_keys /grant "SYSTEM:R"

# 移除多余用户组(可选)
icacls .\.ssh /remove "Users" "Everyone" "Authenticated Users"
icacls .\.ssh\authorized_keys /remove "Users" "Everyone" "Authenticated Users"

# 重启服务
Start-Service sshd

第六步:处理管理员组特殊配置(附加检查)

如果你的 Windows 用户属于 Administrators 组,OpenSSH 默认配置可能会优先使用 C:\ProgramData\ssh\administrators_authorized_keys 而不是用户目录下的文件。

检查 C:\ProgramData\ssh\sshd_config 末尾是否存在:

ini 复制代码
Match Group administrators
       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

两种解决方案

  1. 注释掉这两行 (推荐),统一使用用户目录下的 authorized_keys

  2. 或者将你的公钥写入 C:\ProgramData\ssh\administrators_authorized_keys,并设置权限:

    powershell 复制代码
    icacls "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "SYSTEM:F" /grant "Administrators:F"

修改后记得重启 sshd 服务。

第七步:验证成功

在 Mac 终端执行:

bash 复制代码
ssh ch122633@172.88.67.99

不再提示输入密码,直接进入 Windows 命令行,大功告成!

总结与避坑指南

  1. Windows 公钥认证失败,90% 是权限问题。OpenSSH for Windows 对文件权限极为敏感,任何多余的用户或组写入权限都会导致拒绝。
  2. 永远用 icacls 精确控制权限,不要手动在资源管理器里乱改。
  3. 注意管理员组的特殊配置 ,检查 sshd_config 中的 Match Group administrators 段。
  4. 善用日志 :将 LogLevel 设为 DEBUG3,错误原因一目了然。
  5. 推荐配置 :公钥认证成功后,可以禁用密码登录以增强安全性(PasswordAuthentication no)。

希望这篇记录能帮你少走弯路。如果你也遇到了类似问题,欢迎在评论区交流讨论。


最后更新:2026-04-02

本文首发于个人博客,转载请注明出处。

相关推荐
csdn2015_2 小时前
Set<String> 类型取第一条记录
开发语言·windows·python
csdn2015_2 小时前
List<String> 转换为Set<String>
windows·python·list
getapi2 小时前
Windows 11 安装 uv包括:更新、常用命令、Python 管理、环境切换等,(Astral 的 Python 包/环境工具)完整指南
windows·python·uv
DexterLien2 小时前
EC2 Windows 对 EBS 根卷进行缩容
windows·aws·ec2
朝阳5813 小时前
M3U8 下载助手油猴脚本 - 完全使用指南
前端·javascript·windows
utmhikari3 小时前
【DIY小记】解决MacOS上Edge浏览器bilibili全屏卡顿的问题
前端·macos·性能优化·edge·bilibili
派带星-3 小时前
基于 C++ 的第三方 SDK 封装实践(ASR + 短信服务)
c++·ide·macos
无风听海3 小时前
.NET10之C# Target-typed new expression深入解析
windows·c#·.net
别抢我的锅包肉3 小时前
【python-Pyspark】环境搭建及案例(Windows)
windows