桥接网络模式的 WSL2 的安装与配置
泥浆
编辑于 2024年12月22日 11:00

文本节选自《OpenWrt/WSL下利用nftables修改向Tracker汇报的端口,实现BT下载的全自动STUN内网穿透》​ 

由于原文内容较多,不方便阅读,现把桥接网络模式的 WSL2 的安装与配置部分作出修正并单独发布。

部分内容基于原文章涉及的 WSL2 旁路由 场景进行说明,绝大多数情况不需要,可忽略。

根据微软官方文档,桥接网络模式的 WSL2 要求 Windows 11 22H2 或更高版本。

对于 Windows 10 以及 Windows 11 22H2 以前版本,将使用以下项目

https://github.com/dantmnf/WSLAttachSwitch/

代码块
Shell
自动换行
复制代码
安装 WSL2
  ├─ 启用 Hyper-V
  └─ 安装 WSL2 Linux 发行版

配置 WSL2
  ├─ 配置桥接网络
  ├─ 配置 WSL2 开机自启动
  ├─ 修改 WSL2 Linux 发行版的软件源
  ├─ 配置 WSL2 Linux 发行版的自启动
  ├─ 重启 WSL2 Linux 发行版
  └─ 配置 WSL2 Linux 发行版为旁路由
复制成功

安装 WSL2

依次按下键盘的 Win + X 键,A 键;或右键点击开始按钮,打开 终端管理员(A)

确认标题是否显示 管理员: Windows PowerShell

如无特别说明,本文在 Windows 中的操作默认通过管理员权限的 PowerShell 执行

Windows Terminal 内可使用左键选定,右键点击的方式进行复制粘贴


启用 Hyper-V

确认 Hyper-V 是否已启用

代码块
Shell
自动换行
复制代码
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V
复制成功

State 显示为 Enabled 即为已启用

若显示 Disabled,执行以下命令启用

代码块
Shell
自动换行
复制代码
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
复制成功

需要重启

启用 Hyper-V 不需要开启 CPU 虚拟化,但后续的 WSL2 安装需要

建议在重启时确认 UEFI (BIOS) 中的虚拟化设置


安装 WSL2 Linux 发行版

代码块
Shell
自动换行
复制代码
wsl --update
wsl -v
复制成功

先升级 WSL 组件,可能需要一点时间

升级后运行 wsl -v 确认版本

可选使用 wsl --update --pre-release 更新预发布版

代码块
Shell
自动换行
复制代码
wsl -l -o
wsl --install -d Debian
复制成功

在线获取可用的 WSL2 Linux 发行版列表后,选择 Debian 安装

本文基于 Debian,其他发行版操作细节可能稍有不同

可能需要重启

安装过程中会提示输入用户名和密码,不需要跟 Windows 的用户信息一致

若未开启 CPU 虚拟化,将在设置用户名和密码后提示错误


配置 WSL2

WSL2 安装完成后,输入 exit 返回,或重新打开 PowerShell 继续执行后面的操作


配置桥接网络


创建虚拟网卡

代码块
Shell
自动换行
复制代码
Get-NetAdapter
New-VMSwitch -SwitchName "VETH" -NetAdapterName "以太网" -AllowManagementOS $True -EnablePacketDirect $True -EnableIov $True
复制成功

Get-NetAdapter 获取网络适配器信息,确认连接路由器所用的网卡名称 本文默认网卡名称为“以太网”,请按照实际情况修改

New-VMSwitch 把物理网卡创建为 2 个虚拟网卡,其中一个作为 Windows 使用,另一个将在后续分配给 WSL2 两个虚拟网卡均与路由器在同一链路上

AllowManagementOS 允许 Windows 与虚拟机(WSL2)共享一个物理网卡 这在单网卡的设备上是必须的,否则 Windows 将无可用的网络适配器

若你有多个可连接到路由器的网卡,则 AllowManagementOS 是可选,但仍然建议开启

单网卡下,Windows 的所有流量都需要经过虚拟网卡;若配置 WSL2 为旁路由,则 Windows 的出站流量需要经过 WSL2 的 IP 转发,会有一定的性能损耗 多网卡下,可以为物理网卡和虚拟网卡分别配置跃点数,使主物理网卡作为日常使用的首选,虚拟网卡作为 WSL2 的 旁路由专用 此时使需要经过旁路由的应用绑定 WSL2 虚拟网卡的 IP 地址,即可实现高效的分流 得益于微软近年来的开发与优化,单网卡虚拟化的日常使用也不会感到明显的性能损耗

EnablePacketDirectEnableIov 若受网卡支持,则可提供更好的性能

若提示 不支持虚拟交换机数据包直通功能 或错误代码 0x80070057 ,请执行

