wsl同时使用udp广播和usb

2025/05/02

Tags: wsl udp broadcast usbipd

Table of Contents

0.背景

​ 遇到一个问题, 之前写了一个cv ai 模型辅助训练的工具给客户使用,用于采集我司AI相机的图片,训练模型后再上传回AI相机

这个工具中使用了很多bash环境下的工具, 比如async scp,节约了很多重复造轮子的时间,但也注定了几乎离不开bash环境了

在要windows上运行这个工具,面临这几种方案的选择

毫无疑问,出于对公司的负责,我选择了成本最低的方案1

工业软件经常在在配置设备的Ip之前用udp广播来发现网络设备, 因为udp broadcast运行在 第二层数据链路层, ip在第三层

我写的这个工具也使用了udp广播来发现设备, 同时后期还加入了硬件加密 usb子锁,

所以它需要运行在wsl中,同时使用udp广播和usb接口

1. 同时使用udp广播和usb接口的问题

1.1 wsl usb挂载模式

wsl中已经有成熟的usb方案,即 usbipd.

可以在windows host上把某一个usb设置共享,在wsl中设置挂载

如它的名字, usb ip d, 基于usb/ip协议的daemon程序,它的运行的基础是:

需要windows 和 wsl 可以通过ip 通讯

1.2 wsl的三种网络模式

经常使用wsl的朋友都知道wsl有三种网络工作模式

nat 模式时, wsl运行在一个hyper v 的nat子网络中, 这个网络适配器在ncpa.cpl工具中看不到,但使用ipconfig可以看到,用hyper v网络管理工具也可以看到,应该是防老6误操作,偷感十足. nat天然的不能广播udp, 就像在家里的局域网不能无限制的向上层网络广播一样

mirrored械时, wsl里可以看到所有windows的网络适配器, 这个模式是微软推荐的方式,但这个模式,可能是为了防止udp风暴,这个模式下udp广播是有限制的,随便一搜就能看到很多人在github上讨论谁家的udp包又丢了

最后birgded,这个模式是微软想要铲掉的功能,因为bridge模式下, wsl 的网络像一座孤岛, 完全和windows host隔离了, 它独自占用了一个wsl 外部网络(对应一个物理网卡),所以它也可以对外广播

1.3 问题

结合 1.1 和 1.2 得出, 当需要udp广播的功能时,需要使用bridged网络模式, 此时wsl 和host是网络隔离的, 而windows host 需要通过usbipd->网络共享usb 端口给wsl,所以面临了2选1

2 解

2.1 两路思路

综上所述,想要同时在wsl中使用网络通讯 和 usb

前者貌似可以修改wsl的linux kernal, 让 127.0.0.1访问windows的usb设备变成走内核的模式,但资料很少,并且不确定能不能像usbipd那样单独只配置某个usb 共享

所以我还是从后者入手解决只要让wsl的udp广播到上层windows所在的局域网就行了

2.2 通用openvpn 桥接让wsl udp广播到上层局域网

openvpn支持layer 2 和layer3的桥接, 通常推荐的是性能更高的layer3 tun模式桥接

但udp广播发生在layer2 数据链路层,所以需要用 layer2的 tap模式桥接

2.2.1 openvpn server

google一下从官网下载,双击,driver只选tap ,

#server.ovpn

 1
 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
port 1194
proto udp
dev tap
dev-node tap-bridge  #这个是windows上的网络适配器名称,ncpa.cpl工具中右键tap适配器重命名tap-bridge 

ca ca.crt
cert server.crt
key server.key
dh dh.pem

cipher none
data-ciphers none


#server和  server-bridge两选一

#不桥接 tap  
#server 192.168.8.0 255.255.255.0  

#在ncpa.cpl中选中tap网络适配器和想桥接的网络适配器,手动桥接网络设置ip地址后,填写到下面一行
server-bridge  192.168.8.1 255.255.255.0 192.168.8.10 192.168.8.20   

# 或者不手动设置桥接网络的ip,用自动获取
#server-bridge 

keepalive 10 120

persist-key
persist-tun

status server.log
verb 3
explicit-exit-notify 1  

生成ca.crt , server.crt, server.key, dh.pem

官方文档生成步难又臭 又长, windows在git bash里直接使用下面这些就能生成, 还省得安装openvpn的easy-rsa模块了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

$ cat genkey.sh
# 生成 CA 私钥
openssl genrsa -out ca.key 2048

# 生成 CA 证书
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "//CN=MyVPN-CA"

# 生成 Server 私钥
openssl genrsa -out server.key 2048

# 生成 Server CSR(请求)
openssl req -new -key server.key -out server.csr -subj "//CN=MyVPN-Server"

# 使用 CA 证书签发 Server 证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256

# 生成 Diffie-Hellman 参数
openssl dhparam -out dh.pem 2048

把server.ovpn文件放到 c:\progame file\openvpn\config目录, 运行openvpn后 右下托盘右键连接

如果失败也在右下托盘右键看日志,状态等

windows上配置

2.2.2 client

安装

1
sudo apt install openvpn  #和官方文档不同的是,我不安装easy-ras,因为我不用它
1
2
sudo su #切换到root再操作下面的步骤
cd /etc/openvpn

#client.conf (conf和ovpn是同一种格式的文件,只是linux下后辍名用 conf)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
client
dev tap
proto udp

#这个ip是windows wsl 网络适配器的ip
#wsl会默认被分配一个hyper v 内部网络,ifconfig看得到,ncpa.cpl看不到,这个网络的作用只是用来wsl和host通讯
#并且这个网络配置初始化是写在注册表里的地址,不会变,除非改注册表
#计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\NatNetwork
remote 172.28.208.1 1194 

resolv-retry infinite

nobind

persist-key
persist-tun

ca ca.crt
cert client.crt
key client.key

cipher none
data-ciphers none

verb 3

wsl默认就有openssl了好像,没有的话安装一下

openssl生成 client.crt 和client.key, 参考server生成的好几条命令 , ca.crt 和ca.key用server的就行

1
2
3
4
5
6
7
8
# 生成 Server 私钥
openssl genrsa -out client.key 2048

# 生成 Server CSR(请求)
openssl req -new -key client.key -out server.csr -subj "//CN=MyVPN-Client"

# 使用 CA 证书签发 Server 证书
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650 -sha256

配置好了,也生成证书后

1
sudo openvpn --config client.conf

启动后就看到自动获取到服务中配置的ip地址了, windows 和tap 适配器桥接的网卡有接网线到其他设备的话(通过交换机的多个网络也可以),这时运行在nat 网络里的wsl可以Ping通这些设备, 这些设备 也可以向wsl发送udp广播

如果要让wsl不仅限于单播,需要重新编译wsl内核,打开多播的开关

配置为系统服务之类的前人之述备矣, 本懒汉就不再啰嗦了

>> Home

Comments