Nixos-rebuild remote target with non-root user

I would like to be able to manage multiple hosts from a single flake on my main computer (i.e. without having to keep configurations in sync between machines).

I have my nixos configs set up as a flake with multiple hosts, something like:

nixosConfigurations = {
	host1 = ...
	host2 = ...
};

I can run sudo nixos-rebuild switch --flake .#host1 on host1 to build the local system.

The nixos-rebuild man page shows I can use --target-host to rebuild a remote host.
I cannot, however, get this to run due to permission errors.
Running nixos-rebuild --target-host "host2" --use-remote-sudo test --flake ".#host2" on host1 fails with:

sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required

I can’t find anything on this error in this context (The wiki mentions using nixos-rebuild to rebuild a remote system as a non-root user, but it runs the command in the same way that I have without any indication of this problem).
I have added the remote user to the remote’s nix.settings.trusted-users and the host is in my ~/.ssh/config so running ssh host2 works without needing a password.
On the remote host, I have ssh enabled via services.openssh = { enable = true; };, all other services.openssh options are default.

To do this would I have to enable permitRootLogin for this to work?

I think it might only work if your sudo is password less. At least it works for me like that.

Yeah that works. I don’t know how I feel about turning off the password though (there’s probably no risk, especially now that it’s not hosting any public services but I intend on running a few sites eventually).

Weirdly, if I set the extra security to nopasswd for all:

  security.sudo.extraRules = [{
    users = [ "user" ];
    runAs = "ALL:ALL";
    commands = [{
      command = "ALL";
      options = [ "NOPASSWD" ];
    }];
  }];

It works. But, if I set it to only allow nixos-rebuild without password:

  security.sudo.extraRules = [{
    users = [ "user" ];
    runAs = "ALL:ALL";
    commands = [{
      command = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
      options = [ "NOPASSWD" ];
    }];
  }];

It doesn’t ask for a password when I’m ssh’d into the server (i.e. closed connection then reconnected so it wouldn’t remember if I recently entered my password), but when I’m on my main computer telling it to build the server I still get the complaint that I need to enter my password.

I wonder if the --use-remote-sudo flag is running specific commands using sudo instead of running nixos-rebuild as root as a whole? I would have thought that nixos-rebuild would have called ssh host nixos-rebuild ... if called with a different target but I don’t know. I’ll take a closer look at the script.

In the mean time, this is good for now. Thank you

There’s different ways it can work. Like you can choose where it does the building.

You can look at this blog post for a little more info

Otherwise you might need to read the source

Thanks, I’m working through the source code now. Trying to figure out what commands actually get called with sudo. Looks like just commands called using targetHostCmd and buildHostCmd so think I can white list the few things those call.

1 Like

Actually, don’t think this is possible as it requires running switch-to-configuration which is generated as part of the new system under ${out}/bin/switch-to-configuration. Since the next new system doesn’t exist when the sudoers file is created it can’t be added to the list of commands that don’t require a password.

Think no password for the user is fine so long as no services are run as that user.

1 Like

If you keep the flake in a git repo, you might want to have a look at GitHub - rapenne-s/bento: A KISS deployment tool to keep your NixOS fleet (servers & workstations) up to date.

What I do here is:

  • If a get asked for a password when calls ssh root@myTargetHost then ssh-copy-id root@myTargetHost
  • nixos-rebuild --target-host root@myTargetHost ...

This works fine for me.

@wamserma, I’ve looked at a few deployment methods but I have a simple use case and if nixos-rebuild has a way for doing this, I don’t see a reason to learn a new tool.

@ngiger, using root is another option. I was trying to avoid it for security reasons but allowing another user to run all commands without password, as with the other solution suggested, is probably equivalent. Using a root user may be a little easier to set up since you don’t have to mess with the sudoers file though.

Bento seems reasonably simple and imho is the best way to go if you keep the “no root” requirement. Otherwise set up a key-based root login and use nixos-rebuild.