Authored by Dan Thomson

Non-interactively add a password to the SSH agent

This is a small expect (1) script to make it easy to add a private SSH key to the running SSH agent by passing along the key's password to ssh-add.

The script takes 2 arguments:

  • The SSH private key filename
  • The SSH private key password filename

Due to security concerns, only reading a password from a file is allowed. When using a file with a plaintext password like this, you must make sure that the file only has minimal permissions (ie. only you should be able to read from it) and it should be deleted as soon as possible.

If you want to be extra paranoid, you can make sure to only write the file into memory using a filesystem like tmpfs (remember that tmpfs is still readable from RAM, even if it's encrypted so that doesn't eliminate attack vectors completely). You can also try using something like shred (1) to overwrite the contents of your file before deleting it in order to make sure it's not recoverable.

Use With Gitlab CI and Ansible

The reason this script is here in the first place, is for simplifying the process of using a password-protected SSH key in order to access remote servers through Ansible. Below is an example of what you would need in order to accomplish this task. Your particular needs may be a little bit different, but the gist should be the same:

    - yum -y install expect jq python-pip openssh-clients which
    - pip install yq[yaml]
    - mkdir -p $HOME/.ssh
    - touch $HOME/.ssh/id_rsa
    - chmod 600 $HOME/.ssh/id_rsa
    - echo $KEY | base64 -d > $HOME/.ssh/id_rsa
    - curl -vs > ssh-agent-add-password.exp
    - chmod 755 ssh-agent-add-password.exp
    - eval `ssh-agent`
    - |
      for h in $(yq -r '.all.children["my-group"].hosts | keys | .[]' inventory.yml); do
        echo $KEY_PASSWORD > tmppw
        ./ssh-agent-add-password.exp $HOME/.ssh/id_rsa tmppw
        rm -f tmppw

In this example, $KEY is an SSH key supplied through the Gitlab CI variables section and represents a base64 encoded SSH private key. The $KEY_PASSWORD value is also supplied through the Gitlab CI variables and represents the password used to unlock the private key. We're also assuming that this Ansible deployment is using a inventory.yml file to map out the deployment inventory and that my-group is the group that lists all of the hosts we're connecting to. If this is not the case, then you might need to change the for loop or possibly remove it and just do manual calls to the ssh-agent-add-password.exp; one after the other.

This example also gets more complicated with multiple hosts that have different keys, but should still follow the same general flow.

Finally, we assume a CentOS system (for the initial yum command). If you're running this on a different O/S or distribution, you will need to install dependencies in your own way.

ssh-agent-add-password.exp 592 Bytes
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment