Skip to content

Troubleshoot WSL2 Networking with VPNs

WSL 2 networking uses a virtualized Linux environment. NAT is the default in many installations; mirrored mode is available on Windows 11 22H2 and later and can improve compatibility with VPNs and localhost connections. DNS tunneling can also help WSL use Windows DNS policy. Record Windows and WSL versions before changing settings because available options vary by version.

This guide changes only your per-user WSL settings. Back up any existing .wslconfig file and merge the example settings instead of replacing unrelated entries. Running wsl --shutdown stops all running distributions.


01

Check Versions and Reproduce One Failure

Baseline

From PowerShell, record the WSL version and distribution state. In the affected Linux distribution, test one public hostname and one approved internal hostname while connected to the VPN. Do not include private names or addresses in screenshots or public support posts.

Terminal window
wsl --version
wsl --status
wsl --list --verbose
Terminal window
getent hosts example.com
getent hosts internal.example.com
❯ Illustrative Output (Results Vary)
NAME STATE VERSION
Ubuntu Running 2
<hostname lookup returns one or more addresses>

02

Determine Whether DNS Is the Failing Layer

DNS Check

Use the same approved hostname in Windows and WSL. If Windows resolves it but WSL does not, check DNS tunneling and VPN policy. WSL manages the generated /etc/resolv.conf in common configurations; avoid hard-coding a public resolver for a corporate name.

Terminal window
Resolve-DnsName internal.example.com
Terminal window
cat /etc/resolv.conf
getent hosts internal.example.com
❯ Illustrative Output (Results Vary)
Windows: internal.example.com resolved
WSL: compare the result and error

03

Enable Mirrored Mode and DNS Tunneling

Configuration

On Windows 11 22H2 or later, open %UserProfile%.wslconfig in a text editor. Back up the file first, then merge these settings into its existing [wsl2] section. If the file has no such section, add it. DNS tunneling is enabled by default in supported recent WSL versions, but can be specified explicitly. Inside the affected distro, inspect /etc/wsl.conf: DNS tunneling requires that generateResolvConf has not been disabled. If an older workaround set it to false or made /etc/resolv.conf immutable, back up and review that customization before restoring WSL-managed resolver generation.

[wsl2]
networkingMode=mirrored
dnsTunneling=true
Terminal window
wsl --shutdown
wsl --distribution Ubuntu
❯ Illustrative Output (Results Vary)
WSL restarts with the updated per-user configuration.
If the setting is unsupported, restore the previous .wslconfig and use NAT.

04

Retest One Name and One Local Service

Connectivity

Repeat the DNS query that failed, then test one expected VPN resource. To check Windows-to-WSL localhost forwarding, start a temporary server in WSL bound only to its loopback interface and request it from Windows. After the request completes, stop the server with Ctrl+C in the WSL terminal.

Terminal window
getent hosts internal.example.com
python3 -m http.server 8000 --bind 127.0.0.1
Terminal window
Invoke-WebRequest http://localhost:8000/ -UseBasicParsing
❯ Illustrative Output (Results Vary)
StatusCode: 200

05

Limit Any Inbound LAN Exception

Firewall

Most development does not require exposing WSL services to the local network. If a specific LAN client must reach a service in mirrored mode, first configure that service to listen on the intended interface; binding to 0.0.0.0 exposes it on all IPv4 interfaces. Run PowerShell as administrator, confirm the client’s source address with the network owner, and create a rule limited to that address, protocol, and port. Replace the documentation-only remote address below. Do not set the default inbound action to Allow.

Terminal window
New-NetFirewallHyperVRule -Name 'WSL-Dev-8000' `
-DisplayName 'WSL development server TCP 8000' `
-Direction Inbound `
-Action Allow `
-VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' `
-Protocol TCP -LocalPorts 8000 `
-RemoteAddresses '192.0.2.50' # Replace with the approved client IP.
❯ Illustrative Output (Results Vary)
Rule scope: inbound TCP 8000 from the approved remote address only
Use this only when LAN access is required and approved.

Comments