`root` is not a trusted user → it is, but warning messages say otherwise

For reasons I’ll share below, I need to use my own ad-hoc substituter. To skip configuring signatures etc., I run the command as root. I am however denied access. Both

sudo nixos-rebuild build --option extra-substituters 'unix:///tmp/nix.sock?trusted=true' --flake .

and

sudo nix --option extra-substituters 'unix:///tmp/nix.sock?trusted=true' build .#nixosConfigurations."hostname".config.system.build.toplevel

give me

warning: ignoring untrusted substituter 'unix:///tmp/nix.sock?trusted=true', you are not a trusted user.
Run `man nix.conf` for more information on the `substituters` configuration option.

and use the default substituter instead. When I C-C the command, I also get

error (ignored): error: opening a connection to remote store 'unix:///tmp/nix.sock' previously failed

but I don’t think that’s the primary reason of the failure. To rule that out I tried a completely different command to interact with the store, basically following the documentation of nix log. The command

sudo nix log --store unix:///tmp/nix.sock /nix/store/lmngj4wcm9rkv3w4dfhzhcyij3195hiq-thunderbird-52.2.1

fails with

warning: ignoring the client-specified setting 'store', because it is a restricted setting and you are not a trusted user

and then presents me with some log, probably fetched from the default binary cache.

I’d guess that root is always trusted, but it is even explicitly listed in the config /etc/nix/nix.conf, which is otherwise pretty standard NixOS generated

# WARNING: this file is generated from the nix.* options in
# your NixOS configuration, typically
# /etc/nixos/configuration.nix.  Do not edit it!
allowed-users = *
auto-optimise-store = false
builders = 
cores = 0
max-jobs = auto
require-sigs = true
sandbox = true
sandbox-fallback = false
substituters = https://cache.nixos.org/
system-features = nixos-test benchmark big-parallel kvm
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
trusted-substituters = 
trusted-users = root
extra-sandbox-paths = 
experimental-features = nix-command flakes

Could you please help me understand what’s going on and how I could convince the nix-daemon to do what I want?


In case you are interested in what I am trying to achieve, here you go. I’m happy to also hear your suggestion how to achieve the same goal.

I am running NixOS on a lot of my home machines. When a new release comes out, it means downloading up to 8 GB per device. I obviously have to do it at least once, but it just doesn’t feel right to do it 5×, especially with respect to over-utilizing the free public NixOS infrastructure. So I simply want to upgrade one of my devices and let the other download as much as possible from it and only use the public cache for the few packages where they differ. On the other hand, it is 5 home computers, not 50, so I’m looking for a simple ad-hoc solution, not setting up a full binary cache, configuring signing, marking the signatures as trusted etc. So my plan was to do a regular upgrade on one of the computers and then on all others copy the flake.lock, ssh to the upgraded machine and tunnel nix-daemon’s socket. Then do a regular upgrade on the machine while passing a substituter such that packages on common are downloaded from the upgraded machine. I have root access to all of them so there should not be any security concerns (I could rsync their stores if I wanted to).

Maybe the other side of the socket doesn’t recognize you?

How are the settings there?

Also, I think that running an ad-hoc nix-serve(-ng) might be easier to setup.

I can see connection to the socket made on the other side. The user I am connecting to is not a trusted user on the other side. Does it matter? I though read-only access would be enough.

Anyway that doesn’t explain the error messages as they are emitted on the local side, does it?

I’ll have a look at nix-server, didn’t know about it. Thanks

I do not know the very details of the protocol used here, though my assumption is, that if you use a socket as substitutor or store, that you have to have according permissions on the other side.

And if the socket repliyes with “you are not allowed”, then I do not see why the local CLI shouldn’t print it. But if several different deamons are involved, it would have been nice, if the CLI would tell us, which of these deamons is complaining.

Update: at first I observed that the option -option extra-substituters is ignored, but that was caused by other issues with the invocation.

If I do it exactly as I describe in the original post, it actually works, one just has to also have access to the original store e.g. through a sshfs mount (beware that you have to somehow accessible for the root user, it is not the default for FUSE). Running it with –option extra-substituters ‘unix:///tmp/nix.sock?trusted=true&real=/tmp/remote-store-mount/nix/store’ actually does what I wanted to though it falsely vomits all the errors messages mentioned above.

TL;DR The root user is treated as a trusted user in the end, but it is constantly being logged that it isn’t.