So, I’m opinionated about these things because anyone who spends time administering servers will be, but my 2c:
… unless an attacker exploits a vulnerability in an exposed service that is otherwise unprivileged. This is always the main risk outside of leaking secrets or otherwise accidentally allowing unauthorized access. Even then, many NixOS services are “hardened” and won’t permit unprivileged services elevating their privileges, though this isn’t completely bulletproof.
Personally, I just don’t set root passwords (and thereby prevent root login) and use an account with wheel
permissions that can only be signed into via a public key, which I then use for root auth with pam
. For recovery, you can always boot a live distro and chroot into the system, so root passwords are practically useless and should therefore be disabled IMO.
In practice this probably doesn’t change much; whether sudo
protects the system or if the kernel guards it is splitting hairs, if anything the ssh agent adds a potentially weak link. And again, your homelab setup is unlikely to fall to someone paying hundreds of thousands to crack a hashed password - my setup exchanges that small weakness for the chance of bugs in pam.
You can always add the key to the ~/.ssh/authorized_keys
file by hand, or use something like nixos-anywhere
to install it at initial deploy time, then develop some deployment strategy to update it when needed (or just add another line by hand whenever you rotate, and delete the old one after you confirm you can log in with the new one).
This is an incredibly unlikely way to gain entry into your system, though. If you’re worried about quantum computers recovering your private key, use an ECC key, and use key expiry so you rotate regularly. Guarding public keys is incredibly paranoid, they’re called public for a reason - if this breaks, you’ll have bigger problems than your homelab.
There are a few ways to achieve this, but IMO the best way is to treat your secrets as simple data and deploy them without the NixOS config. If you want to use the NixOS config, for the root password you can use hashedPasswordFile
to point at a file that is somewhere on the host, and then use something like nixos-anywhere
or deploy-rs
to copy the file in the right place when you deploy. Then just don’t check it into version control.
You can also use mutableUsers
and passwd
.
For the public key you would need to write your own systemd service to put it in the right location if you wanted to achieve this. It’s considered public, so the NixOS modules have no built-in support for hiding it.
This concept can be enhanced with sops-nix or agenix, which provide a generic interface for this kind of setup. They also encrypt the secrets at rest. Note that neither requires checking the encrypted secrets into VC, you can just leave them backed up on a USB or something, and again deploy them to the host without nix when needed - data, not config!
With your simple setup, though, I don’t think you need this. The added complexity from this just adds risk - stick to passwd
if you’re paranoid, disable root login altogether and use pam, or keep the hash in your config.