Certificate architecture for signing packages, for NixOS remote rebuilds

Hi all,

I’m trying to see if there are people interested in having a certificate architecture for signing packages. Meaning, people can have their own key that they use for signing packages. Their key are then signed by a Certificate Authority (CA). If a machine trusts such CA, it will accept packages signed by a key signed by the CA.


My situation, which should explain the need:

I’m currently using Nix and NixOS in my company, and we’ve stumbled upon a process road block for administering NixOS machines.

We have some NixOS machines which are offline. Multiple people from our team must be able to administer them. The way we can do it is by giving our team member root ssh access (using SSH keys, or SSH certificates), and do remote rebuild. But, multiple people logging into root is not such a great practice, so we’ve been trying to figure out a way to do remote rebuild using normal users.

In order to use nixos-rebuild --target-host "normal-user@host" --use-remote-sudo, currently we need:

  • passwordless sudo
  • the remote machine must trust the packages that it receives, either:
    • the ssh’ed user is a trusted user (not good, because it’s basically giving root access without authentication)
    • the packages are signed by a trusted key

For this post, I’m ignoring the issues of passwordless sudo (using ssh-agent, etc.).

From an organization point of view, I can’t ask every team member to have their own signing key, because it would be a nightmare to copy their public key on each NixOS machine, even when factorizing that in a “common configuration”. We have the same problem with SSH keys, which we’re currently solving using SSH certificates, so why not do the same thing for signing packages?

Using CI to sign packages is also a no go for us, because there are quite a lot of times where our development machine are disconnected from the internet. It would also mean that we can’t deploy anything if our CI is down. It would also mean we would have to commit and push every time we want to nixos-rebuild test, which would be quite annoying.

What do you all think?

1 Like

This reads like you’re testing in prod.

Not every machine we have is prod, and in our domain of activity, this is also a case we need to handle. We have a lot of hardware that we simply cannot afford to have in duplicates, so it does happen that we need to deploy in “production” directly.

Hi!

I’m not sure I understand the idea. Could someone not deploy a nixos config which includes (in the activation script) a few lines that gives their personal SSH key root access? At that point, wouldn’t this still be equivalent to root SSH access?

To be able to switch to the given configuration, you still need root access (to run the activation script). The user activating the config still needs sudoer rights.

What I’m proposing is only about uploading packages to the Nix store. If they have a Nix signing key, which is signed by a trusted CA, they will be able to upload packages as themselves. It shouldn’t give them root access, because the Nix store can’t have setuid programs, and since they are additional packages, the system shouldn’t depend on them, and wouldn’t run anything from them.

This is unfortunately not true. Being a trusted user (or able to upload arbitrary paths) is effectively root access because a malicious user could use that privilege to escalate user privileges. This is because you’d then have the power to modify any path before uploading/creating it.
With this ability, you could e.g. modify the new sudo store path that will be used after an update before the machine is updated in a way that e.g. always accepts your users escalation requests. You are allowed to do this because you are a trusted user/have a trusted signature. Upon the next deployment, the sudo store path which the new version depends on will already be present and therefore not be fetched from another substituter or built locally and NixOS deploys it with a SUID wrapper.

There are many other ways to do this as every security-critical component all the way down to the kernel is just a Nix store path. As soon as a user can upload arbitrary paths, they can become root if they want to.

In FHS distros, the equivalent would be to allow the user to sign any package and place it in the package cache. That would allow similar attacks.

1 Like