Win搭建:WSL2
目录
参考:
- 基于 Docker Desktop、WSL2 搭建双系统 Docker 环境 (opens new window)
- windows子系统-wsl命令基础用法和无响应问题排查及解决方法 (opens new window)
- 在WSL2中安装CentOS发行版 (opens new window)
- windows开机自动启动wsl,关闭wsl窗口不退出 (opens new window)
- 【全网最全】外网SSH连接WSL全套完整方案 (opens new window)
- WSL2 设置局域网访问 (opens new window)
- 【WSL2小技巧】Win10/Win11 开机自动启动 WSL2 下 Ubuntu 内 Linux 程序 (opens new window)
- WSL2使用systemctl命令的方法,简单快捷 (opens new window)
- wsl2在NAT网络模式下使用主机clash代理 (opens new window)
- WSL2 中访问宿主机 Windows 的代理 (opens new window)
# Win搭建:WSL2
# 环境依赖
# 查看系统版本号命令
winver
2
# 开启 WSL2 服务
打开控制面板 > 程序 > 程序和功能 > 启动或关闭Windows功能,勾选相关虚拟机的设置,点击确定后,等待安装完成后重新启动。

# 检测WSL环境
# 检查 WSL 状态
wsl --status
2
若默认版本不是 2 ,则设置默认版本为2
# 设置默认 WSL 版本为 2
wsl --set-default-version 2
2
# WSL常用命令
# 检查 WSL 状态
wsl --status
# 列出已安装的 Linux 发行版
wsl -l -v
# 进入默认的发行版本,退出执行 exit
wsl
# 终止指定的发行版或阻止其运行,例:wsl --terminate Ubuntu-18.04
wsl --terminate xxx
# 重启wsl服务
wsl --shutdown
# 设置默认 Linux 发行版
wsl --set-default
# 将WSL版本设置为1或2
wsl --set-version
# 设置默认 WSL 版本,例:wsl --set-default-version 2
wsl --set-default-version
# 运行特定的Linux发行版
wsl --distribution --user
# 以特定用户的身份运行
wsl -u , wsl --user
# 更改发行版的默认用户
wsl config --default-user
# 注销或卸载 Linux 发行版
wsl --unregister
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
实时显示时间和 IP 信息:
watch -n1 -t -c 'echo -e "Running ...\n\e[1;32m时间: $(date +"%Y-%m-%d %H:%M:%S")\n\e[1;34mWSL IP: $(hostname -I 2>/dev/null | awk "{print \$1}")\n\e[1;33mHost IP: $(grep nameserver /etc/resolv.conf | awk "{print \$2}" | head -1)\e[0m"'
命令参数说明:
-n1
:每秒刷新一次-t
:不显示顶部标题栏-c
:启用颜色支持
命令输出内容:
- 绿色显示当前时间
- 蓝色显示WSL的IP地址(使用 hostname -I 获取)
- 黄色显示主机(Host)的IP地址(从 /etc/resolv.conf 获取)
- 按 Ctrl+C 可退出监控。
# 安装 CentOS 系统
使用如下命令可查看官方在线的发行版
# 查看官方在线的发行版
wsl --list --online
2

官方没有提供CentOS7,可以从Github仓库下载,选择对用的版本下载:CentOS 7.9-2211 (opens new window)。

下载完成后,解压是两个文件,如下:

双击CentOS7.exe即可安装,第一次安装可能会报错,需要先升级内核,下载wsl_update_x64.msi (opens new window)文件安装即可。
注意:在哪个目录下安装,则会在对应的目录下创建ext4.vhdx虚拟磁盘,不建议放到C盘,这个文件随着时间增长会变得很大,建议拷贝到其他指定目录下执行安装。

