使用公钥身份验证为Windows设置OpenSSH

Cam*_*lie 28 windows ssh openssh public-key-encryption public-key

我在使用公钥认证设置OpenSSH for Windows时遇到问题.

我在本地桌面上工作,可以使用Unix机器或其他OpenSSH for Windows机器上的密钥进行ssh.

我已将构建复制到服务器上,我可以使密码验证工作正常,但是当我使用密钥时,我得到以下问题:

debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug3: start over, passed a different list publickey,password,keyboard-interactive
debug3: preferred publickey,keyboard-interactive,password
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /cygdrive/c/sshusers/jsadmint2232/.ssh/id_rsa
debug3: send_pubkey_test
debug2: we sent a publickey packet, wait for reply
Connection closed by 127.0.0.1
Run Code Online (Sandbox Code Playgroud)

因此,出于测试目的,我一直尝试SSH到localhost,但即使远程尝试,我也会遇到同样的问题.

更奇怪的是,当我启用了密码和公钥时sshd_config,它只会尝试使用密钥,然后使用上述消息轰炸,甚至不会尝试使用密码.

以下是我采取的步骤:

  1. 安装OpenSSH for Windows
  2. mkgroup -l >> ..\etc\group(添加了本地组)
  3. mkgroup -d >> ..\etc\group(添加域组)
  4. mkpasswd -L -u openssh >> ..\passwd(添加了我的本地用户)
  5. mkpasswd -D -u jsadmint2232 >> ..\passwd(添加了我的域用户)
  6. 在passwd中编辑homedir指向c:\ sshusers \%USER% - 其中%USER%是用户名
  7. 启用密码验证,禁用密钥验证
  8. 为jsadmint2232/openssh创建了ssh密钥,并确保文件是在homedirs中创建的
  9. 将authorized_keys文件添加到.ssh dirs中为每个用户添加,并为传入的连接用户添加了密钥
  10. net stop opensshd/net start opensshd
  11. Test Password auth可在本地和远程工作
  12. 更新了sshd_config,以启用密钥身份验证 - 重新启动opensshd
  13. 测试连接并获得上述错误,甚至不尝试密码验证?
  14. 更新了sshd_config,完全禁用密码验证 - 重启opensshd
  15. 测试连接仍然出现上述错误

看来服务器出于某种原因正在终止连接?

n0r*_*0rd 78

以下是Windows 10 v.1803附带的OpenSSH的设置步骤(2018年4月更新.请参阅本文的评论,它可能不适用于1809).

服务器设置(提升的PowerShell):

  1. 安装OpenSSH服务器:Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0.

  2. 启动代理和sshd服务:( Start-Service ssh-agent; Start-Service sshd这将自动生成主机密钥和默认配置$env:ProgramData\ssh).

  3. [可选]安装OpenSSHUtils powershell模块: Install-Module -Force OpenSSHUtils

客户端设置(非高架powershell):

  1. 生成用户密钥:cd $env:USERPROFILE\.ssh; ssh-keygen.exe,按照提示操作,同意默认的建议文件位置.这将创建2个文件:id_rsaid_rsa.pub;

  2. [可选]添加密钥到身份验证代理,因此每次使用时都不必输入密码:( ssh-add .\id_rsa或生成的任何文件);

服务器设置继续(非高架powershell):

  1. 以用户身份登录,要使用的公钥身份验证
  2. cd $env:USERPROFILE; mkdir .ssh; cd .ssh; New-Item authorized_keys;
  3. id_rsa.pub文件的内容从客户端粘贴到.ssh\authorized_keys上一步的文件中.
  4. 正确设置权限(重要!!!):
    1. 运行start .以使用当前文件夹($env:USERPROFILE\.ssh)打开资源管理器;
    2. 右键单击authorized_keys,转到Properties -> Security -> Advanced
    3. 单击"禁用继承";
    4. 出现提示时,选择"将继承的权限转换为对此对象的显式权限";
    5. (真的,非常重要)除了SYSTEM和你自己之外,删除文件上的所有权限.文件上必须有两个权限条目.一些导游建议运行Repair-AuthorizedKeyPermission $env:USERPROFILE\.ssh\authorized_keys-这将尝试将添加sshd用户的权限列表,它打破身份验证,因此,不这样做,或者至少不要在其上添加同意sshd用户).两者SYSTEM和你自己都应该完全控制文件.

