19

I've used WSL Bash/Ubuntu for several years, but for some reason this problem recently appeared.
DNS is unable to resolve any names, both internal and external. The first time I re-installed WSL I think it worked, for a day... but not anymore, even if I reinstall.

From a fresh install of Ubuntu 18.04 from Windows Store:

user@hostname:~$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line.
nameserver <DNS server from wi-fi NIC 1>
nameserver <DNS server from wi-fi NIC 2>
nameserver <DNS server from ethernet 2 (VPN) NIC 1>
search anyconnect.local

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known

user@hostname:~$ ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=16.1 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 16.197/16.197/16.197/0.000 ms

user@hostname:~$ dig +short google.com
user@hostname:~$ dig +short @8.8.8.8 google.com
user@hostname:~$ 

After modifying /etv/resolv.conf:

user@hostname:~$ dig +short google.com

user@hostname:~$ cat /etc/resolv.conf
search <internal-domain>.local
search anyconnect.local
nameserver <DNS server from wi-fi NIC 1>
nameserver <DNS server from wi-fi NIC 2>
nameserver <DNS server from ethernet 2 (VPN) NIC 1>
nameserver <DNS server from ethernet 2 (VPN) NIC 2>
nameserver 8.8.8.8
nameserver 8.8.4.4

user@hostname:~$ ls -la /etc/resolv.conf
-rw-r--r-- 1 root root 167 May 28 09:18 /etc/resolv.conf

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known

user@hostname:~$ ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.0 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.045/17.045/17.045/0.000 ms

# disconnected VPN

user@hostname:~$ dig +short google.com
172.217.21.142

user@hostname:~$ ping google.com -c 1
PING google.com (172.217.21.142) 56(84) bytes of data.
64 bytes from arn11s02-in-f14.1e100.net (172.217.21.142): icmp_seq=1 ttl=53 time=17.4 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.445/17.445/17.445/0.000 ms

user@hostname:~$ dig +short google.com
172.217.21.142

# connected VPN

user@hostname:~$ dig +short google.com

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known
user@hostname:~$ 

As you can see, as soon as I disconnect VPN I have name resolution working flawlessly. However, I stay connected to VPN throughout the day, obviously because it's required to connect to corporate resources.

I'm not dependent on internal DNS on the WSL, though ideally that should work too, but I do need external DNS working.

DNS works as expected locally. I can ping the DNS servers from the VPN NIC, but not the ones from the wi-fi NIC. I've tried reinstalling WSL and also tried using only Google's nameservers in /etc/resolv.conf. Have not updated WSL as apt requires DNS...

Windows 10, version 1909
Ubuntu 18.04 from Windows Store
Cisco AnyConnect VPN ("Allow access to local LAN when connected" is checked)

Anyone have any ideas? Where to start?

4
  • I can ping the DNS servers from the VPN NIC, but not from the WI-FI NIC. That's true for both local Windows PC and WSL. But even if Google's DNS servers are the only one in my resolv config (which I can ping), there is still no name resolution.
    – Morten
    Jun 2 '20 at 10:27
  • 1
    After searching "every" hit from google, I found the following which, for some reason, seems to have resolved the issue. Added options rotate as the first line in /etc/resolv.conf and restarted LxssManager - DNS works. Source: link
    – Morten
    Jun 2 '20 at 11:02
  • That change made DNS work "on a cycle", e.g. every Xth query. I thought resolv.conf would query each nameserver until it got a match or all failed, but that doesn't seem to be the case? If I define search domains and/or the nameservers from my WI-FI NIC and/or Googles DNS servers, DNS doesn't work at all. If I define ONLY the DNS servers from my VPN NIC, DNS works. Apparently this is by design(?) and has something to do with Cisco Anyconnect VPN and (split) DNS? Way above my head, but there it is.
    – Morten
    Jun 4 '20 at 11:04
  • 1
    Only the first 3 nameservers in /etc/resolv.conf will be checked before giving up. If you have more than that in the file they will be ignored. See resolv.conf(5) — Linux manual page. Nov 19 at 22:08
