Hashing plain-text password directly in configuration.nix

Because overwriting files is way more dangerous than asking users to look up some command. I’m not saying we shouldn’t find some solution, but overwriting files isn’t it because it’s a dangerous precedent that’s very much against Nix’s ideal of purity.

Another option is prompting users who haven’t set a password yet for an initial password if they set an option like users.users.will.promptInitialPassword = true;. That’s something I could get behind. systemd-ask-password could be used to make sure it works in as many UIs as possible (e.g. it’d work during nixos-rebuild, during bootup, during plymouth).

6 Likes

Hello

Putting many users with hashed password in a declarative way.

I’ve found a clean solution to that (worked for nixos 22.11 and 23.05)

users.users.username = {
  isNormalUser = true;
  home = "/home/username";
  description = "Username description";
  extraGroups = [ "...." ];
  hashedPassword = "$6 ..... ";
}

hashedPassword is generated by

mkpasswd -m sha-512

Please don’t use -m sha-512 unless you have a specific reason to do so.

NixOS since 22.11 supports a number of stronger hashes, and the default, when no method is passed, would be yescrypt.

2 Likes

mkpasswd -m help lists available methods. sha-512 isn’t listed, but it still works (apparently as an alias to sha512crypt). This produces a hash beginning with $6$, which seems to be the strongest supported by crypt(3) - Linux manual page and the default produced by passwd(1) - Linux manual page .

We’re using libxcrypt, not glibc’s libcrypt, so man crypt(3) is the wrong place to check. And in fact mkpasswd is showing me many algorithms that are stronger than sha512crypt, e.g. scrypt, bcrypt and yescrypt.

$ mkpasswd -m help
Available methods:
yescrypt        Yescrypt
gost-yescrypt   GOST Yescrypt
scrypt          scrypt
bcrypt          bcrypt
bcrypt-a        bcrypt (obsolete $2a$ version)
sha512crypt     SHA-512
sha256crypt     SHA-256
sunmd5          SunMD5
md5crypt        MD5
bsdicrypt       BSDI extended DES-based crypt(3)
descrypt        standard 56 bit DES-based crypt(3)
nt              NT-Hash

What would be the best place to check? And how to change the default of passwd(1)?

And how to change the default of passwd(1)?

Currently hardcoded in /etc/pam.d/passwd, but there are plans to make that configurable in https://github.com/NixOS/nixpkgs/pull/208603.

# Password management.
password sufficient pam_unix.so nullok yescrypt

What would be the best place to check

The hashes are listed in crypt(5) for me.

1 Like

I’m sure it’s much better to handle passwords outside of Nix using for example SOPS. This way passwords are never exposed and can be managed manually or using scripts and tools like yq. sops-nix and agenix make integration easy.