nix-darwin icon indicating copy to clipboard operation
nix-darwin copied to clipboard

Avoid typing password on `darwin-rebuild switch`

Open nikitavoloboev opened this issue 5 years ago • 13 comments

Is it possible to make it so users don't have to type in password every time you run darwin-rebuild switch for first time in a while?

I get that it might be a security issue? But I would still love to overwrite this behavior and not have the password prompt come up for me.

Thank you.

nikitavoloboev avatar Oct 03 '19 18:10 nikitavoloboev

This depends on your sudo config. nix-darwin does not currently have a module that manages /etc/sudoers so you have to do it manually:

run sudo visudo to edit /etc/sudoers, at the end of the file find the line:

%admin		ALL = (ALL) ALL

and change it to:

%admin		ALL = (ALL) NOPASSWD: ALL

C'est tout.

Do note that this means that you won't be prompted for password at all when using sudo. Ever. Not just for darwin-rebuild; which may or may not be what you want. Hope this helps.

kaii-zen avatar Dec 25 '19 17:12 kaii-zen

I was able to get this working via

cat /etc/sudoers.d/10-nix-commands

myuser ALL=(ALL:ALL) NOPASSWD: /run/current-system/sw/bin/darwin-rebuild, /run/current-system/sw/bin/nix-env, /run/current-system/sw/bin/nix-build, /bin/launchctl, /run/current-system/sw/bin/ln, /nix/store/*/activate

although to be clear, im not recommending said sudoers override :)

CorbanR avatar Apr 14 '20 23:04 CorbanR

To add to the above, we can use Nix to manage the new sudoers file:

  environment.etc = {
    "sudoers.d/10-nix-commands".text = ''
      %admin ALL=(ALL:ALL) NOPASSWD: /run/current-system/sw/bin/darwin-rebuild, \
                                     /run/current-system/sw/bin/nix*, \
                                     /run/current-system/sw/bin/ln, \
                                     /nix/store/*/activate, \
                                     /bin/launchctl
    '';
  };

Edit: Please don't do this. See @lilyball's comments further down.

andreykaipov avatar Dec 22 '20 17:12 andreykaipov

~@andreykaipov's solution works~, I wanted to be extra fancy so I did it like this...

environment.etc = {
  "sudoers.d/10-nix-commands".text = let
    commands = [
      "/run/current-system/sw/bin/darwin-rebuild"
      "/run/current-system/sw/bin/nix*"
      "/run/current-system/sw/bin/ln"
      "/nix/store/*/activate"
      "/bin/launchctl"
    ];
    commandsString = builtins.concatStringsSep ", " commands;
  in ''
    %admin ALL=(ALL:ALL) NOPASSWD: ${commandsString}
  '';

Update: do make sure you have a newline at the end like in these examples - otherwise you might lose your sudo ability, like I just did.

Also: I'm still getting this every time I rebuild:

sudo: /private/etc/sudoers.d/10-nix-commands is owned by uid 501, should be 0

Update 2: It still asks me about the password (I assume because of the above). This is true for both my expression above and Andrey's.

Update 3: I put this in the sudoers.d directory manually, it seems to work. Apparently the file that nix-darwin puts a symlink for should also be owned by root, but it's owned by my current user.

Update 4: Don't do this. Read below.

kubukoz avatar Jan 22 '21 02:01 kubukoz

sudo has its -S flag for getting password from stdin.

       -S, --stdin Write the prompt to the standard error and read the password
                   from the standard input instead of using the terminal device.
echo pssw0rd | sudo -S echo hello

Can darwin-rebuild also provide a flag like this?

0ihsan avatar Feb 03 '21 21:02 0ihsan

I started using my touch id for sudo passwords through adding

auth       sufficient     pam_tid.so

to /etc/pam.d/sudo as first line.

0ihsan avatar Mar 01 '21 22:03 0ihsan

@kubukoz

~@andreykaipov's solution works~, I wanted to be extra fancy so I did it like this...

environment.etc = {
  "sudoers.d/10-nix-commands".text = let
    commands = [
      "/run/current-system/sw/bin/darwin-rebuild"
      "/run/current-system/sw/bin/nix*"
      "/run/current-system/sw/bin/ln"
      "/nix/store/*/activate"
      "/bin/launchctl"
    ];
    commandsString = builtins.concatStringsSep ", " commands;
  in ''
    %admin ALL=(ALL:ALL) NOPASSWD: ${commandsString}
  '';

This seems like a fantastic way to hand root access to every process running on your user account.

lilyball avatar Apr 29 '21 18:04 lilyball

How?

kubukoz avatar Apr 29 '21 21:04 kubukoz

You don't require a password already to edit the darwin config file (at least not in the default setup, this is mentioned in https://github.com/LnL7/nix-darwin/issues/326), so no password required to do sudo darwin-rebuild would allow any process running as your user to stuff bad stuff into the darwin config and then apply it to the system, which means they can just run arbitrary stuff as root.

But the other stuff is just as bad. sudo ln not requiring a password means they can e.g. symlink a system LaunchDaemon to point at whatever they want. And sudo launchctl is literally just handing over complete control, at a bare minimum they could load a LaunchDaemon into the system level and have it execute immediately to do whatever they want with root, or use sudo launchctl submit to run arbitrary programs, or sudo launchctl bsexec/asuser to adopt the desired bootstrap namespace/security audit session, or sudo launchctl attach to debug arbitrary processes, or really anything else they want.

If you're going to remove password requirements for any of these commands, you may as well just remove the password requirement entirely for the user.

lilyball avatar Apr 29 '21 21:04 lilyball

If my disk is encrypted, how is it the same? You still need to get into a user account to run anything, no?

(I may be missing something and probably am)

kubukoz avatar Apr 29 '21 22:04 kubukoz

You still need to get into a user account to run anything, no?

Nope, any process on the system can exec out and run those commands as root. You may for example download a shell script from somewhere, not read through it because you assume it's trustworthy, and run it, only to find out it ran sudo launchctl blah and then you're done son! The malicious code might even be part of a Nix package's install phase. 👀

For what it's worth, I've since moved away from nix-darwin, and now run a non-daemon install of Nix, only really using Nix as just a package manager for myself.

andreykaipov avatar Apr 29 '21 22:04 andreykaipov

Screen Shot 2021-10-04 at 12 36 15 I'd recommend installing either https://github.com/biscuitehh/pam-watchid or using pam_tid.so (Touch ID)

DimitarNestorov avatar Oct 04 '21 09:10 DimitarNestorov

At least as of macOS 11, the system already ships with a pam_tid.so TouchID pam module, which you can put in your /etc/pam.d/sudo without having to install anything. Just add this as the very first line:

auth       sufficient     pam_tid.so

lilyball avatar Oct 05 '21 23:10 lilyball

Also note, pam_tid.so is available as a nix-darwin config: https://github.com/LnL7/nix-darwin/blob/088c98a584a38b5f844bb9e9cd32eb28479ca6d7/modules/security/pam.nix#L42

XA21X avatar Sep 24 '22 12:09 XA21X