Python 实现 WSL 2 自动 Windows 主机IP和端口转发,可远程 SSH 登录和访问

WSL 2 安装教程:https://docs.microsoft.com/zh-cn/windows/wsl/wsl2-install

WSL 2 和 WSL 1 一个很大的不同点,WSL 1 是和 Windows 共享 IP 地址,因此可以直接通过主机 IP 地址直接 SSH 登录。

而 WSL 2 则采用了像 VMware 虚拟机一样的 Hyper-V 虚拟网络,本想着直接用 Windows 的端口监听和转发工具netsh interface portproxy add将 Windows 主机地址代理到 WSL 2 ,然鹅 WSL 2 的一个神坑是,每次重启后的 IP 地址不一样。试过 Hyper-V 虚拟网络设置工具,无效,目测每次 WSL 2 重启都删掉先前的 Hyper-V 虚拟网络重新新建一个。

感谢某个大佬提供的解决思路,将 WSL 2 的 IP 地址写入 Windows 的 hosts 文件,然后设置 Windows 的代理转发到 hostname 即可。

不使用 Python 的方法 推荐

下面的保存为 xx.bat 文件:

# 在Ubuntu中添加IP地址192.168.128.10,名为eth0:1 使用时候去掉注释
# wsl -d Ubuntu-20.04 wsl镜像的名称
#  -u root root用户
wsl -d Ubuntu-20.04 -u root ip addr add 192.168.128.10/24 broadcast 192.168.128.255 dev eth0 label eth0:1

# 在Win10中添加IP地址 192.168.128.20
netsh interface ip add address "vEthernet (WSL)" 192.168.128.20 255.255.255.0

下面的保存为 xx.vbs 文件:

set ws=WScript.CreateObject("WScript.Shell") 
ws.Run "bat文件所在的位置", vbhide

设置开机自启:

Windows 计划任务(控制面板搜索计划任务)用 vbs 脚本
1、新建任务
在这里插入图片描述
2、第二步,设置登录时候运行
在这里插入图片描述

3、第三步,设置 vbs 程序
在这里插入图片描述
4、第四步,设置运行条件
在这里插入图片描述
在这里插入图片描述

WSL 安装 SSH 服务 – 必须,自带的 ssh 无法远程登录

重新安装 SSH Server:

# 在 WSL 下运行
sudo apt remove openssh-server
sudo apt install openssh-server

如果需要自定义 SSH Server 端口号,编辑 sshd_config 文件

sudo vim /etc/ssh/sshd_config
# 编辑完成后重启 ssh Server
sudo service ssh --full-restart

sshd_config 文件

# 端口号,默认 22
Port 22
# 允许密码 登陆验证
PasswordAuthentication yes

将 WSL 的 IP 地址写入到 Windows hosts 文件 – 不推荐

在 PowerShell 运行如下命令:

wsl ip a |wsl grep -w "inet" |wsl cut -d " " -f 6 |wsl cut -d "/" -f 1
# 看输出的 IP 地址,根据你的实际情况取
127.0.0.1
172.25.191.98

新建 ChangeWslHosts.py:

import os
# 获得 ip 地址
ip_cmd = 'wsl ip a |wsl grep -w "inet" |wsl cut -d " " -f 6 |wsl cut -d "/" -f 1'
shells = os.popen(ip_cmd).readlines()
wsl_ip = shells[1].split("\n")[0]

# 写入 Windows hosts 文件
file_path = "C:/Windows/System32/drivers/etc/hosts"
with open(file_path, "r") as f:
    lines = f.readlines()

found = False
# 查找 hostname 为 ubuntu 的行
for i, line in enumerate(lines):
    if len(line) > 10 and line.find("ubuntu") > -1:
        found = True
        # 替换为当前的 ip
        lines[i] = wsl_ip + "  ubuntu"
        break

# 没有hostname 为 ubuntu 的行
if not found:
    lines.append("\n" + wsl_ip + "  ubuntu")

# 写入文件
if lines :
    with open(file_path, "w") as f:
        f.write("".join(lines))

新建 ChangeWslHosts.bat 的脚本:可以在 Python 中执行这些命令的

Windows 如果安装了 SSH Server 服务,listenport=22会导致端口冲突,可以更换端口号或者卸载禁用 Windows 的 SSH 服务。

# 获得管理员权限
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
# 用 WSL 的 root 重启 WSL 的 ssh 服务,WSL 的 bug
wsl -u root service ssh --full-restart
# 执行 Python 脚本
python D:/Project/Tools/ChangeWslHosts.py
# 解除 192.168.0.10(Windows IP) 的代理监听
netsh interface portproxy delete v4tov4 listenaddress=192.168.0.10  listenport=22
# 将 192.168.0.10(Windows IP) 转发至 ubuntu(wsl IP) 的 22 端口
netsh interface portproxy add v4tov4 listenaddress=192.168.0.10 listenport=22 connectaddress=ubuntu connectport=22

解除 Windows 代理转发的命令是:

# 解除 192.168.0.10(Windows IP) 的代理监听
netsh interface portproxy delete v4tov4 listenaddress=192.168.0.10  listenport=22

运行 Bat 脚本,运行 ssh 登录命令:

# 192.168.0.10 替换为 你的 Windows 本地 IP地址
ssh user@192.168.0.10

如果其他电脑无法访问,在 Windows 防火墙添加允许 22 端口出入站的规则。

TODO:将 BAT 加入 Windows 的自启。好像加 bat 放入下面的文件夹里就可以诶:

C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
# 或者
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup

TODO 打包成 exe 运行文件


版权声明:本文为u010974701原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。