执行以下命令查看 CentOS 状态
# 列出已安装的 Linux 发行版
wsl -l -v
2
执行一下命令进入默认的(*)的发行版本
# 进入默认的发行版本,退出执行 exit
wsl
2
# 配置局域网SSH访问
# 安装配置SSH
# Win端口转发
# 镜像网络模式
镜像网络模式,无需转发端口
# NAT网络模式
WSL的默认网络模式是NAT,在此模式下其他设备需要通过主机端口转发访问WSL应用。
WSL的对应的IP及应用端口映射到宿主Win对应的端口,命令如下(以管理员身份运行):
netsh interface portproxy add v4tov4 listenport=[Win端口] listenaddress=0.0.0.0 connectport=[WSL中应用端口] connectaddress=[WSL的IP]
检测是否设置成功
netsh interface portproxy show all
参数解析:
netsh interface portproxy add v4tov4
:添加 IPv4 到 IPv4 的端口代理规则。listenport=[Win端口]
:指定 Windows 主机监听的端口。listenaddress=0.0.0.0
:监听所有网络接口(允许外部设备通过任何接口访问)。connectport=[WSL中应用端口]
:指定目标端口(WSL 中应用的端口)。connectaddress=[WSL的IP]
:指定目标地址(WSL 的 IP,通常为wsl hostname -I
获取的 WSL 内部 IP)。
# Win防火墙放行
在Win主机的防火墙开放对应端口,命令如下(以管理员身份运行):
New-NetFirewallRule -DisplayName "Allow SSH on Port 22" -Direction Inbound -Protocol TCP -LocalPort [指定端口] -Action Allow
参数解析:
-DisplayName
:定义规则的名称,显示在防火墙规则列表中。-Direction Inbound
:指定规则方向为入站(允许外部设备访问本机)。-Protocol TCP
:限制协议类型为 TCP。-LocalPort [指定端口]
:绑定到本机的端口。-Action Allow
:定义匹配流量时的动作(允许通过)。
其他命令:
查看所有入站规则
Get-NetFirewallRule -Direction Inbound
1按名称筛选规则
Get-NetFirewallRule -DisplayName "Allow SSH*"
1按端口筛选规则
Get-NetFirewallRule -LocalPort 22,80,443
1删除指定规则
Remove-NetFirewallRule -DisplayName "Allow SSH on Port 22"
1
# 常见问题
# 一、开机自启动问题
启动过程如下: Win开机 >> 执行Win开机脚本 >> 执行WSL系统脚本 >> 启动Linux程序。
# Win开机脚本
原理:使用vb脚本,在Windows开机时执行,运行wsl,并隐藏wsl窗口。
操作:
快捷键Win+R,输入
shell:startup
,打开开机启动的程序目录。在弹出的目录下,新建文本文件并修改文件名为wsl-startup.vbs,编辑文件vb脚本如下:
rem 消息框 Msgbox "开机自动启动wsl" rem 创建Wscript.Shell对象 Set ws = CreateObject("Wscript.Shell") rem 调用Wscript.Shell对象的run方法,执行命令。vbhide是run方法的第二个参数,指定了窗口的显示方式:隐藏。 ws.run "wsl -d CentOS7 -u root /etc/init.wsl", vbhide
1
2
3
4
5
6命令
wsl -d CentOS7 -u root /etc/init.wsl
解释:WSL中启动 CentOS 7 发行版,并以root
用户身份执行/etc/
脚本。
注意:init.wsl 脚本必须预先在WSL发行版本中配置,且具备执行权限。
至此,根据以上操作,即可实现windows开机自动运行wsl,并隐藏窗口,后台运行,且再次打开wsl窗口,关闭后,wsl也不会退出。
此外,要想顺利从外网ssh登录wsl2还需要在windows上设置端口映射。端口映射示例:(待验证)
netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=22 connectaddress=127.0.0.1
# 二、无法使用systemctl命令的问题(默认未启用systemd)
WSL2 中在使用 systemctl 命令会报错:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
2
WSL2中虽然有systemctl命令,命令位置在/usr/bin/systemctl
,但WSL2并没有通过systemd(system daemon,系统守护进程)启动,WSL2中默认没有启用systemd,因此无法使用systemctl命令。
# 解决方式1:(推荐)通过配置启用systemd
【官方】使用 systemd 通过 WSL 管理 Linux 服务 (opens new window)
# 创建
vi /etc/wsl.conf
2
在 wsl.conf
文件中添加以下行,用于 systemd 的 init:
[boot]
systemd=true
2
关闭 Linux 发行版,重启即可
# 关闭
wsl.exe --shutdown
2
发行版重启后,systemd 将会运行。 可使用 systemctl list-unit-files --type=service
命令进行确认,将显示与 Linux 发行版关联的任何服务的状态。
# 解决方式2:通过安装Distrod启用systemd
这里选择安装Distrod来启用systemd。
Distrod是一个基于systemd的WSL2元发行版,它允许您在一分钟内安装Ubuntu,Arch Linux,Gentoo和许多其他带有systemd的发行版,或者使当前的发行版以systemd运行。Distrod还提供内置的自动启动功能和端口转发服务。这允许您在 Windows 启动时启动 systemd 托管服务,并使其可从 Windows 外部访问。
选择1:直接利用Distro安装WSL发行版本
确保默认WSL版本为 2
# 查询
wsl --status
# 设置默认为WSL 版本为 2
wsl --set-default-version 2
2
3
4
下载并解压缩distrod_wsl_launcher-x86_64.zip (opens new window),然后双击exe文件。然后按照向导安装新的发行版。
注意:若要使发行版在 Windows 启动时启动,在WSL2中运行以下命令。
sudo /opt/distrod/bin/distrod enable --start-on-windows-boot
选择2:在当前的发行版中运行systemd
- 下载并运行最新的安装程序脚本。
curl -L -O "https://raw.githubusercontent.com/nullpo-head/wsl-distrod/main/install.sh"
chmod +x install.sh
sudo ./install.sh install
2
3
- 在发行版中启用发行版,有两种选择:
如果要在 Windows 启动时自动启动发行版,请通过以下命令启用 distrod
/opt/distrod/bin/distrod enable --start-on-windows-boot
否则
/opt/distrod/bin/distrod enable
如果要在以后启用自动启动,则可以再次运行 /opt/distrod/bin/distrod enable --start-on-windows-boot
- 重新启动发行版
关闭 WSL 的终端。打开一个新的命令提示符窗口,然后运行以下命令。
wsl --terminate Distrod
重新打开新的 WSL2 窗口后,shell 将在 systemd 会话中运行。
# 安装完毕后,进行验证
systemctl status | cat
# 