客户:

  1. C:\ProgramData\ssh\sshd_config.它应该在这一点上起作用.

尝试使用Windows 10作为服务器,并将自身和Debian Linux作为客户端.

编辑:(请参阅下面的评论部分)当前的Windows构建需要注释掉以下内容

sshd

# Match Group administrators                                                    
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys  
Run Code Online (Sandbox Code Playgroud)

  • 我的问题的另一个后续和解决方案:在Windows 10 1809中,在`C:\ ProgramData\ssh\sshd_config`中有新的特殊配置条目,它定义了对于管理员用户,从`__PROGRAMDATA __/ssh/administrators_authorized_keys`读取密钥.此文件再次需要特殊权限.只有系统用户和管理员组才能访问它. (17认同)
  • 谢谢 !为了能够使用“user/.ssh”中的authorized_keys文件进行无密码密钥身份验证,我需要注释掉“# Match Group Administrators # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys”行,并重新启动服务“OpenSSH SSH Server”。 (6认同)
  • 这是一个巨大的帮助,但权限仍然是一个问题。这 3 个命令修复了该问题: `icacls C:\ProgramData\ssh\administrators_authorized_keys /remove "NT AUTHORITY\Authenticated Users"` 和 `icacls C:\ProgramData\ssh\administrators_authorized_keys /inheritance:r` 和 `get-acl C:\程序数据\ssh\ssh_host_dsa_key | set-acl C:\ProgramData\ssh\administrators_authorized_keys` [来源](https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh) (3认同)
  • 你是我的英雄@n0rd ... 为正确设置权限而苦苦挣扎了几个小时,但似乎 Repair-AuthorizedKeyPermission 设置了 sshd 用户,这确实破坏了它!(我认为它应该在那里供 OpenSSH SSH 服务器进程查看)。多谢! (2认同)
  • 谢谢!我一直在处理这个问题,直到我阅读了您的答案! (2认同)
  • @EliorMalul,我实际上是通过阅读日志发现的。问题是,默认情况下 sshd 不会记录太多日志,您需要将详细程度设置为 11(“sshd_config”中的“LogLevel DEBUG3”)才能从中获取有用的信息。 (2认同)

Ser*_*ral 12

在 PowerShell 中使用此命令序列来更正 administrators_authorized_keys

$acl = Get-Acl C:\ProgramData\ssh\administrators_authorized_keys
$acl.SetAccessRuleProtection($true, $false)
$administratorsRule = New-Object system.security.accesscontrol.filesystemaccessrule("Administrators","FullControl","Allow")
$systemRule = New-Object system.security.accesscontrol.filesystemaccessrule("SYSTEM","FullControl","Allow")
$acl.SetAccessRule($administratorsRule)
$acl.SetAccessRule($systemRule)
$acl | Set-Acl
Run Code Online (Sandbox Code Playgroud)

只有 SYSTEM 和 Administrators 组必须具有文件权限,不能继承。

administrators_authorized_keys 权限集

  • 看起来多么令人惊讶,上述解决方案仅适用于语言设置为英语的系统。例如,在法语版本的 Windows 10 上,您必须将“Administrators”替换为“Administrateurs”,将“System”替换为“Système”。令人惊讶,对吧? (5认同)

小智 8

如果您遇到困难,还有一个技巧是在调试模式下运行 sshd。我这样做了:

  1. 停止sshd服务
  2. 以管理员权限打开 PowerShell 控制台
  3. 输入'sshd -d'
  4. 键入登录从我的客户端机器

结果证明密钥需要在例如C:\ProgramData\ssh\administrators_authorized_keys而不是C:\Users\yourUsers.ssh\authorized_keys

  • 对我来说非常有用的答案。它不仅有助于回答问题是什么,而且有助于下次如何解决类似问题。 (5认同)

Nat*_*ics 7

n0rd 的解决方案是物有所值的,但对于同样属于管理员组的用户来说,这会带来额外的复杂性。如果您正在寻找涉及以下情况的解决方案:

  • 您希望在每个用户的基础上使用公钥(或者您不想使用该administrators_authorized_keys文件)。
  • 而且您不想使用PasswordAuthentication。
  • 并且有些用户也属于admin组。

我遇到的问题是,当我尝试 n0rd 的解决方案时,它对上述条件下的用户不起作用。经过一番修补后,我找到了一个对我来说始终有效的解决方案。遵循n0rd的解决方案,只需更改以下内容

