Am1rr3zA
Am1rr3zA

Reputation: 7411

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

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?

Upvotes: 51

Views: 81405

Answers (6)

Y. Boujraf
Y. Boujraf

Reputation: 67

I am using ubuntu 22.04 LTS server

  1. Install keychain

sudo apt-get update sudo apt-get install keychain

  1. Update your ~/.bashrc or ~/.profile

Start keychain and add your SSH key

eval `keychain --eval --agents ssh id_rsa`

or

eval `keychain --eval --agents ssh id_rsa id_dsa`
  1. Reload your ~/.bashrc or ~/.profile
source ~/.bashrc

or

source ~/.profile

You will add the passphrase then it will be stored

It help me for Ansible script on my controller.

Best Regards

Upvotes: 0

erwin
erwin

Reputation: 738

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

Upvotes: 1

bbaassssiiee
bbaassssiiee

Reputation: 6782

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

Upvotes: -1

dirdi
dirdi

Reputation: 307

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.

Upvotes: 3

Javeed Shakeel
Javeed Shakeel

Reputation: 3417

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.

Upvotes: 94

Am1rr3zA
Am1rr3zA

Reputation: 7411

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

Upvotes: 20

Related Questions