# 三、使用主机代理的问题
# 在NAT网络模式下使用主机clash代理
思路:clash开启局域网代理,wsl2中设置代理
# 设置代理
export http_proxy='http://<Windows IP>:<Port>'
export https_proxy='http://<Windows IP>:<Port>'
2
3
# 查看代理
echo $http_proxy
echo $https_proxy
2
3
实现:自动化脚本
# 添加自动化脚本文件
vi /etc/profile.d/proxy.sh
2
#!/bin/sh
# WSL的IP
wslip=$(hostname -I | awk '{print $1}')
# 主机的IP
hostip=$(ip route show | grep -i default | awk '{ print $3}')
# 代理端口,此处<PORT>替换为想要使用的主机的端口号
port=<PORT>
# 代理地址
PROXY_HTTP="http://${hostip}:${port}"
# 设置代理
set_proxy(){
# http
export http_proxy="${PROXY_HTTP}"
export HTTP_PROXY="${PROXY_HTTP}"
# https
export https_proxy="${PROXY_HTTP}"
export HTTPS_proxy="${PROXY_HTTP}"
}
# 取消设置代理
unset_proxy(){
unset http_proxy
unset HTTP_PROXY
unset https_proxy
unset HTTPS_PROXY
}
# 查询代理设置
test_setting(){
echo "WSL ip:" ${wslip}
echo "Host ip:" ${hostip}
echo "Proxy port:" ${port}
echo "Current http proxy:" $http_proxy
echo "Current https proxy:" $https_proxy
}
# 脚本执行:根据输入的命令执行对应分方法
# 获取参数,第1个输入值
param="$1"
# 根据参数执行命令
if [ -z "$param" ] || [ "$param" == "test" ]; then
test_setting
elif [ "$param" == "set" ]; then
set_proxy
test_setting
elif [ "$param" == "unset" ]; then
unset_proxy
test_setting
else
echo "Unsupported arguments."
test_setting
fi
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
在 ~/.bashrc
配置启用和设置别名 proxy
# 备份
cp ~/.bashrc ~/.bashrc.bak
# 编辑
vi ~/.bashrc
2
3
4
# 代理脚本别名
alias proxy="source /etc/profile.d/proxy.sh"
2
# 加载
source ~/.bashrc
2
脚本别名使用
# 测试
proxy test
# 设置代理
proxy set
# 注销代理
proxy unset
2
3
4
5
6