I have been stuck for 2 days trying to correctly deploy secrets installing NixOS using nixos-anywhere. All I’d like to achieve is declaratively setting passwords for my user and root.
Shell script with which I deploy the configuration:
#!/usr/bin/env bash
# Create a temporary directory
temp=$(mktemp -d)
# Function to cleanup temporary directory on exit
cleanup() {
rm -rf "$temp"
}
trap cleanup EXIT
# Create the directory where sshd expects to find the host keys
install -d -m755 "$temp/etc/sops/age"
# Decrypt your private key from the password store and copy it to the temporary directory
cp /home/sh4k0/.config/sops/age/cetus.txt "$temp"/etc/sops/age/cetus.txt
# Set the correct permissions so sshd will accept the key
chmod 600 "$temp"/etc/sops/age/cetus.txt
# Install NixOS to the host system with our secrets
nixos-anywhere \
--flake ~/.repos/nixcfg#cetus \
--extra-files "$temp" \
--target-host root@192.168.88.62 \
--build-on-remote \
--build-on remote \
--generate-hardware-config nixos-generate-config ~/.repos/nixcfg/hosts/cetus/hardware-configuration.nix
What happens:
The installation goes without error nor warning, and the nixos-anywhere logs are clean.
The key is where it should be on the newly installed host (in /etc/sops/age/cetus.txt), and has correct permissions (600, owned by root). However secrets aren’t anywhere in /run/secrets.d (where I’d expect to find them).
Upon rebooting the freshly installed machine, I briefly see the confirmation of this:
warning: password file '/run/secrets/passwords/root' does not exist
warning: password file '/run/secrets/passwords/sh4k0' does not exist
The only thing I see is a file /run/secrets.d/age-keys.txt on the new host, which I don’t mention anywhere in my config.
I use sops-nix successfully in a very similar manner on a different host (although with the home-manager module), the only difference being that I rebuild it locally, so there is probably something I’m doing wrong when it comes to deploying the configuration over ssh. Anyone has a hint?
@eblechschmidt robably not.
It is not quite clear to me what should be the workflow to set up secrets on a new host (using nixos-anywhere, in this case), and I am likely doing something wrong.
Let’s assume I am installing NixOS from host A to host B.
What I’m doing is: generating an age key on host A and manually transferring it to host B (see shell script above):
…to the location where sops expects to find it (see configuration.nix above):
From my understanding, this should suffice in allowing secrets to be decrypted on the new host upon installing/rebuilding.
Indeed, the key is copied to the correct location in the new host. But for some reason, sops-nix is unable to use it to decrypt secrets.
As stated above, the age key is correctly transfered to the new host in the location specified by the script, but also there is a /run/secrets.d/age-keys.txt which I don’t mention anywhere in my config. Perhaps is it created automatically by nixos-anywhere from an existing ssh key? So should I transfer an ssh key, rather than an age key?
Obviously, the corresponding age key needs to be added to the recipients in .sops.yaml.
Doing all of that, I can deploy new hosts with correctly configured secrets simply by ssh-ing into the installer and running a single nixos-anywhere invocation from another host
If you want to figure out why this is happening, you could grab the activation script logs, it’s likely that there is some issue with how you’re specifying that key.
(Apparently these aren’t logged anywhere with scripted initrd, but if you have systemd initrd enabled, you should be able to journalctl -u initrd-nixos-activation to see the activation script’s output.)