我正在尝试使用 SSH 协议将我的笔记本电脑连接到另一个工作站。在我的两台 Windows PC 上,我都安装了 Ubuntu 以便从终端 (WSL) 工作。我按照在线找到的教程进行安装和配置,但它给了我这个错误。
我已经检查了两台电脑上 ssh 服务是否都在运行,以及端口 22 是否正在监听。
$ sudo ss -tulpn | grep :22
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=227,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=227,fd=4))
$ systemctl status sshd.service
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2023-03-09 10:19:13 CET; 3h 7min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 227 (sshd)
Tasks: 1 (limit: 4031)
Memory: 8.1M
CGroup: /system.slice/ssh.service
└─227 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
Mar 09 10:19:13 LAPTOP-69 systemd[1]: Started OpenBSD Secure Shell server.
Mar 09 10:21:10 LAPTOP-69 sshd[466]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=127.0.0.1 user=helga_cassol
Mar 09 10:21:12 LAPTOP-69 sshd[466]: Failed password for helga_cassol from 127.0.0.1 port 52396 ssh2
Mar 09 10:21:25 LAPTOP-69 sshd[466]: Failed password for helga_cassol from 127.0.0.1 port 52396 ssh2
Mar 09 10:21:29 LAPTOP-69 sshd[466]: Accepted password for helga_cassol from 127.0.0.1 port 52396 ssh2
Mar 09 10:21:29 LAPTOP-69 sshd[466]: pam_unix(sshd:session): session opened for user helga_cassol(uid=1000) by (uid=0)
Mar 09 10:24:21 LAPTOP-69 sshd[531]: Accepted password for helga_cassol from 127.0.0.1 port 60782 ssh2
Mar 09 10:24:21 LAPTOP-69 sshd[531]: pam_unix(sshd:session): session opened for user helga_cassol(uid=1000) by (uid=0)
Mar 09 10:56:00 LAPTOP-69 sshd[5741]: Accepted password for helga_cassol from 127.0.0.1 port 57428 ssh2
Mar 09 10:56:00 LAPTOP-69 sshd[5741]: pam_unix(sshd:session): session opened for user helga_cassol(uid=1000) by (uid=0)
另一项检查:
$ sudo ss -tulpn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=96,fd=13))
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:*
udp UNCONN 0 0 [::1]:323 [::]:*
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=96,fd=14))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=227,fd=3))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=227,fd=4))
我也已经检查过防火墙,sudo ufw status
它处于非活动状态。
使用命令ifconfig
我检查了 Ubuntu 的 IP 地址,但如果我尝试 ping 该 IP,我的笔记本电脑就找不到服务器。
如果我使用 Windows IP,我可以 ping 服务器。
因此看起来正确的 IP 是 Windows IP,而不是为 Ubuntu 创建的 IP。
但当我这样做时:
ssh -vvv [email protected]
结果如下:
OpenSSH_8.9p1 Ubuntu-3, OpenSSL 3.0.2 15 Mar 2022
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: include
/etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 21: Applying options for *
debug2: resolve_canonicalize: hostname 10.0.0.79 is address
debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts' ->
'/home/helga_cassol/.ssh/known_hosts'
debug3: expanded UserKnownHostsFile '~/.ssh/known_hosts2' ->
'/home/helga_cassol/.ssh/known_hosts2'
debug3: ssh_connect_direct: entering
debug1: Connecting to 10.0.0.79 [10.0.0.79] port 22.
debug3: set_sock_tos: set socket 3 IP_TOS 0x10
debug1: connect to address 10.0.0.79 port 22: Connection refused
ssh: connect to host 10.0.0.79 port 22: Connection refused
如果我使用 Ubuntu IP 地址和相同的命令:
ssh [email protected]
结果如下:
connect to host 172.xx.xxx.xx port 22: Connection timed out
您有什么想法吗?提前谢谢您。
答案1
简短回答(TL;DR)
我首选的方法(详见下文)是安装 Windows OpenSSH 服务器并将其用作跳转主机来访问 WSL2 中的 Ubuntu。不要让这个答案的长度吓到你。我只是倾向于详细解释(也许太多了)... ;-)
解释
这里的核心问题是 WSL2 位于 Windows 系统上的 Hyper-V 虚拟机内的单独 NAT 虚拟网络上。这意味着我们必须通过隧道、代理或转发从“真实”网络到 Ubuntu 所在的虚拟网络提供路由。
多年来,已经提出了几种解决方案,但最好的那些(恕我直言)不再(至少目前)适用于从 Microsoft Store 安装的最新版本的 WSL。
大多数解决方案都依赖于端口转发,就像您在评论中提到的教程一样。从历史上看,这很复杂,因为 WSL2 每次启动时都会使用不同的 IP 地址(该教程中也提到过)。不过,这方面也有一些好消息——最新的 WSL 版本(从1.1.0) 现在会在每次重新启动时尝试使用相同的 IP 地址。因此,如果您想使用netsh interface portproxy
该教程中提到的方法(以及WSL 文档),理论上你可以只执行一次而不需要担心“每次重启”机制。
流程
话虽如此,对于通过 SSH 进入 WSL2,我仍然更喜欢使用简单的 SSH 跳转主机。我将在此答案中介绍此设置的一个版本,但如果您想配置 SSH 密钥,还请参阅我原来的超级用户答案关于该主题。
对于基于密码(非密钥)
一度安装/配置视窗OpenSSH 服务器完整说明请参阅链接,但本质上是在 Admin PowerShell 中:
# Install the feature: Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 # Start the sshd service Start-Service sshd # OPTIONAL but recommended: 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." }
Ubuntu OpenSSH 服务器的一次性配置——本质上是编辑
/etc/ssh/sshd_config
以修改端口号。下面我将使用 2222 作为示例。当然,重新启动服务(sudo systemctl restart ssh
如果使用 Systemd;sudo service ssh restart
如果不是)。
对于下面的例子,我假设:
- 您想要访问的 Ubuntu 的 Windows 主机已被命名,并且在网络上以(mDNS 名称) 的
Bubblegum
形式访问,但您也可以在此处替换 IP 地址。bubblegum.local
- 您在 Windows 主机上的用户名是
helga
- 您的 Ubuntu 用户名是
hc
- 上面设置的 Ubuntu SSH 端口是 2222。
然后您可以通过 SSH 从网络上的另一个系统访问 Ubuntu,方法如下:
ssh -J [email protected] -p 2222 hc@localhost
这告诉 SSH 首先登录到跳转主机(Windows SSH 服务器),然后从该主机连接到localhost:2222
,即 Ubuntu SSH 服务器。如果您的用户名都相同,则可以完全省略它们。因此它可以像下面这样干净:
ssh -J bubblegum.local -p 2222 localhost
~/.ssh/config
您可以使用客户端文件进一步简化它。
Host bubblegum_ubuntu # Can be whatever you want
Hostname localhost
User hc # If needed
Port 2222
ProxyJump [email protected]
# Optional, but useful if you access more than one
# WSL distribution on the system to avoid unnecessary
# man-in-the-middle warnings due to different host keys.
UserKnownHostsFile ~/.ssh/known_hosts_bubblegum_ubuntu
有了这个,您就可以:
ssh bubblegum_ubuntu