microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.32k stars 814 forks source link

DNS server coming from vpn network is not reflected in WSL #1350

Closed asvetliakov closed 4 months ago

asvetliakov commented 7 years ago

2016-11-12

sunilmut commented 7 years ago

@asvetliakov - Thanks for reporting the issue. Yes, we are aware of issues with VPN, as you can also see in #416. We are actively working on a solution for this. @misenesi as FYI.

misenesi commented 7 years ago

Hi @asvetliakov, could you please provide output when you do:

ipconfig /all

?

I have a fix prepared for this, but need to verify that your VPN networking interface is reported as point-to-point interface.

asvetliakov commented 7 years ago

@misenesi

PS C:\Users\asvet> ipconfig /all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : Alexey-PC
   Primary Dns Suffix  . . . . . . . :
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : Home

Ethernet adapter Ethernet:

   Connection-specific DNS Suffix  . : Home
   Description . . . . . . . . . . . : Intel(R) Ethernet Connection I217-V
   Physical Address. . . . . . . . . : E0-3F-49-AC-04-1E
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : fe80::5867:7e40:cdf2:456a%25(Preferred)
   IPv4 Address. . . . . . . . . . . : 192.168.1.33(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Lease Obtained. . . . . . . . . . : Wednesday, November 30, 2016 2:28:47 AM
   Lease Expires . . . . . . . . . . : Wednesday, November 30, 2016 2:28:47 PM
   Default Gateway . . . . . . . . . : 192.168.1.1
   DHCP Server . . . . . . . . . . . : 192.168.1.1
   DHCPv6 IAID . . . . . . . . . . . : 65027913
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-1E-92-04-D1-E0-3F-49-AC-04-1E
   DNS Servers . . . . . . . . . . . : 80.58.61.250
                                       80.58.61.254
   NetBIOS over Tcpip. . . . . . . . : Enabled

PPP adapter freechat.com:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : freechat.com
   Physical Address. . . . . . . . . :
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   IPv4 Address. . . . . . . . . . . : 10.61.0.5(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.255
   Default Gateway . . . . . . . . . :
   DNS Servers . . . . . . . . . . . : 10.60.10.121
   NetBIOS over Tcpip. . . . . . . . : Enabled

Ethernet adapter Ethernet 12:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : TAP-Windows Adapter V9
   Physical Address. . . . . . . . . : 00-FF-2F-01-1A-D1
   DHCP Enabled. . . . . . . . . . . : Yes
   Autoconfiguration Enabled . . . . : Yes

Tunnel adapter Local Area Connection* 10:

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Microsoft Teredo Tunneling Adapter
   Physical Address. . . . . . . . . : 00-00-00-00-00-00-00-E0
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   IPv6 Address. . . . . . . . . . . : 2001:0:9d38:6ab8:2cca:22a9:3f57:fede(Preferred)
   Link-local IPv6 Address . . . . . : fe80::2cca:22a9:3f57:fede%19(Preferred)
   Default Gateway . . . . . . . . . : ::
   DHCPv6 IAID . . . . . . . . . . . : 318767104
   DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-1E-92-04-D1-E0-3F-49-AC-04-1E
   NetBIOS over Tcpip. . . . . . . . : Disabled

The one with name 'freechat.com' is my VPN

misenesi commented 7 years ago

Thank you @asvetliakov . I have checked in a fix that will address some of the VPN DNS resolving issues, including yours. Currently for DNS resolving we update /etc/resolv.conf from the service. In this fix I added the capability to manually modify the /etc/resolv.conf file if you wish so, disabling its automatic regeneration.

However, due to how DNS resolving works for various VPN solutions, this fix will only work with strict force tunnel VPN that do not hide their DNS servers for privacy or security reasons. I have a proposal for better solution that is currently under discussion that would work for all VPN scenarios.

blemasle commented 7 years ago

@misenesi With creators update installed, the automic generation cannot be disabled on my system. Even if I remove the first line, it still get regenerated every single time. It's working for /etc/hosts though.

sunilmut commented 7 years ago

@blemasle - @misenesi is no longer with MSFT. It looks like we screwed up the /etc/resolv.conf auto-generation logic, see @benhillis comment in #1908.

Here is the background. By default, bash.exe will auto-generate /etc/resolv.conf every time you launch bash.exe. Then it will try to keep it up to date with changes from Windows, when bash is running. It looks like if you remove the first line, we stop auto-update of the file while bash is running, but forgot to disable the logic to auto-generate during bash launch. We do apologize for the inconvenience and as @benhillis mentions in #1908, we are looking to improve the experience here.

johnarban commented 7 years ago

I don't know if this is still a problem for anyone else. I am on build 16232.rs_prerelease.170624-1334 using WSL with Ubuntu 16.04.2 LTS from the Windows Store and CISCO AnyConnect version 21.12020 , and I still can't connect. I tried removing the commented line in /etc/resolv.conf, but it still get's reset. I don't know if there has a been a fix posted yet, but I haven't found it online if it exists.

mo18 commented 7 years ago

The problem I'm seeing is that the ordering of the dns servers is incorrect when the vpn is connected. as a reslult, I can't resolve any of the hosts behind the vpn. I'm running windows 15063.483 with Cisco Anyconnect. The dns bindings in windows are the following:

> Get-DnsClientServerAddress -AddressFamily ipv4 | Select-Object -ExpandProperty ServerAddresses
10.0.0.51
10.0.0.52
192.168.1.1

in ubuntu the are the following:

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line.
nameserver 192.168.1.1
nameserver 10.0.0.51
nameserver 10.0.0.52
search home xyz.vpn
sunilmut commented 7 years ago

If you are connected to a VPN and lose connectivity within bash, please try the workaround posted here. It should work for Creators Update and above. Post Fall Creators Update, we will be looking at a better support for other VPN solutions.

Thanks to @bradley101, who first pointed out the workaround.

johnarban commented 7 years ago

Thank you that works around that. The only other thing is to get the list of domain suffixes, but that is 2nd order.

nimbixler commented 7 years ago

here's a more automatic workaround that works for me - in my case I only ever connect to one VPN at a time and its nameserver is at the very end of /etc/resolv.conf, which of course is no good.

YMMV but, first...

create a file in /etc/sudoers.d with allowing your username to run sudo with no password; you can restrict this to specific commands if you want but I do it for all (please adjust for your needs). For example let's say your username is linux, so create the file /etc/sudoers.d/00-linux (you can call this whatever you want), with the following text in it:

linux ALL=(ALL) NOPASSWD: ALL

you'll need to of course sudo to root to create that file. Be sure to replace "linux" with whatever your username is in WSL.

Close the shell and all instances of WSL and run a new one, and try it - type sudo -s if you are not prompted for password, it worked. Otherwise please check the syntax.

Next, create this python file in your home directory = call it resolv_flip.py :

#!/usr/bin/python

if __name__ == '__main__':
    with open('/etc/resolv.conf', 'r') as f:
        lines = f.read().splitlines()
    ns = []
    other = []
    for i in lines:
        if i[:11] != 'nameserver ':
            other.append(i)
        elif i[11:][:2] == '8.':
            ns.append(i)
        else:
            ns.insert(0, i)
    with open('/etc/resolv.conf', 'w') as f:
        f.write('\n'.join(other) + '\n')
        f.write('\n'.join(ns) + '\n')

finally, add this to the end of your ~/.bashrc file:

sudo ~/resolv_flip.py

from that point forward every time you run the WSL shell it will flip the nameservers so that anything that doesn't start with 8. will be at the top, but it won't disturb the comment header that is used to autogenerate the file (because we need that information in order for this to work).

It's not perfect but it works fine for me, and it's dead simple.

Enjoy, Leo Reiter

l8nite commented 7 years ago

For me, DNS lookups via my corporate nameserver (on VPN) won't resolve external domains, so just swapping nameserers in resolv.conf only allows me to swap between "only resolve external" and "only resolve internal"

I'm still hoping something can be done to proxy DNS requests out to the windows host resolver.

nimbixler commented 7 years ago

Makes sense.. this worked for me but my DNS does external as well. It's too bad this is isn't properly fixed yet.. it's a great set of tools that are almost unusable as a result.

sunilmut commented 7 years ago

@l8nite - If the VPN DNS server is not able to resolve a name, then glibc resolver should walk the list in /etc/resolv.conf and try the next nameserver on the list. Are you suggesting that that's not happening?

nimbixler commented 7 years ago

that's not how the resolver works on Linux... it only goes to the next server if the primary (or secondary, etc.) is not accessible. Otherwise it would work fine to just keep it as it is. In our case our DNS can do external resolution as well, so it's not a problem for me to just switch the order.

nimbixler commented 7 years ago

@sunilmut FYI, this explains it pretty well: http://man7.org/linux/man-pages/man5/resolv.conf.5.html

specifically: "nameserver Name server IP address Internet address of a name server that the resolver should query, either an IPv4 address (in dot notation), or an IPv6 address in colon (and possibly dot) notation as per RFC 2373. Up to MAXNS (currently 3, see ) name servers may be listed, one per keyword. If there are multiple servers, the resolver library queries them in the order listed. If no nameserver entries are present, the default is to use the name server on the local machine. (The algorithm used is to try a name server, and if the query times out, try the next, until out of name servers, then repeat trying all the name servers until a maximum number of retries are made.)"

unfortunately a name resolution error is not enough to say "try the next one" - it has to actually timeout or fail to connect in order to move to the next.

I don't know how hard or easy this kind of thing is, but perhaps a good long term solution is to just somehow forward NS requests to the native Windows resolver services, which actually do a very good job at this (arguably better than the glibc one).

sunilmut commented 7 years ago

@nimbixler - Thanks for the pointer. So, the default DNS resolver on Ubuntu, network-manager must have a better logic than glibc to do the resolution because obviously it works in native Linux.

Redirecting the DNS requests to Windows service is not totally out of scope, but the solution from WSL point of view will look a bit different because all the NS resolution in Linux happens in user space, where WSL has no role to play.

nimbixler commented 7 years ago

@sunilmut I haven't used desktop Linux in a while, but my guess is that it's providing some sort of caching name service that is being smarter about name resolution on the back end. It may be worth looking into that approach as well - doing whatever NetworkManager (plus whatever name service) does, perhaps even packaging it up that way.

Just trying to help - you guys did a great thing here, want to make sure it gets used ;-)

Leo Reiter

donaldpipowitch commented 6 years ago

I think I made a duplicate of this issue https://github.com/Microsoft/WSL/issues/2884...? Is this the same problem? Are there known workarounds?

dannyk81 commented 6 years ago

@donaldpipowitch check out this solution https://github.com/Microsoft/WSL/issues/2082#issuecomment-369994557

kobenauf commented 6 years ago

It's been almost a year since the last significant comment on this. Is this still being investigated? This still seems like a problem.

Miles92 commented 6 years ago

I also tried to get deadwood running like described here. issue 2082, but it still doesn't work.

Is there any chance of a solution for this?

nfekete commented 6 years ago

I'm using this bash script to generate the proper resolv.conf based on current windows DNS configuration values, which I run each time the windows DNS settings change (i.e. when connecting to a VPN server) or the resolv.conf file gets overwritten by WSL for some reason.

#!/bin/bash

tmp=`mktemp`
powershell="/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe"
trap ctrlC INT

removeTempFiles() {
    rm -f $tmp
}

ctrlC() {
    echo
    echo "Trapped Ctrl-C, removing temporary files"
    removeTempFiles
    stty sane
}

echo "Current resolv.conf"
echo "-------------------"
cat /etc/resolv.conf

echo
echo "Creating new resolv.conf"
echo "------------------------"

{
    head -1 /etc/resolv.conf | grep '^#.*generated'
    nameservers=$($powershell \
        -Command "Get-DnsClientServerAddress -AddressFamily ipv4 | Select-Object -ExpandProperty ServerAddresses" \
        )
    for i in $nameservers; do
        echo nameserver $i
    done
    tail -n+2 /etc/resolv.conf | grep -v '^nameserver'
} | tr -d '\r' | tee $tmp

(set -x; sudo cp -i $tmp /etc/resolv.conf)

removeTempFiles

You can mark this script setuid with owner root, so it doesn't ask for password through sudo every time.

bittonokami commented 5 years ago

I resolved this issue basically by applying the following steps:

1) Locate the VPN adapter over the network settings. To go there: a. Go to Settings b. Click on Network & Internet c. Change adapter options

