Veilig Toegang Krijgen tot Ansible Vault tijdens Ontwikkeling

Richtlijn voor veilig toegang krijgen tot Ansible Vault tijdens ontwikkeling zonder wachtwoorden op te slaan in platte bestanden, met behulp van omgevingsvariabelen en scripts.

Projecten: c2platform/phx/ansible, c2platform.core


Probleem

Bij het ontwikkelen en testen van Ansible playbooks die Ansible Vault gebruiken, kan het uitvoeren van ansible-playbook omslachtig zijn. Je moet telkens het vault-wachtwoord invoeren. Het gebruik van een vault-wachtwoordbestand is een optie, maar dit is niet veilig en wordt beschouwd als slechte praktijk, omdat het risico bestaat op blootstelling van gevoelige informatie.

Context

In Ansible-werk aan projecten die een Ansible Inventarisproject gebruiken die een vault bevat beheerd met Ansible Vault, moet je de vault-wachtzin opgeven om provisioning-fouten te voorkomen. Je kunt dit doen met de --ask-vault-pass vlag:

ansible-playbook site.yml --ask-vault-pass

Als alternatief kun je --vault-password-file gebruiken om een wachtwoordbestand op te geven. Voor meer details, zie de Ansible documentatie  .

Als je een wachtwoordbestand gebruikt, zorg er dan voor dat de permissies ongeautoriseerde toegang voorkomen, en commit het nooit naar broncontrole. Echter, het opslaan van vault-wachtwoorden in bestanden is niet ideaal—het verhoogt beveiligingsrisico’s, omdat fouten gemakkelijk kunnen leiden tot lekken.

Oplossing

Een veiliger alternatief, vooral in hoogbeveiligde omgevingen waar het opslaan van secrets in bestanden onaanvaardbaar is, is om een omgevingsvariabele te gebruiken om het wachtwoord in het geheugen te houden. Stel vervolgens de Ansible-omgevingsvariabele ANSIBLE_VAULT_PASSWORD_FILE in om te verwijzen naar een script dat deze variabele echo’t. Merk op dat ANSIBLE_VAULT_PASSWORD_FILE dient als alternatief voor --vault-password-file. Belangrijk is dat het “wachtwoordbestand” ofwel een platte tekstbestand of een uitvoerbaar script (bijv. Bash of Python) kan zijn dat het wachtwoord output.

Het wachtwoord bevindt zich alleen in het geheugen voor de duur van de shell-sessie, wat acceptabel is voor de meeste omgevingen1.

Voorbeelden en implementatie

Het Ansible inventory-project c2platform/phx/ansible bevat een op Ansible Vault gebaseerde vault (zie map secret_vars).

Deze vault wordt opgenomen via include_vars in de Ansible Secrets-rol c2platform.core.secrets  .

roles/secrets/tasks/main.yml

20    - name: Include secrets
21      ansible.builtin.include_vars:
22        dir: "{{ secrets_dir_item['secrets_dir_item'] }}"
23      loop: >-
24        {{ secrets_dirs_stats['results']
25        | selectattr('stat.exists', 'equalto', True) }}        
26      loop_control:
27        label: "{{ secrets_dir_item['secrets_dir_item'] }}"
28        loop_var: secrets_dir_item
29      when: secrets_dir_item.stat.exists

De Ansible Secrets-rol maakt flexibele configuratie van vault-locaties mogelijk met behulp van een variabele secrets_dirs.

group_vars/all/secrets.yml

---
secrets_dirs:
  - "{{ inventory_dir }}/secret_vars/development"
  - "/runner/project/secret_vars/{{ px_env }}"  #  awx / aap

Op de op Ubuntu gebaseerde desktop pxd-ubuntu-devtop creëert Ansible een script /usr/local/bin/vault-client.sh, zie Instellen van een Ansible Ontwikkel Desktop voor meer informatie. De configuratie die verantwoordelijk is voor het aanmaken van dit bestand bevindt zich in group_vars/ubuntu_devtop/main.yml

group_vars/ubuntu_devtop/main.yml

16    - name: /usr/local/bin/vault-client.sh
17      type: copy
18      dest: /usr/local/bin/vault-client.sh
19      content: |
20        #!/bin/bash
21
22        # vault-client.sh
23        # This script is intended to be used as ANSIBLE_VAULT_PASSWORD_FILE.
24        # It checks if the environment variable PX_ANSIBLE_VAULT_PASSWORD is set.
25        # If set, it echoes the value (returns it).
26        # If not set, it outputs an error to stderr and exits with status 1.
27        # Use the set_vault_password function in your shell (e.g., from .bash_aliases.sh)
28        # to set the variable before running ansible-playbook.
29
30        if [ -z "${PX_ANSIBLE_VAULT_PASSWORD}" ]; then
31            echo "Error: PX_ANSIBLE_VAULT_PASSWORD is not set. Please set it using 'set_vault_password' in your shell session." >&2
32            exit 1
33        fi
34
35        echo "${PX_ANSIBLE_VAULT_PASSWORD}"        
36      mode: "0755"