代码块
Shell
自动换行
复制代码
New-VMSwitch -SwitchName "VETH" -NetAdapterName "以太网" -AllowManagementOS $True -EnableIov $True
复制成功


为 WSL2 添加虚拟网卡


对于 Windows 11 22H2 或更高版本,可直接修改配置文件

代码块
Shell
自动换行
复制代码
cd ~
New-Item .wslconfig
notepad .\.wslconfig
复制成功

cd 切换到用户目录,一般 PowerShell 启动时就位于用户目录,此命令可省略

New-Item 创建 WSL 的自定义配置文件 .wslconfig

notepad 使用记事本编辑配置文件 .wslconfig 由于 PowerShell 输出文本使用 UTF-16 LE 编码,且可能无法修改为 UTF-8 NoBOM 这将导致一些程序无法正确识别文本,因此使用记事本而不是在 PowerShell 内修改配置文件

代码块
Shell
自动换行
复制代码
[wsl2]
networkingMode=bridged
vmSwitch=VETH
ipv6=true
复制成功

粘贴以上内容到 .wslconfig 并保存

networkingMode 指定网络模式为 桥接

vmSwitch 指定网卡为上面创建的虚拟网卡,注意名称一致

ipv6 配置为可选,删除本行即禁用,也可改为 false


对于 Windows 10 以及 Windows 11 22H2 以前版本,将使用以下项目

https://github.com/dantmnf/WSLAttachSwitch/

下载 WSLAttachSwitch.exe

* 请确认 WSL2 已经启动后再执行

代码块
Shell
自动换行
复制代码
WSLAttachSwitch.exe "VETH"
复制成功

