How to define actual SSH host keys (not generate new)?

Hi Everybody,

I found services.openssh.hostKeys where I can specify

[
  {
    bits = 4096;
    openSSHFormat = true;
    path = "/etc/ssh/ssh_host_rsa_key";
    rounds = 100;
    type = "rsa";
  }
  ...
]

Which is cool, but is it also possible to specify existing keys?

For example I’d like to add ed25519 private key into my configuration (which is reasonable short key) and create /etc/ssh/ssh_host_ed25519_key from it and generate /etc/ssh/ssh_host_ed25519_key.pub from that private key (ssh-keygen -f x -y > x.pub).

Thank you!

You would want to use something like sops-nix. Ironically, sops-nix usually uses the host ssh key to decrypt secrets.

The problem is that for safe secret deployment, you always need to at least deploy one secret by some actual secure transfer mechanism (to decrypt all your other secrets). nix-build (and by extension nixos-rebuild and all other NixOS deployment tools) is definitely not such a secure mechanism, since it copies all your sources to the nix store in plain text. Hence, you need to copy over at least one secret by some other mechanism.

Typically the ssh host key is used for this one secret, because practically all servers run an ssh server for access, so it’s conveniently available. It often also needs to be present on the system for you to have access anyway, so by the time you run nixos-rebuild it should already be there.

So your safest options are to copy over that ssh key manually, or to copy a gpg key over manually and deploy the ssh key with sops-nix. Either way, some manual step is involved.

If you plan to deploy more services that work with secrets than just an ssh server I’d recommend figuring out sops-nix, though. It’s very useful for avoiding manual secret management in NixOS deployments.

Thank you @TLATER , I’ll look at sops-nix.

I understand the need and value of secret management. But in case of a host keys… I think of them as an additional check for SSH so I’m not asked Are you sure you want to continue connecting (yes/no/[fingerprint])? Obviously I wouldn’t put my client personal SSH key into Nix configuration…

Would you consider using environment.etc."/etc/ssh/ssh_host_xxx_key for the host keys?

No! ssh uses public key encryption, aka asymmetric key encryption. By making the server side private key publicly known, an attacker can decrypt all messages your computer sends to the server, as well as pretend to be the server side.

It’s not just used for fingerprinting, that’s just to make sure the domain name matches the server you think you’re connecting to, since SSH has no better way to verify that.

Feel free to put the public key in your client configuration in plain text, but publishing your server’s private host key is at least as bad as publishing your root password (as it probably results in that, and likely worse…).

1 Like

As a sops-nix user, who sometimes deploys partially prepared configuration, I usually do the manual installation with a bare minimal config, mostly as generated by the nixos-generate tool.

After installation but prior to rebooting, I place the intended hostkeys where they need to be.

Then I reboot.

After the reboot I finalize my setup by fetching and applying the intended configuration for the host.

This workflow has been succesfully applied in VMs about 2 or 3 times so far.


And I do not know why, but I have the feeling you are asking to reuse a single hostkey across machines… If this is true, simply don’t, unless you manage a fleet of cattle that really are all the same anyway.

3 Likes

I do exactly the same + I add the most simple flake.nix that just loads configuration.nix.

The additional benefit is that the simple configuration (basically just to boot) reveals any possible hardware (or virtualization configuration) issues and makes it much easier to debug than debugging my full config.

2 Likes

Maybe slightly less bad since the keys allow “only” to read the ongoing communication while a root password can be a way to SSH-in but yeah… It is bad. Thank you for the explanation.

Btw. just for fun I tried on a VPS to create

nixosConfigurations.mycomp.config.environment.etc."ssh/ssh_host_ed25519_key"
nixosConfigurations.mycomp.config.environment.etc."ssh/ssh_host_ed25519_key.pub"

and it didn’t work even after I deleted the existing host key and nixos-rebuild switch --flake .#mycomp

Maybe a problem how NixOS deals with existing files, maybe a protection against a security issue… not sure since environment.etc."ssh-todo/..." worked.

Thank you all.