Privilege escalation with Ansible more secure using Vault

Sometimes is necessary to execute the tasks of the Playbook with root user in the remote servers. To escalate privileges is necessary to set become variable to yes: “become: yes”. There are different methods of privilege escalation but the most common to use is sudo method.

For example I’m using in my inventory(/etc/ansible/hosts) the following variables:

# VARS
[all:vars]
ansible_user=remote
#ansible_ssh_pass=PASSWORD
ansible_port=22

With ansible_user variable I’m telling to Ansible which is the user that will connect by ssh to the remotes servers, in my case the user is always “remote“. But this user is not an user with enough privileges to install packages or change some configurations of the system. To do that is necessary to elevate privileges using sudo. Sudo means that when you execute a command with sudo the command is actually executed by the root user, instead the login user. And to activate it we just have to set become variable to yes.

Currently I have commented the line of ansible_ssh_pass variable because I prefer to use a ssh trust relationship between Ansible master and the remote servers. This means that I am able to connect via ssh with the remote user without entering the password.

For example, this is the header of a simple Playbook:

---
- hosts: web
  name: Install the apache web service
  become: yes

FAILED! => {“msg”: “Missing sudo password”}

But is still necessary to configure the sudo password in a secure way avoiding plain text passwords for security reasons. If we don’t have the sudo password correctly configured we will receive the following output:

[remote@ansible]$ ansible-playbook YOUR_PLAYBOOK.yml
PLAY [This is a play within a playbook] ****************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
fatal: [node1]: FAILED! => {"msg": "Missing sudo password"}

PLAY RECAP *********************************************************************************************************************
node1                      : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0 

Option –ask-become-pass

Of course you can add the “–ask-become-pass” option to introduce your sudo password manually in the prompt:

[remote@ansible apache-basic-playbook]$ ansible-playbook --ask-become-pass YOUR_PLAYBOOK.yml 

BECOME password: 

Vault: A secure way to specify the sudo password

1. Add some variables to your Playbook

Add the following variables to your Playbook:

  vars_files:
    - ~/.ansible/my_vault.yml

  vars:
    ansible_become_pass: '{{ su_password }}'
  • – ~/.ansible/my_vault.yml: is the encrypted file with the sudo password we will generate later using ansible-vault command.
  • ansible_become_pass: ‘{{ su_password }}’: is the variable that contain the sudo password value. We will generate later using ansible-vault command.

2. Generate an encrypted vars-file for your password with ansible-vault

The next step is create a new encrypted data file called my_vault.yml. We can do that, running the following command:

[remote@ansible]$ ansible-vault create my_vault.yml
New Vault password: 
Confirm New Vault password: 

After providing the Vault password, an editor will appear and we only need to add the following with our own sudo password, and save de file how we would do with Vi editor (:wq).

su_password: your_sudo_password_for_remote_servers

After executing the previous command, the my_vault.yml file has been created and the content of the file it would be similar to:

[remote@ansible]$ cat my_vault.yml
$ANSIBLE_VAULT;1.1;AES256
34641533663037383731303932356633646264643631353431313636643110643439393933646366
6666666239343761336536303930313537386366313434360a653236383634356466353339616332
61366161365555576365383436623437326434346235633336356634353730376463356136333262
3930356238353730330a326462366334353236664444303236666634646662383662656336303863
62653132353435333534313234343939343733646231366339356566313234383331

Then move my_vault.yml file to ~/.ansible folder:

[remote@ansible]$ mv my_vault.yml ~/.ansible/my_vault.yml

– Create a file to keep your Vault password

Create .vault_pass.txt file to keep your vault password in it. The password should be a string stored as a single line in the file.

[remote@ansible]$ vi ~/.ansible/.vault_pass.txt

PASSWORD

Ensure permissions on the file are such that no one else can access your key and do not add your key to source control:

[remote@ansible]$ chmod 640 ~/.ansible/.vault_pass.txt

– Add ANSIBLE_VAULT_PASSWORD_FILE environment variable

And add the environment variable ANSIBLE_VAULT_PASSWORD_FILE to .bash_profile file of the remote user:

[remote@ansible]$ vi ~/.bash_profile

# ANSIBLE
ANSIBLE_VAULT_PASSWORD_FILE=~/.ansible/.vault_pass.txt
export ANSIBLE_VAULT_PASSWORD_FILE

3. Executing the Playbook with Privilege Escalation

Finally to run our playbook using the privilege escalation option and the encrypted sudo password we’ve already created, we can execute the following command:

Introducing your Vault password in the prompt:

[remote@ansible]$ ansible-playbook --ask-vault-pass YOUR_PLAYBOOK.yml

Vault password: 

Or without any prompt:

[remote@ansible]$ ansible-playbook YOUR_PLAYBOOK.yml
PLAY [This is a play within a playbook] ********************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************************************
ok: [node1]

TASK [install httpd packages] ******************************************************************************************************************************
changed: [node1] => (item=[u'httpd', u'mod_wsgi'])

TASK [create site-enabled directory] ***********************************************************************************************************************
ok: [node1]

TASK [copy httpd.conf] *************************************************************************************************************************************
ok: [node1]

TASK [copy index.html] *************************************************************************************************************************************
changed: [node1]

TASK [start httpd] *****************************************************************************************************************************************
changed: [node1]

RUNNING HANDLER [restart apache service] *******************************************************************************************************************
changed: [node1]

PLAY RECAP *************************************************************************************************************************************************
node1                      : ok=7    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Documentation:

https://docs.ansible.com/ansible/latest/user_guide/become.html

https://docs.ansible.com/ansible/latest/user_guide/playbooks_vault.html

Compartir:

This article was written by RoberMB

?OS, ☁️Cloud, ?️Cybersecurity, ✈️Traveling ... ................ Always learning. ?‍☠️?‍☠️?‍☠️ CEH v10, CPHE, ICPP+(In progress) ?‍☠️?‍☠️?‍☠️

Leave a Reply

Your email address will not be published. Required fields are marked *