Windows Subsystem for Linux 2 (WSL2) has a virtualized ethernet adapter with its own unique IP address (usually 172.x.x.x). Services run in WSL2 cannot be directly accessed by remote computers. There is a simple solution: using netsh
to forward connection.
This script will discover service run on WSL, and then forward the host port to WSL and configure appropriate firewall rules.
- a launcher to make it faster to start this script
- get the notification of program binding port in real time (NEED HELP)
- Since we use
netsh
, we cannot support UDP. - We scan service periodicity and it might not suitable for service that frequently changing listening ports.
Built on Hyper-V, WSL2 is a a real virtual machine, which has independent virtual network (in a different network segment from the host). We discuss the incoming and outgoing directions of network packets from external network respectively:
INCOME: If the firewall of the Host is configured properly, the external computer can access the port on the physical network interface of the host, but the service on WSL listens on its own virtual network interface.
OUTCOME: Windows will complete the network address translation (NAT address translation), and WSL always accesses the external network with the host's IP, Windows can also correctly handle the response from the external network in the way of NAT address translation. Therefore, there is no obstacle for WSL to access the external network or PASSIVELY accept the results returned by the external network.
Reference:
https://docs.microsoft.com/en-us/windows/wsl/compare-versions
If you rely on a Linux distribution to have an IP address in the same network as your host machine, you may need to set up a workaround in order to run WSL 2. WSL 2 is running as a hyper-v virtual machine. This is a change from the bridged network adapter used in WSL 1, meaning that WSL 2 uses a Network Address Translation (NAT) service for it's virtual network, instead of making it bridged to the host Network Interface Card (NIC) resulting in a unique IP address that will change on restart. To learn more about the issue and workaround that forwards TCP ports of WSL 2 services to the host OS, see WSL GitHub repository issue 4150, NIC Bridge mode (TCP Workaround).
Therefore, if we can listen to some ports on the host, and then forward the packets of external computers to appropriate port of WSL, the external computers can "directly" access the services on WSL.
Out of the box, no configuration required, only three simple step.
-
Open Windows Terminal with administrators privilege.
The simplest way:
Win
+X
-> Windows PowellShell**(admin)** -
Open WSL Terminal
Run
wsl
in the console. (If you install multiple distribution, you may usewsl -d Ubuntu-20.04
etc.) -
Run this script
If you haven't installed this script, run:
pip install wsl_port_forwarding
Once it is installed, just run:
port_forwarding
. If everything is OK, something like this will be displayed in console.
Script will run automatically configure forwarding and firewall rules for the ports that WSL service bind on. You can access the services on the WSL as if they were on the host. For example, when the host IP is 192.168.1.1
and the WSL IP is 172.28.1.1
, you can just connect to python3 by 192.168.1.1:11311
instead of 172.28.1.1:11311
, while 192.168.1.1
may be directly accessed by external network.
- WSL2
- python3.6+ in WSL2
- Windows administrators privilege
there are two ways to install
- Use pip to install (recommend)
pip install wsl_port_forwarding
then: port_forwarding
to start this program.
- Download from source
wget https://raw.githubusercontent.com/ColorsWind/WSL-Port-Forwarding/main/src/wsl_port_forwarding/port_forwarding.py
then: python3 port_forwarding.py
to start.
The added rules will be deleted automatically when the script exits normally, so you only need to delete the script. That is, if you install by pip, use pip uninstall wsl_port_forwarding
, or if you install from source, just delete port_forwarding.py
.
If you need to manually delete the configuration added by the script, you can run in powershell (or cmd) in Windows with administrators privilege.
netsh.exe interface portproxy reset ipv4
netsh.exe advfirewall firewall del rule name='WSL Auto Fowards'
WARNING: All netsh
portproxy ipv4 rules will be clean.
Command parameters:
usage: port_forwarding [-h] [--mode {auto,manual}] [--interval INTERVAL] [--allow ALLOW]
[--disallow DISALLOW] [--windows_ip WINDOWS_IP] [--wsl_ip WSL_IP]
[--ignore_exception] [--gen_config] [--clean_rules]
A script that enable outside program access WSL2 ports by port forwarding.
optional arguments:
-h, --help show this help message and exit
--mode {auto,manual} when to update port forwarding rule.
--interval INTERVAL how often are network state changes detected (auto mode only).
--allow ALLOW program name that allows external access to the port
--disallow DISALLOW program name that disallows external access to the port
--windows_ip WINDOWS_IP
windows ip that external can access
--wsl_ip WSL_IP wsl ip that windows can access
--ignore_exception whether interpret script when exception occurs
--gen_config generate config in ~/.wsl_port_forwarding.json
--clean_rules clean all netsh port forwarding rule and relevant firewall rules
Configuration:
Although the script can work well without configuration, we still provide some customizable configurations. Run port_forwarding --gen-config
, then edit ~/.wsl_port_forwarding.json
. Note when there is a configuration, it will print Successfully load config.
first every time you run this script.
{
"update_interval": 0.5,
"windows_ip": "0.0.0.0",
"wsl_ip": "172.28.1.1",
"ignore_exception": false, // if true, every time program encounter a exception it will pause
"allow_program_name": [], // if set, program that is not in this list will be ignore
"disallow_program_name": [] // if set, program that is in this list will be ignore
}
MIT License
Copyright (c) 2022 ColorsWind
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
At present,
netsh
only supports TCP forwarding, so the script can only deal with TCP protocol. -
No simply way to get notification when a program bind a port in Linux is found, so currently the script just gets binded ports at regular intervals (default: 0.5s). In the worst case, there is a delay of 0.5s from the external network can access service on WSL to that port has been bound. Therefore, the script may not be suitable for occasions with high frequency and low delay.