Skip to content

Use dedicated SSH keypair for "none" backend.#201

Merged
edolstra merged 6 commits intoNixOS:masterfrom
aszlig:none-improvements
Oct 26, 2015
Merged

Use dedicated SSH keypair for "none" backend.#201
edolstra merged 6 commits intoNixOS:masterfrom
aszlig:none-improvements

Conversation

@aszlig
Copy link
Member

@aszlig aszlig commented Jun 19, 2014

This should make the "none" backend a bit more useful as we only need to provide a key or passphrase on machine creation and from thereon we only use the SSH keys within NixOps' state database.

If you have a large set of "none" machines and want to export/import them, this should no longer require to move around ssh_configs or even entries in your hosts file.

In addition, this fixes the situation where you need to build on the target machines and the none backend wasn't able to provide a private key for the to be generated nix.machines file.

VM test result: https://headcounter.org/hydra/job/nixops/none-improvements/tests.none_backend/latest
(also required fixing the VM tests)

This is related to #200 and after talking to @joelton on IRC it turned out he was on Darwin, so NixOps was trying to build on the target machine(s), which in turn requires explicitly specifying a private key. As we now have the keypair in our own db, this is no longer an issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use users.extraUsers.root.openssh.authorizedKeys to set the key? get_physical_spec can already emit it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At that point we can't deploy the machine yet (or at least only in a very complicated way), because this actually sets the key that's to be used for creating the machine in the first place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating the machine? It already exists, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More or less it exists, yes. But you can't necessarily deploy to it, especially if you use password authentication.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, you must be able to deploy to it, because otherwise you wouldn't be able to ssh to it to add the key.

BTW, there are also some security implications here. For instance, I currently use the none backend to manage machines from a machine that doesn't have their private keys, but instead uses the SSH agent. So a compromise of the central machine doesn't necessarily lead to a compromise of the others. But if you generate new private keys on the central machine, that's no longer the case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, the machine is "created" like this:

graph

Of course the SSH private key resides in the deployment specification, but using plain ssh without relying on ssh_util does have the advantage that we don't need to rely on the configuration of the host and as said: We even can use password auth for the first step.

I'm not sure I understand what you exactly mean by security implications, but for example if you use SSH agent forwarding it indeed will cause the key from the agent to be detached from the deployment. But IIUC the other backends provide their own SSH keypairs as well, so someone getting access to the state database (s)he will have access to all the machines anyway. So if that's a concern we could also encrypt the state database file.

That aside, if all our backends internalize the SSH stuff entirely, we could remove quite a lot of the cruft from ssh_util, for example handling of host keys and other factors (like for example the mentioned remote builds) that could get in the way of SSH operations. And of course, in order to protect the database, we could still encrypt it and/or the user could use external programs to do that on his/her own.

In the end, what I'd expect from NixOps is that no matter which deployment someone imports, you shouldn't need to configure additional things ("Please import this, then configure x, then you need to set y and some z and something over there. Oh, you're on OS X or cygwin, well... then you need ...") just to get it working.

Another option would be to make this an entirely different backend and we leave none as-is.

@edolstra
Copy link
Member

Okay, so I have two issues with this:

  • I don't really understand why it's needed. For NixOps to connect to a machine via the none backend in the first place, it necessarily already has a key, so there is no need for NixOps to create a new one.
  • We shouldn't add keys to /root/.ssh/authorized_keys but via users.extraUsers.root.openssh.authorizedKeys. The former is not declarative, and keys listed there tend to accumulate over time (e.g. causing people to have access to a machine who no longer should).

@aszlig
Copy link
Member Author

aszlig commented Jul 22, 2014

For the first point: It's no longer needed to have a key with this approach, and as said, it makes export/import of deployments way easier if you don't have to move around private keys that you might even use for other machines outside of that deployment. Another reason to do this in the long term is to properly isolate SSH access inside NixOps so we don't stumble on issues related to the current users ssh_config or their installed OpenSSH version at any point.

However, I agree with the second point, though it would be needed to do it in two stages (one temporarily for creation and the second during deployment). Doing it temporarily would increase complexity here, because we have to modify authorized_keys for deleting the key. Any better idea on that?

@edolstra
Copy link
Member

Yes, I agree in principle that deploying keys is a good thing, I just prefer not to have it done via authorized_keys.

I'm not really clear on the "creation" thing given that the none backend is intended for deployment to pre-existing NixOS machines. What is running on that machine and what needs to be created?

@pikajude
Copy link

Creation of the deployment? The first time the deployment is created, nixops won't know how to access the machine, will it?

@aszlig
Copy link
Member Author

aszlig commented Jul 23, 2014

Well, it's not "creation" in the sense of "installing" a machine but just putting the SSH public key on it, so a better term would be "creating an initial machine state". The machine itself would be a preinstalled NixOS system.

aszlig added a commit to openlab-aux/vuizvui that referenced this pull request Oct 6, 2014
We want to have container support and exportable none backends, as in
NixOS/nixops#201.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
aszlig added a commit to aszlig/nixops that referenced this pull request Oct 23, 2015
We now no longer create a .ssh/authorized_keys file, as suggested by
@edolstra in:

NixOS#201 (comment)

The key is created in the machine state and passed via the physical
specification and we're checking for the cur_toplevel in the machine
state to ensure that we've deployed already.

So until the first deployment, NixOps (or better OpenSSH) either asks
for a password or if there's a key available uses the external key.

That way, we can also deploy configurations with users.mutableUsers set
to false, because it requires to either have a password or a key set in
the configuration and otherwise won't build.

Of course, we also adapted the VM test to properly test for this change.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
@aszlig
Copy link
Member Author

aszlig commented Oct 23, 2015

@edolstra: Now it's no longer adding a key to ~/.ssh/authorized_keys as you suggested.

aszlig added a commit to aszlig/nixops that referenced this pull request Oct 23, 2015
Use dedicated SSH keypair for "none" backend.
aszlig added a commit to openlab-aux/vuizvui that referenced this pull request Oct 23, 2015
Instead of merging all those PRs via the patches attribute, I've now
created a branch that has all those PRs merged, which are:

 * NixOS/nixops#201: Use dedicated SSH keypair for "none" backend
 * NixOS/nixops#348: Fixup and refactor Hetzner backend tests
 * NixOS/nixops#349: hetzner: Don't create /root/.ssh/authorized_keys
 * NixOS/nixops#350: Fix tests for the "none" backend

So our version of NixOps now should now correctly cope with
users.mutableUsers set to false.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
@edolstra
Copy link
Member

@aszlig This is giving a merge conflict in tests/none-backend.nix. Should #350 be merged first?

@aszlig
Copy link
Member Author

aszlig commented Oct 26, 2015

@edolstra: You could merge #350 and I'll rebase this branch afterwards.

This should make the "none" backend a bit more useful as we only need to
provide a key _or_ passphrase on machine creation and from thereon we
only use the SSH keys within NixOps' state database.

If you have a large set of "none" machines and want to export/import
them, this should no longer require to move around ssh_configs or even
entries in your hosts file.

In addition, this fixes the situation where you need to build on the
target machines and the none backend wasn't able to provide a private
key for the to be generated nix.machines file.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
We now set up a vm_id, so on "nixops check" we can properly show whether
the target machine exists or not.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
The value is the vm_id we generated on create() and currently is more or
less just for consistency and to check whether the vm_id exists on
"nixops info".

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
This ensures that the test will fail, should nixops still try to use the
external SSH key.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Thanks to @joelteon for noticing this. We obviously don't want to break
ssh-copy-id nor our own implementation if we want to add another public
key.

Also add a test to ensure this won't break in the future.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
We now no longer create a .ssh/authorized_keys file, as suggested by
@edolstra in:

NixOS#201 (comment)

The key is created in the machine state and passed via the physical
specification and we're checking for the cur_toplevel in the machine
state to ensure that we've deployed already.

So until the first deployment, NixOps (or better OpenSSH) either asks
for a password or if there's a key available uses the external key.

That way, we can also deploy configurations with users.mutableUsers set
to false, because it requires to either have a password or a key set in
the configuration and otherwise won't build.

Of course, we also adapted the VM test to properly test for this change.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
@aszlig aszlig force-pushed the none-improvements branch from 379fcae to 8ad1138 Compare October 26, 2015 12:55
@aszlig
Copy link
Member Author

aszlig commented Oct 26, 2015

@edolstra: Rebased against current master.

edolstra added a commit that referenced this pull request Oct 26, 2015
Use dedicated SSH keypair for "none" backend.
@edolstra edolstra merged commit 03e308a into NixOS:master Oct 26, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants