Confusion about sops and setting user passwords

I’ve already successfully set up my main user with a password from a sops file in a private repo. But I struggle to set it up on another machine for a different user.

My sops file look like this:

users:
    nindouja:
        session: $6$salt$hash
    magik:
        session: $6$salt$hash

And somewhere in my dot files I set up the password like this:

{
  lib,
  pkgs,
  config,
  ...
}: let
  userPasswordSopKey = "users/${config.nindouja.user.username}/session";
in {
  users = {
    mutableUsers = false;
    users.${config.nindouja.user.username} = {
      isNormalUser = true;
      hashedPasswordFile = config.sops.secrets.${userPasswordSopKey}.path;
      description = lib.mkForce config.nindouja.user.name;
      extraGroups = ["wheel"];
    };
  };

  sops = {
    secrets = {
      "${userPasswordSopKey}" = {neededForUsers = true;};
    };
  };
}

On the new machine, I run a home-manager then a nixos rebuild. Once it’s over, and without closing my session i open a new one (auth is done via keys), so I run sudo -v to check the password that is supposed to match magik’s hash and it works, I now have access to sudo command. So everything looks fine there…
Except when I do sudo reboot, wait 5min and reconnect, I cannot pass the sudo -v validation. At this point no password that could match actually matches; not the same one that work before reboot nor the one I set up during Nix’s GUI install process.

I’ve also tried to set both hash in the secrets to nindouja’s one. Same result, it builds, I can connect with nindouja’s password until I reboot.

I went as far as believing that mkpasswd needed to be run on the same machine that will use the hash for some salt or pepper purposes; so I edited my secret flakes from the target before rebuild. Same results.

I really don’t unerstand what’s happening and I have the feeling there’s an obvious dumb thing I’m missing again :confused: Can someone help be debug this ?

In case you need more informations about my dotfiles, here is a link to the file mentioned above; you can browse the full repo from there. I tried to made the readme good enough.

I forgot to mention that after I rebuild and before I reboot, i see the correct hash in /etc/shadow. And when I reboot and try to connect to the machine via VNC with Gnome interface it cannot find my user at all (i have to input my username). Even tho I can login without problem via ssh with that same user.

I tried again tonight on a physical machine and not a VM. I got the exact same results. This time I took the time to check the before and after /etc/passwd and /etc/shadow files.

/etc/passwd had the same entry for my user nindouja.

/etc/shadow got edited to put the new hash for my user and removed root’s one.

I configured the new PC with the same user and sops secret that I’m using on my main PC (the one working since months). And the shadow file has the exact same username and hash. The only difference between main PC and new PC shadow file is the part after the hash; which I believe is the date of the last password change, so irrelevant in my case.

Maybe a fisrt clue provided by tejing on discord;

Is there a race condition between the secret decrypter service and the availability of the key in question? If the key is available when restarting the descrypter service due to a nixos-rebuild, but not during boot, that could result in the behavior you’re describing, I think. Would also show in logs.

When installing i first copy a dev ssh ley into my future real ssh key location. Then I build my home-manager (which override the key) and then my system.

Here is the relevant home-manager config;
{
inputs,
config,

}: let
username = config.nindouja.user.username;
secretsDirectory = builtins.toString inputs.ninja-secrets;
homeDirectory = config.home.homeDirectory;
in {
imports = [
inputs.sops-nix.homeManagerModules.sops
];

sops = {
defaultSopsFile = “${secretsDirectory}/secrets.yaml”;
age = {
sshKeyPaths = [“${homeDirectory}/.ssh/id_ed25519”];
keyFile = “${homeDirectory}/.config/sops/age/keys.txt”;
generateKey = true;
};
secrets = {
“private_keys/${username}” = {
path = “${homeDirectory}/.ssh/id_ed25519”;
};
};
};
}

So potentials problems could be:

  • SSH key having changed between rebuilds
  • The age key not being up to date as it was generated with v1 of the ssh key and not regenaerated after the actuall ssk key have been reset

I have tried deleting the age file to regenerate it with another build before the reboot. It changed nothing.

For the first potential problem I dont know how to test it easily right now.

Below are the logs of a rebuild (home + host); it is not the first one tho as it’s super long. But I believe sops infos are there.

[NINJA] - Syncing home with configuration
[NINJA] - $ nh home switch --configuration user /home/nindouja/.dotfiles
> Building home configuration
Finished at 21:38:16 after 10s
> Comparing changes
<<< /home/nindouja/.local/state/nix/profiles/home-manager
>>> /run/user/1000/nix-shell.FCHW9u/nh-home-dWC1FI/result
No version or selection state changes.
Closure size: 3117 -> 3117 (0 paths added, 0 paths removed, delta +0, disk usage +0B).
> Activating configuration
Starting Home Manager activation
Activating checkFilesChanged
Activating checkLinkTargets
Activating writeBoundary
Activating linkGeneration
Cleaning up orphan links from /home/nindouja
No change so reusing latest profile generation 1
Creating home file links in /home/nindouja
Activating createXdgUserDirectories
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
Activating dconfSettings
Activating onFilesChange
Activating reloadSystemd
Activating sops-nix
[NINJA] - Syncing host with configuration
[NINJA] - $ nh os switch --hostname system /home/nindouja/.dotfiles
> Building NixOS configuration
Finished at 21:38:29 after 11s
> Comparing changes
<<< /run/current-system
>>> /run/user/1000/nix-shell.FCHW9u/nh-os-Z005Y1/result
No version or selection state changes.
Closure size: 3129 -> 3129 (0 paths added, 0 paths removed, delta +0, disk usage +0B).
> Activating configuration
activating the configuration...
sops-install-secrets: Imported /etc/ssh/ssh_host_rsa_key as GPG key with fingerprint cf94756a2073ed230a322f598ce2eae15a246fee
sops-install-secrets: Imported /home/nindouja/.ssh/id_ed25519 as age key with fingerprint age1zu09gu7wj6tjwgpf8xlcrpe63t4wft7xs2wdxxg53m2lws7s4atqfwlakt
setting up /etc...
sops-install-secrets: Imported /etc/ssh/ssh_host_rsa_key as GPG key with fingerprint cf94756a2073ed230a322f598ce2eae15a246fee
sops-install-secrets: Imported /home/nindouja/.ssh/id_ed25519 as age key with fingerprint age1zu09gu7wj6tjwgpf8xlcrpe63t4wft7xs2wdxxg53m2lws7s4atqfwlakt
reloading user units for nindouja...
restarting sysinit-reactivation.target
> Adding configuration to bootloader
[NINJA] - Post sync task
[NINJA] - Staging commons (flake, ect)
[NINJA] - $ git add --intent-to-add config/base-config.json
[NINJA] - $ git add -v -- . :!homes :!hosts
[NINJA] - Staging nindouja specific configs
[NINJA] - $ git add -v -- ./homes/nindouja/config.nix ./hosts/GAMETOP/config.nix
[NINJA] - Commiting changes
[NINJA] - $ git commit -m [Ninja] Auto commit via ninja script - Sync command - 2024-07-29 21:38
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

I fixed it !!

If you want the exact details you can check the current commit in my dotfiles repo and it’s parent made on the same date.

To sum it up, I’m not 100% sure but I strongly believe it was due to conflicts with sops and th keys used to decrypt my secrets. i was using a key for building my home config; that build would override that key so I can build my system with it.

During the process an age key was derived from the ssh key into two locations (one for home one for host) and once I override the key, I failed to reset one of those age key.

Sorry if it’s unclear, it is not completly clear for me either. What I’m doing for now is I have a dev ssh key to build my host. That create my user ssh key wich can be used to build my home.