CONTENT
Where the module is installed?
How does it work?
WSL2 Configuration Requirements
What happens during WSL Instance startup?
What happens when WSL Hyper-V Network Adapter is being setup?
How to deactivate this module?
How to completely remove this module?
This project is an attempt to address WSL networking issues that can be viewed in details in numerous posts over several long standing issues at WSL project. Here are a couple of them:
Main points of frustration are:
-
WSL SubNet is changing after every Windows system reboot varying within wide range of Private IPv4 addresses:
172.16.0.0/12, 192.168.0.0/16, 10.0.0.0/8
. -
All running WSL Instances have the same random IP address within WSL SubNet although default SubNet prefix length for some reason is 16 (which is enough for 65538 ip addresses!).
-
There is no documented way to control IP address of WSL network adapter and / or of a specific WSL instance.
WSL IP Handler is a Powershell Module which puts together several of the "fixes" / scripts that have been posted over time in the issues mentioned above and aims to provide easy, percistant and automated control over:
-
IPv4 properties of vEthernet (WSL) network adapter.
-
IP addresses assignments within WSL SubNet to WSL instances.
-
DNS resolution for Windows host and WSL instances within WSL SubNet.
In other words what WSL should have been doing out-of-the-box.
-
Windows 10.
Please be aware that the module is not being tested to work on Windows 11. Which does not mean it will not work, but since Windows 11 introduced new WSL features this might affect how the module operates.
-
PowerShell 7.1+.
-
WSL 2 enabled / installed.
This module is not being tested to work with WSL 1
-
Administrative access on the windows machine, where the module will be used.
-
Ubuntu or Fedora family OS as WSL instance.
Other versions might work, but the module is being tested only with the above two.
-
Unicode UTF-8 support enabled in Windows Settings.
To download and copy the module to Modules folder of Powershell profile for Current User run the following commands from Powershell prompt:
Command below will download the installation script and will prompt you to choose whether to use git.exe
(if git
can be found in PATH
) or use zippied repository:
Invoke-WebRequest https://raw.githubusercontent.com/wikiped/Wsl-IpHandler/master/Install-WslIpHandlerFromGithub.ps1 | Select -ExpandProperty Content | Invoke-Expression
Otherwise you can use any of the below two methods to install the module.
New-Item "$(split-path $Profile)\Modules" -Type Directory -ea SilentlyContinue
cd "$(split-path $Profile)\Modules"
git clone https://github.com/wikiped/Wsl-IpHandler
New-Item "$(split-path $Profile)\Modules" -Type Directory -ea SilentlyContinue
cd "$(split-path $Profile)\Modules"
Invoke-WebRequest -Uri https://codeload.github.com/wikiped/Wsl-IpHandler/zip/refs/heads/master -OutFile 'Wsl-IpHandler.zip'
Expand-Archive -Path 'Wsl-IpHandler.zip' -DestinationPath '.'
Remove-Item -Path 'Wsl-IpHandler.zip'
Rename-Item -Path 'Wsl-IpHandler-master' -NewName 'Wsl-IpHandler'
After executing above commands in How to get this module the module is installed in a Powershell profile directory for the current user.
Run Split-Path $Profile
to see location of the profile directory.
When Import-Module SomeModule
command is executed, Powershell looks for SomeModule
in this directory (among others).
It is important to be aware of the fact that WSL2 does not yet support windows network shares within linux, so if the module is installed on a network share it will NOT be working correctly. To mitigate this issue the module checks where it is installed and warns the user of the problem.
When WSL IP Handler is activated (with Install-WslIpHandler
command) it stores required network configuration in ~\.wsl-iphandler-config
file. This configuration is then used by Powershell scripts on Windows host and Bash scripts on WSL Instance where it has been activated to ensure IP Addresses determinism.
There are two ways how IP Address persistance of WSL Hyper-V Network Adapter can be achieved with this module:
-
On-Demand: The adapter is created (if it is not present) or modified (if was created beforehand by Windows) to match the required network configuration when the user runs
wsl
command through Powershell session. -
On-Logon: The adapter is created by a Scheduled Task that runs on user logon. This way the user does not have to use Powershell (interactively) to ensure WSL adapter's network configuration matches required.
The following sections describe which files are modified (outside of module's directory) on Windows host and WSL instance(s).
WSL uses two configuration files:
-
~/.wslconfig
on Windows -
/etc/wsl.conf
on Linux
Wsl-IpHandler module requires default configuration of some of the settings of /etc/wsl.conf
to work correctly (settings below do not have to be present in the file!):
[interop]
enabled = true
appendWindowsPath = true
[automount]
enabled = true
[network]
generateResolvConf = true
On Windows side in ~\.wslconfig
there is one setting which has side effect on WSL2 networking and which affects this module operation:
[wsl2]
swap = ...
The problem appears when swap setting is enabled and the swap file in use is using NTFS compression.
This is a known WSL2 issue (#4731, #5286, #5336, #5437) causing linux eth0
interface to be in a DOWN
state when WSL instance starts. This makes the WSL network unavailable and hence the module non-operational.
The solution to this problem is to either disable swap or disable NTFS compression on a swap file. This module by default opts for disabling swap in .wslconfig
:
[wsl2]
swap = 0
For these reasons the module validates WSL configuration both on windows side and linux side to ensure correct behavior.
- File modified during module activation:
~\.wsl-iphandler-config
- File modified (if necessary) during module activation:
~\.wslconfig
- File modified (optionally) during module activation:
$Profile.CurrentUserAllHosts
(Powershell Profile file) - File modified (if necessary) during startup of WSL Instance:
%WINDOWS%\System32\Drivers\etc\hosts
- New file created during module activation:
/usr/local/bin/wsl-iphandler.sh
- New file created during module activation:
/etc/profile.d/run-wsl-iphandler.sh
- New file created during module activation:
/etc/sudoers.d/wsl-iphandler
- New file created during module activation:
/etc/wsl-iphandler.conf
- File modified (if necessary) during module activation:
/etc/wsl.conf
- File modified (if necessary) during startup of WSL Instance:
/etc/hosts
Files modified during Module Activation
- Bash scripts are copied to the specified WSL Instance and
/etc/wsl-iphandler.conf
file is used to save Windows host name. - Network configuration parameters are saved to
~\.wsl-iphandler-config
on Windows host:- In Static Mode if WSL Instance IP address is not specified - the first available IP address will be selected automatically;
- In Dynamic Mode IP address offset (1-254) will be selected automatically based on those already used (if any) or 1;
- Powershell profile file is modified (if not opted out) to ensure on demand availability of WSL Hyper-V Network Adapter with required configuration.
- New Scheduled Task created (optionally) to ensure WSL Hyper-V Network Adapter is configured at logon.
When wsl
alias is executed from Powershell prompt:
- All arguments of the call are checked for presence of "informational" parameters (i.e. those parameters that do not require launch (initialization) of WSL Instance).
- If present:
wsl.exe
is executed with all arguments passed 'as is'.
- Otherwise:
~\.wsl-iphandler-config
is checked for Gateway IP Address:- If found - Static Mode detected:
- If WSL Hyper-V Adapter is present - it is checked to have network properties matching those saved during activation. If there is a mismatch - adapter is removed and new one created.
- If adapter is not present - it is created.
- If found - Static Mode detected:
wsl.exe
is executed with all arguments passed 'as is'.
- Before starting
wsl.exe
and after WSL Network Adapter had to be created the module will poll forvEthernet (WSL)
Network Connection availability every 3 seconds and when network connection becomes available then actually invokewsl.exe
. There is a timeout of 30 seconds to wait for the connection to become available. - If
vEthernet (WSL)
Network Connection is not available after specified Timeout (30 seconds by default) Exception will be thrown. - Timeout can be changed by setting
-Timeout
parameter:wsl -Timeout 60
.
- If present:
Note that
wsl
command (not the same aswsl.exe
) in this section refers to Powershell Alias that is created by this module and which is available only when this module is imported into current Powershell session, either manually or automatically through modified Powershell profile.
When Install-WslIpHandler
is executed with parameter -UseScheduledTaskOnUserLogOn
the module creates a new Scheduled Task named Wsl-IpHandlerTask
under Wsl-IpHandler
folder. The task has a trigger to run at user logon.
If parameter -AnyUserLogOn
was specified to Install-WslIpHandler
(along with -UseScheduledTaskOnUserLogOn
) then the task will run at logon of ANY user. Otherwise the task will run only at logon of specific user - the one who executed Install-WslIpHandler
command.
Since Scheduled Task runs the script in non-interactive mode in a hidden terminal window there will be no usual messages from the script. To be informed of the success/failures during execution of Scheduled Task there are Toast Notifications which are enabled by default when Install-WslIpHandler
is executed with parameter -UseScheduledTaskOnUserLogOn
. To disable toast notifications run Set-WslScheduledTask
without -ShowToast
parameter. See Get-Help Set-WslScheduledTask
for more information.
Note that it takes some time for Windows to execute its startup process (including logon tasks among other things). So it will take some time before WSL Hyper-V Network Adapter will become available.
IP Address handling at WSL instance's side is done with user's profile file modification. Therefore it will not work when WSL instance has been launched after wsl.exe --shutdown
with a command like this: wsl ping windows.host
(which is an example of non-interactive session). The reason for this is that Bash does not execute user's profile script in non-interactive sessions.
In all other cases when wsl
is executed to open a terminal (i.e. interactive session) profile script will run:
- Bash script
wsl-iphandler.sh
will be executed to:- Add WSL Instance IP address to eth0 interface. In Dynamic Mode IP address is obtained first from IP offset and Windows Host gateway IP address.
- Add Windows host gateway IP address to
/etc/hosts
if not already added. - Run Powershell script on Windows host to add WSL Instance IP address with its name to Windows
hosts
if not already added.
A workaround to ensure execution of profile script in non-interactive Bash session is to run command like this (from Powershell):
wsl.exe -e env BASH_ENV=/etc/profile bash -c 'ping windows.host'
Regardless of whether the module operates in On-Demand or On-Logon mode there a several steps taken to ensure the adapter is properly configured:
-
Check if the adapter exists and is already configured as required. If yes - nothing is done.
-
If the adapter does not exist yet or is mis-configured - it is removed (
wsl --shutdown
is executed beforehand). -
Check if there are any other network connections having IP network configuration that overlaps (conflicts) with the one specified for WSL adater (through parameters or from
~\.wsl-iphandler-config
file). -
If there are conflicts and overlapping network is from one of Hyper-V adapters (
Ethernet
orDefault Switch
) - conflicting adapter will be recreated to take IP network subnet that does not conflict with WSL Adapter. -
Any other conflicting network will cause the module to throw an error and it is up to the user to either choose a different IP Subnet for WSL adapter of reconfigure IP settings of conflicting network connection.
-
When no conflicts are found (or they have been resolved) WSL adapter is created.
By default, if Static mode of operation has been specified, activation script will modify Powershell profile file (by default $Profile.CurrentUserAllHosts). The only thing that is being added is wsl
command alias. Actual command that will be executed is Invoke-WslExe
. If modification of the profile is not desirable there is a parameter -DontModifyPsProfile
to Install-WslIpHandler
command to disable this feature.
To modify / restore profile manually at any time there is Set-ProfileContent
and Remove-ProfileContent
commands to add or remove modifications.
Created alias works ONLY from within Powershell sessions with user profile loading enabled (which is the default behavior).
See Execution of command alias for details on what happens when it is executed.
Profile modification takes effect after Powershell session restarts!
WSL IP Handler operates in two modes:
- Dynamic
- Static
Mode selection is based on configuration parameters provided when running activation command Install-WslIpHandler
.
In table below No
- means Parameter NOT specified
and Yes
- means Parameter has some value specified
):
🡇 Parameter ⋰ Mode 🡆 | Dynamic | Static | Invalid |
---|---|---|---|
GatewayIpAddress | No | Yes | No |
WslInstanceIpAddress | No | Yes | No | Yes |
Available capabilities depend on the Mode of operation:
🡇 Feature ⋰ Mode 🡆 | Dynamic | Static |
---|---|---|
Static WSL Network Adapter IP Address | No | Yes |
Static WSL Instance IP Address | No | Yes |
Unique IP Address of WSL Instance | Yes | Yes |
DNS Records | Yes | Yes |
In Static mode WSL IP Handler creates or replaces (if necessary) WSL Hyper-V Network adapter with properties specified during module activation.
In Dynamic mode WSL IP Handler does not interfere with how Windows manages WSL network properties.
-
Import Module.
Import-Module Wsl-IpHandler
All commands that follow below require that the module has been imported with above command.
-
Activate Module.
-
Activate in Dynamic Mode:
Install-WslIpHandler Ubuntu
-
Activate in Static Mode:
To get WSL Instance IP address assigned automatically:
Install-WslIpHandler -WslInstanceName Ubuntu -GatewayIpAddress 172.16.0.1
To assign static IP address to WSL Instance manually:
Install-WslIpHandler -WslInstanceName Ubuntu -GatewayIpAddress 172.16.0.1 -WslInstanceIpAddress 172.16.0.2
-
Activate in Static Mode without modifying Powershell profile
Install-WslIpHandler -WslInstanceName Ubuntu -GatewayIpAddress 172.16.0.1 -WslInstanceIpAddress 172.16.0.2 -DontModifyPsProfile
-
Activate in Static Mode without modifying Powershell profile and enabling WSL adapter setup during logon
Install-WslIpHandler -WslInstanceName Ubuntu -GatewayIpAddress 172.16.0.1 -WslInstanceIpAddress 172.16.0.2 -UseScheduledTaskOnUserLogOn -DontModifyPsProfile
-
-
Use WSL Instance.
Execute from Powershell prompt:
(Feel free to reboot the computer or execute
Remove-WslNetworkAdapter
beforehand to see that the changes are persistent after system reboot)wsl -d Ubuntu
From shell prompt within WSL Instanace of Ubuntu:
> ping -c 1 windows PING windows (172.16.0.1) 56(84) bytes of data. 64 bytes from windows (172.16.0.1): icmp_seq=1 ttl=128 time=0.417 ms --- windows ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.417/0.417/0.417/0.000 ms
From Powershell in Windows Host:
> ping -n 1 Ubuntu Pinging Ubuntu [172.16.0.2] with 32 bytes of data: Reply from 172.16.0.2: bytes=32 time<1ms TTL=64 Ping statistics for 172.16.0.2: Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0ms
-
Do I have to use Powershell to benefit from this module?
If Powershell is not part of day-to-day use it is still possible to benefit from this module's features.
Powershell is needed to 1) install (i.e. download) and 2) activate the module for all WSL instances where IP address control is required.
For this to work the module has to be activated with two switch parameters to Install-WslIpHandler
:
Install-WslIpHandler <...other parameters...> -DontModifyPsProfile -UseScheduledTaskOnUserLogOn
This will setup WSL Hyper-V Network Adapter configuration during user logon, without any need to use Powershell to start any WSL instance.
From Powershell prompt execute:
Uninstall-WslIpHandler -WslInstanceName Ubuntu
If WSL Instance being removed had Static IP address and it is the only one remaining all network configuration settings (Windows Host Name and Gataway IP Address) will also be removed along with Scheduled Task and Powershell profile modifications.
Even after Wsl-IpHandler was deactivated on all WSL instances WSL Hyper-V Network Adapter will remain active until next reboot or manual removal with Remove-WslNetworkAdapter
command.
To update this module to the latest version in github repository run in Powershell prompt:
Update-WslIpHandlerModule
Before completely removing the module it is recommended to make sure the module has been deactivated on all WSL instances.
To remove the module - delete the module's folder. It's location can be checked with:
(Import-Module Wsl-IpHandler -PassThru | Get-Module).ModuleBase
Or execute from Powershell prompt:
Import-Module Wsl-IpHandler
Uninstall-WslIpHandlerModule
Run / Execute command:
control international
Then in the opened window select tab: Administrative -> Change system locale...
Select option Beta: Use Unicode UTF-8 for worldwide language support
in the opened window.
To see list of all available commands from this module, execute in Powershell::
Get-Command -Module Wsl-IpHandler
To get help on any of the commands, execute Get-Help <Command-Name>
, i.e.:
Get-Help Install-WslIpHandler
To get help on a particular parameter of a command add -Parameter <ParameterName>
, i.e.:
Get-Help Install-WslIpHandler -Parameter UseScheduledTaskOnUserLogOn
This module is using the code (sometimes partially or with modifications) from the following projects (in no particular order):
Create a known IP address for WSL2 VM by Biswa96
wsl2-custom-network by Sami Korhonen
wsl2ip2hosts by Jakob Wildrain
PsIni by Oliver Lipkau
IP-Calc by saw-friendship