win10 linux 子系统 wsl2实现ip自动转发

本文介绍如何在Windows 10的WSL2环境中,通过bash和VBS脚本解决因系统更新导致的wsl子系统IP变化问题,实现自动的IP转发,确保服务在系统重启后仍能无缝连接。

win10 系统带linux子系统有两个版本

第一个是wsl, 它与windows 系统公用同1个ip地址, 但是没有自己内核, 不支持docker
第二个版本是wsl2, 它可以使用docker,但是它的网卡每次启动都随机使用ip, 所以重启后每次都必须手动进行ip 转发。

例如:

netsh interface portproxy reset
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=22 connectaddress=192.168.44.155 connectport=22
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8091 connectaddress=192.168.44.155 connectport=8091
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3351 connectaddress=192.168.44.155 connectport=3351
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3352 connectaddress=192.168.44.155 connectport=3352
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3353 connectaddress=192.168.44.155 connectport=3353
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3354 connectaddress=192.168.44.155 connectport=3354
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3355 connectaddress=192.168.44.155 connectport=3355
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=3356 connectaddress=192.168.44.155 connectport=3356
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8888 connectaddress=192.168.44.155 connectport=8888
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=192.168.44.155 connectport=8080
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8081 connectaddress=192.168.44.155 connectport=8081
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8761 connectaddress=192.168.44.155 connectport=8761
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8890 connectaddress=192.168.44.155 connectport=8890
netsh interface portproxy show all

但由于微软系统的不稳定性, 经常无故重启, 大部分都是更新引起的, 禁了更新一两周内仍会自己重启, 好智障。

一旦重启后,由于wsl的子系统ip地址变了, 所有的服务都连不上…

痛定思楚, 便有了下面的解决办法。



1. 编写bash 脚本获取子系统ip

由于安装了docker 的关系, 简单的hostname -l 会返回两个ip, 而我们只想要eth0 网卡那个。

gateman@DESKTOP-UIU9RFJ:~$ hostname -I
192.168.77.113 172.17.0.1 

但是在上一级语言去 call linux管道命令是很麻烦的, 所以编写了脚本getip 去获取ip

gateman@DESKTOP-UIU9RFJ:~$ cat /usr/bin/getip
ifconfig  eth0 | head -n2 | grep inet | awk '{print$2}'
gateman@DESKTOP-UIU9RFJ:~$ getip
192.168.77.113
gateman@DESKTOP-UIU9RFJ:~$ 

这个就是我们想要的.



2. 编写vbs脚本进行自动ip转发

在下面的目录创建1个posts.vbs文件
C:\Users\xxxxxxx\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

内容
只有3个地方有可能要修改
1是 第一行wsl2 name
2是 要转发的端口list
3是 存放ip地址的临时文件位置

wslname = "Ubuntu" 'the name of your wls system, could be checked by command wsl -l

Dim ports
'the ports which need to process ip forward
ports = Array(22,8080,8091,3351,3352,3353,3354,3355,3356,8888,8081,8761,8890)

'the file to store wls ip
ipTemp = "C:\Temp\wslip.txt"


If WScript.Arguments.Length = 0 Then
    'to get the admin right to run the ip forward commands
    CreateObject("Shell.Application").ShellExecute "wscript.exe" _
    , """" & WScript.ScriptFullName & """ RunAsAdministrator", , "runas", 1
    WScript.Quit
End If

Set fso = CreateObject("Scripting.FileSystemObject")
Set objShell = CreateObject("WScript.Shell")

'to get the eth0 ip address of the sub linux system, the script getip is in /usr/bin, and save the ipadress to C:\Temp\wslip.txt
writeip = objShell.Run("cmd /c ""wsl -d " + wslname + " -u root getip"">" + ipTemp,0,True)

'wscript.sleep(1000)'just incase some network problem

'get the ip from ip file
Set f = fso.OpenTextFile(ipTemp, 1)
wslip = f.ReadAll()
f.Close()

'execute the ip forward command for each port number from the list
For i = 0 To UBound(ports)
    port = ports(i)
    command = "cmd /c ""netsh interface portproxy add v4tov4 listenport=" & port & " listenaddress=0.0.0.0 connectport=" & port & " connectaddress=" + wslip
    forwarding = objShell.Run(command,0,True)
Next

重启后
用powershell执行下面命令就可以看到自动ip转发是否成功

PS C:\Users\gateman> netsh interface portproxy show all

侦听 ipv4:                 连接到 ipv4:

地址            端口        地址            端口
--------------- ----------  --------------- ----------
0.0.0.0         22          192.168.77.113  22
0.0.0.0         8091        192.168.77.113  8091
0.0.0.0         3351        192.168.77.113  3351
0.0.0.0         3352        192.168.77.113  3352
0.0.0.0         3353        192.168.77.113  3353
0.0.0.0         3354        192.168.77.113  3354
0.0.0.0         3355        192.168.77.113  3355
0.0.0.0         3356        192.168.77.113  3356
0.0.0.0         8888        192.168.77.113  8888
0.0.0.0         8080        192.168.77.113  8080
0.0.0.0         8081        192.168.77.113  8081
0.0.0.0         8761        192.168.77.113  8761
0.0.0.0         8890        192.168.77.113  8890

P2911 [USACO08OCT] Bovine Bones G 是洛谷【入门 4】数组中的一道题目。题目描述为 Bessie 喜欢棋盘游戏和角色扮演游戏,她说服 Farmer John 带她去一家爱好商店,在那里她购买了三个骰子用于投掷,这些骰子分别有 S1、S2 和 S3 个面[^1]。 在解题代码方面,有 Java 和 C++ 两种实现。Java 代码通过定义一个长度为 81 的数组统计不同和值出现的次数,通过嵌套循环模拟掷骰子的过程,将每个和值对应的数组元素加 1,同时更新最大出现次数及其对应的和值,最后输出最大出现次数对应的和值[^2]。示例代码如下: ```java import java.util.Scanner; public class P2911_1 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int s1 = sc.nextInt(), s2 = sc.nextInt(), s3 = sc.nextInt(); int[] arr = new int[81]; int max = 0; int temp = 0; for (int i = 1; i <= s1; i++) { for (int j = 1; j <= s2; j++) { for (int k = 1; k <= s3; k++) { arr[i + j + k]++; if (temp < arr[i + j + k]) { max = i + j + k; temp = arr[i + j + k]; } } } } System.out.println(max); sc.close(); } } ``` C++ 代码同样使用数组统计和值出现的次数,先通过三重循环模拟掷骰子得到所有可能的和值并更新对应次数,再遍历所有可能的和值范围,找出出现次数最多且和值最小的结果并输出[^3]。示例代码如下: ```cpp #include<bits/stdc++.h> using namespace std; int s1, s2, s3, res; int cnt[20000]; int maxn = -1e9; int main() { scanf("%d%d%d", &s1, &s2, &s3); for (int i = 1; i <= s1; ++i) { for (int j = 1; j <= s2; ++j) { for (int k = 1; k <= s3; ++k) { cnt[i + j + k]++; } } } for (int i = 3; i <= s1 + s2 + s3; ++i) { if (cnt[i] > maxn) maxn = cnt[i], res = i; } printf("%d", res); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值