NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.13k stars 13.42k forks source link

`systemd.sysusers.enable` breaks `hashedPasswordFile` #318365

Closed TheRealGramdalf closed 1 month ago

TheRealGramdalf commented 2 months ago

Describe the bug

After enabling systemd.sysusers.enable (ref) while enabling hashedPasswordFile, attempting to nixos-rebuild boot --flake .# fails with cat: /persist/secrets/passwdfile.gramdalf: No such file or directory

Steps To Reproduce

Steps to reproduce the behavior:

  1. Enable systemd.sysusers.enable
  2. Add a normalUser with a hashedPasswordFile (ref)
  3. Attempt to nixos-rebuild boot --flake .#

Expected behavior

The hashedPasswordFile is used, but not added to /nix/store

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

The suggested nix log only gives a single error line, complaining that the file doesn't exist. Copy/pasting the cat command works, I assume this to be due to the nix build environment being sanitized, with limited access to the filesystem as a whole. The source comes from this part of the file, which attempts to read the hashedPasswordFile at build time rather than activation (which was the previous behavior) Semi related to https://github.com/NixOS/nixpkgs/issues/307159

Notify maintainers

@nikstur @NickCao

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

nix on  main [$!?]
❯ nix-info -m
 - system: `"x86_64-linux"`
 - host os: `Linux 6.8.12, NixOS, 24.11 (Vicuña), 24.11.20240531.57610d2`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.2`
 - nixpkgs: `/nix/store/5jgh89kgmrb687c254wxdac4cj5hqjw8-source`

Add a :+1: reaction to issues you find important.

con-f-use commented 2 months ago

Can see the same problem. Here's a reproducing VM config:

{ pkgs, config, ... }:

{
  users.mutableUsers = false;
  users.users.root.hashedPassword = "";
  services.getty.autologinUser = "root";

  systemd.sysusers.enable = true;
  users.users."main" = {
    isNormalUser = true;
    group = "main";
    # Start vm once, create this file, uncomment, re-build & restart vm
    # hashedPasswordFile =  "/var/lib/secrets/mainpw";
  };
  users.groups."main" = {};

  system.stateVersion = config.system.nixos.release;
  virtualisation.vmVariant = {
    virtualisation = {
      mountHostNixStore = true;
      writableStoreUseTmpfs = false;
    };
  };
}
# Build with:
#   NIXOS_CONFIG="$PWD/configuration.nix" nixos-rebuild build-vm --max-jobs auto --builders '' 
#   # ...you might need `nix-shell -p nixos-rebuild` as it's only installed on NixOS
# Run with:
#   ./result/bin/run-*-vm &
nikstur commented 1 month ago

This only happens when mutableUsers = false because we currently statically (i.e. at build time) generate /etc/passwd and friends. It cannot read a hashedPasswordFile from outside the Nix store in this scenario.

con-f-use commented 1 month ago

I'd say that's a pretty big deal, because it's security relevant - people might unexpectedly end up with an insecure password or lock themselves out of a system - and because of the docs currently imply it works with immutable users:

The full path to a file that contains the hash of the user’s password. The password file is read on each system activation. [...] If the option users.mutableUsers is true, the password defined in one of the three options will only be set when the user is created for the first time. After that, you are free to change the password with the ordinary user management commands. If users.mutableUsers is false, you cannot change user passwords, they will always be set according to the password options.

~It used to work~, it's dangerous, so it should be ~reverted or~ fixed or at the very least very clearly documented and warned about.

Edit: Sorry, forget that this was aboutsysusers.

nikstur commented 1 month ago

It used to work, it's dangerous, so it should be reverted

It cannot have ever worked with systemd-sysusers. There is nothing to revert. If you want the old behaviour you simply do not enable sysusers.

My comment also simply explained why what happens happens. I never said that it shouldn't be fixed.

Additionally, systemd-sysusers does not attempt to entirely emulate what the users-groups.pl script does. It most likely will never be able to.

systemd-sysusers is experimental right now, which is clearly indicated in the option description.