确保ssh_config设置了以下设置:

AuthorizedKeysFile  .ssh/authorized_keys 
PasswordAuthentication no
PubkeyAuthentication yes
Run Code Online (Sandbox Code Playgroud)

另外,请确保注释掉“匹配组管理员”设置:

#Match Group administrators
#       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
Run Code Online (Sandbox Code Playgroud)

确保在服务器C:\Users\username\.ssh\authorized_keys文件中包含客户端的公钥。

最后,为了帮助将用户与帐户匹配,我发现更具体地了解客户端上的用户数据很有帮助。我没有使用普通的用户名,而是使用用户名以及服务器上用户的域。就我而言,我客户的C:\Users\UserName\.ssh\config文件如下所示:

Host my_short_name
  HostName my.serveraddress.net
  User serversname\username
  IdentityFile .ssh\id_rsa
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我的 Windows 10 服务器将被称为serversname(在设备名称下)。通过以这种方式指定用户,我可以避免密码身份验证。

作为一个额外的好处,这与 PowerShell 7 的默认 shell 配合得很好。甚至我的默认 PowerShell 配置文件也可以通过 ssh 工作,并且我得到了对 posh-git 和 oh-my-posh 的完全支持。但是,我发现建议将 PowerShell 设置为默认 shell 环境的默认方法(通过编辑ssh_conf以包含“子系统 powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo”)不适用于我。相反,在服务器上使用提升的 PowerShell 窗口中的命令:

New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "c:/progra~1/powershell/7/pwsh.exe" -PropertyType String -Force
Run Code Online (Sandbox Code Playgroud)

这只是创建一个注册表项。如果需要,您可以随时弹出注册表以将其删除。

  • 我不知道这有帮助的确切原因,但评论“匹配组管理员”设置解决了我的问题。正如下面有人所说,这可能是由服务器上使用的非英语区域设置引起的。 (2认同)

Cam*_*lie 6

我已经解决了这个问题...

它与启动服务的帐户有关-该帐户正在使用本地系统帐户-该帐户正在阻止其访问发布密钥和authorized_keys文件。

一旦我停止了该服务并以尝试连接的用户身份启动,它就可以工作了!

因此,基本上,您需要从一个服务帐户开始,然后外部用户以该用户身份进入。

  • 您“停止服务并以我试图连接的用户身份启动”是什么意思?我不认为你的意思是我使用我的实际域用户帐户。那么你建议我从一个服务帐户开始,但是哪个? (3认同)
  • 我建议在研究这个答案之前阅读下面@n0rd 的答案。 (2认同)

Fre*_*ers 5

这只是我的@n0rds 很棒答案的脚本版本。

将此脚本放在带有您的私钥/公钥/对的目录中并运行!

PowerShell.exe -ExecutionPolicy Bypass -File "C:\bypass\prompt\standard.ps1" 2>&1>$null

Add-WindowsCapability -Online -Name OpenSSH.Server
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH SSH Server' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22 -Program "%WINDIR%\System32\OpenSSH\sshd.exe"

#Must Enable ssh-agent before starting
Set-Service -Name ssh-agent -StartupType Automatic
Set-Service -Name sshd -StartupType Automatic
Start-Service ssh-agent; Start-Service sshd

$sshdir="$env:USERPROFILE\.ssh"
mkdir $sshdir
copy .\id_rsa $sshdir\
cat  $sshdir\id_rsa
copy .\*.pub  $sshdir\authorized_keys
cat $sshdir\authorized_keys
ssh-add $sshdir\id_rsa

$sshd_config="C:\ProgramData\ssh\sshd_config" 
(Get-Content $sshd_config) -replace '#PubkeyAuthentication', 'PubkeyAuthentication' | Out-File -encoding ASCII $sshd_config
(Get-Content $sshd_config) -replace 'AuthorizedKeysFile __PROGRAMDATA__', '#AuthorizedKeysFile __PROGRAMDATA__' | Out-File -encoding ASCII $sshd_config
(Get-Content $sshd_config) -replace 'Match Group administrators', '#Match Group administrators' | Out-File -encoding ASCII $sshd_config
cat C:\ProgramData\ssh\sshd_config

Restart-Service ssh-agent; Restart-Service sshd

Write-Host "Use this to Login/test Now"
write-host ssh $env:UserName@localhost
Run Code Online (Sandbox Code Playgroud)