17

Resolved.

Ubuntu subsystem (WSL) could not resolve corporate and non corporate domains while on or off vpn.

Fixed.

Must create /etc/wsl.conf file and add an entry to kill the resolv.conf file from auto generating on reboot. Add the code block to /etc/wsl.conf:

[network] 

generateResolvConf = false

Then reboot the ubuntu subsystem by opening powershell as admin and running command:

wsl --shutdown

Now, Re-open ubuntu subsystem

use these commands in order:

cd /etc
ls

This directory should show the 'resolv.conf' file (which is a symbolic link). The link should now be red indicating the link leads to no where. Delete the resolv.conf link and create a new /etc/resolv.conf file

In the new resolv.conf file, write this code block

search    your.domain.com
nameserver    x.x.x.x
nameserver    x.x.x.x
nameserver    y.y.y.y

Where X is the DNS address configured in the Cisco Anyconnect VPN adapter. Locate the Cisco VPN adapter in network settings, right click on the Cisco VPN adapter and click 'properties', now highlight IPv4 and click 'properties'. Then note the Preferred DNS and Alternate DNS and copy those into the resolv.conf file.

And Y is your normal IPv4 DNS address

Now restart the subsystem again from Powershell. NOTE: If this did not work, that means that the resolv.conf file was blown away by the subsystem again. In order for this to work, the wsl.conf file has to be read by the system. If it is not being read, try reinstalling the subsystem or upgrading to 20.04.

5
  • Thanks for your contribution. My setup is still working, but I will certainly look into this the next time I experience any issues (which I probably will). I will say though, that my resolv.conf file was not changed between boots as I checked this every now and then. Not that I remember 2 months back, but I don't think my resolv.conf ever was a symlink (isn't now at least). I may have changed it at some point, for some reason...
    – Morten
    Oct 1 '20 at 6:46
  • This worked like a charm for me. Thank you!
    – mgarde
    Mar 3 at 9:49
  • Perfect. Windows 10 users can look up their DNS servers by opening PowerShell and executing Get-DnsClientServerAddress.
    – dmn
    Mar 3 at 14:00
  • Wow, it took me long enough to find this. Works like a charm!
    – SliceThePi
    Oct 30 at 1:49
  • 1
    I did rm and add resolv.conf but system kept overwriting it. chattr -f +i finally stopped it. But dns is not functioning. My WSL is 20.04.
    – old-monk
    Nov 5 at 1:54
5

See here a workaround based on a conflict observed with IPv6 DNS Servers:

https://github.com/microsoft/WSL/issues/1350#issuecomment-742454940

Please note an important fact, and workaround:

The DNS servers from VPN connections are not added to /etc/resolv.conf when another network adapter is using IPv6 DNS servers, which seems to cause kind of conflict (additional IPv4 DNS servers are discarded).

Check the adapters that use IPv6 DNS servers :

Get-DnsClientServerAddress -AddressFamily IPv6 | Where-Object ServerAddresses -NE "{}" | Select-Object -ExpandProperty InterfaceAlias

Get their related adapter binding

Get-NetAdapterBinding -ComponentID ms_tcpip6 | Where-Object Name -In (Get-DnsClientServerAddress -AddressFamily IPv6 | Where-Object ServerAddresses -NE "{}" | Select-Object -ExpandProperty InterfaceAlias)

Disable IPv6 for each adapter binding (or directly for all adapters) using Powershell with administrator privileges:

Disable-NetAdapterBinding -Name "Wi-Fi" -ComponentID ms_tcpip6 -PassThru
Disable-NetAdapterBinding -Name "Network Bridge" -ComponentID ms_tcpip6 -PassThru
...
Disable-NetAdapterBinding -Name "*" -ComponentID ms_tcpip6 -PassThru

Alternatively, simply disable IPv6 on the ethernet/wifi adapter using Windows UI:

image

Now the nameservers are correctly added when VPN connection is enabled, and removed when VPN is disabled.

