appbox-cookbook icon indicating copy to clipboard operation
appbox-cookbook copied to clipboard

Setup ssh-keypair for deployment

Open bjensen opened this issue 11 years ago • 12 comments

This might be out of scope, but I think that the job of this recipe is to get your application setup so that you are ready to do first time install of your app (for example cap deploy:setup). In order for this to possible, we need to have the right keys in place (deploy key for private repos).

I am thinking of using attributes to get the private and public keys and simply add those to the .ssh directory with the proper naming and permissions.

What do you think?

bjensen avatar Apr 28 '13 11:04 bjensen

Currently, you can upload your public ssh key(s) by set this attribute:

node["appbox"]["deploy_keys"] = [
  "ssh public key 1",
  "ssh public key 2"
]

I guess this is suitable for SSH agent forwarding method.

@bjensen I usually use SSH agent forwarding for deployment. Perhaps you can share what is the manual workflow to setup deploy keys? I'm interested to integrate it into the cookbook :)

teohm avatar Apr 30 '13 00:04 teohm

I dont use ssh agent forwarding. It adds a dependency on your own development machine.

Instead I create a new rsa keypair and add the public key as deploy key of my private repository on github.

I then check that the key works as intended by doing

nordplaner-backup@prod:~$ ssh -t [email protected]

Hi bjensen/nordplaner-backup! You've successfully authenticated, but GitHub does not provide shell access. Connection to github.com closed.

Obviously the keypair would have to be created in advance and copied over into the .ssh directory when cooking,

bjensen avatar Apr 30 '13 08:04 bjensen

Do you prefer to create the key pair directly on the remote server, or create the key pair on your local machine then upload the private key to remote server?

Huiming

teohm avatar Apr 30 '13 09:04 teohm

I prefer being given the option to set it as an attribute like so:

node["appbox"]["deploy_private_key"] = [
  "ssh private key 1",
]
node["appbox"]["deploy_public_key"] = [
  "ssh public key 1",
]

I think the node["appbox"]["deploy_key"] variable should be renamed to node["appbox"]["deploy_authorized_key"]. I think that is much more descriptive of what it is actually doing. But thats just me :-)

bjensen avatar Apr 30 '13 09:04 bjensen

Come to think of it. I think this is better:

node["appbox"]["deploy"]["authorized_keys"]
node["appbox"]["deploy"]["private_keys"]
node["appbox"]["deploy"]["public_keys"]

bjensen avatar Apr 30 '13 09:04 bjensen

Brian, do you want to work on this issue and submit a PR?

btw, should the deploy account on remote server has multiple private keys? I wonder how we should store them in ~/.ssh

teohm avatar Apr 30 '13 09:04 teohm

I dont mind creating this if we can agree on a solution :-)

In order to support multiple apps then we need to support multiple deploy keys. ssh will use the first one it finds for all github repos. In order to get around this there are 3 ways we go do this:

  1. Use of ssh-agent as you do
  2. Create a user for each app
  3. Use git aliases

If we use option 1 then we add a dependency on the client machine. If we use option 3 then it will pollute, having to add the alias in capistrano/whiskey_disk deployment for example. I think we should go with option 2 as we will separate the deployed apps and it will simply the setup of the ssh keys significantly.

What do you think?

bjensen avatar Apr 30 '13 12:04 bjensen

Just my 2¢: deploy keys can only be added once on GitHub. Either on a pseudo-user who has access to all the repos you want to deploy, or added as a "deploy key" to exactly one repository.

I looked into their OAuth-based thing quickly, but it didn't really make sense to me. I'll have to experiment with this later.

All of this to say, the method I've been doing it recently is with a pseudo-user, but me and my client saw it as an imperfect approach (that user has access to everything and its key has been spread far and wide on a bunch of servers).

Thanks to this set of cookbooks I'm actually experimenting with SSH agent forwarding at the moment. I also thought it required setup on deployer machines -- as in installing something -- but it's not the case. At least on Mac OSX. The only different thing I need to do is add the param in my .ssh/config. E.g.:

Host testbox
  ForwardAgent  yes
  Hostname      ...

The agent forwarding method comes with its own caveats, though. But since we're setting up these machines ourselves, it's a tradeoff I'm willing to make. I wouldn't use agent forwarding to connect to systems I don't trust completely.

Here's the GitHub doc to set it up, btw.

webmat avatar Apr 30 '13 18:04 webmat

Using an ssh-agent is not an option for me. @webmat you are right regarding the deploy keys. Thats why Im leaning up making a user for each deployed app.

bjensen avatar Apr 30 '13 18:04 bjensen

Hi @bjensen,

If we adopt option 2 (Create a user for each app), does it make sense to have a config like this?

node["appbox"]["deploy_users"] = [
  { "user": "deploy_app1", "public_key": "<ssh public key>", "private_key": "<ssh private key>" },
  { "user": "deploy_app2", "public_key": "<ssh public key>", "private_key": "<ssh private key>" }
]

And perhaps we will have a new recipe to:

  1. create deploy users, with the provided username, public & private keys.
  2. append node["appbox"]["deploy_keys"] into each deploy user's ~/.ssh/authorized_keys, to enable remote SSH login.
  3. add deploy users to apps group, to provide write permission to access apps directory.

teohm avatar May 02 '13 00:05 teohm

I have fixed this and pull be submitting a pull request. However I have not been able to test it thoroughly since I have been having issues with dependent recipies. For example rubyenv: https://github.com/RiotGames/rbenv-cookbook/issues/31

I have been using too much time fiddling with versions of chef and vagrant. If only we could improve the testability of appbox. Ideas @teohm ?

bjensen avatar May 05 '13 12:05 bjensen

One thing's for sure: when working with Vagrant, I now always add a "vagrant" role to my node file.

# node/name.json:
run_list: ["role[vagrant]", ...]

# roles/vagrant.rb:
name "vagrant"
description "Keeps vagrant user as a sudoer"
run_list "recipe[sudo]"
default_attributes authorization: { sudo: {users: ["vagrant"],
passwordless: true} }

Where the vagrant user is set to passwordless sudo access. I had no problem with Ubuntu, but had problems on CentOS.

I've spent quite a while puzzling why I couldn't "vagrant halt" anymore, when first trying out CentOS :-)

webmat avatar May 05 '13 18:05 webmat