Open-source project
sakai135/wsl-vpnkit avatar
sakai135/wsl-vpnkit

wsl-vpnkit: WSL 2 networking when a Windows VPN blocks it

Provides network connectivity to WSL 2 when blocked by VPN

2,966 stars213 forksShellMIT

At a glance

What is it?
wsl-vpnkit restores network connectivity inside WSL 2 when a Windows VPN breaks it, without administrator rights or Windows-side changes. It ships as an importable distro or a standalone script, and it is a fallback for cases where mirrored mode and .wslconfig options do not help.
Who is it for?
Adopt wsl-vpnkit when ping 1.2.3.4 fails inside WSL 2 after connecting a Windows VPN and mirrored mode or .wslconfig options have not fixed it, and when you cannot or will not change Windows settings. Do not adopt it if the ping succeeds, since the README points those users to the Microsoft troubleshooting page instead, or if you cannot run Windows executables from your distro, because wsl-gvproxy.exe must execute.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The failure wsl-vpnkit targets: WSL 2 with no route once the VPN is up

Connect a Windows VPN and WSL 2 can lose connectivity entirely. The README frames the project around exactly that symptom, and it is careful about scope: before installing anything, it tells you to run ping 1.2.3.4 inside WSL 2. If that ping succeeds, wsl-vpnkit is not the answer, and the README points to the Microsoft troubleshooting page for "WSL has no network connectivity once connected to a VPN" instead. The project is for the remaining cases, where WSL 2 networking options such as mirrored mode and other .wslconfig settings do not resolve the issue.

The stated constraints are what make it interesting. It requires no changes to Windows settings and no administrator privileges on the Windows host, which matters on managed machines where both are out of reach. It is a workaround, not a networking stack replacement, and the README treats it as the last step in a sequence rather than the first.

How wsl-vpnkit restores the route: gvproxy, a TAP interface and the gateway IP

The mechanism visible in the repository is a small set of cooperating pieces. The wsl-vpnkit shell script is the entry point. It calls wsl-gvproxy.exe, a Windows executable run from inside the distro through WSL interop, and wsl-vm, which handles interface creation depending on the PREEXISTING setting. The script also needs to know the WSL 2 gateway IP, which it normally reads from /mnt/wsl/resolv.conf, and the interface used to restore the default route, taken from the detected route or falling back to eth0.

The PREEXISTING variable describes the split. When it is 1 (the default), wsl-vpnkit creates and configures a TAP interface itself. When it is 0, wsl-vm creates the interface and configures it with DHCP, and that mode is what the example config file pairs with GVPROXY_CONFIG. So the data flow is: a Windows-side proxy process, a TAP interface inside WSL 2, and a default route pointed at that interface, with the gateway address discovered from WSL's own resolver configuration. The repository layout reflects this, with the wsl-vpnkit script, wsl-vpnkit.service, wsl-vpnkit.yaml and a distro/ directory at the top level.

Installing wsl-vpnkit as a distro and starting it

Option A is the distro install. Download wsl-vpnkit-amd64.wsl, or wsl-vpnkit-arm64.wsl on ARM64, from the latest release and open it to import the distro into WSL 2. The advantage the README gives is concrete: this path lets you start wsl-vpnkit even when your existing distro has no network connectivity, which is the situation you are probably in.

Start it in the foreground with:

sh
wsl.exe -d wsl-vpnkit --cd /app wsl-vpnkit

If the import fails because your WSL release predates support for importing .wsl distro files, the README gives a PowerShell fallback. Support for that import was added in WSL release 2.4.4:

pwsh
wsl --import wsl-vpnkit "$env:USERPROFILE\wsl-vpnkit" wsl-vpnkit.wsl --version 2

The destination folder is $env:USERPROFILE\wsl-vpnkit, and you replace wsl-vpnkit.wsl with the path to the downloaded file. To update the distro install, unregister the existing distro and open the new file:

sh
wsl.exe --unregister wsl-vpnkit

Running the standalone script in an existing distro

Option B installs the script into a distro you already use. The README gives an Ubuntu example that installs dependencies, downloads the .wsl package, unpacks the needed files and moves them into /usr/local/bin:

sh
sudo apt-get install iproute2 iptables iputils-ping dnsutils curl jq yq
curl -fL https://github.com/sakai135/wsl-vpnkit/releases/latest/download/wsl-vpnkit-amd64.wsl -o wsl-vpnkit.wsl
tar --strip-components=1 -xf wsl-vpnkit.wsl app/wsl-vpnkit app/wsl-vpnkit.yaml app/wsl-gvproxy.exe app/wsl-vm app/wsl-vpnkit.service
rm wsl-vpnkit.wsl
sudo mv wsl-vpnkit wsl-gvproxy.exe wsl-vm /usr/local/bin/
sudo wsl-vpnkit

After that, the script runs in the foreground. The same section shows the optional systemd setup, moving wsl-vpnkit.service into /etc/systemd/system/ and enabling it with systemctl enable and systemctl start. In the distro install, the service file is copied out of the distro first:

sh
wsl.exe -d wsl-vpnkit --cd /app cat /app/wsl-vpnkit.service | sudo tee /etc/systemd/system/wsl-vpnkit.service
sudo systemctl enable wsl-vpnkit
sudo systemctl start wsl-vpnkit
systemctl status wsl-vpnkit

Configuration is environment-variable driven. DEBUG set to 1 enables debug output. CHECK_HOST defaults to host.containers.internal and is used by startup DNS diagnostics. GVPROXY_PATH and VMEXEC_PATH point at the executables. GVPROXY_CONFIG is disabled by default and expects a gvproxy YAML file, which requires yq. For the full list the README points at the wsl-vpnkit script itself, which is the honest answer: the table is a summary, not the contract.

The interop requirement is the sharpest limitation

wsl-vpnkit requires the WSL 2 distro to be able to run Windows executables, because wsl-gvproxy.exe is a Windows binary. The README states that the interop setting is enabled by default in WSL 2 and in the wsl-vpnkit distro, but it also documents the failure: a cannot execute binary file: Exec format error message. The check is whether /usr/lib/binfmt.d/WSLInterop.conf exists. If it does not, the README gives the fix:

sh
sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'
sudo systemctl restart systemd-binfmt

There is a second, Windows-side failure mode. Security configurations on the host may only permit running executables in certain directories. The README's answer is to copy wsl-gvproxy.exe somewhere permitted and point GVPROXY_PATH at it, which also requires enabling automount in the wsl-vpnkit distro's wsl.conf:

sh
wsl.exe -d wsl-vpnkit --cd /app sed -i -- "s/enabled=false/enabled=true/" /etc/wsl.conf
wsl.exe -d wsl-vpnkit --cd /app GVPROXY_PATH=/mnt/c/path/wsl-gvproxy.exe wsl-vpnkit

That is a real constraint: a distro with interop disabled, or a host policy that blocks execution from the wrong path, breaks the tool before any networking question is reached. The resolv.conf diagnostic is a third. wsl-vpnkit normally reads /mnt/wsl/resolv.conf for the gateway IP. If you set a custom DNS configuration by editing /etc/resolv.conf, the README says to set generateResolvConf=false in wsl.conf, and on older WSL versions where /mnt/wsl/resolv.conf is unavailable it falls back to /etc/resolv.conf. In the standalone setup with a custom DNS configuration, you are expected to set WSL2_GATEWAY_IP yourself. Nothing in the README suggests these are avoidable; they are the cost of doing this from inside the distro without touching Windows.

Where mirrored mode and the Microsoft guidance fit

The most useful comparison is not another tool but the built-in path wsl-vpnkit deliberately steps around. WSL 2 networking options, including mirrored mode, and other .wslconfig options may resolve the connectivity problem, and the README says to try them first. Those options are configuration on the Windows side; wsl-vpnkit is a userspace workaround that runs inside the distro and needs no Windows changes and no administrator rights. The trade is that you are now maintaining a proxy process, a TAP interface and a default route inside WSL, plus a systemd unit if you want it to start automatically, in exchange for not touching the host.

The README also lists a VS Code note: if the Remote WSL extension takes a long time to open a folder, enable the setting "Connect Through Localhost". That is the kind of integration detail that tells you what this tool sits between. If mirrored mode works in your environment, use it. wsl-vpnkit exists for the environments where it does not.

Maintenance, updates and the MIT licence

The repository is not archived, and the last push was on 2026-09-23, one day before this writing, with releases v0.4.5 on 2026-09-01, v0.4.4 on 2026-08-19 and v0.4.3 on 2026-08-05. That is a recent cadence, but the README makes one upgrade cost explicit: updating the distro install means unregistering the wsl-vpnkit distro and importing the new .wsl file, which resets that distro. The standalone script path avoids that, but it puts the update burden on you, since the files are unpacked from the release archive by hand.

The licence is MIT, which permits use, modification and redistribution with the licence and copyright notice retained. That is a statement about the licence text, not advice about your situation; if you redistribute the bundled Windows executable, check the terms that apply to it separately, because the repository does not state which components carry which notice beyond the repository-level LICENSE file.

Editorial conclusion

Adopt wsl-vpnkit when ping 1.2.3.4 fails inside WSL 2 after connecting a Windows VPN and mirrored mode or .wslconfig options have not fixed it, and when you cannot or will not change Windows settings. Do not adopt it if the ping succeeds, since the README points those users to the Microsoft troubleshooting page instead, or if you cannot run Windows executables from your distro, because wsl-gvproxy.exe must execute. Verify first that /usr/lib/binfmt.d/WSLInterop.conf exists, that /mnt/wsl/resolv.conf is readable or WSL2_GATEWAY_IP is set, and that your WSL release supports importing .wsl files, or plan to use the wsl --import fallback shown in the README.

Frequently asked questions

What does wsl-vpnkit do?

It provides network connectivity for WSL 2 when a Windows VPN blocks access, without changes to Windows settings or administrator privileges on the Windows host. It runs a proxy and sets up a TAP interface and default route inside the distro.

How do I install wsl-vpnkit?

Download wsl-vpnkit-amd64.wsl or wsl-vpnkit-arm64.wsl from the latest release and open it to import the distro, or install the wsl-vpnkit script into an existing distro by unpacking the release archive. The README gives an Ubuntu example for the standalone path.

How do I use wsl-vpnkit?

Run wsl.exe -d wsl-vpnkit --cd /app wsl-vpnkit to start it in the foreground, or copy the service file into your distro and enable it with systemctl. Configuration is done through environment variables such as DEBUG, GVPROXY_PATH and WSL2_GATEWAY_IP.

What is wsl-vpnkit?

It is a tool that restores WSL 2 network connectivity when a Windows VPN blocks it, intended for cases where mirrored mode and other .wslconfig options do not work. It requires no Windows settings changes and no administrator rights on the host.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sakai135/wsl-vpnkit on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sakai135-wsl-vpnkit.svg)](https://hysenlabs.com/projects/sakai135-wsl-vpnkit)