With VPN connected:

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 192.168.1.1
nameserver xx.xx.xx.x1 # obfuscated company dns
nameserver xx.xx.xx.x2 # obfuscated company dns
search home

With VPN disconnected:

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 192.168.1.1
search home
4
  • 1
    This latest answer from MS should be the accepted as the correct answer.
    – xpt
    Apr 18 at 13:29
  • Thank you so much, it works beautifully :) May 18 at 8:44
  • This solution enables the switching of nameserver listing based on the presence or absence VPN of for my Ubuntu/WSL1. It's the least intrusive. However, I still got the error of "Name or service not known".
    – Yu Shen
    Oct 28 at 2:25
  • Actually, the other problem of still having "Name or service not known" is not related. It turned out to be due to missing DNS suffix, once I manually used full qualified hostname with the domain suffix, the ping worked.
    – Yu Shen
    Oct 29 at 3:43
4

Edited resolv.conf to contain only the DNS servers provided by the Cisco Anyconnect VPN NIC:

nameserver X.X.X.X
nameserver X.X.X.X

Now DNS in WSL works flawlessly both when connected to and disconnected from VPN.
This is above my head, but apparently it has something to do with Cisco Anyconnect VPN and (split) DNS.

1

This worked for me so hopefully it will save someone else some frustration.

Create /etc/wsl.conf

[network] 

generateResolvConf = false

Remove or backup /etc/resolv.conf

sudo rm -f /etc/resolv.conf

Restart wsl from a command prompt

wsl --shutdown

Start a new bash session and DNS resolution should work exactly as on the host.

0

I ran into this in the last few days and it was driving me nuts. The solutions floating around were all WAY too hackish for my tastes. I created a very simple wsl-resolv-handler.ps1 (see script block later in this message) which can automagically set the correct nameserver order, create a correct search line, based on the InterfaceMetric.

Basically, you can set a lower (== higher priority) InterfaceMetric for your VPN interface as follows (start a powershell as admin):

 # Get a list of interfaces, Note the InterfaceIndex and InterfaceMetric for your VPN adapter
> Get-NetIpInterface
# For example, if your VPN adapter has InterfaceIndex 12, we're setting
# the InterfaceMetric to 10, making sure 10 is lower than whatever your
# WiFi or Ethernet adapter has
> Set-NetIPInterface -InterfaceIndex 12 -InterfaceMetric 10 

After your interface metrics are set a-ok, you can use the script in the script-block below. The top of the script contains a complete explanation for how to use + a few settings (WslDistroName and ResolvConfFile) that need to be correct.

# Before attempting to run this script, review and/or follow the 
# following steps.
#
# 0. Make sure you can execute powershell scripts. Start Powershell as an
#    administrator and execute:
#
#      Set-ExecutionPolicy RemoteSigned

# 1. Make sure you disable wsl's broken resolv.conf handler.
#    Create /etc/wsl.conf with the following 2 lines (without the pound signs):
#
#      [network]
#      generateResolvConf = false
#
#    After that, make sure you issue a wsl.exe --shutdown.
#
# 2. Configure your WSL distro name in $WslDistroName below and make sure we're
#    pointing at your resolv.conf file in $ResolvConfFile. Also make sure we can write 
#    to the resolv.conf file. I had to set permissions pretty broadly at 666.
#
# 3. Schedule this script with Task Scheduler:
#
#      * Click Action –> Create Task…
#      * Give your task a name in the General tab
#      * Click on the Triggers tab and then click New…
#      * In the "Begin the task" menu, choose “On an event.” Then, choose:
#
#          Log: Microsoft-Windows-NetworkProfile/Operational
#          Source: NetworkProfile
#          Event ID: 10000
#
#      * Event ID 10000 is logged when you connect to a network. Add another
#        one when a disconnect would occur (Event ID 10001):
#
#          Log: Microsoft-Windows-NetworkProfile/Operational
#          Source: NetworkProfile
#          Event ID: 10001
#
#      * Go to the Conditions tab. Make sure it runs regardless of AC adapter
#        connected/disconnected, peruse the other options there.
#
#      * Go to the Actions tab. Add a run script action and then:
#
#          Program/script: powershell.exe
#          Arguments: -noprofile -file "c:\where\you\stored\wsl-resolv-handler.ps1"
#

$WslDistroName = "Debian"
$ResolvConfFile = [string]::Format("\\wsl$\{0}\etc\resolv.conf", $WslDistroName)

function Convert-To-UnixLineEndings($path) {
  $oldBytes = [io.file]::ReadAllBytes($path)
  if (!$oldBytes.Length) {
      return;
  }
  [byte[]]$newBytes = @()
  [byte[]]::Resize([ref]$newBytes, $oldBytes.Length)
  $newLength = 0
  for ($i = 0; $i -lt $oldBytes.Length - 1; $i++) {
      if (($oldBytes[$i] -eq [byte][char]"`r") -and ($oldBytes[$i + 1] -eq [byte][char]"`n")) {
          continue;
      }
      $newBytes[$newLength++] = $oldBytes[$i]
  }
  $newBytes[$newLength++] = $oldBytes[$oldBytes.Length - 1]
  [byte[]]::Resize([ref]$newBytes, $newLength)
  [io.file]::WriteAllBytes($path, $newBytes)
}

Function Pause ($message)
{
    # Check if running Powershell ISE
    if ($psISE)
    {
        Add-Type -AssemblyName System.Windows.Forms
        [System.Windows.Forms.MessageBox]::Show("$message")
    }
    else
    {
        Write-Host "$message" -ForegroundColor Yellow
        $x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}

$NetworkInterfaces  = Get-NetIPInterface -AddressFamily IPv4 | Where-Object ConnectionState -EQ 'Connected' | Where-Object NlMtu -LT 9001
$DNSServerAddresses = Get-DnsClientServerAddress -AddressFamily IPv4
$DNSClients = Get-DnsClient

$Entries = $NetworkInterfaces | ForEach-Object {
  [PSCustomObject]@{
    'InterfaceAlias'      = $_.InterfaceAlias
    'InterfaceIndex'      = $_.InterfaceIndex
    'InterfaceMetric'     = $_.InterfaceMetric
    'DNSServerAddresses'  = ($DNSServerAddresses | Where-Object InterfaceIndex -EQ $_.InterfaceIndex | Where-Object AddressFamily -EQ 2).ServerAddresses
    'DNSSuffixes'  =  @(($DNSClients | Where-Object InterfaceIndex -EQ $_.InterfaceIndex).ConnectionSpecificSuffix) + @(($DNSClients).ConnectionSpecificSuffixSearchList | Out-Null)
  }
} | Sort-Object InterfaceMetric -Unique

$CommentLine = [string]::Format("# Generated by wsl-resolv-handler.ps1.")
Write-Output $CommentLine | Set-Content -Path $ResolvConfFile
$SearchLine = [string]::Format("search {0}", ($Entries.DNSSuffixes -join " "))
  Write-Output $SearchLine | Add-Content -Path $ResolvConfFile
$Entries | ForEach-Object {
  $_.DNSServerAddresses | ForEach-Object {
    $NameServerLine = [string]::Format("nameserver {0}", $_)
    Write-Output $NameServerLine | Add-Content -Path $ResolvConfFile
  }
}

Convert-To-UnixLineEndings $ResolvConfFile

Pause "Press any key to continue..."

Save the above script as wsl-resolv-handler.ps1 and follow the instructions in the comments. Good luck + have fun (note, this approach should work with any type of VPN or network topology changes, it will work without manual stupidity as long as you configure it correctly and set up the task in Windows Task Manager correctly. You don't need elevated permissions to run this, as long as the script can write to /etc/resolv.conf)!

Note: I've also posted this answer to the most relevant github issue for this (there are a HUGE number of github issues about the brokenness of wsl's resolv.conf generator) here: https://github.com/Microsoft/WSL/issues/2884#issuecomment-928299305

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.