I use several SSH keys side by side and I would like to be able to tell streisand to use a specific one. I can make my own .ssh/config file to access my host properly afterwards. An optional command line flag would be nice.
Can you provide an example of what your desired workflow for this would look like? Ansible needs to be able to connect in the absence of an .ssh/config file in order to do the initial server configuration in a seamless way.
Right now the way that you would do this is by running the playbook directly on a new server that was created outside of Streisand instead of using the ./streisand command.
You can tell Ansible to use a specific key - in the inventory file, add something like:
[streisand-host:vars]
ansible_ssh_private_key = /path/to/keyfile
This presumes that you already have a host instead of letting streisand provision one for you, and that the host details are also in the inventory file.
Would it be satisfactory for Streisand to generate a short-lived SSH keypair just for Ansible deployment?
At the end of installation it could install your_favorite_key.pub into authorized_keys, then delete its own public key.
Would it be satisfactory for Streisand to generate a short-lived SSH keypair just for Ansible deployment?
Yes, that would be better than what is happening right now for my use case.
@jmusarra's workaround doesn't work for me with current master using digital ocean.
The server's IP address is unknown so streisand-host can't be defined in advance and it needs to be defined in order for the YAML inventory file to validate:
Attempted to read "inventories/inventory" as ini file: inventories/inventory:4: Section [streisand-host:vars] not valid for undefined group: streisand-host
I also tried re-starting the installation using the existing server option but the private key file is not honored:
What is the IP of the existing server: 138.xx.xx.58
THIS WILL OVERWRITE CONFIGURATION ON THE EXISTING SERVER.
STREISAND ASSUMES 138.xx.xx.58 IS A BRAND NEW UBUNTU INSTANCE AND WILL
NOT PRESERVE EXISTING CONFIGURATION OR DATA.
ARE YOU 100% SURE THAT YOU WISH TO CONTINUE?
Please enter the word 'streisand' to continue: streisand
Confirmed. Continuing
Warning: Identity file /home/xxxx/.ssh/id_rsa not accessible: No such file or directory.
Permission denied (publickey).
I tried setting both ansible_ssh_private_key or ansible_ssh_private_key_file (found via google) and it did not work.
Should I file a separate issue about this?
Yes, file a bug.
We have a meta-issue that all of these little hacks with the inventory aren鈥檛 documented very well.
Yes, file a bug.
Done. See #923.
Not sure if this addresses the issue but I've managed to use a specified keyfile with set_fact in the past.
Extract below from another playbook.
- name: switch user
set_fact:
ansible_user: "{{ ubuntu_common_deploy_user_name }}"
ansible_ssh_private_key_file: "{{ local_deploy_path }}/ssh/{{ inventory_hostname }}/{{ ubuntu_common_deploy_user_name }}/{{ default_ssh_key }}"
ansible_become_pass: "{{ admin_password }}"
when: adminlocal_exists.stat.exists == True
I'm looking at this feature request.
The work-around suggested in @jmusarra's comment likely worked at the time of writing (Jun 2016) but it hasn't for as long as I've personally been helping maintain Streisand.
@darth-veitcher Unfortunately the same is true of your workaround. That configures the SSH key that Ansible uses to talk to the host but Streisand makes additional use of a SSH public key that is currently assumed to be in ~/.ssh/id_rsa 100% of the time. I'm working on a branch to change this but I wanted to clarify this point. You would be right for most any other Ansible project, just not Streisand.
I have a branch (cpu-specify-ssh-key) implementing this feature request on my fork: https://github.com/cpu/streisand/commit/134e00ab8fe33ebbf6b1b668672b8ce2db66cd46 @obilodeau Early testing welcome!!
I haven't opened a PR for this commit yet since it builds on top of #936 but I expect I will be able to merge it in the next week or so.
@cpu: Everything went well up to:
TASK [Wait for cloud-init to complete] ************************************************************************************************************************
fatal: [138.xx.xx.209]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '138.197.168.209' (ED25519) to the list of known hosts.\r\nPermission denied (publickey).\r\n", "unreachable": true}
I can login with root@IP with the key:
ssh -i <key> [email protected]
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
root@vpn:~# exit
Digital Ocean provider.
@obilodeau What's the output from ssh-add -l?
Presently there's no provisions in place to load the key automatically like the way you're specifying with -i in your manual invocation of ssh. You will need the key loaded before running Streisand. I could probably make that clearer (or maybe set ansible_ssh_private_key_file?)
ssh-add -l outputs a lot of keys including the key I specified with streisand_ssh_key. However, it's clear what is happening now as I've been through this before: I have more than 5 keys in my agent and the correct key is after the 5th one which means I'm rejected by the server due to too many authentication failures: https://security.stackexchange.com/questions/65120/ssh-always-too-many-authentication-failures
In my ssh usage pattern, I work-around this by using an .ssh/config with pinned keys per server.
I think ansible_ssh_private_key_file should be set if streisand_ssh_key is set.
@obilodeau That makes sense. So if you clear your SSH agent and only add the key you're specifying for use with Streisand the branch provisions the server correctly?
I think ansible_ssh_private_key_file should be set if streisand_ssh_key is set.
I'll take a look at adding that to my branch this weekend.
Thanks for the testing!
Test results:
I can't easily clear my SSH agent. I use GNOME which provides an SSH Agent via GNOME Keyring. Keys are loaded automatically:
The SSH agent automatically loads files in ~/.ssh which have corresponding *.pub paired files.
-- https://wiki.gnome.org/Projects/GnomeKeyring/Ssh
Using ssh-add -d or -D only locks keys, they are not removed from the keyring.
So this is why setting ansible_ssh_private_key_file would be required.
That said for testing purposes, I moved out all of my keys and faced the same problem:
fatal: [165.xx.xx.160]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '165.xx.xx.160' (ED25519) to the list of known hosts.\r\nPermission denied (publickey).\r\n", "unreachable": true}
It's then that I remembered that I've worked around my numerous key problem by applying this .ssh/config block:
Host *
IdentitiesOnly yes
Man page says:
Specifies that ssh(1) should only use the authentication identity and certificate files explicitly configured in the ssh_config files or passed on the ssh(1) command-line, even if ssh-agent(1) or a PKCS11Provider offers more identities. The argument to this keyword must be yes or no (the default). This option is intended for situations where ssh-agent offers many different identities.
Removing that option fixed the problem. Again I think setting ansible_ssh_private_key_file would be the sensible thing to do.
I was able to complete the setup and connect to the streisand instance successfully!
@obilodeau TIL something about Gnome-keyring. That's an interesting behaviour.
Removing that option fixed the problem. Again I think setting ansible_ssh_private_key_file would be the sensible thing to do.
Great - I'll pursue that path this week. Thanks for flagging the need for this.
I was able to complete the setup and connect to the streisand instance successfully!
Excellent! :key: :chart_with_upwards_trend: :tada: I'm happy to hear it works modulo the ansible_ssh_private_key aspect.
I caught my branch up with master and reworked the existing SSH key customization to play nicer with ansible_ssh_private_key. After cloning https://github.com/cpu/streisand/tree/cpu-specify-ssh-key at 2877aed8cc7d3c03c201aa25e05e53858d479b19 I was able to:
ed25519 key in /tmp/custom-streisand with a passphrase.ssh-agent./streisand/tmp/custom-streisand during the customization step for my SSH private keyI was able to do the same choosing Linode instead of Digital Ocean. It should work for all providers (except GCE, due to https://github.com/jlund/streisand/issues/919). For completeness I also tried an existing server after manually adding /tmp/streisand-custom.pub to the /root/.ssh/authorized_keys file before running ./streisand on another machine and giving the existing server IP.
I'm out of time to work on this today and still need to fix the broken CI tests. I suspect I will have a PR open to add this feature to master in the next few days.
I fixed the CI failings and opened a PR to get this merged to master.
All set. Master now supports specifying your own SSH key.
I gave space before and after equal and it worked.
if there is no space it wont work.
Most helpful comment
You can tell Ansible to use a specific key - in the inventory file, add something like:
[streisand-host:vars]ansible_ssh_private_key = /path/to/keyfileThis presumes that you already have a host instead of letting streisand provision one for you, and that the host details are also in the inventory file.