5.6. Changing an IdM service vault secret when compromised using Ansible
Follow this procedure to reuse an Ansible playbook to change the secret stored in a service vault when a service instance has been compromised. The scenario in the following example assumes that on webserver3.idm.example.com, the retrieved secret has been compromised, but not the key to the asymmetric vault storing the secret. In the example, the administrator reuses the Ansible playbooks used when storing a secret in an asymmetric vault and retrieving a secret from the asymmetric vault onto IdM hosts. At the start of the procedure, the IdM administrator stores a new PEM file with a new secret in the asymmetric vault, adapts the inventory file so as not to retrieve the new secret on to the compromised web server, webserver3.idm.example.com, and then re-runs the two procedures.
Prerequisites
You have configured your Ansible control node to meet the following requirements:
- You are using Ansible version 2.15 or later.
-
You have installed the
ansible-freeipapackage. - The example assumes that in the ~/MyPlaybooks/ directory, you have created an Ansible inventory file with the fully-qualified domain name (FQDN) of the IdM server.
-
The example assumes that the secret.yml Ansible vault stores your
ipaadmin_passwordand that you have access to a file that stores the password protecting the secret.yml file.
-
The target node, that is the node on which the
freeipa.ansible_freeipamodule is executed, is part of the IdM domain as an IdM client, server or replica. - You have created an asymmetric vault to store the service secret.
-
You have generated a new
httpdkey for the web services running on IdM hosts to replace the compromised old key. -
The new
httpdkey is stored locally on the Ansible controller, for example in the /usr/share/ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/vault/private-key-to-an-externally-signed-certificate.pem file.
Procedure
Navigate to the ~/MyPlaybooks/ directory:
$ cd ~/MyPlaybooks/Open your inventory file and make sure that the hosts onto which you want to retrieve the secret are defined correctly in the
webserverssection. For example, to instruct Ansible to retrieve the secret to webserver1.idm.example.com and webserver2.idm.example.com, enter:[ipaserver] server.idm.example.com [webservers] webserver1.idm.example.com webserver2.idm.example.com重要Make sure that the list does not contain the compromised webserver, in the current example webserver3.idm.example.com.
Make a copy of the data-archive-in-asymmetric-vault.yml Ansible playbook file from the relevant collections directory. For example:
$ cp /usr/share/ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/vault/data-archive-in-asymmetric-vault.yml data-archive-in-asymmetric-vault-copy.yml- Open the data-archive-in-asymmetric-vault-copy.yml file for editing.
Modify the file by setting the following variables in the
freeipa.ansible_freeipa.ipavaulttask section:-
Indicate that the value of the
ipaadmin_passwordvariable is defined in the secret.yml Ansible vault file. -
Set the
namevariable to the name of the vault, for example secret_vault. -
Set the
servicevariable to the service owner of the vault, for example HTTP/webserver.idm.example.com. -
Set the
invariable to "{{ lookup('file', 'new-private-key-to-an-externally-signed-certificate.pem') | b64encode }}". This ensures that Ansible retrieves the file with the private key from the working directory on the Ansible controller rather than from the IdM server. Set the
actionvariable tomember.This the modified Ansible playbook file for the current example:
--- - name: Tests hosts: ipaserver gather_facts: false vars_files: - /home/user_name/MyPlaybooks/secret.yml tasks: - freeipa.ansible_freeipa.ipavault: ipaadmin_password: "{{ ipaadmin_password }}" name: secret_vault service: HTTP/webserver.idm.example.com in: "{{ lookup('file', 'new-private-key-to-an-externally-signed-certificate.pem') | b64encode }}" action: member-
Indicate that the value of the
- Save the file.
Run the playbook:
$ ansible-playbook --vault-password-file=password_file -v -i inventory.file data-archive-in-asymmetric-vault-copy.yml- Open the retrieve-data-asymmetric-vault-copy.yml file for editing.
Modify the file by setting the following variables in the
freeipa.ansible_freeipa.ipavaulttask section:-
Indicate that the value of the
ipaadmin_passwordvariable is defined in the secret.yml Ansible vault file. -
Set the
namevariable to the name of the vault, for example secret_vault. -
Set the
servicevariable to the service owner of the vault, for example HTTP/webserver1.idm.example.com. -
Set the
private_key_filevariable to the location of the private key used to retrieve the service vault secret. -
Set the
outvariable to the location on the IdM server where you want to retrieve the new-private-key-to-an-externally-signed-certificate.pem secret, for example the current working directory. Set the
actionvariable tomember.This the modified Ansible playbook file for the current example:
--- - name: Retrieve data from vault hosts: ipaserver become: no gather_facts: false vars_files: - /home/user_name/MyPlaybooks/secret.yml tasks: - name: Retrieve data from the service vault freeipa.ansible_freeipa.ipavault: ipaadmin_password: "{{ ipaadmin_password }}" name: secret_vault service: HTTP/webserver1.idm.example.com vault_type: asymmetric private_key: "{{ lookup('file', 'service-private.pem') | b64encode }}" out: new-private-key-to-an-externally-signed-certificate.pem state: retrieved-
Indicate that the value of the
Add a section to the playbook that retrieves the data file from the IdM server to the Ansible controller:
--- - name: Retrieve data from vault hosts: ipaserver become: true gather_facts: false tasks: [...] - name: Retrieve data file fetch: src: new-private-key-to-an-externally-signed-certificate.pem dest: ./ flat: true mode: 0600Add a section to the playbook that transfers the retrieved new-private-key-to-an-externally-signed-certificate.pem file from the Ansible controller on to the webservers listed in the
webserverssection of the inventory file:--- - name: Send data file to webservers become: true gather_facts: no hosts: webservers tasks: - name: Send data to webservers copy: src: new-private-key-to-an-externally-signed-certificate.pem dest: /etc/pki/tls/private/httpd.key mode: 0444- Save the file.
Run the playbook:
$ ansible-playbook --vault-password-file=password_file -v -i inventory.file retrieve-data-asymmetric-vault-copy.yml