WSL2 中确认网卡是否已经添加(通常为 eth1

代码块
Shell
自动换行
复制代码
ip a
复制成功

通常,能见到 eth1 但无分配地址,这是因为 WSL2 中还未配置网卡

根据 WSL2 发行版,配置方法不同,这里示例 Debian 与 Ubuntu

Debian

代码块
Shell
自动换行
复制代码
echo iface eth1 inet dhcp >>/etc/network/interface
echo iface eth1 inet6 dhcp >>/etc/network/interface
sudo systemctl restart networking
复制成功

Ubuntu

代码块
Shell
自动换行
复制代码
cat >/etc/netplan/99-bridged.yaml <<EOF
network:
  ethernets:
    eth1:
      dhcp4: true
      dhcp6: true
EOF
sudo chmod 600 /etc/netplan/99-bridged.yaml
sudo netplan apply
复制成功

* IPv6 配置可选


每次重启 WSL2 时,需要重新执行 WSLAttachSwitch 分配虚拟网卡

可为 WSL2 配置自启执行 WSLAttachSwitch.exe

示例假设 WSLAttachSwitch.exe 在 C:\Windows\

示例使用 /sbin/mount.rc 自启(参照后述的 配置 WSL2 Linux 发行版的自启动

代码块
Shell
自动换行
复制代码
touch /sbin/mount.rc
echo /mnt/c/windows/WSLAttachSwitch.exe "VETH" --mac 00:15:5d:12:34:56 >>/sbin/mount.rc
# echo systemctl restart networking >>/sbin/mount.rc
# echo netplan apply >>/sbin/mount.rc
复制成功

请根据 WSL2 发行版选择重载网络配置的命令(可能不需要

WSL 中执行 exe 需要使用绝对路径,不可 cd 到目录下执行 exe

WSLAttachSwitch.exe 在 C:\Windows\ 下时,则可直接执行 WSLAttachSwitch.exe

建议请加上 --mac 参数,固定网卡的 mac 地址

建议事先测试 WSLAttachSwitch.exe 能否在 WSL2 中正常执行

如提示 Invalid argument,可通过 cmd.exe 嵌套执行

代码块
Shell
自动换行
复制代码
cmd.exe /c WSLAttachSwitch.exe
复制成功

若需要使用 cmd.exe,请自行修改自启脚本的对应部分


如需固定 IP 地址,可使用路由器静态分配,或根据你的 Linux 发行版配置静态 IP 地址。


配置 WSL2 开机自启动

以下命令返回 PowerShell 执行

代码块
Shell
自动换行
复制代码
New-Item WSL_AutoStart.vbs
notepad .\WSL_AutoStart.vbs
复制成功

New-Item 继续在用户目录创建 VBS 脚本 WSL_AutoStart.vbs

notepad 使用记事本编辑 VBS 脚本 WSL_AutoStart.vbs

代码块
Shell
自动换行
复制代码
createobject("wscript.shell").run "wsl",0
复制成功

将此行粘贴到 WSL_AutoStart.vbs 中并保存,用作后台静默运行 wsl 命令

代码块
Shell
自动换行
复制代码
$SETTINGS = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries
$TRIGGER = New-ScheduledTaskTrigger -AtStartup
$ACTION = New-ScheduledTaskAction -Execute "$env:USERPROFILE\WSL_AutoStart.vbs"
Register-ScheduledTask WSL_AutoStart -User $env:USERNAME -Password '你的密码' -Settings $SETTINGS -Trigger $TRIGGER -Action $ACTION
复制成功

逐条执行以上命令,注意 $ 号不能缺少

请在最后一行输入你当前用户的密码

此操作将创建一个名为 WSL_AutoStart 的任务计划,在系统启动时触发,运行上面创建的 VBS 静默运行脚本

代码块
Shell
自动换行
复制代码
taskschd
复制成功

打开任务计划程序,从左侧导航栏选择 任务计划程序库 确认创建的 WSL_AutoStart(通常在列表最底下)


PowerShell 下的操作到此暂告一段落,后续的命令将在 WSL2 内执行

代码块
Shell
自动换行
复制代码
wsl
复制成功

在 PowerShell 内执行 wsl,或点击终端标签页右侧的下箭头,打开 Debian

代码块
Shell
自动换行
复制代码
sudo -i
复制成功

sudo 登录 root 用户,要求输入当前 WSL2 用户的密码 密码输入时不会有回显反馈,打错的话直接按 Enter 键 重试

本文在 WSL2 中的命令默认以 root 权限执行


修改 WSL2 Linux 发行版的软件源

Debian 的官方软件源在国外,网络体验极差,建议更改为国内源

这里采用的是 清华大学开源软件镜像站

代码块
Shell
自动换行
复制代码
cp /etc/apt/sources.list /etc/apt/sources.list.bak
sed -i 's_http:\/\/.*debian\.org_https://mirrors.tuna.tsinghua.edu.cn_' /etc/apt/sources.list
apt update
apt upgrade
复制成功

cp 备份 /etc/apt/sources.list/etc/apt/sources.list.bak sed/etc/apt/sources.list 中的默认服务器地址改为清华镜像 apt update 更新软件包列表 apt upgrade 升级已安装的软件包,升级过程中会确认,输入 Y (不分大小写)


若软件包列表更新失败,可能是 Debian 没有预装 HTTPS 支持 需要从官方源安装 apt-transport-httpsca-certificates

代码块
Shell
自动换行
复制代码
mv /etc/apt/sources.list.bak /etc/apt/sources.list
apt update
apt install apt-transport-https ca-certificates
复制成功

mv 移动 /etc/apt/sources.list.bak/etc/apt/sources.list apt update 更新软件包列表 apt install 安装 ca-certificates

软件包列表更新时可能会在中途卡着,这时候可以按下 Ctrl + C 键中止更新,直接执行后面的安装命令(可能需要尝试多次)

成功后再重新尝试开始的操作


配置 WSL2 Linux 发行版的自启动

新版 WSL2 已支持通过 systemd 管理自启,但本文章方案仍可用


WSL2 的开机自启动与其他 Linux 发行版稍有差别,需要利用自启动脚本 /sbin/mount.rc

代码块
Shell
自动换行
复制代码
echo 'none none rc defaults 0 0' | tee -a /etc/fstab
touch /sbin/mount.rc
chmod +x /sbin/mount.rc
复制成功

echotee 输出配置到 /etc/fstab touch 创建自启动脚本 /sbin/mount.rc chomd 赋予自启动脚本 /sbin/mount.rc 执行权限

代码块
Shell
自动换行
复制代码
nano /sbin/mount.rc
复制成功

nano 编辑自启动脚本 /sbin/mount.rc

粘贴以下内容,启动时将修改内核参数

代码块
Shell
自动换行
复制代码
#!/bin/bash

sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
复制成功

#!/bin/bash 指定脚本的解释器,不可缺少

sysctl 修改内核参数 net.ipv4.ip_forward=1 表示开启 IPv4 转发 net.ipv6.conf.all.forwarding=1 表示开启 IPv6 转发

开启 IP 转发,Linux 才能作为 IP 网关(路由器)使用,此处仅作示例,可选

nano 下,按下 Ctrl + O 键 保存,Enter 键 确认,Ctrl + X 键 退出编辑


重启 WSL2 Linux 发行版

WSL2 的初期配置就此完成,重启确认配置

输入 exit 返回,或重新打开 PowerShell

代码块
Shell
自动换行
复制代码
wsl --shutdown
复制成功

关闭 WSL2 Linux 发行版,等待8秒

配置更改的 8 秒规则 必须等到运行你的 Linux 发行版的子系统完全停止运行并重启,配置设置更新才会显示。 这通常需要关闭发行版 shell 的所有实例后大约 8 秒。

代码块
Shell
自动换行
复制代码
wsl
复制成功

确认 WSL2 是否正常启动 如果系统不支持 WSL2 的桥接网络模式,或虚拟网卡配置不正确,将会提示错误

代码块
Shell
自动换行
复制代码
ip a
sysctl net.ipv4.ip_forward
sysctl net.ipv6.conf.all.forwarding
复制成功

ip a 查看网络接口的 IP 地址,这个地址将在配置旁路由时用到 此时 eth0 接口的 IPv4 地址应该与路由器及下载设备同网段(通常是 192.168.x.x)

sysctl 查看 IPv4 与 IPv6 转发的内核参数,自启动脚本正常执行时,应显示 net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding = 1


桥接网络模式下,WSL2 的 IP 地址一般不会发生变化

如需固定 WSL2 的 IP 地址,建议在主路由上绑定,一般 Linux 发行版的配置方法很可能不适用于 WSL2


以下将配置 WSL2 Linux 发行版为旁路由

若你的使用场景不需要拦截流量,则不必要


配置 WSL2 Linux 发行版为旁路由

在确认 WSL2 的网络正常工作后,即可把 Windows 或局域网其他设备的网关地址改为 WSL2 的局域网地址,作为旁路由使用

以下命令在 PowerShell 中以管理员权限执行


为防止 IP 意外变动,请先给 Windows 的虚拟网卡指定静态 IP 地址

* 注意,这里配置的是 Windows 上的静态 IP 地址,并非 WSL2 的

代码块
Shell
自动换行
复制代码
Get-NetAdapter
复制成功

Get-NetAdapter 获取网卡列表,确认刚才创建的虚拟网卡,名称应该是 “vEthernet (VETH)”

代码块
Shell
自动换行
复制代码
$GWIP="192.168.5.1"
$PCIP="192.168.5.241"
Remove-NetIPAddress -InterfaceAlias "vEthernet (VETH)" -IPAddress $PCIP -PrefixLength 24 -DefaultGateway $GWIP -Confirm:$false
New-NetIPAddress -InterfaceAlias "vEthernet (VETH)" -IPAddress $PCIP -PrefixLength 24 -DefaultGateway $GWIP
Set-DnsClientServerAddress -InterfaceAlias "vEthernet (VETH)" -ServerAddresses ($GWIP,"119.29.29.29")
复制成功
  • $GWIP 改为你的主路由的 IP 地址

  • $PCIP 改为你要配置的静态 IP 地址,要求与主路由及 WSL2 处于同一网段

  • IP 地址的引号不能省略

  • 如果你想配置的静态 IP 地址 $PCIP 与当前地址一致时,请先运行 Remove-NetIPAddress 删除后再 New-NetIPAddress 创建

Remove-NetIPAddress 当前地址与静态地址一致时,删除 Windows 虚拟网卡的当前地址

New-NetIPAddress 给 Windows 虚拟网卡指定静态地址,此处把主路由设置为默认网关

Set-DnsClientServerAddress 指定静态地址会关闭 DHCP 服务,还需要设置 DNS 服务器 此处把首选 DNS 设为主路由,备用 DNS 设为 DNSPod (119.29.29.29)


对于单网卡与多网卡用户,后面的操作会有不同


单网卡用户执行以下命令

$WSLIP 改为 WSL2 的 IP 地址

代码块
Shell
自动换行
复制代码
$WSLIP="192.168.5.31"
route ADD -p 0.0.0.0 MASK 0.0.0.0 $WSLIP METRIC 1
复制成功

route ADD 添加一条网关为 WSL2 的默认路由


多网卡用户可设置跃点数,指定日常使用的网卡

$WSLIP 改为 WSL2 的 IP 地址

代码块
Shell
自动换行
复制代码
$WSLIP="192.168.5.31"
Get-NetAdapter
Set-NetIPInterface -InterfaceAlias "vEthernet (VETH)" -InterfaceMetric 1000
route ADD -p 0.0.0.0 MASK 0.0.0.0 $WSLIP METRIC 1 IF <接口索引>
复制成功

Get-NetAdapter 获取网卡列表,确认虚拟网卡 “vEthernet (VETH)” 的接口索引(ifIndex),添加默认路由时需要指定

Set-NetIPInterface 设置虚拟网卡跃点数为 1000,只有绑定该接口的程序才会使用该网卡,不影响主网卡的日常使用

route ADD 添加一条网关为 WSL2 的默认路由,多网卡下需要指定接口索引


WSL2 网关的跃点数为 1,会优先于上一步配置的主路由网关

这样配置的目的是,当 WSL2 发生故障时,会转移到主路由作为默认网关,不会丢失网络

* 此方法同样适用于 WSL2 以外的旁路由场景


WSL2 现在已经作为旁路由用作 Windows 的 IPv4 默认网关

但由于 WSL2 上除了开启转发之外什么也没配置,所以看上去并没有任何区别