无密码 SSH 登录 WSL2 失败

无密码 SSH 登录 WSL2 失败

我已遵循 Scott Hanselman 的指示找到这篇博客文章设置 open-ssh 服务器

总之我做了以下事情:

# in WSL2 - install openssh-server
sudo apt install openssh-server

# in WSL2 - check ssh version
ssh -V # -> OpenSSH_8.2p1 Ubuntu-4ubuntu0.4, OpenSSL 1.1.1f  31 Mar 2020

# in WSL2 - generate new host keys
ssh-keygen -t ras -b 4096 -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key

私钥的权限设置为600,公钥为644

我的sshd_config供你参考

#   $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

Include /etc/ssh/sshd_config.d/*.conf

Port 2222
#AddressFamily any
ListenAddress 0.0.0.0
#ListenAddress ::

#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin prohibit-password
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# Expect .ssh/authorized_keys2 to be disregarded by default in future.
# @amin: Removed second one AuthorizedKeysFile  .ssh/authorized_keys .ssh/authorized_keys2
AuthorizedKeysFile  .ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

# override default of no subsystems
Subsystem   sftp    /usr/lib/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#   X11Forwarding no
#   AllowTcpForwarding no
#   PermitTTY no
#   ForceCommand cvs server

在 WSL2 上我们没有,systemd所以我用以下方式启动 SSHservice ssh start

现在,如果我打开Powershell并使用 ssh 进入我的 WSL2,ssh -p 2222 myuser@wsl2ip我可以毫无问题地使用我的密码登录。

接下来,我通过运行将我的 Windows 公钥从 Win 复制到 WSL2

type $env:USERPROFILE\.ssh\id_rsa.pub | ssh -p 2222 myUser@wsl2 "cat >> .ssh/authorized_keys"

那里的内容看起来像

ssh-rsa AAAAB3N************O1s= myWinUser@DESKTOP-AE*****

我的 WSL2 中的权限~/.ssh如下

-rw------- 1   575 Jan 17 14:32 authorized_keys
-rw------- 1    97 Aug 30 11:17 config
-r-------- 1   411 Dec  2  2020 id_ed25519
-rw------- 1   100 Dec  2  2020 id_ed25519.pub
-rw------- 1  3389 Jan 17  2021 id_rsa
-rw-r--r-- 1   749 Jan 17  2021 id_rsa.pub
-rw-r--r-- 1  4866 Oct  7 16:19 known_hosts

,并PasswordAuthentication通过no在 WSL2 的sshd_config

每次我尝试使用我的 ssh 密钥登录时都会得到

myuser@wsl2ip: Permission denied (publickey)

RSA如果我使用、RSA4096ED25519键重复相同的过程,就会发生同样的事情。

是什么赋予了?

答案1

一些想法:

  • 首先,失败的最可能原因是 Ramhound 在评论中提到的密钥权限。您刚刚提到将私钥从 Windows 复制到~/.ssh/authorized_keys,但没有提到更改权限。尝试:

    chmod 600 ~/.ssh/authorized_keys
    
  • 希望这会起作用,但如果不起作用,请尝试:

    sudo service ssh stop
    sudo mkdir /run/sshd
    sudo chmod 0755 /run/sshd
    sudo /usr/sbin/sshd -d
    

    这将sshd在前台运行并进行额外的调试。希望将告诉您密钥被拒绝的原因。


在 WSL2 中启用 SSH 的首选方法

您在问题中链接的页面是这样的:

在你阅读后续内容之前,请勿按照本文中的说明进行操作如何从外部机器通过 SSH 进入 Windows 10 上的 Bash 和 WSL2并为您做出了正确的决定!

所以我很好奇为什么您选择较旧的端口转发方法,而不是他提出的将 Windows OpenSSH shell 设置为bash.exe(过时的信息,但仍然有效)命令的替代方法。

无论如何,我(和其他人)认为 Hanselman 的技术还有更好的替代方案。

此方法的优点:

  • 无需端口转发
  • 由于它依赖于 Windows 服务,因此需要最少的防火墙工作
  • 即使安装了多个 WSL 发行版也能正常工作
  • 适用于sshfs、、、scpAnsiblesftp以及任何需要真实 SSH 连接的应用程序或服务。

总结如下:

  • 我们依靠 WSL2 将 Windows 上的“localhost”连接转发到 WSL(又名 localhost 转发)的能力。
  • 我们使用 Windows OpenSSH 服务器作为 WSL2 OpenSSH 服务器的 JumpHost。

初始设置与 Hanselman 的“简单方法”相同。首先启用 Windows OpenSSH 服务器在端口 22 上。

  • (特别是对于未来的读者)我建议只需遵循 Microsoft 文档即可获得最新信息,但我也会在此处复制相关命令。从 PowerShell:

    # Sounds like you had the Client already installed, at least
    Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 
    Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
    
    Start-Service sshd
    Set-Service -Name sshd -StartupType 'Automatic'
    
    # Confirm the Firewall rule is configured. It should be created automatically by setup. Run the following to verify
    if (!(Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue | Select-Object Name, Enabled)) {
        Write-Output "Firewall Rule 'OpenSSH-Server-In-TCP' does not exist, creating it..."
        New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
    } else {
        Write-Output "Firewall rule 'OpenSSH-Server-In-TCP' has been created and exists."
    }
    
  • 如果您是 Windows 安装的管理员,建议--编辑C:\Program Data\ssh\sshd_config并注释掉以下几行:

    #Match Group administrators
    #       AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
    
  • 当您编辑该内容时,我假设您需要设置:

    PasswordAuthentication no
    
  • 默认情况下,Windows OpenSSH 会查找C:\Program Data\ssh\administrators_authorized_keys(参见这个问题)。通过注释掉这些行,您将改用您的%userprofile%\.ssh\authorized_keys

  • 将您的公钥添加到%userprofile%\.ssh\authorized_keys。确保权限严格这个答案(或相关答案)。

  • 确认您可以使用密钥从 WSL 登录到 Windows OpenSSH:

    ssh -i <path_to_private_key> "${HOSTNAME}.local"
    

到现在为止,你确实终端已经可以通过 Windows OpenSSH 访问 WSL2。

从网络上的任意一台机器:

ssh -t <windows_host_or_ip> wsl

这将wsl在连接到 Windows 后简单地运行命令。

这适用于 shell 访问,但如果您需要对 WSL 进行“真正的” ssh 访问以用于 Andible、sshfs、sftp、scp 等,请继续阅读...

接下来(对于其他阅读本文的人来说)在 WSL 中配置 OpenSSH。您已经完成了这一部分。端口2222是一个不错的选择。

将您的公钥复制到~/.ssh/authorized_keys(已为您完成)并确保您的权限正确(如上所述)。

如果还没有,请ssh-agent通过以下方式添加您的私钥:

eval $(ssh-agent) # under Linux
ssh-add <path_to_key

(注意:Windows 也支持ssh-add。只需确保“OpenSSH 身份验证服务”正在运行)。

此时,您可以使用 Windows 主机作为您的 JumpHost,如下所示:

ssh -J <windows_host_or_ip> -p 2222 localhost

这连接到视窗OpenSSH 服务器(在端口 22 上)然后转身并连接到localhost:2222,即您的 WSL2 实例。

如上所述,这现在适用于scpsshfs等。


可选:

此技术有一个“副作用”,即localhost无论您使用哪个端口或跳转主机进行连接,它都会被存储为相同的“已知主机”。因此,如果您以这种方式连接到多个 WSL 实例,ssh就会开始抱怨潜在的中间人问题。

避免这种情况(并且总体上简化事情)的最佳方法是Host在 中创建一个条目~/.ssh/config。假设您的 Windows 主机名是bubblegum,而您的 WSL 发行版是ubuntu。将以下内容添加到~/.ssh/config

Host bubblegum_ubuntu  # Can be whatever you want
Hostname localhost
User <username> # If needed
Port 2222
ProxyJump bubblegum
UserKnownHostsFile ~/.ssh/known_hosts_bubblegum_ubuntu

这会将known_host条目重定向到一个文件仅有的用于该特定主机。

这也意味着您现在可以:

ssh bubblegum_ubuntu
scp bubblegum_ubuntu:/home/username/filename .
sftp bubblegum_ubuntu
sshfs bubblegum_ubuntu:/ /mountpoint

相关内容