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 GNOME Keyring of omgevingsvariabelen.

Projecten: c2platform/phx/ansible , c2platform.core


Probleem

Bij het ontwikkelen en testen van Ansible-playbooks die Ansible Vault gebruiken, moet je het vault-wachtwoord herhaaldelijk opgeven, wat omslachtig is. Het gebruik van een vault-wachtwoordbestand brengt het risico met zich mee van blootstelling van gevoelige informatie en wordt beschouwd als slechte praktijk.

Context

In Ansible engineering-werk aan projecten die een Ansible-inventarisproject gebruiken dat 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 verhoogt beveiligingsrisico’s, omdat fouten gemakkelijk kunnen leiden tot lekken.

Oplossing

Gebruik GNOME Keyring standaard voor het opslaan van het Ansible Vault-wachtwoord, omdat dit veiliger en handiger is. Het slaat het wachtwoord versleuteld op in de sleutelring van de gebruiker, toegankelijk over sessies heen met een GUI.

Voor SSH-sessies zonder GUI, gebruik een omgevingsvariabele PX_ANSIBLE_VAULT_PASSWORD als fallback. Stel de Ansible-omgevingsvariabele ANSIBLE_VAULT_PASSWORD_FILE in op een script dat deze variabele echo’t. Merk op dat ANSIBLE_VAULT_PASSWORD_FILE dient als alternatief voor --vault-password-file. Het “wachtwoordbestand” kan ofwel een platte tekstbestand of een uitvoerbaar script (bijv. Bash of Python) 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.

Voordelen

  • Verbetert de beveiliging door het vermijden van plaintext-opslag van gevoelige wachtwoorden.
  • Verbetert het gemak voor ontwikkelaars, vermindert herhaalde wachtwoordinvoer.
  • Ondersteunt zowel GUI- als non-GUI-toegangsmethoden voor flexibiliteit in ontwikkelomgevingen.

Voorbeelden en implementatie

Het Ansible-inventarisproject  c2platform/phx/ansible bevat een op Ansible Vault gebaseerde vault (zie map  secret_vars). Deze aanpak is compatibel met de Automation Controller (AWX) van Ansible Automation Platform (AAP), zie Geheimen Beheren met Ansible Vault in AAP / AWX voor meer informatie. Dit Ansible-inventarisproject bevat de definitie/configuratie van een op Ubuntu gebaseerde desktop pxd-ubuntu-devtop. Het aanmaken van dit knooppunt is deel van handleiding Ansible ontwikkeldesktop in PHX-domein .

Een andere handleiding Ansible met Kerberos opzetten 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. Standaard wordt de GNOME Keyring gebruikt voor veilige opslag, met een fallback naar de omgevingsvariabele als er geen GUI beschikbaar is. Deze setup stelt Tony in staat om veilig toegang te krijgen tot de Ansible Vault op de desktop pxd-ubuntu-devtop.

Optie 1: GNOME Keyring

Op deze desktop creëert Ansible het script vault-client-keyring.sh. De configuratie die verantwoordelijk is voor het aanmaken van dit bestand wordt hieronder getoond:

 group_vars/ubuntu_devtop/main.yml

18    - name: Vault client scripts
19      type: copy
20      defaults:
21        mode: "0755"
22      resources:
23        - dest: /usr/local/bin/vault-client.sh
24          src: vault-client.sh
25        - dest: /usr/local/bin/vault-client-keyring.sh
26          src: vault-client-keyring.sh

 plays/dev/files/vault-client-keyring.sh

#!/usr/bin/env bash
# vault-client-keyring.sh - print the Ansible Vault password from Secret Service (GNOME Keyring/libsecret)
#
# Usage:
#   1) Store password in keyring (attributes: ansible=vault):
#        Interactive:  secret-tool store --label="Ansible Vault Password" ansible vault
#        Non-interactive (stdin):  printf '%s' 'YOUR_PASSWORD' | secret-tool store --label="Ansible Vault Password" ansible vault
#   2) Use with Ansible:
#        ansible-playbook --vault-password-file /usr/local/bin/vault-client-keyring.sh play.yml
#      or set in ansible.cfg:  vault_password_file = /usr/local/bin/vault-client-keyring.sh
#
# Requirements:
#   - secret-tool (Debian/Ubuntu: package libsecret-tools; RHEL/Fedora: libsecret)
#   - A running/unlocked Secret Service (e.g., GNOME Keyring). On headless hosts a valid D-Bus session is required.
#
# Security:
#   - This script prints the password to stdout for Ansible; avoid running it manually unless needed.

set -o nounset -o pipefail

main() {
    if ! command -v secret-tool >/dev/null 2>&1; then
    echo "Error: secret-tool not found. Install libsecret-tools (Debian/Ubuntu) or libsecret (RHEL/Fedora)." >&2
    exit 2
    fi

    # Lookup attributes; defaults: ansible=vault. Override via env: KEYRING_VAULT_ATTR_KEY / KEYRING_VAULT_ATTR_VAL
    local attr_key="${KEYRING_VAULT_ATTR_KEY:-ansible}"
    local attr_val="${KEYRING_VAULT_ATTR_VAL:-vault}"

    # Fetch secret; suppress secret-tool stderr
    local pw
    if ! pw="$(secret-tool lookup "$attr_key" "$attr_val" 2>/dev/null)"; then
    echo "Error: no secret found for ${attr_key}=${attr_val}. Store it first with 'secret-tool store'." >&2
    exit 3
    fi

    if [ -z "${pw}" ]; then
    echo "Error: secret is empty. Store a non-empty value." >&2
    exit 4
    fi

    # Print without trailing newline; avoids accidental whitespace
    printf '%s' "${pw}"
}

