109

As far as I've been able to work out, the official process for changing which DNS server is used by WSL2 on Windows 10 is as detailed below. (WSL2 is the new release of the Windows Subsystem for Linux, which runs an actual Linux kernel in a lightweight VM on Windows 10.)

However, this process doesn't work for me - I end up with a system that simply times out and can't resolve any addresses whatsoever.

What am I doing wrong?

Here's the process as I've pieced it together so far:

1. Turn off generation of /etc/resolv.conf

Using your Linux prompt, (I'm using Ubuntu), modify (or create) /etc/wsl.conf with the following content

[network]
generateResolvConf = false

(Apparently there's a bug in the current release where any trailing whitespace on these lines will trip things up.)

2. Restart the WSL2 Virtual Machine

Exit all of your Linux prompts and run the following Powershell command

wsl --shutdown

3. Create a custom /etc/resolv.conf

Open a new Linux prompt and cd to /etc

If resolv.conf is soft linked to another file, remove the link with

rm resolv.conf

Create a new resolv.conf with the following content

nameserver 1.1.1.1

4. Restart the WSL2 Virtual Machine

Same as step #2

5. Start a new Linux prompt.

Profit!

Update March 18, 2020

My /etc/hosts file contains this:

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateHosts = false
127.0.0.1       localhost
127.0.1.1       [redacted]  bearps-desktop

10.168.244.140  host.docker.internal
10.168.244.140  gateway.docker.internal
127.0.0.1       kubernetes.docker.internal

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

The file /etc/switch.conf does not exist.

The tool resolvectl is not on my path; it doesn't exist at /usr/bin/resolvectl.

Likewise systemd-resolve is not on my path; it doesn't exist at /usr/bin/systemd-resolve.

Bevan
  • 2,913

6 Answers6

54

The process I documented above is correct - this is how you change the DNS settings under WSL2.

My mistake was in using the well known public DNS Servers for CloudFlare (1.1.1.1) and Google (8.8.8.8 & 8.8.4.4) for testing purposes. It turns out that my local network blocks me from using public DNS.

When I tested the above process with the correct internal DNS server IP address, everything worked properly.

Bevan
  • 2,913
13

Adding to other answers here you also want to set resolv.conf immutable.

sudo chattr +i /etc/resolv.conf

In my case it was being deleted on every boot, even with wsl.conf.

For that reason, I created this small program that automates everything with one shell:

https://github.com/epomatti/wsl2-dns-fix-config

4

When creating/editing /etc/resolv.conf I kept getting errors like this one:

cat: /etc/resolv.conf: No such file or directory

I was able to resolve these issues by removing and recreating it from scratch. Both operations require running as root (using sudo didn't work for me)

rm /etc/resolv.conf
echo nameserver 8.8.8.8 > /etc/resolv.conf
4

I had to do this from home (coronavirus) and ultimately ended up writing a Powershell Admininstrator Prompt script to launch my distro (debian). Also note this launches the default distro specified by WSL, you'll need to change the last line if that's not the case. Look for the \\wsl$\[distro name] if yours isn't also called Debian, just type the first part in a Windows Explorer path to reach WSL2, i.e. in the explorer top bar enter \\wsl$\ and it will list your distributions.

This will pull the DNS server from the Windows host, create a new resolv.conf, and write it in Unix format to the WSL2 instance. So you do need to edit /etc/wsl.conf to:

[network]
generateResolvConf = false

So a super user tried to change that to resolv.config; if that file exists because you are using a different Linux distribution, well then I suppose it's the file you want instead. So modify accordingly. Although I've never seen that file in any documentation, and I'm not sure the edit of my post was correct.

Then kick off PowerShell Admin Prompt and run like ./debian.ps1 (if that's what you name the file):

# Filename: debian.ps1
# 
# Get the DNS server of the Windows machine, save into variable nameserver
$nameserver = Get-WmiObject -Namespace root\cimv2 -Query "Select dnsserversearchorder from win32_networkadapterconfiguration" | where {$_.DNSServerSEarchOrder -ne $null} | select -ExpandProperty DNSServerSearchOrder
# Convert nameserver object into a string
$nameserver = Out-String -InputObject $nameserver
# Run Set-Contents (sc) to write the resolv.conf file in a public location as it has DOS formatted line endings written by PowerShell, not readable by Linux
sc -Path 'c:\Users\Public\Documents\resolv.conf' -Value ('nameserver ' + $nameserver) -Encoding utf8
# Convert the DOS formatted file into UNIX format for WSL2 and write it in the proper place (\etc\resolv.conf, its primary location is \\wsl$\[distro_name] from Windows)
[string]::Join( "`n", (gc 'c:\Users\Public\Documents\resolv.conf')) | sc '\\wsl$\debian\etc\resolv.conf'
# Launch the default WSL2 distribution - if you want to use another one, specify in the line below
wsl.exe

This has been tested under Debian Buster and a Zscaler (corporate) VPN. It's a good starting point, hope it saves someone the headaches I encountered getting DNS access on my corporate PC's WSL2 instance!

Matt
  • 141
4

Very detailed answers about changing it. I just wanted to use the default and get on with it. Followed a few guides like the first answer, didn't work for me. I only changed /etc/wsl.conf and it works again.

sudo nano /etc/wsl.conf

Insert or change in this file:

[network]
generateResolvConf = true

Insert in Powershell/CMD:

wsl --shutdown

or:

wsl --terminate <<Linux distro>>

Done and done. Let me know if this worked for you.

My setup was messed up because Tailscale changed it when i started it. Now it's working again.

Zegert
  • 41
1
/etc/resolv.conf

This file is created by default after each WSL launch.

You need to edit the file that generates /etc/resolv.conf on the Windows side.


Edit this file:

`/mnt/etc/resolv.conf`

That works for me.