WSL2 uses Hyper-V for networking. The WSL2 network settings are ephemeral and configured on demand when any WSL2 instance is first started in a Windows session. The configuration is reset on each Windows restart and the IP addresses change each time. The Windows host creates a hidden switch named "WSL" and a network adapter named "WSL" (appears as "vEthernet (WSL)" in the "Network Connections" panel). The Ubuntu instance creates a corresponding network interface named "eth0".
Assigning static IP addresses to the network interfaces on the Windows host or the WSL2 Ubuntu instance enables support for the following scenarios:
- Connect to an Ubuntu instance from the Windows host using a static IP address
- Connect to the Windows host from an Ubuntu instance using a static IP address
This guide assumes PowerShell 7 and:
Variable | Value |
---|---|
WSL distribution | Ubuntu 20.04 |
WSL instance name | Ubuntu-20.04 |
Windows host IP address | 192.168.2.1 |
Ubuntu instance IP address | 192.168.2.2 |
Network subnet (subnet mask) | 192.168.2.0/24 (255.255.255.0) |
Note It's best to pick a subnet in the private address range.
Configure connectivity from the Windows host to the Ubuntu instance:
-
Assign the Ubuntu instance IP address to the "eth0" network interface in Ubuntu (after every restart).
sudo ip address add 192.168.2.2/24 brd + dev eth0
Configure connectivity from the Ubuntu instance to the Windows host:
-
Add a Windows firewall allow rule (once only).
The "vEthernet (WSL)" network interface uses the "Public" Windows network profile so all traffic from the Ubuntu instance to the host is blocked by default. Allow all inbound traffic from the "vEthernet (WSL)" network interface.
# Requires "Run as Administrator" New-NetFirewallRule -Name 'WSL' -DisplayName 'WSL' -InterfaceAlias 'vEthernet (WSL)' -Direction Inbound -Action Allow
Note Any existing rules blocking inbound traffic for applications on the Windows host will take precedence over this rule, so remove or disable these where required. Such rules can be created automatically by Windows when an application is first run. Windows shows the user a UAC modal asking for permission to create a firewall rule.
-
Assign the Windows host IP address to the "WSL" network interface in Windows (after every restart).
# Requires "Run as Administrator" New-NetIPAddress -InterfaceAlias 'vEthernet (WSL)' -IPAddress '192.168.2.1' -PrefixLength 24
All the steps above in a PowerShell script.
$WslInstanceName = 'Ubuntu-20.04'
$WindowsHostIPAddress = '192.168.2.1'
$UbuntuInstanceIPAddress = '192.168.2.2'
$SubnetMaskNumberOfBits = 24
$WslFirewallRuleName = 'WSL'
$WslNetworkInterfaceName = 'vEthernet (WSL)'
$UbuntuNetworkInterfaceName = 'eth0'
# Ensure the "vEthernet (WSL)" network adapter has been created by starting WSL.
Write-Host 'Ensure WSL network exists...'
wsl --distribution "$WslInstanceName" /bin/false
Write-Host 'WSL network exists'
# All inbound traffic from Ubuntu through Windows firewall and assign a static IP address to the "vEthernet (WSL)"
# network adapter in Windows.
Write-Host 'Configuring Windows host network...'
Start-Process 'pwsh' -Verb RunAs -Wait -ArgumentList '-ExecutionPolicy Bypass', @"
-Command & {
Write-Host 'Checking firewall...'
If (-Not (Get-NetFirewallRule -Name '$WslFirewallRuleName' -ErrorAction SilentlyContinue)) {
Write-Host 'Configuring firewall...'
New-NetFirewallRule -Name '$WslFirewallRuleName' -DisplayName '$WslFirewallRuleName' -InterfaceAlias '$WslNetworkInterfaceName' -Direction Inbound -Action Allow
Write-Host 'Finished configuring firewall'
}
Else {
Write-Host 'Already configured firewall'
}
Write-Host 'Checking network interface...'
If (-Not (Get-NetIPAddress -InterfaceAlias '$WslNetworkInterfaceName' -IPAddress '$WindowsHostIPAddress' -PrefixLength $SubnetMaskNumberOfBits -ErrorAction SilentlyContinue)) {
Write-Host 'Configuring network interface...'
New-NetIPAddress -InterfaceAlias '$WslNetworkInterfaceName' -IPAddress '$WindowsHostIPAddress' -PrefixLength $SubnetMaskNumberOfBits
Write-Host 'Finished configuring network interface'
}
Else {
Write-Host 'Already configured network interface'
}
}
"@
Write-Host 'Finished configuring Windows host network'
# Assign a static IP address to the "eth0" network interface in Ubuntu.
Write-Host 'Configuring Ubuntu instance network...'
wsl --distribution "$WslInstanceName" --user root /bin/sh -c "if !(ip address show dev $UbuntuNetworkInterfaceName | grep -q $UbuntuInstanceIPAddress/$SubnetMaskNumberOfBits); then ip address add $UbuntuInstanceIPAddress/24 brd + dev $UbuntuNetworkInterfaceName; fi"
Write-Host 'Finished configuring Ubuntu instance network'
Hello,
Thank you for pointing me in the right direction.
Based on your solution I managed to have a persistent like configuration to set a static IP range even after host reboot.
What I did was :
I added a new IP adress (192.168.123.1) to vEthernet WSL using netsh command (Admin prompt)
I changed the wsl config by setting the "generateResolvConf" to false in /etc/wsl.conf
I deleted the generated /etc/resolv.conf and I created a new one with my DNS servers (and I used a chattr +i /etc/resolv.conf to make sure it will stay the same)
I added a new IP adress to my wsl distribution using these commands :
I persisted the changes by :
The first one launches a wsl -d $distro --user root bash -c 'ping -c 1 -W 1 8.8.8.8' in order to initialize vEthernet WSL after reboot (should be basedon the user that has access to the distros)
The second one was done based on the "system" user to execute a netsh command to add the IP adress to vEthernet WSL, and it is executed right after the first one.
This configuration allowed me to change the IP adress to a range of my choice and have these changes persist.
Overall, it wasn't that easy to do, so let's hope Microsoft adds the customization of the IP range as a feature in future WSL2 releases.