Skip to content

Instantly share code, notes, and snippets.

@wildlarva
Last active May 29, 2025 09:16
Show Gist options
  • Save wildlarva/0539212ad6bf0bf1450b38726e1a42de to your computer and use it in GitHub Desktop.
Save wildlarva/0539212ad6bf0bf1450b38726e1a42de to your computer and use it in GitHub Desktop.
WSL Port Forwarding Example for UDP
#--------------------------------------------------------
# Background: WSL UDP port forwarding
#--------------------------------------------------------
# Microsoft recommends "netsh interface portproxy" for port forwarding, but it does not support UDP for now.
# See https://learn.microsoft.com/en-us/windows/wsl/networking#accessing-a-wsl-2-distribution-from-your-local-area-network-lan.
# For UDP port forwarding, you can use Windows NAT mechanism.
# See https://gist.github.com/the-moog/e7a1b5150ce9017309afbcf91848e622.
#--------------------------------------------------------
# Configure Windows NAT for port forwarding
#--------------------------------------------------------
# It's hard to configure the default WSL NAT network, which is blackbox, to do port forwarding.
# Instead, set up a new NAT network for port forwarding.
# The new NAT network must not conflict with the default WSL NAT network.
# Assign new IP address to WSL switch
# Two IP addresses must be configured, one for the WSL switch and one for the guest, as follows:
# WSL switch: 192.168.100.1
# WSL guest: 192.168.100.2
New-NetIPAddress -InterfaceAlias "vEthernet (WSL)" -IPAddress 192.168.100.1 -PrefixLength 24
# Add NAT network
New-NetNat -Name "WSL-NAT" -InternalIPInterfaceAddressPrefix 192.168.100.0/24
# Add UDP port forwarding from WSL host to guest on port 2222
Add-NetNatStaticMapping -NatName "WSL-NAT" -Protocol UDP -ExternalIPAddress 0.0.0.0/0 -ExternalPort 2222 -InternalIPAddress 192.168.100.2 -InternalPort 2222
#--------------------------------------------------------
# Configure WSL guest to assign IP address
#--------------------------------------------------------
# Configure new IP address on WSL
# The new IP address needs to be the same as the one specified in port forwarding
wsl -u root ip address add 192.168.100.2/24 dev eth0
@c2vi
Copy link

c2vi commented Jul 14, 2024

I also needed to change default route in WSL, to make it work.

I followed those steps and got udp packets to the wsl, however no responses.
Before this nat, my wsl already has the ip: 172.22.142.240/20.
and output of ip route is:

default via 192.168.100.1 dev eth0
172.22.128.0/20 dev eth0 scope link  src 172.22.142.240
192.168.100.0/24 dev eth0 scope link  src 192.168.100.2

In wireshark I saw

  • on the external Ethernet the incoming packets from: external_linux_pc - to: ip_of_windows_pc_with_wsl
  • on the vEthernet the incoming packets from: external_linux_pc - to: 192.168.100.2
  • on the vEthernet the outgoing packets from: 172.22.142.240 - to: external_linux_pc
  • no outgoing packets on the external Ethernet
    my wsl somehow responds from the ip it had before setting up this NAT, which makes windows think this is part of another "connection" and therefore not sent out the external Ethernet Interface.

To fix this, I had to change the default route to use the new address:

sudo ip route del default eh0
sudo ip route add default via 192.168.100.1 dev eth0

@leptonJay
Copy link

Thank a lot. it worked for me just fine. i only need to run the last command every time my wsl restarts. Even AI coudn't help but this worked fine, thanks again.

@Dracrius
Copy link

Can someone please clarrify what each of these completely random ip's are supposed to be. I tried rereading this half a dozen times and I'm still lost.

For clarity we have the WSL IP (current versions of wsl have this set to a static ip you can find in the registy or with wsl -d "distroname" hostname -I), and the Windows host ip.

When using netsh we only use 0.0.0.0 and the WSL IP.

I think its very unclear what WSL Switch and WSL Guest represent.

WSL also tends to use 172.23.x.x addresses so I can't even begin to guess what IP's I use where as my local IPs are much diffeent.

@Dracrius
Copy link

I'm trying to connect to udp port 53 on WSL ip 172.23.210.17 from other machines on the network from its host windows machines ip of 192.168.168.240:53.

So that other machines can use a dns I'm running in wsl.

@c2vi
Copy link

c2vi commented May 29, 2025

I'm trying to connect to udp port 53 on WSL ip 172.23.210.17 from other machines on the network from its host windows machines ip of 192.168.168.240:53.

So that other machines can use a dns I'm running in wsl.

The easier solution might be to just set the Networking Mode to bridged, which would make forwarding not necessary, but wouldn't work if windows itself listens for udp packets on port 53.

@c2vi
Copy link

c2vi commented May 29, 2025

about clarifying: let me try...

the "vEthernet (WSL)" is the name of the Interface on windows through which packets to the wsl VM should go out/come in.
the "WSL switch: 192.168.100.1" is an extra ip you assign on the "vEthernet (WSL)" (which then has two ips the "172.x.x.x" one and this custom 192.168.100.1 (which can be arbitrary))
the "WSL guest: 192.168.100.2" is the extra ip in the same "192.168.100.0/24" network which you assign in linux to the interface "eth0" (which is the interface through which packets to/from windows should go through). this "eth0" interface then also has 2 ips 192.168.100.2 and the hardcoded 172.x.x.x
the udp forwarding is then setup through this manually created "192.168.100.0/24" network which on the windows side you give the name "WSL-NAT" (on linux i don't think networks have names associated with them....)

let me know if this helps,
hope what i wrote here is correct....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment