NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
11.97k stars 1.46k forks source link

DNS resolution breaks on NixOS when having static resolv.conf #11004

Open dasJ opened 1 month ago

dasJ commented 1 month ago

This breaks on NixOS when having static resolv.conf. Nix now copies the /etc/resolv.conf symlink (pointing to /etc/static) to the sandbox, resulting in a dangling symlink and breaking all DNS resolution inside the sandbox.

2.19.4: image

2.19.5: image

Originally posted by @dasJ in https://github.com/NixOS/nix/issues/10456#issuecomment-2200473299

kjahn-feti commented 1 month ago

Hi, @dasJ, could you please include the command you used to produce the above screenshots or a MWE, so I could learn and try to reproduce the issue for myself? Many thx!

dasJ commented 1 month ago

Yeah would've been an obvious thing to do :D

nix-build -E '(import <nixpkgs> {}).runCommand "test" {outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";} "ls -la /etc"'
roberth commented 1 month ago

I think the simplest solution is to make a copy of the resolv.conf contents.

Alternatively, we could resolve the symlink and add its target to the sandbox-paths for FODs. That's more accurate, but also more complicated and riskier.

Yet another alternative is to make NixOS point /etc/resolve.conf directly into the store instead of /etc/static, so that NixOS can add it to sandbox-paths. That's less atomic, but atomic switching is a bit of misnomer anyway, considering the limitations of systemd.

Note that these options all need to work to support changes to resolv.conf during a build (e.g. switching wifi while building, or nixos-rebuild switch on a server with concurrent Nix users), but here again the solution to just copy the contents seems simplest, by not having to change sandbox-paths after creating the sandbox.

dasJ commented 1 month ago

Yet another alternative is to make NixOS point /etc/resolve.conf directly into the store

Would work in this specific case, but would not work on non-nixos-systems with systemd-resolved: https://wiki.archlinux.org/title/Systemd-resolved#DNS

mgdbbrt commented 1 month ago

DNS via systemd-resolved is already broken on non-NixOS systems since #10456.

edolstra commented 3 weeks ago

Alternatively, we could resolve the symlink and add its target to the sandbox-paths for FODs.

I think this is the easiest fix (resolve the paths in sandbox-paths but not other paths like the input closure).

nixos-discourse commented 3 weeks ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2024-07-31-nix-team-meeting-minutes-166/49972/1

edolstra commented 3 weeks ago

Unfortunately I can't reproduce this. On Nix 2.24.0 and NixOS 24.05, I get:

# ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 23 Aug  2 16:58 /etc/resolv.conf -> /etc/static/resolv.conf

# nix-build -E '(import <nixpkgs> {}).runCommand "test" {outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";} "ls -la /etc"'
this derivation will be built:
  /nix/store/x5jdrr0h57kqmf6d9nj7w9wpzfmikwbl-test.drv
building '/nix/store/x5jdrr0h57kqmf6d9nj7w9wpzfmikwbl-test.drv'...
total 226
dr-xr-xr-x 3 nobody nogroup      9 Aug  2 15:06 .
drwxr-x--- 9 nobody nixbld       9 Aug  2 15:06 ..
-rw-r--r-- 1 nobody nogroup     41 Aug  2 15:06 group
-r--r--r-- 4 nobody nogroup     66 Jan  1  1970 hosts
-rw-r--r-- 1 nobody nogroup     33 Aug  2 15:06 nsswitch.conf
-rw-r--r-- 1 nobody nogroup    130 Aug  2 15:06 passwd
-r--r--r-- 2 nobody nogroup     42 Jan  1  1970 resolv.conf
-r--r--r-- 2 nobody nogroup 561132 Jan  1  1970 services
drwxr-xr-x 3 nobody nogroup      3 Aug  2 15:06 ssl
amarshall commented 3 weeks ago

Tested on various versions on non-NixOS where /etc/resolv.conf is a symlink to /run/systemd/resolve/resolv.conf:

Those that succeed, /etc/resolv.conf within the sandbox is a regular file.

So this is fixed in newer versions. I believe the fix is https://github.com/NixOS/nix/pull/10482. Would be nice if that was backported to the broken versions.