Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSL 2 keeps overwriting resolv.conf #5420

Closed
Rimobul opened this issue Jun 16, 2020 · 57 comments
Closed

WSL 2 keeps overwriting resolv.conf #5420

Rimobul opened this issue Jun 16, 2020 · 57 comments

Comments

@Rimobul
Copy link

Rimobul commented Jun 16, 2020

Environment

Windows build number: Microsoft Windows [Version 10.0.19041.264]
Your Distribution version: Ubuntu 18.04
Whether the issue is on WSL 2 and/or WSL 1: WSL 2

Steps to reproduce

Previously, I had my WSL in version 1 and everything worked fine. Then I decided to upgrade to WSL 2 and - similar to many others - I lost internet connection. Thankfully, I could easily bring it back by running:

sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'

Apparently, it was just a DNS issue. I could live with that. However, then I restarted my WSL and the nameserver was set back to 172.31.208.1. So I decided to do exactly what was written in the comments in /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

And ran the following lines:

sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'

I was proud that I resolved the issue so elegantly until I restarted my WSL again. Now, resolv.conf was in red and not accessible from Ubuntu. When I tried to access it from Windows, I saw just an empty file.

Expected behavior

After restarting WSL, resolv.conf keeps the user-defined values.

Actual behavior

After restarting WSL, resolv.conf is empty or not accessible at all.

@0xbadfca11
Copy link

/etc/resolv.conf is symlink to /run/resolvconf/resolv.conf, and /run is tmpfs.
You have to delete symlink before editing.

@Rimobul
Copy link
Author

Rimobul commented Jun 17, 2020

@0xbadfca11 That did not help. I ran:

sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'

But after restarting WSL, I see the following:

image

@Rimobul
Copy link
Author

Rimobul commented Jun 19, 2020

Ok, so I finally found solution in an old ticket: #1908 (comment)

So the full set of commands that have to be run is:

sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf

@vctsvz
Copy link

vctsvz commented Jan 12, 2021

sudo tee /etc/wsl.conf > /dev/null << EOF
[network]
generateResolvConf=false
EOF

echo -e 'nameserver 8.8.8.8\nnameserver 8.8.4.4' | sudo tee /etc/resolv.conf > /dev/null;
sudo chattr -f +i /etc/resolv.conf;

@jnawk
Copy link

jnawk commented Feb 2, 2021

There's no point mucking about with /etc/wsl.conf - it's utterly ignored, and the chattr +i part of the solution amounts to "make the file completely immutable", thereby preventing whatever WSL nonsense is clobbering the file at startup from doing what it pleases. The note in /etc/resolv.conf about how to prevent /etc/resolv.conf from being clobbered is just total fabrication.

@d4v3y0rk
Copy link

There's no point mucking about with /etc/wsl.conf - it's utterly ignored, and the chattr +i part of the solution amounts to "make the file completely immutable", thereby preventing whatever WSL nonsense is clobbering the file at startup from doing what it pleases. The note in /etc/resolv.conf about how to prevent /etc/resolv.conf from being clobbered is just total fabrication.

I can confirm that the wsl.conf does nothing and that using the solution mention above with the +i attribute does work.

@ahickey-sfdc
Copy link

wsl --shutdown

It seems that changes to wsl.conf are only read when the subsystem completely restarts. I kept trying to get /etc/resolv.conf to stick around and it was overwritten every time I started a new wsl instance even with the +i attribute on /etc/resolv.conf. The only way to get it to stay for me was to do a wsl --shutdown once.

@hermdog
Copy link

hermdog commented Mar 22, 2021

sudo tee /etc/wsl.conf > /dev/null << EOF
[network]
generateResolvConf=false
EOF

echo -e 'nameserver 8.8.8.8\nnameserver 8.8.4.4' | sudo tee /etc/resolv.conf > /dev/null;
sudo chattr -f +i /etc/resolv.conf;

Yeah, sudo chattr -f +i /etc/resolv.conf set the file to immutable, and prevents the os from changing this file.

@hermdog
Copy link

hermdog commented Mar 22, 2021

wsl --shutdown

It seems that changes to wsl.conf are only read when the subsystem completely restarts. I kept trying to get /etc/resolv.conf to stick around and it was overwritten every time I started a new wsl instance even with the +i attribute on /etc/resolv.conf. The only way to get it to stay for me was to do a wsl --shutdown once.

Save the content in /etc/resolve.conf
Add to /etc/wsl.conf
[network]
generateResolvConf=false

run wsl --shutdown in powershell
return to linux, remove the old empty resolv.conf (bad link)
create a new resolv.conf with the saved content, as well as any change you want to stick around.

this should solve your problem.

@DesignByOnyx
Copy link

If you need to make changes to the file after running sudo chattr +i ..., then change the plus sign to a minus sign:

# make file mutable again
sudo chattr -i /etc/resolv.conf

@mdrijwan
Copy link

mdrijwan commented Aug 5, 2021

Ok, so I finally found solution in an old ticket: #1908 (comment)

So the full set of commands that have to be run is:

sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf

that worked for me like charm. thanks a bunch!

@anomaly256
Copy link

anomaly256 commented Aug 18, 2021

Save the content in /etc/resolve.conf
Add to /etc/wsl.conf
[network]
generateResolvConf=false

run wsl --shutdown in powershell
return to linux, remove the old empty resolv.conf (bad link)
create a new resolv.conf with the saved content, as well as any change you want to stick around.

this should solve your problem.

This just results in resolv.conf being deleted every time wsl starts for me now. Only workaround is to chattr +i resolv.conf which shouldn't be necessary - and I'm kind of astonished by how long this issue has persisted. Is it really so hard to just leave the dang file alone if generateResolvConf=false?

@kskalski
Copy link

On current Windows 11 build the /etc/resolv.conf (and /run/resolvconf/resolv.conf) are no longer generated (at least while using generateResolvConf=false in /etc/wsl.conf), however they are also not preserved after reboot.

Also, trying to set +i attribute on them results in error for me:

$ sudo chattr +i /etc/resolv.conf
chattr: Operation not supported while reading flags on /etc/resolv.conf
$ sudo chattr +i  /run/resolvconf/resolv.conf
chattr: Inappropriate ioctl for device while reading flags on /run/resolvconf/resolv.conf

@johnou
Copy link

johnou commented Sep 13, 2021

On current Windows 11 build the /etc/resolv.conf (and /run/resolvconf/resolv.conf) are no longer generated (at least while using generateResolvConf=false in /etc/wsl.conf), however they are also not preserved after reboot.

Also, trying to set +i attribute on them results in error for me:

$ sudo chattr +i /etc/resolv.conf
chattr: Operation not supported while reading flags on /etc/resolv.conf
$ sudo chattr +i  /run/resolvconf/resolv.conf
chattr: Inappropriate ioctl for device while reading flags on /run/resolvconf/resolv.conf

I had to delete /etc/resolv.conf first as it was a symlink to /run/resolvconf/resolv.conf you can verify by running stat /etc/resolv.conf

@pduchnovsky
Copy link

pduchnovsky commented Oct 16, 2021

I simply use this every time I set up a new WSL instance..

sudo bash -c 'echo -e "[network]
generateResolvConf = false" > /etc/wsl.conf
rm /etc/resolv.conf
echo -e "options timeout:1 attempts:1 rotate
nameserver 1.1.1.1
nameserver 1.0.0.1" > /etc/resolv.conf
chattr -f +i /etc/resolv.conf'

works even on windows 11.

@Aziks0
Copy link

Aziks0 commented Jun 1, 2022

@kevin-he-01 I'm on Windows 10.

This issue was about WSL2 on Windows 10, it then gets confusing because no one is saying if they are on W10 or W11.

Anyway, Windows being a mess, the solution from @0xbadfca11 works perfectly on W10, but apparently doesn't work on W11, as you and @anomaly256 stated. So I have no solution for W11, sorry (other than chattr +i I guess).