main "$@"

Het script vault-client-keyring.sh gebruikt secret-tool om het wachtwoord op te halen uit GNOME Keyring en output het voor Ansible om te gebruiken. Deze methode is veilig en persistent over sessies heen zolang de sleutelring is ontgrendeld.

De Ansible engineer kan de terminal aanpassen en een functie phx-vault-password toevoegen om eenvoudig het vault-wachtwoord op te halen en in te stellen met secret-tool.

function phx-vault-password() {
    local pw=$(secret-tool lookup ansible vault 2>/dev/null)
    if [ -z "${pw}" ]; then
        echo "Password doesn't exist or is empty, lets add/set it!"
        pw=$(secret-tool store --label 'Ansible Vault Password' ansible vault >&2)
        echo "Vault password has been set." >&2
    else
        echo "Vault password is already set."
    fi
    export ANSIBLE_VAULT_PASSWORD_FILE=/usr/local/bin/vault-client-keyring.sh
}

Deze aanpak wordt in detail beschreven in:

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

phx-vault-password

De output hieronder toont het resultaat van het uitvoeren van het commando:

(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault-password
Password doesn't exist or is empty, lets add/set it!
Password:
Vault password has been set.
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$

Als je het commando voor de eerste keer uitvoert, word je gevraagd om een wachtwoord in te stellen voor de GNOME Keyring. Het Ansible Vault-wachtwoord zal daar worden opgeslagen voor gemak (je hoeft het wachtwoord niet elke keer op te geven wanneer je Ansible gebruikt) en ook beveiliging. Het is een veilige plek. De screenshot hieronder toont de GNOME Keyring-prompt die vraagt om wachtwoord en wachtwoordbevestiging.

Daarna kun je de vault gebruiken zonder wachtzin-prompts, bijvoorbeeld zoals hieronder getoond:

ansible-vault view secret_vars/development/main.yml
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault-password
Enter Ansible Vault passphrase:
PX_ANSIBLE_VAULT_PASSWORD has been set for this shell session.
(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

Optie 2: SSH (geen GUI)

Voor omgevingen zonder GUI, zoals SSH-sessies, creëert Ansible het script vault-client.sh. De configuratie die verantwoordelijk is voor het aanmaken van dit bestand wordt hieronder getoond:

 group_vars/ubuntu_devtop/main.yml

18    - name: Vault client scripts
19      type: copy
20      defaults:
21        mode: "0755"
22      resources:
23        - dest: /usr/local/bin/vault-client.sh
24          src: vault-client.sh
25        - dest: /usr/local/bin/vault-client-keyring.sh
26          src: vault-client-keyring.sh

 plays/dev/files/vault-client.sh

#!/bin/bash

# vault-client.sh
# This script is intended to be used as ANSIBLE_VAULT_PASSWORD_FILE.
# It checks if the environment variable PX_ANSIBLE_VAULT_PASSWORD is set.
# If set, it echoes the value (returns it).
# If not set, it outputs an error to stderr and exits with status 1.
# Use the set_vault_password function in your shell (e.g., from .bash_aliases.sh)
# to set the variable before running ansible-playbook.

if [ -z "${PX_ANSIBLE_VAULT_PASSWORD}" ]; then
    echo "Error: PX_ANSIBLE_VAULT_PASSWORD is not set. Please set it using 'set_vault_password' in your shell session." >&2
    exit 1
fi

echo "${PX_ANSIBLE_VAULT_PASSWORD}"

Het script vault-client.sh controleert op de omgevingsvariabele PX_ANSIBLE_VAULT_PASSWORD en output het als het is ingesteld, biedt een fallback voor non-GUI-toegang.

function phx-vault-password-env() {
    local password
    echo -n "Enter Ansible Vault passphrase: " >&2
    read -s password
    echo >&2  # Add a newline after the hidden input
    export PX_ANSIBLE_VAULT_PASSWORD="$password"
    echo "PX_ANSIBLE_VAULT_PASSWORD has been set for this shell session." >&2
    export ANSIBLE_VAULT_PASSWORD_FILE=/usr/local/bin/vault-client.sh
}

Deze aanpak wordt in detail beschreven in:

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

phx-vault-password-env

En vervolgens de vault bekijken zonder wachtzin-prompts met:

ansible-vault view secret_vars/development/main.yml
(pxd) tony@pxd-ubuntu-devtop:~/git/gitlab/c2/ansible-phx$ phx-vault-password-env
Enter Ansible Vault passphrase:
PX_ANSIBLE_VAULT_PASSWORD has been set for this shell session.
(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-env niet wordt gebruikt (en dus PX_ANSIBLE_VAULT_PASSWORD niet is ingesteld), resulteert dit in een fout2.

Merk op dat als ANSIBLE_VAULT_PASSWORD_FILE niet is ingesteld, dit resulteert in een bericht3.

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. ↩︎

  2. Als phx-vault-password-env 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$
    
     ↩︎
  3. 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-inventarisproject c2platform/phx/ansible in ansible.cfg, er een regel staat met vault_password_file:

     ansible.cfg

    vault_password_file=vpass
    

    In inventarisprojecten die worden geconsumeerd door Ansible Automation Platform, 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

    245  end
    246end
    247    
    
     ↩︎