Skip to content
This repository has been archived by the owner on Feb 4, 2022. It is now read-only.

Use ssh keys instead of password based auth #3

Closed
psiayn opened this issue May 21, 2021 · 11 comments · Fixed by #5
Closed

Use ssh keys instead of password based auth #3

psiayn opened this issue May 21, 2021 · 11 comments · Fixed by #5
Assignees

Comments

@psiayn
Copy link
Owner

psiayn commented May 21, 2021

Copying of keys ( if not done already ) should probably be done in the init phase.

@Gituser143
Copy link
Contributor

Hi! Could I work on this?

@psiayn
Copy link
Owner Author

psiayn commented Jun 1, 2021

Yeah sure!

For choosing which keys to use, I guess you could create a separate key file for heiko specifically or you could use the system's keys. Anything is fine.

@Samyak2
Copy link
Collaborator

Samyak2 commented Jun 1, 2021

The way it was done in the the previous heiko was this: pesos/heiko@4874dce

Yeah xD, the ssh package handled parsing the ssh config by default if the password wasn't given.

It appears that the Golang ssh package does not do this

There is a ssh_config package that parses SSH config files, but it looks like it hasn't been maintained well and will require quite some work to load keys, port, etc. This has been done here.

Let us know if you find any better package for this.

@Gituser143
Copy link
Contributor

Yeah sure!

For choosing which keys to use, I guess you could create a separate key file for heiko specifically or you could use the system's keys. Anything is fine.

I was thinking it would look for a default set of keys, unless a specific key is specified through the config file or maybe as a command line arg. If any issue is encountered, it could return immediately.

Also, just to confirm, this should happen right before the spawning of routines in init.go right?

@Gituser143
Copy link
Contributor

It appears that the Golang ssh package does not do this

I did see this, I'll do a little bit of digging before I get started on this then.

@Samyak2
Copy link
Collaborator

Samyak2 commented Jun 1, 2021

I was thinking it would look for a default set of keys, unless a specific key is specified through the config file or maybe as a command line arg. If any issue is encountered, it could return immediately.

Yes, this is correct. Just to confirm, by config file you mean the SSH config file, right? (~/.ssh/config, etc.)

Also, just to confirm, this should happen right before the spawning of routines in init.go right?

I was thinking it would be in internal/connection as that handles all of the SSH stuff. But yes, it should be initialised before connecting to any node. Which means not only in init.go but also in start.go.

@Gituser143
Copy link
Contributor

Yes, this is correct. Just to confirm, by config file you mean the SSH config file, right? (~/.ssh/config, etc.

Yep!

@Gituser143
Copy link
Contributor

@Samyak2 @psiayn, when using SSH keys, shouldn't the keys first be exported to the node, following which connections can be made? Normally what I've come across is the key being copied by using something like ssh-copy-id which requires password auth, following which, the keys are transferred and connections can happen by using the keys.

Are we looking for something similar where the user types in a password and after authentication, keys are transferred and we
proceed? I'm asking this because I'm sure if I start by copying keys over or just read the key and attempt to establish connections.

@Samyak2
Copy link
Collaborator

Samyak2 commented Jun 2, 2021

The way it was done in the previous implementation was like this:

  • The user would be responsible for transferring keys to the node (using ssh-copy-id like you said) and marking the host as known (which can be done by SSH'ing into the node once and accepting the confirmation message)
  • Add node username, key file, etc. to the SSH config
  • Heiko only uses information from the SSH config to read the correct key and SSHs into it

The same can be done here for an initial implementation.


user types in a password and after authentication, keys are transferred and we
proceed

This is a good idea and would make the process smoother. This can be done in heiko init which is responsible for setting up connections to the nodes. The same key(s) can then be used in heiko start. Although I'm not sure on a few finer details that will go into implementing this. For example:

  • Do we generate a new key or use an existing one?
  • Do we use the same key for all nodes or make new keys for each node?
  • Some SSH servers are configured to not allow password auth, the user will have to handle the keys here. In which case, we will have to first check if the auth is successful. Only if the auth isn't working we try to transfer keys. Or an alternative approach to get around this.
  • Do we edit the user's SSH config? - after we have transferred the keys, we need to store the key name/path somewhere to be used later by heiko start. If we make our own local SSH config, we will have to read both of them (since some of them may be configured by the user in their config).

just read the key and attempt to establish connections

You can go ahead with this! We will need this anyway, even if keys are transferred. Once we iron out the above details we can start implementing it.

Any ideas or draft PRs are ofcourse very welcome 😄, even if the details aren't complete.

@Gituser143
Copy link
Contributor

Gituser143 commented Jun 2, 2021

  • Do we generate a new key or use an existing one?

I was thinking we could look at the heiko config for that, if a key path is provided, use that, else resort to a default.

  • Do we use the same key for all nodes or make new keys for each node?

As the user specifies in the config right?

  • Some SSH servers are configured to not allow password auth, the user will have to handle the keys here. In which case, we will have to first check if the auth is successful. Only if the auth isn't working we try to transfer keys. Or an alternative approach to get around this.

If the auth isn't working, we won't be able to transfer keys even if we want to right? Then we can just return with an error or log that the node is unreachable.

  • Do we edit the user's SSH config? - after we have transferred the keys, we need to store the key name/path somewhere to be used later by heiko start. If we make our own local SSH config, we will have to read both of them (since some of them may be configured by the user in their config).

I don't see why this is necessary, we know which keys to use from the heiko config file, we can straight away attempt to transfer those and attempt to establish connections right? We can stick to the default ssh configs too.

EDIT: I'll get started on the key read and transfer, I'll send a draft PR when I've covered some ground.

@Samyak2
Copy link
Collaborator

Samyak2 commented Jun 2, 2021

I was thinking we could look at the heiko config for that, if a key path is provided, use that, else resort to a default.

That makes sense. If the key path isn't provided do we generate a new key just for heiko?

As the user specifies in the config right?

I meant when it's not specified in the SSH config, we only generate the keys then (if the key file is provided in the config, we don't need to generate our own)

If the auth isn't working, we won't be able to transfer keys even if we want to right? Then we can just return with an error or log that the node is unreachable.

Yes that makes sense. What I meant here is that we shouldn't try to override nodes that are already configured by the user. On a second thought, this is taken care of by the above solution (generate key only when it isn't provided in the config)

I don't see why this is necessary, we know which keys to use from the heiko config file, we can straight away attempt to transfer those and attempt to establish connections right? We can stick to the default ssh configs too.

Here is what I was thinking it would look like:

  • If a key isn't provided in the SSH config, we generate a new key just for heiko (maybe a new key for each node or one key for all nodes). The idea is that we shouldn't (mis-)use existing keys of the user that they would be using for other purposes (git, ssh into other remote servers, etc.).
  • While connecting to a node, we first check if it exists in the SSH (and heiko) config. If the key exists, it's straightforward. Otherwise, we need to try the heiko key generated (above). If that fails or if there are multiple heiko keys, we will need to try each of them (+ the default key). This can lead to too many auth failures on the node and it may reject the auth. This can be solved either by having just one shared key or by specifying the key somewhere (we shouldn't be editing the heiko config so the only other place I could think of was the SSH config).

The best solution I can see is having just one heiko key that is shared by all heiko daemons and nodes (even if it's a different config).


These are my personal preferences (and biases xD) for an ideal solution:

  • keys should be specified in the SSH config as they usually are
  • if (and only if) I don't specify a key, heiko should generate one for me and use that
  • auth shouldn't fail once it's set up (using heiko init)
  • heiko init should be idempotent i.e., running heiko init again (or many times) shouldn't try to generate new keys (or add them to the node) once everything is setup

What do you think?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants