Setup New User and SSH Key Auth. using Ansible on Ubuntu 18.04

Ansible is a simple automation tool that automates software applications deployment, cloud provisioning, and configuration management. It's a server orchestration tool that helps you to manage and control a large number of server nodes from single places called 'Control Machines'. Ansible was created by Michael DeHaan in 2012 and is written in Python and Powershell.

In this tutorial, we will learn how to deploy a new user and enable the SSH Key-Based authentication using the automation tool Ansible. We will also learn how to configure the Ansible 'Control Machine', as well as how to write simple ansible playbook.

Prerequisites

  • 2 or more Ubuntu 18.04 Servers
    • 10.0.15.10      control-machine
    • 10.0.15.21      ansi01
    • 10.0.15.22      ansi02
  • Root privileges

What we will do?

  1. Setup Ansible Control Machine
  2. Define User and SSH Key
  3. Create Inventory File
  4. Create Ansible Playbook
  5. Deploy Server Using Playbook
  6. Testing

Step 1 - Setup Ansible Control Machine

In this tutorial, we will be using the Ubuntu 16.04 servers as the Ansible 'Machine Control' and ansible hosts. The first step we need to do is to set up the 'control machine'.

We will install python and ansible on the ansible 'control machine' by running the following command.

sudo apt install python ansible -y

Setup Ansible Control Machine

After the installation is complete, we will add a new system user.

We will add a new user named 'provision' in order to perform server provisioning using Ansible.

Add new user 'provision' and give the user a password.

useradd -m -s /bin/bash provision
passwd provision

Now add the 'provision' user for sudo without the password by creating new configuration file under the '/etc/sudoers.d/' using the command below.

echo  -e 'provision\tALL=(ALL)\tNOPASSWD:\tALL' > /etc/sudoers.d/provision

A new user has been created, and now it can use sudo without a password.

Add user

Step 2 - Define User and SSH Key

In this step, we will define the user for ansible hosts. This user will be automatically created by ansible, so we just need to define the username, password, and the ssh public key.

For each server ('ansi01' and 'ansi02'), we will create a new user named 'provision' with password 'secret01'. And we need to encrypt the 'secret01' password using the mkpasswd command.

Encrypt the 'secret01' password using the command below.

mkpasswd --method=SHA-512
TYPE THE PASSWORD 'secret01'

Note:

Make sure the 'whois' package is installed on the system, or you can install using the following command.

sudo apt install whois -y

And you will get the SHA-512 encrypted password.

Define User and SSH Key

Next, we will generate a new ssh-key.

Login to the 'provision' user and generate the ssh key using the ssh-keygen command.

su - provision
ssh-keygen -t rsa

Now the user and password have been defined, and the ssh key has been created l(ocated at the '.ssh' directory).

user and password have been defined

Step 3 - Create New Inventory

In this step, we will define the inventory files for all server hosts.

Login as the 'provision' user and create a new directory for the project.

su - provision
mkdir -p ansible01/

Go to the 'ansible01' directory and create a new inventory file 'inventory.ini' using vim.

cd ansible01/
vim inventory.ini

Paste the following configuration there.

[webserver]
ansi01 ansible_host=10.0.15.21
ansi02 ansible_host=10.0.15.22

Save and exit.

Now create a new ansible configuration file 'ansible.cfg'.

vim ansible.cfg

Paste the following configuration there.

[defaults]
inventory = /home/provision/ansible01/inventory.ini

Save and exit.

Create New Inventory

The ansible inventory file has been created, and our ansible scripts will be located under the 'provision' user, inside the 'ansible01' directory.

Step 4 - Create Ansible Playbook

Ansible Playbook is set of instructions that you send to run on a single or group of server hosts. It represents the ansible-provisioning, where the automation is defined as tasks, and all jobs like installing packages, editing files, will be done by ansible modules.

In this step, we will create a new ansible playbook to deploy a new user, deploy the ssh key, and configure the ssh service.

Before we create a new ansible playbook, we will scan all server fingerprint using the ssh-keyscan command as below.

ssh-keyscan 10.0.15.21 >> ~/.ssh/known_hosts
ssh-keyscan 10.0.15.22 >> ~/.ssh/known_hosts

Those servers fingerprint will be stored at the '.ssh/known_hosts' file.

Create Ansible Playbook

Note:

If you have a lot of server nodes, you can save your host list and then manually scan the ssh key fingerprint using bash script as shown below.

for i in $(cat list-hosts.txt)
do
ssh-keyscan $i >> ~/.ssh/known_hosts
done

Next, create the ansible playbook named 'deploy-ssh.yml' using vim.

vim deploy-ssh.yml

Paste following the ansible playbook there.

---
- hosts: all
  vars:
    - provision_password: '$6$w9S3t7x1kRtmG0u$6nVU9KZsC12Q8DYI4FtgKPy.e/cq/jseB/.DViTO1SpUnoCy.dxcOf8hyfitGq5V0yhgXccxzlqm2o.I3SlDJ0'
  gather_facts: no
  remote_user: root

  tasks:

  - name: Add a new user named provision
    user:
         name=provision
         password={{ provision_password }}

  - name: Add provision user to the sudoers
    copy:
         dest: "/etc/sudoers.d/provision"
         content: "provision  ALL=(ALL)  NOPASSWD: ALL"

  - name: Deploy SSH Key
    authorized_key: user=provision
                    key="{{ lookup('file', '/home/provision/.ssh/id_rsa.pub') }}"
                    state=present

  - name: Disable Password Authentication
    lineinfile:
          dest=/etc/ssh/sshd_config
          regexp='^PasswordAuthentication'
          line="PasswordAuthentication no"
          state=present
          backup=yes
    notify:
      - restart ssh

  - name: Disable Root Login
    lineinfile:
          dest=/etc/ssh/sshd_config
          regexp='^PermitRootLogin'
          line="PermitRootLogin no"
          state=present
          backup=yes
    notify:
      - restart ssh

  handlers:
  - name: restart ssh
    service:
      name=sshd
      state=restarted

Save and exit.

On the playbook script:

  • we create the 'deploy-ssh.yml' playbook script to be applied on all servers defined in the 'inventory.ini' file.
  • we create the ansible variable 'provision_password', containing the encrypted password for the new user.
  • Set the Ansible facts to 'no'.
  • Define the 'root' user as a remote user to perform tasks automation.
  • We create new tasks for adding a new user, add the user to the sudoers, and upload the ssh key.
  • We create new tasks for configuring the ssh services, disabling the root login, and disable password authentication. Tasks for configuring the ssh will trigger the 'restart ssh' handlers.
  • We create a handler to restart the ssh service.

Step 5 - Run the Playbook

Login to the 'provision' user and go to the 'ansible01' directory.

su - provision
cd ansible01/

Now run the the 'deploy-ssh.yml' playbook using the command as shown below.

ansible-playbook deploy-ssh.yml --ask-pass

Type your root password, and you will get the result as below.

Run the Playbook

All tasks for deploying a new user and ssh key have been completed successfully.

Step 6 - Testing

Test using ansible command.

ansible webserver -m ping
ansible webserver -m shell -a id

Now you will get the green messages as below.

Testing Ansible

Now we can manage those 'ansi01' and 'ansi02' servers using Ansible, and the 'provision' user will be default user for Ansible.

Testing connection to the servers

ssh 10.0.15.21
ssh 10.0.15.22

And you will be connected to each server using the default key '.ssh/id_rsa' file, and using the user 'provision'.

Test server connection

Another test

Deploying new user and ssh-key using ansible has been completed successfully.

Reference

Share this page:

Suggested articles

1 Comment(s)

Add comment

Comments

From: Pete at: 2018-05-23 17:25:00

In the real world, where we have constant attackers, best to avoid simple accounts.  Always use a random account for ansible management on every host and let ansible deal with it. Adding a 5+ numbers to the end of the username is usually sufficient.