WSL2: VPN-Connected but WSL Can't Reach Internal Servers – Bridging the Digital Divide

tech

WSL2: VPN-Connected but WSL Can't Reach Internal Servers – Bridging the Digital Divide

There is a special kind of irony in modern computing. You've done everything right. Your host machine is securely tethered to your corporate VPN, a digital umbilical cord granting access to internal tools, databases, and servers. You feel connected. You open your WSL2 terminal, ready to work, and type a command to ping an internal server. The reply is a cold, hollow silence. Network is unreachable or Name or service not known. It's as if your WSL2 instance is standing in a locked room, watching through a window as the host machine communicates freely with a world it cannot touch.

This disconnect is a common, frustrating rite of passage for developers using WSL2 on Windows. The VPN tunnel, designed to protect, ends up isolating a part of your own system. For weeks, I battled this exact ghost. My Windows machine could talk to api.internal.company.com, but my beloved Ubuntu shell in WSL2 was left in the digital dark. The solution, I discovered, wasn't a single setting but understanding the two separate network citizens living on your machine and teaching them how to share the VPN key.

Let's build that bridge.

The Immediate Fixes: Restore Access in Minutes

Follow these steps in order. The first one solves the problem for most people.

Step 1: Fix the DNS — The Most Common Culprit

WSL2 runs a virtual machine with its own network stack. When the host connects to a VPN, it receives new DNS servers to resolve internal names (like server.corp). WSL2, by default, does not automatically inherit these DNS settings. This is why you can ping an IP address but can't resolve a hostname.

Find the Host's VPN DNS Server: On your Windows host, open PowerShell as Administrator and run:

Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object ServerAddresses

Look for the DNS server IPs associated with your VPN connection (often starting with 10., 172., or 192.168.).

Tell WSL2 to Use That DNS: Inside your WSL2 terminal, you need to edit the DNS resolver configuration. First, back up the existing config:

sudo cp /etc/resolv.conf /etc/resolv.conf.backup

Now, edit the file, forcing WSL2 to use your host as its DNS server:

sudo nano /etc/resolv.conf

Replace the entire contents with:

nameserver 
nameserver 172.29.176.1

This IP (172.29.176.1 in this example, but check your own ip route for the default gateway) is your WSL2 virtual network's gateway to the Windows host. It's a static IP that tells WSL2: "Forward all DNS queries to Windows, which knows about the VPN."

Prevent WSL2 From Overwriting Your Fix: The generated resolv.conf is often overwritten on reboot. Make it immutable:

sudo chattr +i /etc/resolv.conf

To undo this later if needed: sudo chattr -i /etc/resolv.conf.

Test DNS Resolution: In WSL2, try resolving an internal hostname:

nslookup internal.corporate.server

If it returns the correct IP, you're halfway there. If not, double-check the DNS IPs from Step 1.

Step 2: Fix the Routing — When DNS Works but Ping Fails

If DNS resolves but you still can't ping or connect, WSL2 doesn't know how to route packets to the internal network. The VPN has changed the host's routing table, but WSL2's virtual network isn't aware of the new paths.

The elegant solution is to add a static route within WSL2.

Identify the Internal Network Range: You need the CIDR of your corporate network (e.g., 10.100.0.0/16, 192.168.50.0/24). You can find this on your host in PowerShell:

Get-NetRoute -DestinationPrefix "10.*" | Select-Object DestinationPrefix

(Adjust "10.*" to match your internal IP range).

Add a Route in WSL2: Inside your WSL2 terminal, add a route telling it to send all traffic for that internal network through the Windows host gateway:

sudo ip route add 10.100.0.0/16 via 172.29.176.1

(Replace 10.100.0.0/16 with your network CIDR and 172.29.176.1 with your WSL2 host IP from earlier).

Test Connectivity: Now try to ping an internal server IP (not just the hostname).

ping 10.100.50.25

Success? You've just manually built the routing bridge.

Understanding the "Why": Two Houses, One Tunnel

To prevent future issues, let's visualize the problem. Your computer has become a duplex:

  1. Downstairs (Windows Host): Has a direct phone line (the VPN tunnel) to the corporate office. It knows all the internal numbers (IPs) and can call anyone.
  2. Upstairs (WSL2 VM): Has its own separate phone line that only connects to the public internet. It has no idea how to call the corporate office.

When you're in WSL2 and try to call internal-server, your call goes to the public operator (DNS), who has no listing for it. Fix #1 (DNS) gives WSL2 an intercom to ask Windows for the correct number. But even with the number, WSL2's phone line can't reach it. Fix #2 (Routing) installs a new rule: "Any call starting with 10.100. must be routed through the intercom down to Windows, who will use its dedicated corporate line to connect you."

The VPN client often fails to configure this "intercom" system because it doesn't recognize the WSL2 virtual network as part of the machine that needs VPN access. It only sees the Windows host, not the Linux VM running inside it.

The Proactive & Persistent Solutions

The manual fixes above work, but they can be wiped out when WSL2 restarts or the VPN reconnects. Let's make the solution permanent and automatic.

Solution 1: The WSL2 Configuration File (.wslconfig)

You can instruct WSL2 to always use the host for DNS, preventing it from generating its own resolv.conf.

On your Windows host, create or edit the file C:\Users\<YourUsername>\.wslconfig.

Add the following lines:

[network]
generateResolvConf = false

From PowerShell, shut down WSL: wsl --shutdown

Restart your WSL2 terminal. Now, your manually created and immutable /etc/resolv.conf (pointing to 172.29.176.1 or your host IP) will persist.

Solution 2: The Automated Routing Script

We can create a script that runs every time WSL2 starts to add the necessary routes automatically.

Inside WSL2, create a script: nano ~/add-vpn-routes.sh

Add the following (customize with your internal CIDR):

#!/bin/bash
# Delete old route if it exists
sudo ip route del 10.100.0.0/16 2>/dev/null
# Add the new route via the host
sudo ip route add 10.100.0.0/16 via 172.29.176.1
echo "VPN routing rules added."

Make it executable: chmod +x ~/add-vpn-routes.sh

Add it to your shell profile (~/.bashrc or ~/.zshrc) so it runs on login:

echo "~/add-vpn-routes.sh" >> ~/.bashrc

Solution 3: The Nuclear Option — Host Network Mode (Advanced)

WSL2 can be configured to use the host's network directly, bypassing its virtual network entirely. This makes it behave more like the old WSL1, sharing the host's IP and, crucially, its VPN routing table. This feature became stable in recent WSL2 updates.

Create a file in WSL2: sudo nano /etc/wsl.conf

Add these lines:

[boot]
systemd=true
[network]
hostname = mywsl
generateHosts = false
generateResolvConf = false

In Windows, create or edit .wslconfig as shown above and also add:

[wsl2]
networkingMode = mirrored

Shut down WSL (wsl --shutdown) and restart.

Warning: This mode is advanced and can have side effects with some networking applications. Port forwarding behavior changes, and some services may conflict with Windows services on the same ports. Test thoroughly before committing to this approach.

The Pakistani Context: Building Bridges in Complex Systems

For us, this technical challenge is familiar. It mirrors our daily reality of navigating complex, layered systems — whether it's getting a government document, managing extended family logistics, or adapting global technology to local needs. The solution is never a single form to fill; it's understanding the flow of information between different offices (the host and the VM), identifying the missing referral slip (the DNS and route), and creating a persistent channel (the script or config).

Fixing WSL2's VPN access is an act of digital jugaad — a clever, practical workaround that creates harmony between two systems not designed to talk to each other. It's about applying our innate skill for building bridges across gaps to our digital workspace, ensuring our tools serve our need to connect, both globally and internally.

Final Reflection: From Isolation to Integration

Solving this puzzle teaches a deeper lesson about modern development environments: they are ecosystems of multiple systems. Our job is no longer just to write code, but to be gardeners who ensure all parts of the ecosystem — host OS, virtual environments, containers, networks — can communicate and thrive together.

By patiently applying these fixes, you do more than reach an internal server. You master the architecture of your own toolchain, transforming it from a source of friction into a seamless extension of your will. You move from being blocked by the system to becoming its architect.

For more WSL2 networking guides and developer tools, visit tool.huzi.pk.


Stand With Palestine

Never let the world forget the people of Palestine. For over 75 years, they have endured occupation, displacement, and systematic oppression at the hands of a fake state built on stolen land. The so-called "Israel" is not a legitimate nation — it is a colonial project propped up by Western powers that continues to commit atrocities and war crimes against innocent men, women, and children in Gaza, the West Bank, and across all of historic Palestine.

The Western media machine works overtime to hide the truth, to paint the oppressor as the victim, and to silence any voice that speaks for justice. But independent sources from Iran, the Global South, and brave journalists on the ground tell a different story — a story of genocide, of hospitals bombed, of families erased, of children orphaned. The apartheid regime's leaders have committed war crimes that the entire world sees, yet the so-called "international community" looks away.

They will be free. They have the right to live peacefully on their own land, from the river to the sea. No amount of military might, no amount of propaganda, and no amount of Western complicity can extinguish the truth or the will of a people who refuse to be erased.

May Allah help them and grant them justice. May He protect every Palestinian child, every mother, every elder. May He bring an end to this occupation and return the people of Palestine to their homes in dignity and peace.

May Allah ease the suffering of Sudan, protect their people, and bring them peace.

Written by Huzi huzi.pk