2) Right click on the VPN virtual network, and click on properties. 3) In my case I selected IPv4, and then click on properties 4) You will see the DNS settings that are set statically

You will need to copy these DNS settings to your /etc/resolv.conf. It is advisable that if the DNS failover is turned on you can add all of the DNS settings from various adapters. A simple script that generates a bash file with the commands for all of the adapters is as the following;

function PopulateDNSServers()
{
    $DNSServers = Get-DnsClientServerAddress | Select-Object –ExpandProperty ServerAddresses

    #Create the bash file
    $FileName = 'C:\Users\' + $env:USERNAME + "\WSLDNSFix.bash"
    Write-Host $FileName

    New-Item $FileName -type file

    echo "#!/bin/bash" >> $FileName
    echo "sudo cp /etc/resolv.conf{,.bkp}" >> $FileName
    echo "sudo rm /etc/resolv.conf" >> $FileName
    echo "sudo touch /etc/resolv.conf" >> $FileName

    foreach($serverAddress in $DNSServers)
    {        
        $lineToAdd = "nameserver " + $serverAddress
        $Command = "sudo sh -c ""echo " + $lineToAdd + " >>/etc/resolv.conf"""
        echo $Command >> $FileName

    }
}

Once these are done, you can restart your WSL, and should be good.

