[GH-ISSUE #3649] private-etc=resolv.conf will not update for changed DNS server #2299

Open
opened 2026-05-05 08:59:27 -06:00 by gitea-mirror · 10 comments
Owner

Originally created by @haarp on GitHub (Sep 29, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3649

Hello,

I have witnessed this problem with Discord, but I believe it to be a generic issue.

With private-etc=resolv.conf, the jail will receive a copy of the system's resolv.conf. If the system is now moved to a different location/network with a different DNS server, the system's resolv.conf will be updated to use the new server, but the jail's resolv.conf will not. DNS requests will henceforth fail in the jail as they try to use an unreachable server.

Ideally the jail's resolv.conf should be kept in sync with the system's, but this might require special handling of this file.
Alternatively, the DNS server in the jail's resolv.conf could be set to a globally reachable one instead of the local network's one, such as 1.1.1.1, with dns=1.1.1.1. But this unlikely to be in everyone's interest.

Reproduce

  • firejail --noprofile --private-etc=resolv.conf bash -c 'while true; do cat /etc/resolv.conf; getent hosts google.com; sleep 5; done'
  • While this runs, move the machine to a different network with different DNS resolver
  • -> resolv.conf won't be updated, getent fails.

Environment
Gentoo Linux, firejail-0.9.62-r1

Thanks!

Originally created by @haarp on GitHub (Sep 29, 2020). Original GitHub issue: https://github.com/netblue30/firejail/issues/3649 Hello, I have witnessed this problem with Discord, but I believe it to be a generic issue. With `private-etc=resolv.conf`, the jail will receive a copy of the system's resolv.conf. If the system is now moved to a different location/network with a different DNS server, the system's resolv.conf will be updated to use the new server, but the jail's resolv.conf will not. DNS requests will henceforth fail in the jail as they try to use an unreachable server. Ideally the jail's resolv.conf should be kept in sync with the system's, but this might require special handling of this file. Alternatively, the DNS server in the jail's resolv.conf could be set to a globally reachable one instead of the local network's one, such as 1.1.1.1, with `dns=1.1.1.1`. But this unlikely to be in everyone's interest. **Reproduce** - `firejail --noprofile --private-etc=resolv.conf bash -c 'while true; do cat /etc/resolv.conf; getent hosts google.com; sleep 5; done'` - While this runs, move the machine to a different network with different DNS resolver - -> resolv.conf won't be updated, getent fails. **Environment** Gentoo Linux, firejail-0.9.62-r1 Thanks!
gitea-mirror added the
bug
networking
labels 2026-05-05 08:59:27 -06:00
Author
Owner

@rusty-snake commented on GitHub (Sep 29, 2020):

Ideally the jail's resolv.conf should be kept in sync with the system's, but this might require special handling of this file.

Instead of coping, we could bind-mount all the file.

Alternatively, the DNS server in the jail's resolv.conf could be set to a globally reachable one instead of the local network's one, such as 1.1.1.1, with dns=1.1.1.1.

Sending all the DNS-query of everybody to clownflare. bad idea. What we could do is setting it 127.0.0.1 (or what ever) and have a simple dns-forwarder there. Such as dnsmasq. Or we can use fdns, but not everyone want this.

<!-- gh-comment-id:700706563 --> @rusty-snake commented on GitHub (Sep 29, 2020): > Ideally the jail's resolv.conf should be kept in sync with the system's, but this might require special handling of this file. Instead of coping, we could bind-mount all the file. > Alternatively, the DNS server in the jail's resolv.conf could be set to a globally reachable one instead of the local network's one, such as 1.1.1.1, with dns=1.1.1.1. Sending all the DNS-query of everybody to clownflare. bad idea. What we could do is setting it 127.0.0.1 (or what ever) and have a simple dns-forwarder there. Such as dnsmasq. Or we can use fdns, but not everyone want this.
Author
Owner

@haarp commented on GitHub (Sep 29, 2020):

Instead of coping, we could bind-mount all the file.

According to the manpage, bind-mounts only work as root, so that's unfortunately not a solution most of the time

Sending all the DNS-query of everybody to clownflare. bad idea.

Indeed. And running an additional local service is probably not a great option either. This is a bit tricky.

<!-- gh-comment-id:700781236 --> @haarp commented on GitHub (Sep 29, 2020): > Instead of coping, we could bind-mount all the file. According to the manpage, bind-mounts only work as root, so that's unfortunately not a solution most of the time > Sending all the DNS-query of everybody to clownflare. bad idea. Indeed. And running an additional local service is probably not a great option either. This is a bit tricky.
Author
Owner

@rusty-snake commented on GitHub (Sep 29, 2020):

Instead of coping, we could bind-mount all the file.

According to the manpage, bind-mounts only work as root, so that's unfortunately not a solution most of the time.

The --bind option is restricted to root for security reasons (btw: there is a FR to allow it for users in there home). (bind-)mounting isn't a issue since firejail is suid.

This should work I think (will test later):

--whitelist=/etc/resolv.conf
<!-- gh-comment-id:700925560 --> @rusty-snake commented on GitHub (Sep 29, 2020): >> Instead of coping, we could bind-mount all the file. > > According to the manpage, bind-mounts only work as root, so that's unfortunately not a solution most of the time. The `--bind` option is restricted to root for security reasons (btw: there is a FR to allow it for users in there home). (bind-)mounting isn't a issue since firejail is suid. This should work I think (will test later): ``` --whitelist=/etc/resolv.conf ```
Author
Owner

@haarp commented on GitHub (Sep 29, 2020):

This should work I think (will test later):

--whitelist=/etc/resolv.conf

Just tested it, it doesn't. --whitelist doesn't seem to propagate system changes down to the whitelisted file(s), only the other way around (?)

Also, --private-etc=foo,bar,baz --whitelist=/etc/foo don't seem to work in combination, bar and baz are missing.
Even weirder is the case --private-etc=bar,baz --whitelist=/etc/foo. /etc is now completely empty.

<!-- gh-comment-id:700985708 --> @haarp commented on GitHub (Sep 29, 2020): > This should work I think (will test later): > > ``` > --whitelist=/etc/resolv.conf > ``` Just tested it, it doesn't. `--whitelist` doesn't seem to propagate system changes down to the whitelisted file(s), only the other way around (?) Also, `--private-etc=foo,bar,baz --whitelist=/etc/foo` don't seem to work in combination, bar and baz are missing. Even weirder is the case `--private-etc=bar,baz --whitelist=/etc/foo`. /etc is now completely empty.
Author
Owner

@rusty-snake commented on GitHub (Sep 30, 2020):

Just tested it, it doesn't. --whitelist doesn't seem to propagate system changes down to the whitelisted file(s), only the other way around (?)

In general are changes from system to sandbox propagated. However if resolv.conf is a file (not a symlink) it can be edited (which will work) or replaced (which does not work) by the controlling program.

This means bind-mounting doesn't help either.

<!-- gh-comment-id:701289119 --> @rusty-snake commented on GitHub (Sep 30, 2020): > Just tested it, it doesn't. --whitelist doesn't seem to propagate system changes down to the whitelisted file(s), only the other way around (?) In general are changes from system to sandbox propagated. However if resolv.conf is a file (not a symlink) it can be edited (which will work) or replaced (which does not work) by the controlling program. This means bind-mounting doesn't help either.
Author
Owner

@smitsohu commented on GitHub (Dec 26, 2020):

Also, --private-etc=foo,bar,baz --whitelist=/etc/foo don't seem to work in combination, bar and baz are missing.
Even weirder is the case --private-etc=bar,baz --whitelist=/etc/foo. /etc is now completely empty.

@haarp Combining --private-etc and whitelist is possible but not very meaningful. To get you closer to where you want, just use whitelist exclusively

ignore private-etc
whitelist /etc/resolv.conf
whitelist /etc/foo
whitelist /etc/bar
whitelist /etc/baz
[...]

But as @rusty-snake says, this only works if /etc/resolv.conf is updated by writing to the file. It doesn't work if the file is updated by replacing it, which seems to be what NetworkManager does, only for example.

<!-- gh-comment-id:751357452 --> @smitsohu commented on GitHub (Dec 26, 2020): > Also, --private-etc=foo,bar,baz --whitelist=/etc/foo don't seem to work in combination, bar and baz are missing. Even weirder is the case --private-etc=bar,baz --whitelist=/etc/foo. /etc is now completely empty. @haarp Combining `--private-etc` and `whitelist` is possible but not very meaningful. To get you closer to where you want, just use `whitelist` exclusively ``` ignore private-etc whitelist /etc/resolv.conf whitelist /etc/foo whitelist /etc/bar whitelist /etc/baz [...] ``` But as @rusty-snake says, this only works if `/etc/resolv.conf` is updated by writing to the file. It doesn't work if the file is updated by replacing it, which seems to be what NetworkManager does, only for example.
Author
Owner

@msva commented on GitHub (Jun 8, 2021):

isn't it still a way to somehow fix/workaround that (in case of NetworkManager)?

<!-- gh-comment-id:857219965 --> @msva commented on GitHub (Jun 8, 2021): isn't it still a way to somehow fix/workaround that (in case of NetworkManager)?
Author
Owner

@rusty-snake commented on GitHub (Jun 9, 2021):

If NM operates in rc-manager=symlink mode and /etc/resolv.conf is a symlink to /run/NetworkManager/resolv.conf it should work I guess.

<!-- gh-comment-id:857864654 --> @rusty-snake commented on GitHub (Jun 9, 2021): If NM operates in rc-manager=symlink mode and `/etc/resolv.conf` is a symlink to `/run/NetworkManager/resolv.conf` it should work I guess.
Author
Owner

@msva commented on GitHub (Aug 25, 2021):

Well, actually, it is symlink to /run/systemd/resolve/resolv.conf. And it's content changes every time when NM connects to different networks with different DNS servers (but not inside jail).

BTW, /run/NetworkManager/resolv.conf somewhy contains an address of systemd-resolved (127.0.0.53) instead of current connection's DNS servers.

<!-- gh-comment-id:905653140 --> @msva commented on GitHub (Aug 25, 2021): Well, actually, it is symlink to `/run/systemd/resolve/resolv.conf`. And it's content changes every time when NM connects to different networks with different DNS servers (but not inside jail). BTW, `/run/NetworkManager/resolv.conf` somewhy contains an address of systemd-resolved (`127.0.0.53`) instead of current connection's DNS servers.
Author
Owner

@aurelf commented on GitHub (May 19, 2025):

I'm running into this issue, which I can reliably reproduce (with NetworkManager on Arch) and none of the workarounds seem to work (only solution now is to restart Firefox every time I change network). Here is some of the tests I did:

  • resolv.conf is a symlink to /run/NetworkManager/resolv.conf but it wasn't initially, and it didn't change anything.
  • firejail --dns.print reports the same (incorrect) DNS as can be seen from file:///run/NetworkManager/resolv.conf or file:///run/NetworkManager/resolv.conf
  • when passing --dns=1.1.1.1 dns.print first reports 1.1.1.1 but on the next network change it goes back to the initial DNS settings, and breaks.

So it looks like that whatever the configuration I'm using, the same initial resolv.conf is forced on network change. Any idea where to look at?

<!-- gh-comment-id:2890197657 --> @aurelf commented on GitHub (May 19, 2025): I'm running into this issue, which I can reliably reproduce (with NetworkManager on Arch) and none of the workarounds seem to work (only solution now is to restart Firefox every time I change network). Here is some of the tests I did: - `resolv.conf` is a symlink to `/run/NetworkManager/resolv.conf` but it wasn't initially, and it didn't change anything. - `firejail --dns.print` reports the same (incorrect) DNS as can be seen from `file:///run/NetworkManager/resolv.conf` or `file:///run/NetworkManager/resolv.conf` - when passing `--dns=1.1.1.1` dns.print first reports 1.1.1.1 but on the next network change it goes back to the initial DNS settings, and breaks. So it looks like that whatever the configuration I'm using, the same initial `resolv.conf` is forced on network change. Any idea where to look at?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#2299
No description provided.