How to run an ansible-playbook with a passphrase-protected-ssh-private-key?
Asked Answered
D

5

50

I have created an autoscaling group for Amazon EC2 and I have added my public key when I created the AMI with packer, I can run ansible-playbook and ssh to the hosts.

But there is a problem when I run the playbook like this ansible-playbook load.yml I am getting this message that I need to write my password

Enter passphrase for key '/Users/XXX/.ssh/id_rsa':
Enter passphrase for key '/Users/XXX/.ssh/id_rsa':
Enter passphrase for key '/Users/XXX/.ssh/id_rsa':

The problem is it doesn't accept my password (I am sure I am typing my password correctly).

I found that I can send my password with ask-pass flag, so I have changed my command to ansible-playbook load.yml --ask-pass and I got some progress but again for some other task it asks for the password again and it didn't accept my password

[WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [localhost] *************************************************************************************************************

TASK [ec2_instance_facts] ****************************************************************************************************
ok: [localhost]

TASK [add_host] **************************************************************************************************************
changed: [localhost] => (item=xx.xxx.xx.xxx)
changed: [localhost] => (item=yy.yyy.yyy.yyy)

PLAY [instances] *************************************************************************************************************

TASK [Copy gatling.conf] *****************************************************************************************************
ok: [xx.xxx.xx.xxx]
ok: [yy.yyy.yyy.yyy]
Enter passphrase for key '/Users/ccc/.ssh/id_rsa': Enter passphrase for key '/Users/ccc/.ssh/id_rsa':
Enter passphrase for key '/Users/ccc/.ssh/id_rsa':
Enter passphrase for key '/Users/ccc/.ssh/id_rsa':
Enter passphrase for key '/Users/ccc/.ssh/id_rsa':

If I don't use ask-pass flag even the task [Copy gatling.conf] doesn't complete and complaining about could not access the hosts. By adding the flag this part passes, but my next task again asks for pass.

How should I solve this issue? What am I doing wrong here?

Deckard answered 10/5, 2018 at 16:31 Comment(0)
D
21

I solved it by running ssh-add once and use it like if it's not password protected.

Deckard answered 27/6, 2018 at 18:55 Comment(0)
K
90

In ansible There is no option to store passphrase-protected private key

For that we need to add the passphrase-protected private key in the ssh-agent

Start the ssh-agent in the background.

# eval "$(ssh-agent -s)"

Add SSH private key to the ssh-agent

# ssh-add ~/.ssh/id_rsa

Now try running ansible-playbook and ssh to the hosts.

Kuykendall answered 24/7, 2018 at 14:10 Comment(5)
Best description for meBlackford
thanks a lot, it helped me quite a bit !Entoblast
can this be added to the playbook in some way?Aboveboard
Could you explain how did that solved the issue? I mean what does starting the agent in the background really do with Ansible? Is it just caching the passphrase?Tko
@MohammedNoureldin Correct, Ansible uses ssh which in turn checks ssh-agent for cached identitiesSeddon
D
21

I solved it by running ssh-add once and use it like if it's not password protected.

Deckard answered 27/6, 2018 at 18:55 Comment(0)
H
3

Building up on @javeed-shakeel's answer, I added the following lines to my .bashrc:

command -v ansible > /dev/null &&
    alias ansible='ssh-add -l > /dev/null || ssh-add 2> /dev/null && ansible'
command -v ansible-playbook > /dev/null &&
    alias ansible-playbook='ssh-add -l > /dev/null || ssh-add 2> /dev/null && ansible-playbook'

This will run ssh-add before ansible(-playbook) iff there was no key added to the ssh-agent, yet. This has the advantage that one does not need to run ssh-add by hand and one will be asked for the passphrase only if it is necessary.

Hudis answered 9/8, 2020 at 22:18 Comment(1)
I had to add the path of my private key to the ssh-add command because it doesn't use the standard name command -v ansible > /dev/null && alias ansible='ssh-add -l > /dev/null || ssh-add ~/.shh/name_of_private_key 2> /dev/null && ansible'Detour
J
1

ansible_sshpass_prompt & ansible_ssh_pass

If you don't want to use ssh-add / ssh-agent for some reason, you can still reliably use encrypted/passphrase protected SSH keys with your Ansible Playbooks by setting:

ansible_sshpass_prompt: Enter passphrase for key
ansible_ssh_pass: <my key's passphrase>
ansible_private_key_file: <~/.ssh/my-ssh-key>

(Or the same in ansible.cfg under [defaults] without the ansible_ prefix)

You'll need the host running Ansible to have sshpass installed. (Part of your package manager via pacman -S sshpass | apt install sshpass | dnf install sshpass)

If you read Ansible's ssh.py concerning sshpass_prompt, you can see how it works. (first read the comment then check the code for references to sshpass_prompt) https://github.com/ansible/ansible/blob/339452c1050b5b8fa6fd916e00519dff90443ceb/lib/ansible/plugins/connection/ssh.py#L65

Basically, the sshpass binary will look for the SSH key passphrase prompt (which you defined as Enter passphrase for key), and supply your passphrase's key to decrypt it. There was a lot of discussion in the Ansible's github issues if you want more details:

Pull #68874, Issue #34722, Issue #54743, Pull #81356, Issue #31988, Issue #81342, Pull #82181

To add a passphrase to your existing SSH key, use:

ssh-keygen -o -p -f <~/.ssh/my-ssh-key>

And if you run into problems and need to remove the passphrase, use:

ssh-keygen -p -f <~/.ssh/my-ssh-key>

Security Considerations

If you use this method, best to make sure the passphrase is stored encrypted in an Ansible Vault. This excellent github repo shows you how to connect selfhosted bitwarden or another password manager to your Ansible Vault, so you can have hassle free security comparable to SSH Agent, without manually entering your password. This could easily be adapted to work for a whole team if needed.

https://github.com/ironicbadger/compose-secret-mgt

Jerilynjeritah answered 25/6, 2024 at 12:12 Comment(0)
T
0

A passphrase is something else than a password. When ssh asks for a password, then you login as a user with a password that is checked by the computer you ssh into. It might be a company-wide password (AD, LDAP, etc.), or a local admin password.

A passphrase is used to encrypt the private key of your ssh key-pair. Typically the key-pair is generated with ssh-keygen, this command asks for a passphrase twice when you create your key-pair. That is for security, because when there is no passphrase on the private key, then anyone with a copy of the file can impersonate you! The passphrase is an added factor to the security.

ssh-agent is a program that creates a session for the use of your key-pair.

If you want to automate in GitLab with the use of an encrypted ssh key-pair this might help:

  ##
  ## Install ssh-agent if not already installed.
  ## (change apt-get to yum if you use an RPM-based image)
  ##
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'

  ##
  ## Run ssh-agent (on the Ansible control host)
  ##
  - eval $(ssh-agent)

  ##
  ## Create the SSH directory and give it the right permissions
  ##
  - mkdir -p ~/.ssh
  - chmod 700 ~/.ssh

  ## Create a shell script that will echo the environment variable SSH_PASSPHRASE
  - echo 'echo $SSH_PASSPHRASE' > ~/.ssh/tmp && chmod 700 ~/.ssh/tmp
  ## If ssh-add needs a passphrase, it will read the passphrase from the current
  ## terminal if it was run from a terminal.  If ssh-add does not have a terminal
  ## associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the
  ## program specified by SSH_ASKPASS and open an X11 window to read the
  ## passphrase.  This is particularly useful when calling ssh-add from a
  ## .xsession or related script. Setting DISPLAY=None drops the use of X11.

  ## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
  ## We're using tr to fix line endings which makes ed25519 keys work
  ## without extra base64 encoding.
  ## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
  ##
 
  - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | DISPLAY=None SSH_ASKPASS=~/.ssh/tmp ssh-add -

  ##
  ## Use ssh-keyscan to scan the keys of your private server. Replace example.com
  ## with your own domain name. You can copy and repeat that command if you have
  ## more than one server to connect to.
  ##
  - ssh-keyscan example.com >> ~/.ssh/known_hosts
  - chmod 644 ~/.ssh/known_hosts

Tackett answered 1/9, 2021 at 14:47 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.