文本节选自《OpenWrt/WSL下利用nftables修改向Tracker汇报的端口,实现BT下载的全自动STUN内网穿透》
由于原文内容较多,不方便阅读,现把桥接网络模式的 WSL2 的安装与配置部分作出修正并单独发布。
部分内容基于原文章涉及的 WSL2 旁路由 场景进行说明,绝大多数情况不需要,可忽略。
根据微软官方文档,桥接网络模式的 WSL2 要求 Windows 11 22H2 或更高版本。
对于 Windows 10 以及 Windows 11 22H2 以前版本,将使用以下项目
https://github.com/dantmnf/WSLAttachSwitch/
安装 WSL2
├─ 启用 Hyper-V
└─ 安装 WSL2 Linux 发行版
配置 WSL2
├─ 配置桥接网络
├─ 配置 WSL2 开机自启动
├─ 修改 WSL2 Linux 发行版的软件源
├─ 配置 WSL2 Linux 发行版的自启动
├─ 重启 WSL2 Linux 发行版
└─ 配置 WSL2 Linux 发行版为旁路由 依次按下键盘的 Win + X 键,A 键;或右键点击开始按钮,打开 终端管理员(A)
确认标题是否显示 管理员: Windows PowerShell
如无特别说明,本文在 Windows 中的操作默认通过管理员权限的 PowerShell 执行
Windows Terminal 内可使用左键选定,右键点击的方式进行复制粘贴
启用 Hyper-V
确认 Hyper-V 是否已启用
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V State 显示为 Enabled 即为已启用
若显示 Disabled,执行以下命令启用
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All 需要重启
启用 Hyper-V 不需要开启 CPU 虚拟化,但后续的 WSL2 安装需要
建议在重启时确认 UEFI (BIOS) 中的虚拟化设置
安装 WSL2 Linux 发行版
wsl --update
wsl -v 先升级 WSL 组件,可能需要一点时间
升级后运行 wsl -v 确认版本
可选使用 wsl --update --pre-release 更新预发布版
wsl -l -o
wsl --install -d Debian 在线获取可用的 WSL2 Linux 发行版列表后,选择 Debian 安装
本文基于 Debian,其他发行版操作细节可能稍有不同
可能需要重启
安装过程中会提示输入用户名和密码,不需要跟 Windows 的用户信息一致
若未开启 CPU 虚拟化,将在设置用户名和密码后提示错误
WSL2 安装完成后,输入 exit 返回,或重新打开 PowerShell 继续执行后面的操作
配置桥接网络
创建虚拟网卡
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 地址,即可实现高效的分流 得益于微软近年来的开发与优化,单网卡虚拟化的日常使用也不会感到明显的性能损耗
EnablePacketDirect 与 EnableIov 若受网卡支持,则可提供更好的性能
若提示 不支持虚拟交换机数据包直通功能 或错误代码 0x80070057 ,请执行
New-VMSwitch -SwitchName "VETH" -NetAdapterName "以太网" -AllowManagementOS $True -EnableIov $True
为 WSL2 添加虚拟网卡
对于 Windows 11 22H2 或更高版本,可直接修改配置文件
cd ~
New-Item .wslconfig
notepad .\.wslconfig cd 切换到用户目录,一般 PowerShell 启动时就位于用户目录,此命令可省略
New-Item 创建 WSL 的自定义配置文件 .wslconfig
notepad 使用记事本编辑配置文件 .wslconfig 由于 PowerShell 输出文本使用 UTF-16 LE 编码,且可能无法修改为 UTF-8 NoBOM 这将导致一些程序无法正确识别文本,因此使用记事本而不是在 PowerShell 内修改配置文件
[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 已经启动后再执行
WSLAttachSwitch.exe "VETH" WSL2 中确认网卡是否已经添加(通常为 eth1)
ip a 通常,能见到 eth1 但无分配地址,这是因为 WSL2 中还未配置网卡
根据 WSL2 发行版,配置方法不同,这里示例 Debian 与 Ubuntu
Debian
echo iface eth1 inet dhcp >>/etc/network/interface
echo iface eth1 inet6 dhcp >>/etc/network/interface
sudo systemctl restart networking Ubuntu
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 发行版的自启动)
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 嵌套执行
cmd.exe /c WSLAttachSwitch.exe 若需要使用 cmd.exe,请自行修改自启脚本的对应部分
如需固定 IP 地址,可使用路由器静态分配,或根据你的 Linux 发行版配置静态 IP 地址。
配置 WSL2 开机自启动
以下命令返回 PowerShell 执行
New-Item WSL_AutoStart.vbs
notepad .\WSL_AutoStart.vbs New-Item 继续在用户目录创建 VBS 脚本 WSL_AutoStart.vbs
notepad 使用记事本编辑 VBS 脚本 WSL_AutoStart.vbs
createobject("wscript.shell").run "wsl",0 将此行粘贴到 WSL_AutoStart.vbs 中并保存,用作后台静默运行 wsl 命令
$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 静默运行脚本
taskschd 打开任务计划程序,从左侧导航栏选择 任务计划程序库 确认创建的 WSL_AutoStart(通常在列表最底下)
PowerShell 下的操作到此暂告一段落,后续的命令将在 WSL2 内执行
wsl 在 PowerShell 内执行 wsl,或点击终端标签页右侧的下箭头,打开 Debian
sudo -i sudo 登录 root 用户,要求输入当前 WSL2 用户的密码 密码输入时不会有回显反馈,打错的话直接按 Enter 键 重试
本文在 WSL2 中的命令默认以 root 权限执行
修改 WSL2 Linux 发行版的软件源
Debian 的官方软件源在国外,网络体验极差,建议更改为国内源
这里采用的是 清华大学开源软件镜像站
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-https 与 ca-certificates
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
echo 'none none rc defaults 0 0' | tee -a /etc/fstab
touch /sbin/mount.rc
chmod +x /sbin/mount.rc echo 与 tee 输出配置到 /etc/fstab touch 创建自启动脚本 /sbin/mount.rc chomd 赋予自启动脚本 /sbin/mount.rc 执行权限
nano /sbin/mount.rc nano 编辑自启动脚本 /sbin/mount.rc
粘贴以下内容,启动时将修改内核参数
#!/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
wsl --shutdown 关闭 WSL2 Linux 发行版,等待8秒
配置更改的 8 秒规则 必须等到运行你的 Linux 发行版的子系统完全停止运行并重启,配置设置更新才会显示。 这通常需要关闭发行版 shell 的所有实例后大约 8 秒。
wsl 确认 WSL2 是否正常启动 如果系统不支持 WSL2 的桥接网络模式,或虚拟网卡配置不正确,将会提示错误
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 的
Get-NetAdapter Get-NetAdapter 获取网卡列表,确认刚才创建的虚拟网卡,名称应该是 “vEthernet (VETH)”
$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 地址
$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 地址
$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 上除了开启转发之外什么也没配置,所以看上去并没有任何区别