De handleiding Ansible opzetten met Kerberos op een PHX-ontwikkeldesktop simuleert hoe een Ansible-desktop wordt gebruikt binnen het PHX-domein. Het integreert Kerberos en Ansible Vault op een veilige manier met behulp van omgevingsvariabelen.

In de handleiding voegt domeingebruiker “Tony” een bash-functie phx-vault-password toe aan zijn ~/.bash_aliases en exporteert ANSIBLE_VAULT_PASSWORD_FILE. Deze setup stelt Tony in staat om veilig toegang te krijgen tot de Ansible Vault op de desktop pxd-ubuntu-devtop zonder Vagrant. Het demonstreert hoe dit te doen in een air-gapped PHX-domein door het wachtwoord alleen in het geheugen te houden, zonder opslag in platte bestanden:

function phx-vault-password() {
    local password
    echo -n "Voer Ansible Vault-wachtzin in: " >&2
    read -s password
    echo >&2  # Voeg een nieuwe regel toe na de verborgen invoer
    export PX_ANSIBLE_VAULT_PASSWORD="$password"
    echo "PX_ANSIBLE_VAULT_PASSWORD is ingesteld voor deze shell-sessie." >&2
}
export ANSIBLE_VAULT_PASSWORD_FILE="/usr/local/bin/vault-client.sh"

Met deze aanpak kan een gebruiker het wachtwoord instellen in hun shell-sessie met:

phx-vault-password

En vervolgens de vault bekijken met wachtwoordinvoer:

ansible-vault view secret_vars/development/main.yml
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault-password
Voer Ansible Vault-wachtzin in:
PX_ANSIBLE_VAULT_PASSWORD is ingesteld voor deze shell-sessie.
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ alias phx-vault
alias phx-vault='ansible-vault edit secret_vars/development/main.yml'
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-vault view secret_vars/development/main.yml
---
# ad
px_ad_admin_password: Supersecret!

# cacerts_server
px_cacerts2_ca_domain_passphrase: huhohleSh8Beis9

# vagrant ssh
px_vagrant_ssh_id_rsa: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn

Als phx-vault-password niet wordt gebruikt (en dus PX_ANSIBLE_VAULT_PASSWORD niet is ingesteld), resulteert dit in een fout:

(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-playbook plays/mgmt/ad.yml
[WARNING]: Error in vault password file loading (default): Vault password
client script /usr/local/bin/vault-client.sh returned non-zero (1) when getting
secret for vault-id=default: b"Error: PX_ANSIBLE_VAULT_PASSWORD is not set.
Please set it using 'set_vault_password' in your shell session.\n"
ERROR! Vault password client script /usr/local/bin/vault-client.sh returned non-zero (1) when getting secret for vault-id=default: b"Error: PX_ANSIBLE_VAULT_PASSWORD is not set. Please set it using 'set_vault_password' in your shell session.\n"
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$

Merk op dat als ANSIBLE_VAULT_PASSWORD_FILE niet is ingesteld, dit resulteert in een bericht:

(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ ansible-playbook plays/mgmt/ad.yml | tee provision.log
[WARNING]: Error getting vault password file (default): The vault password file
/home/tony@c2.org/git/gitlab/c2/ansible-phx/vpass was not found
ERROR! The vault password file /home/tony@c2.org/git/gitlab/c2/ansible-phx/vpass was not found

Dit komt omdat in het PHX Ansible inventory-project c2platform/phx/ansible in ansible.cfg, er een regel staat met vault_password_file:

ansible.cfg

vault_password_file=vpass

In inventory-projecten die worden geconsumeerd door Ansible Automatiseringsplatform ( AAP ) , wordt deze instelling meestal niet gemaakt. Maar in de open-source PHX ontwikkelomgeving, die Vagrant gebruikt, wordt dit bestand vpass aangemaakt door Vagrant zoals je kunt zien in de Vagrantfile. Omdat dit slechts een Ansible ontwikkelomgeving is, is beveiliging geen groot probleem; alles is open source, dus het vault-wachtwoord is secret.

Vagrantfile

231# vpass file for Ansible vault secrets.yml
232vpass_file = File.join(File.dirname(__FILE__), 'vpass')
233File.open(vpass_file, 'w') { |f| f.write('secret') } unless File.exist? vpass_file

Aanvullende Informatie


  1. Dit is acceptabel maar niet ideaal voor hooggevoelige omgevingen. Als iemand je sessie compromitteert (bijv. via malware), zouden ze env vars kunnen dumpen. Voor productie/automatisering, overweeg integratie met een secret manager zoals HashiCorp Vault, AWS Secrets Manager, of pass in plaats van handmatige invoer ↩︎