nix-darwin
nix-darwin copied to clipboard
Avoid typing password on `darwin-rebuild switch`
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.
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.
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 :)
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'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.
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?
I started using my touch id for sudo passwords through adding
auth sufficient pam_tid.so
to /etc/pam.d/sudo
as first line.
@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.
How?
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.
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)
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.
I'd recommend installing either https://github.com/biscuitehh/pam-watchid or using
pam_tid.so
(Touch ID)
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
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