deven commented 5 years ago

Here is a shorter bash function to fix the nameserver list using "ed":

# Fix /etc/resolv.conf for VPN.
vpn() {
   [ -s /run/resolvconf/resolv.conf -a -L /etc/resolv.conf ] && sudo cp --remove-destination /run/resolvconf/resolv.conf /etc/resolv.conf
   local sudo="sudo"
   if [ -w /etc/resolv.conf ]; then sudo=""; fi
         $sudo ed -s /etc/resolv.conf <<'EOF'
H
a
#EOF
.
kx
g/^nameserver /d
.-1r !/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Command '$x = Get-NetAdapter | Group-Object -AsHashtable -Property ifIndex; Get-DnsClientServerAddress -AddressFamily ipv4 | where {$x[$_.InterfaceIndex].Status -eq "Up"} | Select-Object -ExpandProperty ServerAddresses | foreach {"nameserver " + $_}' | sed 's/\r//g'
'xd
wq
EOF
}

What this does, step-by-step:

  1. If "/run/resolvconf/resolv.conf" exists and is not empty, and if "/etc/resolv.conf" is also a symbolic link, then copy "/run/resolvconf/resolv.conf" to "/etc/resolv.conf", removing the destination file first, to replace the symbolic link with a copy. (On my system, WSL no longer uses "/run/resolvconf/resolv.conf", so this line may not be needed.)
  2. Set a local bash variable (within the function only) of "sudo" to "sudo". This will be used to run "sudo" by default for the "ed" command below.
  3. If "/etc/resolv.conf" is already writable, set the "sudo" variable to "", so that "ed" will run directly instead of under "sudo".
  4. Run "$sudo ed" to run "sudo" if necessary and run "ed" to update the list of nameservers in "/etc/resolv.conf", discarding the editor output. The following lines through the EOF marker contain "ed" commands:
    • H — Enable error explanations.
    • a — Append to the file after the current line (which starts as the last line of the file).
    • #EOF — This is a marker line being added to the end of the file.
    • . — This line is a delimiter marking the end of the lines to append.
    • kx — Mark the current line (the #EOF line just added) with the letter "x".
    • g/^nameserver /d — Delete all lines starting with "nameserver ". This will leave the current line as the first line after the last matching line.
    • .-1r !/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe [...] — Insert the output of the specified PowerShell command (fetching the nameservers from the Win32 side) before the current line. The #EOF line prevents an error here if the file was empty or contained only nameserver lines.
    • 'xd — Delete the line marked with the letter "x", which is the #EOF line added earlier.
    • wq — Save the file and exit.
    • EOF — This is the delimiter line for the "ed" script, so bash knows where it ends.

UPDATE: Fixed PowerShell command to only include DNS servers for network adapters which are up.

UPDATE 2: Refactored to work more reliably.

UPDATE 3: Fix the "ed" script to work correctly even if "/etc/resolv.conf" is empty or contains only nameserver lines.

chiamarc commented 5 years ago

Deven,

This works great unless you only have nameserver entries in your resolv.conf. This was my situation so I had to elide the command to move to the previous line '-' and just make it kx because I was already at the first line. Is there a more general way to do this?

matthiassb commented 5 years ago

@chiamarc I am curious, does the GIST I provided here resolve your DNS issues?

deven commented 5 years ago

@chiamarc

Deven,

This works great unless you only have nameserver entries in your resolv.conf. This was my situation so I had to elide the command to move to the previous line '-' and just make it kx because I was already at the first line. Is there a more general way to do this?

Yes, I came up with a solution and edited my comment above to fix this problem. The new version should work for your situation. I updated the explanation as well.

chiamarc commented 5 years ago

Thanks @deven !

mathrb commented 5 years ago

@deven thanks for the workaround. Any idea with executing the script change the layout of the bash? bash_1 bash_2

coltenkrauter commented 4 years ago

This simple solution worked for me: Fix DNS resolution in WSL2

sgarcia-dev commented 4 years ago

None of the solutions work for me while running a VPN :( Might it have something to do that running the powershell command, I just get a single "192.168.1.1" address (same as before connecting)?

Also, when I inspect the connection properties in the command panel -> IPv4 settings -> DNS address, I just get "DNS resolved dynamically", and can't see what the true DNS address is of my currently connected VPN.

Does someone have any ideas?

nimbixler commented 4 years ago

I don't know how relevant this is anymore, but this works for me (a bash function that I run from .bashrc):

dnsfix () { /mnt/c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2 | grep --color=auto -e '^ [0-9]' | sed 's/^/nameserver/' | sudo tee /etc/resolv.conf > /dev/null }

If I ever connect to VPN and have a WSL session open already, and don't want to open another one, I just type dnsfix in the shell manually. Otherwise running a new session will do this. Note that you have to have passwordless sudo setup for your shell user, which I did like this:

ler@LAPTOP-LEO:~$ cat /etc/sudoers.d/00-ler ler ALL=(ALL) NOPASSWD: ALL

replace ler with whatever your username is for WSL of course.

mglants commented 4 years ago

I don't know how relevant this is anymore, but this works for me (a bash function that I run from .bashrc):

dnsfix () { /mnt/c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2 | grep --color=auto -e '^ [0-9]' | sed 's/^/nameserver/' | sudo tee /etc/resolv.conf > /dev/null }

If I ever connect to VPN and have a WSL session open already, and don't want to open another one, I just type dnsfix in the shell manually. Otherwise running a new session will do this. Note that you have to have passwordless sudo setup for your shell user, which I did like this:

ler@LAPTOP-LEO:~$ cat /etc/sudoers.d/00-ler ler ALL=(ALL) NOPASSWD: ALL

replace ler with whatever your username is for WSL of course.

/mnt/c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2 | grep --color=auto -e '^ [0-9]' | sed 's/^/nameserver/' |tr -d '\r' | sudo tee /etc/resolv.conf > /dev/null

Thank you for your awesome script. Added fix on DOS CR-LF

gitfool commented 4 years ago

I'm in the same boat as @sgarcia-dev:

None of the solutions work for me while running a VPN :( Might it have something to do that running the powershell command, I just get a single "192.168.1.1" address (same as before connecting)?

mglants commented 4 years ago

I'm in the same boat as @sgarcia-dev:

None of the solutions work for me while running a VPN :( Might it have something to do that running the powershell command, I just get a single "192.168.1.1" address (same as before connecting)?

Look at mine comment

gitfool commented 4 years ago

@MGlants that doesn't work for me either, since it only returns 192.168.1.1, which is already in /etc/resolv.conf:

~$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line.
nameserver 192.168.1.1
nameserver fec0:0:0:ffff::1
nameserver fec0:0:0:ffff::2

~$ /c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2 | grep --color=auto -e '
^ [0-9]' | sed 's/^/nameserver/'
nameserver 192.168.1.1
robberphex commented 4 years ago

For WSL1 on Win 10 2004, WSL1 works very well with VPN:

Just need to enable [network]generateResolvConf.

I.e.

robert@OFFICE-LAPTOP:~$ cat /etc/resolv.conf
nameserver 192.168.124.1 # dns server from local connection
nameserver 127.0.0.1 # dns server from VPN connection
nameserver fec0:0:0:ffff::1 # IPv6 dns server, actually useless for me
robert@OFFICE-LAPTOP:~$ #disconnect VPN
robert@OFFICE-LAPTOP:~$ 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.124.1
nameserver fec0:0:0:ffff::1
nameserver fec0:0:0:ffff::2
robert@OFFICE-LAPTOP:~$ #connect VPN
robert@OFFICE-LAPTOP:~$ 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.124.1
nameserver 127.0.0.1
nameserver fec0:0:0:ffff::1

This solution works with MoitonPro and built-in L2TP VPN.

zahaim commented 4 years ago

I don't know how relevant this is anymore, but this works for me (a bash function that I run from .bashrc):

dnsfix () { /mnt/c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2 | grep --color=auto -e '^ [0-9]' | sed 's/^/nameserver/' | sudo tee /etc/resolv.conf > /dev/null }

If I ever connect to VPN and have a WSL session open already, and don't want to open another one, I just type dnsfix in the shell manually. Otherwise running a new session will do this. Note that you have to have passwordless sudo setup for your shell user, which I did like this:

ler@LAPTOP-LEO:~$ cat /etc/sudoers.d/00-ler ler ALL=(ALL) NOPASSWD: ALL

replace ler with whatever your username is for WSL of course.

I encountered 2 little problems with this script:

I solved those by adding a dash at the end of the cut command then I installed dos2unix utility to get rid of windows newlines. Working script looks as follows for me now:

$ cat dnsfix.sh 
#!/bin/bash
# helper script to update dns setting while on VPN
/mnt/c/Windows/system32/ipconfig.exe /all | grep --color=auto "DNS Servers" | cut -d ":" -f 2- | grep --color=auto -e '^ [0-9]' | sed 's/^/nameserver/' | sudo tee /etc/resolv.conf > /dev/null
sudo dos2unix /run/resolvconf/resolv.conf
matthiassb commented 4 years ago

@zahaim check out my GIST It's an Init.d service to keep DNS in sync

To support IPv6 as well as IPv6 remove -AddressFamily IPv4 from line 22

thebiss commented 4 years ago

There's probably a way to do this with 1 line of awk, but here's my fix. This handles ipv4 AND ipv6 and search parameters. Don't know if it's i18n aware.

dnsfix () {     
    local search=$(grep -F "search" /etc/resolv.conf);
    local ipv4dnsraw=$(/mnt/c/Windows/system32/netsh.exe interface ip show dns | tr -d '\r');
    local ipv6dnsraw=$(/mnt/c/Windows/system32/netsh.exe interface ipv6 show dns | tr -d '\r');
    local nameservers=$( printf '%s\n%s\n' "${ipv4dnsraw}" "${ipv6dnsraw}" | grep -iF "DNS Servers" | grep -v "None" | cut -c 43- |  uniq | sed 's/^/nameserver /')
    printf '%s on %s\n%s\n%s\n' '# generated by dnsfix' "`date`" "${nameservers}" "${search}" | sudo tee /etc/resolv.conf;
}

Which generates the following /etc/resolv.conf

# generated by dnsfix on Thu Apr 16 14:04:20 EDT 2020
nameserver X.X.X.X
nameserver XXXX:6940:6b2e::1
search example.net

Update This still doesn't handle VPN-added search domains. That information doesn't appear to be available via IPCONFIG or NETSH.

atorr0 commented 4 years ago

WSL1: For some people may work this simple script, while keeping the file automatically managed by WSL:

cat /etc/resolv.conf | sort | sudo tee /etc/resolv.conf

Generating the following result:

# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line.
nameserver 172.12.34.56
nameserver 8.8.4.4
nameserver 8.8.8.8
search my-home-lan corporate.com
thebiss commented 4 years ago

Note that sorting may inadvertently place DNS servers added by the VPN lower in the search list, preventing resolution of internal hostnames known only that DNS.

For example, unlike Google (8.8.8.8), cloudflare (1.1.1.1) would always appear first.

davidegiunchi commented 4 years ago

I solved the problem. In my case the problem was that the OpenVPN configuration that i was using, didn't set any dns resolver, so windows was correctly using google dns, but wsl didn't set any dns. I solved by modifying the openvpn client configuration by adding this line:

dhcp-option DNS 1.1.1.1

with this option set, when i connect to openvpn, the dns is getting correctly set even on linux wsl.

zahaim commented 4 years ago

@zahaim check out my GIST It's an Init.d service to keep DNS in sync

To support IPv6 as well as IPv6 remove -AddressFamily IPv4 from line 22

I was to try it but then I moved to wsl2. Thanks for sharing anyway :)

ebc-conscia commented 4 years ago

To neatly and automatically update your resolv.conf file, it is only neccessary to reload Lxss. In the case of split-tunneling, my experience is that nameserver rotation does the trick. I basically just added this alias to my .bashrc file as a workaround: alias reload='powershell.exe -Command "{Restart-Service LxssManager}" && echo "options rotate" | sudo tee -a /run/resolvconf/resolv.conf'

Of course be sure to check whether the /etc/wsl.conf file is configured correctly:

[network] generateResolvConf = true

brelian commented 4 years ago

WSL1 still appears this issue. I solved this problem after adding DNS list from Windows into wsl /etc/resolve.conf. Thanks, @mo18 .

ebc-conscia commented 4 years ago

Please add the name-servers from the VPN to the top of the resolv.conf file! This would solve the issue for a lot of people. While my file is auto-generated as I (re-)launch WSL, the VPN DNS is put dead last and nothing works.

The blissful ignorance that everyone seems to live in, is that it actually matters to put more than one DNS server in your config. EVERY SINGLE APPLICATION in the world will time out before trying server 2. The first server in the list matters.

Thanks!

cifkao commented 4 years ago

Please add the name-servers from the VPN to the top of the resolv.conf file! This would solve the issue for a lot of people. While my file is auto-generated as I (re-)launch WSL, the VPN DNS is put dead last and nothing works.

Can confirm this. The VPN DNS gets added to resolv.conf, but as the last entry, and it never gets used. It would be great to get this fixed in WSL 1.

Christopher-bit commented 4 years ago

To neatly and automatically update your resolv.conf file, it is only neccessary to reload Lxss. In the case of split-tunneling, my experience is that nameserver rotation does the trick. I basically just added this alias to my .bashrc file as a workaround: alias reload='powershell.exe -Command "{Restart-Service LxssManager}" && echo "options rotate" | sudo tee -a /run/resolvconf/resolv.conf'

Of course be sure to check whether the /etc/wsl.conf file is configured correctly:

[network] generateResolvConf = true

thanks a lot! I came up with this problem too and I'm counting it on my wrongly editing of the wsl.conf. Anyway I fixed it by using your experience. Thx a lot!