Server configuration with manually-provided encryption keys

Hello everyone,

I am planning to extend my current configuration to a home server that hosts file-related services. These files are encrypted on a separate disk with LUKS. My current approach is to log on the machine remotely every time it restarts (not often) and send the key manually, so that it is only stored in a volatile way on the server.

I know about solutions like agenix/ragenix to manage secrets properly, but they seem to force the key to be stored in cleartext on the server, which I don’t want to happen. My thoughts were to look for:

  • a way to log in and interact with age to decrypt the secrets;
  • a way to declare a service that has to start as soon as I have decrypted the given secrets.

I am by no means an expert, and I’d be very grateful to get feedback on idiomatic approaches in Nix for that kind of problems, if they exist, as well as getting any suggestion other suggestion. Thank you

agenix/ragenix stores the plaintext key in a volatile area of the server.

It is unclear if you want more than that and for this, you would have to explain your threat model and against what you want to defend yourself that agenix would make you vulnerable to.

Thanks for your answer. The secrets themselves are stored in a volatile place once decrypted, but the age decryption key is stored in plaintext on the disk (so that the secrets can be accessible at boot, if I am correct). That is, someone with physical access to the device, even shut down, can easily access the content of the encrypted disks through this age key, which I believe defeats the point of full-disk encryption (the device has no TPM or anything).

My question is whether the age decryption key itself may be not stored on the disk, or stored but encrypted with a symmetric passphrase, in a way that would still be convenient to use; allowing to do something like these hypothetical shell commands:

# log in the server
$ ragenix --unlock-secrets --identity /path/to/my/encrypted/age-key # prompts for passphrase
# either the secret-dependent services start automatically from there or can be conveniently started
$ systemctl start disk-dependent-services  

You are free to use an age plugin that enable this, I don’t know if agenix/ragenix supports age plugins, but sops-nix do (it’s recent), therefore, anything that can be expressed via a plugin should be feasible.

1 Like

If you have full disk encryption, then the decryption key for the secrets is also covered by that disk encryption; for example the ssh host key that’s the default/recommended key for agenix.

The purpose of agenix (and similar) is to not have secrets readable in the nix configuration and in the store. Those are world-readable, whereas the ssh host key is not. You’re correct about the ability to decrypt the secrets using that key if the disk is unencrypted and you have physical access, but that’s not what agenix is for.

What you might want to look into is enabling ssh in stage 1, and using that to enter the disk encryption passphrase, so the server can boot from there. You’re going to need something that provides the key externally, and this is one well-supported way.

Otherwise, if the server needs to be running (without disk encryption, other than for this data volume) for other components, and you want to decrypt just this disk and then have services start, you can make those services depend on the mount unit for the filesystem in question.

1 Like

I am indeed in the case where other services don’t need the volume. You’re right, It would be best to only configure the disk dependency from the systemd service point of view, and then log in to start them. I guess I was too eager to try to use ragenix :slight_smile: Thank you for this clarification! I’ll just have to look for how to configure in nix a service to not start at boot but I believe it’s already covered on the internet.