SSH Key-based authentication setup in LINUX (or) UNIX based OS is one of the major platformservices related task and most frequently executed task by Unix admins. Ansible, An IT Automation tool could automate this tedious task as well.
SSH Key based authentication is indispensable when it comes to automation. Even some of the Ansible related tasks like SCP and RSYNC(synchronize) requires SSH Key based authentication to be enabled before running the ansible playbook.
In this post, we are going to see
How to enable the SSH Key-based authentication setup between multiple servers (or) hostsusing Ansible ad-hoc
commands and playbook
Or How to transfer SSH Keys using ansible playbook and ad-hoc commands.
Table of Contents
The Objective
I have two Red Hat Enterprise Linux servers named mwiapp01
and mwiapp02
and I have to enable SSH key based (passwordless) authentication between them, in both directions.
Index
- The Plan ( What we are trying to achieve in this article)
- SSH Key creation and Exchange using Ansible AD HOC commands
- SSH Key Creation and Exchange using Ansible Playbook
- Using Shell Module
- Using the authorized_key module
- SSH Key Creation and Exchange between multiple hosts
The Plan
We are going to see how to achieve our objective (or) requirement using Ansible ad-hoc command and ansible playbook with and without SSH authorized_key module.
Now we will see how to do this with both Ansible ad-hoc commands and playbook.
Let us consider that I have already grouped these servers into a host group named “app” in ansible_hosts
inventory file
Ansible AD-HOC Commands – Ansible SSH Key
In this method, we are going to use the Ansible ad hoc commands to perform the ssh key exchange and to copy the ssh keys between hosts. to know more about ansible ad hoc command refer to this article
Step 1: Create SSH Private key using SSH-KEYGEN for the user weblogic
[emailprotected]:~$ ansible app -m shell -a "ssh-keygen -q -b 2048 -t rsa -N '' -C 'creating SSH' -f ~/.ssh/id_rsa creates='~/.ssh/id_rsa'" -i ansible_hosts -b --become-user=weblogicmwiapp02 | SUCCESS | rc=0 >>mwiapp01 | SUCCESS | rc=0 >>
Step 2: Make sure the Private key file is created
[emailprotected]:~$ ansible app -m shell -a "ls -lrt ~/.ssh/id_rsa" -i ansible_hosts -b --become-user=weblogicmwiapp02 | SUCCESS | rc=0 >>-rw------- 1 weblogic weblogic 1679 Sep 10 17:25 /home/weblogic/.ssh/id_rsamwiapp01 | SUCCESS | rc=0 >>-rw------- 1 weblogic weblogic 1675 Sep 10 17:25 /home/weblogic/.ssh/id_rsa
Step 3:Fetch the Key Public Key from the servers to the ansible master
[emailprotected]:~$ ansible app -m fetch -a "src='~/.ssh/id_rsa.pub' dest='buffer/{{inventory_hostname}}-id_rsa.pub' flat='yes'" -i ansible_hosts -b --become-user=weblogicmwiapp02 | SUCCESS => { "changed": true, "checksum": "e128efa0cf4008d6f0a8652da44249d016a1c4fb", "dest": "/Users/aksarav/VirtualBox VMs/vagrantVM/buffer/mwiapp02-id_rsa.pub", "md5sum": "92332ffb86a310f2f7fa55e9e18e1f65", "remote_checksum": "e128efa0cf4008d6f0a8652da44249d016a1c4fb", "remote_md5sum": null}mwiapp01 | SUCCESS => { "changed": true, "checksum": "8ccbec5b91fd027e0e3ba8ca6fe2fa5e6faec0e8", "dest": "/Users/aksarav/VirtualBox VMs/vagrantVM/buffer/mwiapp01-id_rsa.pub", "md5sum": "f46044276aba3e4e6d4e918192676b76", "remote_checksum": "8ccbec5b91fd027e0e3ba8ca6fe2fa5e6faec0e8", "remote_md5sum": null}
Step 4: Copy the public key files to their respective destination servers to update authorized_keys
. mwiapp01 server’s public key mwiapp01-id_rsa.pub
would go to mwiapp02 server and vice versa
4a) Copy the mwiapp01
public key to mwiapp02
and update authorized key using ansible authorized_key module
[emailprotected]:~$ ansible app -m authorized_key -a "user='weblogic' state='present' key='{{ lookup('file','buffer/mwiapp01-id_rsa.pub')}}'" --limit=mwiapp02 -i ansible_hosts -b --become-user=weblogicmwiapp02 | SUCCESS => { "changed": true, "comment": null, "exclusive": false, "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDIRJwtqDW614wf9vKm51oTi3mNt4CkYXB7aLxhT1sEsZILUBYBLFqc78QB2eqelmbvgWN471CcR4XAYPxImB+ibZLhBuLqz49lPWpaVl+D55THVJFiCJ5MrXZBeSD73hRX0y1cR4kuPflaYLodz/sNOeScufomlhs+cQzwGpShSXqNtTJMl9KqqWnczBut6mdK5X/+ETruCTVigLrKfoAGDbpFHm2MNuVNud34HUffKcnqXz8ihbH1tmlW5jy+j6mMDsMNfIA7coP/bKoa2vVMX1sFpAQQCPhejLV26IYM5fYABVYrzxLtaiioylRyvSWl7NFTpgua+dtkbdV7aEWr creating SSH", "key_options": null, "keyfile": "/home/weblogic/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "unique": false, "user": "weblogic", "validate_certs": true}
4b)Copy the mwiapp02
‘s public key to mwiapp01
and update authorized key using ansible authorized_key module
[emailprotected]:~$ ansible app -m authorized_key -a "user='weblogic' state='present' key='{{ lookup('file','buffer/mwiapp02-id_rsa.pub')}}'" --limit=mwiapp01 -i ansible_hosts -b --become-user=weblogicmwiapp01 | SUCCESS => { "changed": true, "comment": null, "exclusive": false, "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDh50TVgulXoAEcRz0rn8SEXgVVoLpaebqk+PvhpRO27JbGC6WMlwpDNxEOdXjEn9Qlotm7zF/JUAjXaxEiPS7P5QSQjSTRxBu6YrTEV8sPnJyiocp+ll+1U74r18R88jE03+JOdxDroKROz3qpfT/vqzTHi6hnMdWs0n8vE09+oWPorW9lqrdWQ0C+AZShIWoSc/9nrLVDXci4rxhbwgrzyJbPd77sbV5yDoDfFLTKf3z3NQ48Gku/7zTdTNxrHOz8wop5Iqy7fqfH7jWAxlT0mWdJ6Ac+++ARj+x/v59hNfwMswc3rI2fE4tPNXIKC9tcnwVG3teaV1h4XxpHyWEt creating SSH", "key_options": null, "keyfile": "/home/weblogic/.ssh/authorized_keys", "manage_dir": true, "path": null, "state": "present", "unique": false, "user": "weblogic", "validate_certs": true}
Step 5:Validate the SSH Key-based authentication between each server as weblogic
user ( If everything we did is correct, we should be able to execute commands over SSH from one another.
5a) Invoke SSH login from mwiapp01
to mwiapp02
and execute uname -n command
[emailprotected]:~$ ansible app -m shell -a "ssh mwiapp02 'uname -a'" -i ansible_hosts -b --become-user=weblogic --limit=mwiapp01mwiapp01 | SUCCESS | rc=0 >>Linux mwiapp02 3.10.0-514.2.2.el7.x86_64 #1 SMP Wed Nov 16 13:15:13 EST 2016 x86_64 x86_64 x86_64 GNU/Linux
5b)Invoke SSH login from mwiapp02
to mwiapp01
and execute uname -n command
[emailprotected]:~/VirtualBox VMs/vagrantVM$ ansible app -m shell -a "ssh mwiapp01 'uname -a'" -i ansible_hosts -b --become-user=weblogic --limit=mwiapp02mwiapp02 | SUCCESS | rc=0 >>Linux mwiapp01 3.10.0-514.2.2.el7.x86_64 #1 SMP Wed Nov 16 13:15:13 EST 2016 x86_64 x86_64 x86_64 GNU/Linux
Ansible Playbook to Exchange keys between hosts
Type1: With Ansible Shellmodule and Typical Commands
In this method, We are not going to use any ansible in-built module and every step is done manually by executing the shell command. The Playbook contains the following tasks
- Create an SSHPrivate and Public Key using
ssh-keygen
command - Fetch generated key files from remote servers [mwiapp01,mwiapp02] to ansible master
- Copy the file from the master to remote destination servers
- Add the public to the mentioned user’s
authorized_keys
file
---- name: Exchange Keys between servers become: yes become_user: weblogic hosts: app tasks: - name: SSH KeyGen command shell: > ssh-keygen -q -b 2048 -t rsa -N "" -C "creating SSH" -f ~/.ssh/id_rsa creates="~/.ssh/id_rsa" - name: Fetch the keyfile from one server to another fetch: src: "~/.ssh/id_rsa.pub" dest: "buffer/{{ansible_hostname}}-id_rsa.pub" flat: yes - name: Copy the file from master to the destination copy: src: "buffer/{{item.dest}}-id_rsa.pub" dest: "/tmp/remote-id_rsa.pub" when: "{{ item.dest != ansible_hostname }}" with_items: - { dest: "{{groups['app'][1]}}"} - { dest: "{{groups['app'][0]}}"} - name: add the public key into Authorized_keys file to enable Key Auth shell: "cat /tmp/remote-id_rsa.pub >> ~/.ssh/authorized_keys" register: addtoauth
Type2: With Ansible authorized_key module
In this method, we are going to use the ansible built-in module named "authorized_key"
. The following playbook has three steps
- Create an SSHPrivate and Public Key using
ssh-keygen
command - Fetch generated key files from remote servers [mwiapp01,mwiapp02] to ansible master
- Use the authorized_key module to copy the file remote machine and add it to the mentioned user’s
authorized_keys
file ( If you could notice, the authorized_key module is actually performing the step3 and step4 from the manual method )
---- name: Exchange Keys between servers become: yes become_user: weblogic hosts: app tasks: - name: SSH KeyGen command tags: run shell: > ssh-keygen -q -b 2048 -t rsa -N "" -C "creating SSH" -f ~/.ssh/id_rsa creates="~/.ssh/id_rsa" - name: Fetch the keyfile from one server to another tags: run fetch: src: "~/.ssh/id_rsa.pub" dest: "buffer/{{ansible_hostname}}-id_rsa.pub" flat: yes - name: Copy the key add to authorized_keys using Ansible module tags: run authorized_key: user: weblogic state: present key: "{{ lookup('file','buffer/{{item.dest}}-id_rsa.pub')}}" when: "{{ item.dest != ansible_hostname }}" with_items: - { dest: "{{groups['app'][1]}}"} - { dest: "{{groups['app'][0]}}"}
Ansible SSH Key Exchange between multiple hosts
Though the previously given examples have talked about Creating and Exchanging the Keys between only two servers. With a Simple modification in the same playbook. you would be able to achieve Exchanging the SSH Keys across multiple servers (or) all the servers in the host group.
Here is the Playbook to exchange SSH key between multiple hosts.
---- name: Exchange Keys between servers hosts: multi tasks: - name: SSH KeyGen command tags: run shell: > ssh-keygen -q -b 2048 -t rsa -N "" -C "creating SSH" -f ~/.ssh/id_rsa creates="~/.ssh/id_rsa" - name: Fetch the keyfile from the node to master tags: run fetch: src: "~/.ssh/id_rsa.pub" dest: "buffer/{{ansible_hostname}}-id_rsa.pub" flat: yes - name: Copy the key add to authorized_keys using Ansible module tags: runcd authorized_key: user: vagrant state: present key: "{{ lookup('file','buffer/{{item}}-id_rsa.pub')}}" when: "{{ item != ansible_hostname }}" with_items: - "{{ groups['multi'] }}"
What is the difference
we have changed the loop with_items to parse all the servers in the host group instead of two specific servers. These are the two modified lines from the previous example.
when: "{{ item != ansible_hostname }}" with_items: - "{{ groups['multi'] }}"
Playbook execution Output
We have saved the Type1 playbook in the name sshkey-exchange-t1.yaml
and executed it. and here is the output.
In the last task. you could see that we successfully initiated an SSH connection from one another and ran the uname -a
command
Hope it helps.
We recommend the following article in case if you are looking to exchange IP between multiple hosts in Ansible. adding an IP in /etc/hosts file of multiple hosts in Ansible.
ansible update /etc/hosts file with IP of all hosts across all hosts
For any questions (or) support. Please feel free to comment
Rate this article [ratings]
Cheers,
Rumen Lishkov
Follow us onFacebook orTwitterFor more practical videos and tutorials. Subscribe to our channelFind me on Linkedin My ProfileFor any Consultation or to hire us [emailprotected]If you like this article. Show your Support! Buy me a Coffee.
Signup for Exclusive "Subscriber-only" Content
More from Middleware Inventory
How to enable SSH Key based authentication - Passwordless SSH
How to SSH without Password into remote Linux Server is the question that every Engineer working on Linux might have come across. Sometimes the Question we seek could be different like ssh command without password ssh to the remote server without password SSH without password from Shell Script SCP to…
Vagrant Private key - Ansible SSH Permission Denied - How to resolve.
While building VMs with Vagrant and trying to run ansible-playbook with them over SSH connection. We get exceptions like Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password The execution and the error would like something similar to the below. This post presumes that you are using the…
How to Ignore SSH Host Key Verification
While running a script to login to multiple remote servers using sshpass (or) keybased authentication (or) while logging to remote server using ssh (or) while copying the file using SCP. There are chances we might have encountered this "Host Key Verification failed" message. All the time we cannot do manual…
How to create SSH public Key from SSH private key is a question made me write this post. Though we would be able to achieve the SSH key-based authentication by producing the private key. Sometimes it is necessary that we must have the SSH public key. Especially when we are…
Ansible get ip address of current host or target
How to get the IP address of the current or remote host in Ansible. That's the question, this article is going to address. While running a Playbook you might have had a requirement where you need to get the IP address of the connected and current remote host. There are…