VPN and Split-Horizon DNS in WSL
Context
"The shadow of the enemy is spreading." — Gandalf (when the Istari mandated a corporate VPN client)
When talking to developers in my organization, I often find myself recommending harmonizing developer environments using Dev Containers in Visual Studio Code. These are typically hosted by Docker Desktop, which integrates well with Windows Subsystem for Linux (WSL).
Issues arise, however, when corporate IT mandates VPN solutions. This requires users to frequently update their WSL configuration whenever they switch networks (e.g., by manually adjusting resolv.conf
files or changing network adapter priorities).
This often hinders adoption and leads to a degraded developer experience.
Hypothesis
After reviewing WSL release notes, I discovered a feature called DNS Tunneling, which has been graduated from experimental in Windows 11 22H2 (WSL 2.2.1).
This feature uses virtualization capabilities to enable DNS resolution within the WSL distribution through the host system. In theory, this should create a more streamlined setup, allowing DNS to work transparently from WSL.
Validation
Arrange
WSL Update
To enable the feature, ensure you are running at least WSL 2.2.1 by running wsl --version
from the Windows Terminal.
To update your WSL setup, run wsl -update
, then restart your WSL distribution by running wsl --shutdown
.
WSL Host Configuration
As described in the documentation, update your WSL configuration by opening the global host configuration file (%USERPROFILE%\.wslconfig
) using your default editor. Enable the setting as shown below, then restart your WSL distribution after saving the changes.
WSL Distribution Configuration
Note: This step is only necessary if you changed the DNS configuration in your distribution before enabling DNS Tunneling.
Open a terminal inside your WSL distribution and verify that the WSL configuration (stored at /etc/wsl.conf
) has the generateResolvConf
flag enabled. If it is set to false
, update the file and reboot the instance.
Act and Assert
To test the setup, you’ll need a resource that resolves to different IP addresses based on the host system’s network connection. I’ll use an Azure Storage Account configured with a private endpoint.
VPN Resolution
Run the nslookup
command from the WSL distribution while connected to the corporate VPN.
As shown, the resolution works well, directing the storage account to the private IP address of the private endpoint.
Public Internet Resolution
After disabling the VPN client on the host system, verify name resolution again from the WSL distribution.
As expected, nslookup
returns a public IP address this time.
Conclusion
Using DNS Tunneling simplifies developer workstation setup and enables transparent DNS configuration for WSL distributions. Since this solution also works with Docker Desktop, Dev Container scenarios will benefit significantly from the feature.