why did you close this as completed the same day it was created anyway?

@anomaly256 This issue was for Windows 10, and it was closed because the solution was provided. See what I wrote above.

I think that the appropriate issue for you both is #6977.

@jnawk
Copy link

jnawk commented Jun 1, 2022

Of course Microsoft won't fix it, they want to create the false impression that Linux is unstable and crap, and that everyone should just use Windows instead.

@ghost
Copy link

ghost commented Jun 7, 2022

@jnawk @kevin-he-01 @anomaly256 @Aziks0

Hello! Thanks for bringing this to my attention. This issue #8030 may provide some context to this, granted this change was made for WSL on Windows 11. For the time being, I would make a backup copy of your custom /etc/resolv.conf file before enabling/disabling the generateResolvConf option. After it is disabled (meaning post-restart), any changes made to the /etc/resolv.conf file should persist unless the option is enabled again.

@kevin-he-01
Copy link

Thank you! I think #8030 is exactly describing what many of us are facing. It's good to see that it is already fixed in the preview Store version, so I expect some later Windows releases will include it.
I prefer to have a stable version of WSL so I will not risk installing the Store version for now.

@ShahrinNakkhatra-optimizely

Ok, so I finally found solution in an old ticket: #1908 (comment)

So the full set of commands that have to be run is:

sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf

Hi, sudo chattr +i /etc/resolv.conf doesn't work for me. What works is sudo chattr +i /etc/. I mean I can apply this on the whole directory and make it read-only. But that doesn't stop resolv.conf from being overwritten the next time I reboot either.

@OttomanZ
Copy link

OttomanZ commented Aug 3, 2022

Setting DNS in /etc/resolv.conf

By default /etc/resolv.conf is overwritten in WSL,
so in order to go ahead and set the DNS to your preferred choice, you need to go ahead and create a new file /etc/wsl.conf and add the following configuration to the file.

[network]
generateResolvConf = false

In your /etc/resolv.conf go ahead and add your nameserver
as follows

sudo rm -r /etc/resolv.conf
sudo nano /etc/resolv.conf

Configuration

nameserver 1.1.1.1
nameserver 8.8.8.8

Final / Most Important Step

Run the following command in your terminal, Note: Do not close your terminal while doing this entire process or it may overwrite your /etc/resolv.conf

  1. Force Disable Overwrite using -f +i, (to enable again you can do -i flag).
sudo chattr -f +i /etc/resolv.conf
  1. In a new Powershell terminal window, run the following command without closing the above terminal.
wsl --shutdown

Then, start wsl again.

wsl

This Should Fix It!

@framerate
Copy link

Odd, for some reason resolv.conf is no long writeable?
image

@jnawk
Copy link

jnawk commented Aug 12, 2022

Odd, for some reason resolv.conf is no long writeable? image

If you've made the file immutable with chattr +i then yeah, you won't be able to remove it even with sudo - first you'll have to undo the immutability with chattr -i

@admin-nesing
Copy link

nothing worked for me but what worked for me was to edit ~/.bashrc file. Just add the following line to the end:

echo 'nameserver 8.8.8.8' | sudo tee -a /etc/resolv.conf > /dev/null

@SeattleRex
Copy link

Of course Microsoft won't fix it, they want to create the false impression that Linux is unstable and crap, and that everyone should just use Windows instead.

I kind of get the opposite impression. The 100+ instances of Debian I've used before have all worked quite well, and resolv.conf has never been a problem ... until I tried to run Debian on Windows. Leave it to M$ to f *** up a stable aspect of a stable OS.

M$ could screw up a one-car funeral.

@SeattleRex
Copy link

I simply use this every time I set up a new WSL instance..

sudo bash -c 'echo -e "[network]
generateResolvConf = false" > /etc/wsl.conf
rm /etc/resolv.conf
echo -e "options timeout:1 attempts:1 rotate
nameserver 1.1.1.1
nameserver 1.0.0.1" > /etc/resolv.conf
chattr -f +i /etc/resolv.conf'

works even on windows 11.

I don't know whether to laugh, cry, or give you kudos and just move on.

A few years from now, I can see:

"Hey guys, I finally figured out how to make it work, each time you want to use Debian, cat the source directories of debian--src, pipe it to gcc, wait a few minutes, and PRESTO! It's so intuitive, anyone could do it!"

@jnawk
Copy link

jnawk commented Aug 21, 2022

Of course Microsoft won't fix it, they want to create the false impression that Linux is unstable and crap, and that everyone should just use Windows instead.

I kind of get the opposite impression. The 100+ instances of Debian I've used before have all worked quite well, and resolv.conf has never been a problem ... until I tried to run Debian on Windows. Leave it to M$ to f *** up a stable aspect of a stable OS.

M$ could screw up a one-car funeral.

you rather make my point, but think if this was your only experience with Linux.

@qwang07
Copy link

qwang07 commented Sep 16, 2022

Try this, it works for me:

$ cat /etc/wsl.conf
[network]
generateResolvConf = false

[boot]
command = echo "nameserver 1.1.1.1" > /etc/resolv.conf

It also works after reboot/shutdown the WSL.

However, it only works with one line, when I try:

$ cat /etc/wsl.conf
[network]
generateResolvConf = false

[boot]
command = echo "nameserver 1.1.1.1\nnameserver 8.8.8.8" > /etc/resolv.conf

After restart WSL, resolv.conf will be empty.

@liudonghua123
Copy link

liudonghua123 commented Sep 16, 2022

@qwang07 This line echo "nameserver 1.1.1.1\nnameserver 8.8.8.8" > /etc/resolv.conf is incorrect. You can't use \n in echo command without -e option.

liudonghua@DESKTOP-DELL:~$ echo "nameserver 1.1.1.1\nnameserver 8.8.8.8" > /tmp/resolv.conf
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv.conf
nameserver 1.1.1.1\nnameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$ # 
liudonghua@DESKTOP-DELL:~$ # use cat with Ctrl+D 
liudonghua@DESKTOP-DELL:~$ cat > /tmp/resolv-1.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
# press Ctrl+D to terminate
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv-1.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$ # use cat with EOL delimiter
liudonghua@DESKTOP-DELL:~$ cat > /tmp/resolv-2.conf << EOL
> nameserver 1.1.1.1
> nameserver 8.8.8.8
> EOL
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv-2.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$ # use echo with unfinished quotes
liudonghua@DESKTOP-DELL:~$ echo "nameserver 1.1.1.1
> nameserver 8.8.8.8" > /tmp/resolv-3.conf
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv-3.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$ # use echo -e
liudonghua@DESKTOP-DELL:~$ echo -e "nameserver 1.1.1.1\nnameserver 8.8.8.8" > /tmp/resolv-4.conf
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv-4.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$
liudonghua@DESKTOP-DELL:~$ cat << EOL > /tmp/resolv-5.conf
> nameserver 1.1.1.1
> nameserver 8.8.8.8
> EOL
liudonghua@DESKTOP-DELL:~$ cat /tmp/resolv-5.conf
nameserver 1.1.1.1
nameserver 8.8.8.8
liudonghua@DESKTOP-DELL:~$ ll /tmp/resolv*
-rw-r--r-- 1 liudonghua liudonghua 38 Sep 16 11:38 /tmp/resolv-1.conf
-rw-r--r-- 1 liudonghua liudonghua 38 Sep 16 11:42 /tmp/resolv-2.conf
-rw-r--r-- 1 liudonghua liudonghua 38 Sep 16 12:16 /tmp/resolv-3.conf
-rw-r--r-- 1 liudonghua liudonghua 38 Sep 16 12:20 /tmp/resolv-4.conf
-rw-r--r-- 1 liudonghua liudonghua 38 Sep 16 12:48 /tmp/resolv-5.conf
-rw-r--r-- 1 liudonghua liudonghua 39 Sep 16 11:37 /tmp/resolv.conf
liudonghua@DESKTOP-DELL:~$

@manoxs
Copy link

manoxs commented Nov 30, 2022

nothing worked for me but what worked for me was to edit ~/.bashrc file. Just add the following line to the end:

echo 'nameserver 8.8.8.8' | sudo tee -a /etc/resolv.conf > /dev/null

This is the only workaround that work for me, the only comment is that it requires admin access to modify resolv.conf, I found a work around, Adding a script when login.

  cd /etc/profile.d

  sudo vim./resolvFix.sh
 (you write commands here, for ex: echo 'nameserver 8.8.8.8' | sudo tee -a /etc/resolv.conf > /dev/null)

  sudo chmod +x resolvFix.sh

@m29a
Copy link

m29a commented Dec 16, 2022

Try restarting windows after changing wsl.conf
I had issue with adding widows PATH to wsl PATH and it didn't work until I restart pc

@y1ngyang
Copy link

Ok, so I finally found solution in an old ticket: #1908 (comment)

So the full set of commands that have to be run is:

sudo rm /etc/resolv.conf
sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
sudo bash -c 'echo "[network]" > /etc/wsl.conf'
sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
sudo chattr +i /etc/resolv.conf

thank you

@slycordinator
Copy link
Contributor

And for portability sake, it might be better to use printf instead.

If your script uses /bin/sh, the -e option for echo likely will cause it to print the '-e'

In dash:

$ echo -e "nameserver 1.1.1.1\nnameserver 8.8.8.8"
-e nameserver 1.1.1.1
nameserver 8.8.8.8
$ printf 'nameserver %s\nnameserver %s\n' 1.1.1.1 8.8.8.8
nameserver 1.1.1.1
nameserver 8.8.8.8
$

@qwang07 This line echo "nameserver 1.1.1.1\nnameserver 8.8.8.8" > /etc/resolv.conf is incorrect. You can't use \n in echo command without -e option.

@teeesss
Copy link

teeesss commented Jan 5, 2024

I like this approach.

Makes /root/resolv.conf.sh executable using wsl.conf boot command
Deletes the /etc/resolv.conf file on start-up
Runs the script /etc/resolv.conf.sh and populated with DNS servers from the script.
Change the servers as desired: DNS_SERVERS=("9.9.9.9" "1.1.1.1" "8.8.8.8")
Outputs a log file to /root/resolv.conf.log

vi /etc/wsl.conf

[boot]
command = /bin/bash chmod +x /root/resolv.conf.sh; /bin/bash /root/resolv.conf.sh > /root/resolv.conf.log 2>&1
systemd=true

vi /root/resolv.conf.sh

#!/bin/bash

# Specify the DNS servers
DNS_SERVERS=("9.9.9.9" "1.1.1.1" "8.8.8.8")

# Log file path
LOG_FILE="/root/resolv.conf.log"

# Delete the existing /etc/resolv.conf
sudo rm /etc/resolv.conf

# Create or update the /etc/resolv.conf file
for server in "${DNS_SERVERS[@]}"; do
    echo "nameserver $server" | sudo tee -a /etc/resolv.conf
done

# Log the changes to the specified log file
echo "DNS servers updated: $(date)" | sudo tee -a "$LOG_FILE"

@gpettey-ercot
Copy link

gpettey-ercot commented Oct 17, 2024

This or a similar issue is recurring. With Ubuntu 24.04, generateResolvConf=false in /etc/wsl.conf is no longer being respected. The file is overwritten every time with a bad configuration for my network.

wsl --version
WSL version: 2.3.24.0
Kernel version: 5.15.153.1-2
WSLg version: 1.0.65
MSRDC version: 1.2.5620
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.22621.4317

The solution to this was setting values in /etc/systemd/resolved.conf, e.g. DNS=1.1.1.1 8.8.8.8 and Domains=example.com.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests