同局域网ssh连接wsl2
简介
如果在Windows使用Ubuntu系统而不想使用虚拟机,wsl是一种不错的选择,提供了一个相对传统虚拟机还不错的功能,但是如果我们想远程这个wsl则是比较麻烦,这里主要介绍一下如何在同一个局域网下使用ssh连接wsl。
首先如果不是同局域网的电脑,可以选择zerotier,当然zerotier局域网服务器很卡,所有我们可以考虑自己使用卫星服务器组网,具体的教程可以看这个github仓库一分钟私有部署zerotier-planet服务,这个github仓库附带如何进行组网的教程,只需要你有一台带公网的服务器。
系统配置
我这里使用的是Ubuntu22.04系统,其实这个无所谓,你使用redhat、centos等Linux系统,只要能开启ssh服务就行,然后安装常规的配置系统就行,这些教程网上的很多。然后我们给wsl开启网络的镜像。
主要是就是在Windows中的C:\Users\<your_username>
目录下创建一个.wslconfig文件,然后在文件中写入如下内容
[experimental]
autoMemoryReclaim=gradual
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
然后重启wsl就行,然后在开启了firewall = true的情况下,需要确保 Windows 防火墙允许外部设备通过 SSH 连接 WSL。
在 Windows 系统中,打开 “Windows Defender 防火墙”,选择 “高级设置”。
在 “入站规则” 中,查看是否有允许 SSH 连接(通常是端口 22)的规则。如果没有,可以通过 “新建规则” 来创建。在新建规则向导中,选择 “端口”,指定 SSH 端口(如 22),并设置允许连接,按照向导步骤完成规则的创建,使外部设备能够访问 WSL 中的 SSH 服务。
之后就可以连接了,如果是使用了zerotier,ssh的地址为zerotier分配的地址。
下面是涵盖了从在 WSL 中配置 SSH 服务器到在 Windows 主机上设置端口转发,以便从局域网其他计算机访问 WSL 的整个过程。
从局域网访问 WSL (通过 SSH)
本文档将引导你完成设置过程,允许你从同一局域网内的其他计算机通过 SSH 安全地连接到你的 Windows Subsystem for Linux (WSL) 实例。这对于远程开发、管理或在 WSL 中运行服务非常有用。
目标读者: 需要从局域网访问其 WSL 环境的用户。
主要步骤:
- 在 WSL 中安装和配置 OpenSSH 服务器。
- 为 WSL 设置静态(或可预测的)IP 地址(推荐)。
- 配置 Windows 主机防火墙以允许 SSH 连接。
- 在 Windows 主机上设置端口转发规则,将连接导向 WSL。
- 从远程客户端连接。
第 1 步:在 WSL 中安装和配置 OpenSSH 服务器
首先,我们需要在你的 WSL 发行版(例如 Ubuntu)内部安装并运行 SSH 服务。
-
打开你的 WSL 终端。
-
更新软件包列表:
sudo apt update
-
安装 OpenSSH 服务器:
sudo apt install openssh-server
-
配置 SSH 服务器 (
sshd_config
):- 使用文本编辑器(如 nano)编辑配置文件。需要
sudo
权限。sudo nano /etc/ssh/sshd_config
- 重要配置项检查与修改:
Port 22
: 确认 SSH 监听的端口。默认是 22。你可以根据需要更改,但后续步骤中的端口号也需相应修改。ListenAddress 0.0.0.0
: 确保这一行存在且没有被注释掉(前面没有#
)。这让 SSH 监听所有 IPv4 地址。如果你也需要 IPv6,可以保留或添加ListenAddress ::
。如果ListenAddress
被注释掉了,默认通常也是监听所有地址,但也建议明确指定0.0.0.0
。PasswordAuthentication yes
: 确保这一行是yes
且没有被注释掉,以允许使用密码登录。这是最简单的开始方式。注意: 为了更高的安全性,推荐配置 SSH 密钥认证,并在配置成功后将此项设为no
。PermitRootLogin prohibit-password
或PermitRootLogin no
: 推荐保持此设置,禁止 root 用户直接通过密码登录。
- 保存并关闭文件: 在
nano
中,按Ctrl+X
,然后按Y
确认保存,最后按Enter
。
- 使用文本编辑器(如 nano)编辑配置文件。需要
-
启动 SSH 服务:
- 对于使用 systemd 的 WSL 发行版(如较新的 Ubuntu on WSL):
sudo systemctl start ssh
- 对于不使用 systemd 的旧版 WSL:
sudo service ssh start
- 对于使用 systemd 的 WSL 发行版(如较新的 Ubuntu on WSL):
-
检查 SSH 服务状态:
- 使用 systemd:
确保状态显示为sudo systemctl status ssh
active (running)
。 - 不使用 systemd:
确保服务正在运行。sudo service ssh status
- 使用 systemd:
-
(可选) 设置 SSH 服务开机自启:
- 使用 systemd:
sudo systemctl enable ssh
- 使用 systemd:
-
验证监听端口: 确认
sshd
正在监听所有 IPv4 地址的端口 22(或其他你配置的端口):sudo ss -tulnp | grep ':22'
你应该看到类似
tcp LISTEN 0 128 *:22 *:*
或tcp LISTEN 0 128 0.0.0.0:22 *:*
的输出。
第 2 步:为 WSL 设置静态 IP 地址 (强烈推荐)
WSL 2 默认使用动态 IP 地址,这使得依赖 IP 的端口转发规则在重启后失效。设置静态 IP 可以解决这个问题。
-
获取当前网络信息 (在 WSL 中):
ip addr show eth0 # 查找类似 inet 172.x.x.x/20 的 IP 和子网 ip route | grep default # 查找类似 default via 172.x.x.1 的网关
记下你的子网范围和网关 IP。
-
选择一个静态 IP: 在你的子网范围内选择一个通常不会被 DHCP 分配的地址(例如
172.x.x.250
)。 -
创建启动脚本 (
~/set_static_ip.sh
):#!/bin/bash # --- 配置你的网络信息 --- STATIC_IP="172.23.15.250/20" # <<< 修改为你选择的静态 IP 和子网掩码位数 GATEWAY_IP="172.23.0.1" # <<< 修改为你查到的网关 IP INTERFACE="eth0" CURRENT_IP=$(ip addr show $INTERFACE | grep 'inet ' | awk '{print $2}') if [ "$CURRENT_IP" = "$STATIC_IP" ]; then # echo "IP address already set to $STATIC_IP" # 可以取消注释以显示信息 exit 0 fi echo "Setting static IP to $STATIC_IP for $INTERFACE..." sudo ip addr flush dev $INTERFACE sudo ip addr add $STATIC_IP dev $INTERFACE sudo ip route add default via $GATEWAY_IP dev $INTERFACE echo "Static IP set."
- 重要: 将脚本中的
STATIC_IP
和GATEWAY_IP
替换为你自己的值。 - 赋予执行权限:
chmod +x ~/set_static_ip.sh
- 重要: 将脚本中的
-
配置无密码
sudo
(仅限此脚本):- 极其小心操作! 运行
sudo visudo
。 - 在文件末尾添加一行 (将
<your_wsl_username>
替换为你的 WSL 用户名):<your_wsl_username> ALL=(ALL) NOPASSWD: /home/<your_wsl_username>/set_static_ip.sh
- 保存并退出 (
Ctrl+X
,Y
,Enter
)。
- 极其小心操作! 运行
-
配置脚本在 WSL 启动时运行:
- 编辑你的 shell 配置文件,例如
~/.bashrc
或~/.profile
:nano ~/.bashrc
- 在文件末尾添加:
(将# Set static IP at shell startup /home/<your_wsl_username>/set_static_ip.sh > /dev/null 2>&1
<your_wsl_username>
替换为你的 WSL 用户名。> /dev/null 2>&1
用于抑制脚本输出) - 保存并退出。
- 编辑你的 shell 配置文件,例如
-
测试:
- 在 Windows PowerShell 或 CMD 中运行
wsl --shutdown
。 - 重新打开 WSL 终端。
- 运行
ip addr show eth0
检查 IP 是否已设置为你配置的静态地址。
- 在 Windows PowerShell 或 CMD 中运行
第 3 步:配置 Windows 主机防火墙
你需要允许来自局域网的 SSH 连接通过 Windows 防火墙。
-
以管理员身份打开“高级安全 Windows Defender 防火墙”:
- 可以在 Windows 搜索中搜索 “wf.msc”。
-
创建入站规则:
- 在左侧选择“入站规则”。
- 在右侧选择“新建规则…”。
- 规则类型: 选择“端口”,点击“下一步”。
- 协议和端口: 选择“TCP”,选择“特定本地端口”,输入
22
(或者你在sshd_config
中设置的其他端口),点击“下一步”。 - 操作: 选择“允许连接”,点击“下一步”。
- 配置文件: 关键步骤! 确保勾选了你当前局域网连接使用的配置文件(通常是“专用”)。如果不确定,可以暂时将“域”、“专用”、“公用”都勾选上进行测试。点击“下一步”。
- 名称: 给规则起一个描述性名称,例如
WSL SSH Access
或Allow SSH Port 22 Inbound
。 - 点击“完成”。
-
检查第三方防火墙: 如果你安装了任何第三方杀毒软件或防火墙,请检查其设置,确保它们也允许 TCP 端口 22 的入站连接,或者暂时禁用它们进行测试。
第 4 步:在 Windows 主机上设置端口转发
对于 WSL 2,你需要将 Windows 主机接收到的 SSH 连接请求转发到 WSL 的(现在是静态的)内部 IP 地址。
-
以管理员身份打开 Windows PowerShell。
-
添加端口转发规则:
netsh interface portproxy add v4tov4 listenport=22 listenaddress=0.0.0.0 connectport=22 connectaddress=<你的WSL静态IP地址>
- 重要: 将
<你的WSL静态IP地址>
替换为你在第 2 步中为 WSL 设置的静态 IP 地址。 listenport=22
: Windows 主机监听的端口。listenaddress=0.0.0.0
: Windows 主机监听所有 IPv4 地址。connectport=22
: 要连接的 WSL 内部端口。connectaddress=<你的WSL静态IP地址>
: 要连接的 WSL 目标 IP。
- 重要: 将
-
验证规则 (可选):
netsh interface portproxy show all
你应该能看到刚刚添加的规则。
-
注意: 这个
netsh
规则在添加后是持久的,系统重启后仍然有效。因为它现在指向一个固定的 WSL IP,所以它能持续工作。
第 5 步:从远程客户端连接
现在,你可以从局域网内的另一台计算机尝试连接了。
-
获取目标 Windows 主机的 IP 地址: 在目标 Windows 主机上运行
ipconfig
,找到其在局域网中的 IPv4 地址(例如192.168.1.100
)。 -
在远程客户端上打开终端或 SSH 客户端。
-
使用 SSH 命令连接:
ssh <你的WSL用户名>@<目标Windows主机的IP地址>
例如:
ssh alin@192.168.1.100
- 如果你的 WSL SSH 端口不是 22,使用
-p
参数指定:ssh -p <端口号> <你的WSL用户名>@<目标Windows主机的IP地址>
- 如果你的 WSL SSH 端口不是 22,使用
-
首次连接: 你会看到一个关于主机密钥指纹的提示,输入
yes
继续。 -
输入密码: 输入你在 WSL 中的用户密码。
如果一切顺利,你现在应该已经成功登录到你的 WSL 环境了!
故障排除
- 连接超时 (Connection timed out):
- 检查远程客户端是否能
ping
通目标 Windows 主机的 IP 地址。 - 仔细检查目标 Windows 主机上的防火墙规则(Windows Defender 和第三方),确保端口 22 的 TCP 入站连接被允许,并且规则应用于正确的网络配置文件。
- 检查远程客户端是否能
- 连接被拒绝 (Connection refused):
- 确认 WSL 内部的
sshd
服务正在运行 (sudo systemctl status ssh
)。 - 确认 WSL 内部
sshd
正在监听0.0.0.0:22
(sudo ss -tulnp | grep ':22'
)。 - 仔细检查 Windows 上的
netsh interface portproxy show all
规则,确保connectaddress
指向正确且当前有效的 WSL 静态 IP 地址。 - 再次彻底检查 Windows 防火墙和第三方防火墙,确保它们没有明确拒绝连接。
- 检查目标 Windows 主机上是否有其他服务(如 Windows 自带的 OpenSSH Server)占用了端口 22。
- 确认 WSL 内部的
- 权限被拒绝 (Permission denied):
- 确认输入的 WSL 用户名和密码正确。
- 检查 WSL 内 sshd_config 中的
PasswordAuthentication
是否为yes
。 - 检查是否有
AllowUsers
或DenyUsers
等指令限制了登录。
- 使用
ssh -vvv
: 在远程客户端上运行ssh -vvv <user>@<host>
可以提供详细的连接过程调试信息,有助于定位问题点。