GNU/Linux >> Linux Esercitazione >  >> Linux

Gestire i segreti nei tuoi playbook Ansible

Finalmente è successo. Sei andato all-in con Ansible. Hai letto tutti gli ottimi articoli, visto i casi d'uso e sei entusiasta di iniziare a creare un'infrastruttura ripetibile e gestire la tua configurazione come codice. C'è solo un problema:hai un file di configurazione o un'attività che richiede una password o altre informazioni mission-critical. Sai che non dovresti memorizzare la password nei tuoi file di testo in chiaro, quindi non sei sicuro di dove dovrebbe andare.

Non temere, questo articolo ti guida attraverso le diverse opzioni per la gestione delle informazioni riservate nei tuoi playbook. Che tu stia cercando soluzioni semplici, come richiedere a un amministratore di inserire una password, o opzioni più complesse, come l'integrazione con un ambiente di gestione dei segreti esistente, Ansible ti copre.

[ Potrebbe interessarti anche: Demistificare Ansible per gli amministratori di sistema Linux ]

Richiedi

Se stai appena iniziando il tuo viaggio con Ansible ed eseguendo manualmente tutti i tuoi playbook, utilizzare un prompt interattivo direttamente nel tuo playbook è una soluzione semplice. Un richiesta fa sì che Ansible chieda all'utente le variabili desiderate e le memorizzi ogni volta che viene eseguito un playbook. Considera il seguente playbook, che garantisce l'esistenza di una chiave API in un file di configurazione:

---

- hosts: all
  gather_facts: false
  vars_prompt:
    - name: api_key
      prompt: Enter the API key
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"

Quando eseguo questo playbook, Ansible mi chiede alla riga di comando utilizzando il messaggio nel parametro prompt:

# ansible-playbook -i inventory.ini main.yml
Enter the API key:

L'input fornito dalla riga di comando verrà archiviato nella api_key variabile, che può quindi essere utilizzata nella riproduzione come qualsiasi variabile normale.

Sebbene i prompt variabili siano facili da implementare, li supererai se si investe nell'utilizzo di Ansible per la gestione completa della configurazione. Man mano che la gestione della configurazione matura, inizierai a eseguire i playbook in modo non interattivo e non ci sarà nessuno davanti al terminale per inserire le password. È qui che entra in gioco Ansible Vault.

Vault Ansible

Una delle mie funzionalità Ansible preferite è Ansible Vault, che fornisce funzionalità di crittografia dei contenuti nativi. Ansible Vault può crittografare e decrittografare variabili e file arbitrari, il che significa che puoi usarlo per proteggere file variabili che contengono segreti o persino crittografare interi file di configurazione sensibili. Ansible Vaults ha molte funzionalità avanzate, ma questo articolo si concentrerà sulle basi.

I file YAML standard contenenti segreti in chiaro possono essere facilmente crittografati con ansible-vault encrypt comando:

# Plaintext YAML file
$ cat secrets_file.enc
api_key: SuperSecretPassword

# Encrypt the file with ansible-vault
$ ansible-vault encrypt secrets_file.enc
New Vault password:
Confirm New Vault password:
Encryption successful

# Confirm that the file now contains encrypted content
$ cat secrets_file.enc
$ANSIBLE_VAULT;1.1;AES256
38396162626134393935663839666463306231653861336630613938303662633538633836656465
3637353766613339663032363538626430316135623665340a653961303730353962386134393162
62343936366265353935346336643865643833353737613962643539373230616239346133653464
6435353361373263640a376632613336366430663761363339333737386637383961363833303830
34336535623736313031313162353831666139343662653665366134633832646661

Quando eseguo il mio playbook, posso passare il file delle variabili crittografate e dire ad Ansible di richiedermi la password. Ansible decrittograferà il file e utilizzerà le variabili che ho definito, proprio come se avessi passato un normale file di variabili:

$ cat main.yml
---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"


$ ansible-playbook -i inventory.ini -e @secrets_file.enc --ask-vault-pass main.yml
Vault password:

PLAY [all] ***********************************************************************************

TASK [Ensure API key is present in config file] **********************************************
changed: [localhost]

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

$ cat /etc/app/configuration.ini
API_KEY=SuperSecretPassword

In precedenza ho descritto il motivo per cui si utilizza un vars_prompt non è l'ideale in un ambiente automatizzato perché richiede l'intervento manuale dell'utente. Allora, in che cosa è diverso un Ansible Vault? Ansible Vault consente di specificare un file di password che contiene la password di decrittografia per il Vault:

$ cat password_file 
password

$ ansible-playbook -i inventory.ini -e @secrets_file.enc --vault-password-file password_file main.yml

PLAY [all] ***********************************************************************************

TASK [Ensure API key is present in config file] **********************************************
changed: [localhost]

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

Assicurati di impostare le autorizzazioni appropriate sul file della password di decrittografia in modo che solo l'utente che esegue il playbook possa accedervi. In alternativa, considera l'utilizzo di uno script per accedere alla password in fase di esecuzione da un sistema di archiviazione password esterno.

Ora che il mio file variabile è crittografato, ho bisogno di un modo per modificarlo. Esistono due modi per modificare un Ansible Vault crittografato. Puoi modificare il file sul posto oppure puoi decrittografarlo completamente, modificarlo e quindi crittografarlo nuovamente. Entrambi i metodi sono mostrati di seguito.

# The edit command will launch a text editor, such as vim
$ ansible-vault edit secrets_file.enc 
Vault password: 

# The decrypt command will fully decrypt the file, allowing you to manipulate it how you see fit.
$ ansible-vault decrypt secrets_file.enc 
Vault password: 
Decryption successful

# Notice that the file has been decrypted
$ cat secrets_file.enc 
api_key: SuperSecretPassword

# Don't forget to re-encrypt the file when you're done!
$ ansible-vault encrypt secrets_file.enc 
New Vault password: 
Confirm New Vault password: 
Encryption successful
$ cat secrets_file.enc 
$ANSIBLE_VAULT;1.1;AES256
33373832393864613335393836616538373639353538306462366464303939303838316337336662
6235303936636465366363643761383462356335336239640a356161653166643134663762323136
34616431303434646338343265666135666263633162383662323164396266616638313936303863
3337626365313666630a326465663239653731613637303437666164346531636361653837326166
34396232623138616364393130303036653564643435636639316264636531336161

L'uso di un Ansible Vault per i segreti è uno dei miei metodi preferiti per archiviare dati sensibili. Il vantaggio di questo approccio è che puoi effettivamente archiviare i tuoi dati sensibili nel controllo del codice sorgente, fianco a fianco con i tuoi normali playbook. Poiché questi file sono crittografati, questo approccio comporta pochi rischi purché tu scelga una password complessa. Come ogni segreto condiviso, è una buona idea ruotare frequentemente la password di crittografia. Ansible offre anche diverse funzionalità avanzate per i Vault, come la possibilità di avere password diverse per diversi Vault. Assicurati di consultare la documentazione per scoprire modi straordinari per proteggere i tuoi segreti utilizzando le funzionalità native di Ansible.

Utilizzo di un gestore di password esistente

I due approcci precedenti sono approcci puramente Ansible per affrontare la gestione dei segreti. Tuttavia, molte organizzazioni dispongono già di strumenti, come HashiCorp Vault o Thycotic Secret Server. La community di Ansible ha scritto una serie di moduli personalizzati per interagire con questi tipi di sistemi.

Il seguente playbook utilizza una ricerca per ottenere un segreto da HashiCorp Vault e quindi utilizzarlo in un'attività:


---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ lookup('hashi_vault', 'secret=config-secrets/data/app/api-key:data token=s.FOmpGEHjzSdxGixLNi0AkdA7 url=http://localhost:8201')['key'] }}"

Puoi trovare una varietà di plugin per diversi strumenti di gestione dei segreti su Ansible Galaxy. Come per qualsiasi progetto supportato dalla community, è una buona idea controllare il codice in modo da capire come gestisce i tuoi dati e i tuoi segreti. Potresti anche voler scrivere il tuo.

L'uso di un plug-in o di un modulo di ricerca è adatto alle organizzazioni che dispongono già di uno strumento di gestione dei segreti maturo e desiderano semplicemente che Ansible consumi i segreti da questo sistema esistente. L'ovvio compromesso è la ridotta semplicità:le esecuzioni di Playbook ora dipendono dalla disponibilità di un sistema esterno e fare affidamento su un modulo supportato dalla community (o scriverne uno personalizzato) può richiedere molto tempo.

Una nota sulla registrazione

È importante ricordare che la crittografia dei dati inattivi (ad esempio, in un Ansible Vault o in un sistema di segreti esterni) non significa che i dati siano protetti dall'output accidentale in un file di registro Ansible. Se il modulo che chiami registra il tuo segreto durante le sue normali operazioni o quando si verifica un errore, quel segreto potrebbe essere esposto nei tuoi file di registro. Sia che tu stia archiviando questi registri in un sistema centrale o semplicemente utilizzando la visualizzazione di output standard predefinita, è importante proteggere i tuoi segreti dall'esposizione accidentale.

L'output di seguito proviene dallo stesso playbook Ansible che ho utilizzato per questo tutorial. Tuttavia, ho aumentato il livello di debug di Ansible con -vvv . Nota che il mio segreto (API_KEY=SuperSecretPassword ) viene esposto direttamente nell'output di debug. Ho ripulito un po' questo snippet, quindi non preoccuparti se provi questo e il tuo output sembra leggermente diverso.

TASK [Ensure API key is present in config file] ***********************************************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  invocation:
    module_args:
      attributes: null
      backrefs: false
      backup: false
      content: null
      create: false
      delimiter: null
      directory_mode: null
      firstmatch: false
      follow: false
      force: null
      group: null
      insertafter: null
      insertbefore: null
      line: API_KEY=SuperSecretPassword
      mode: null
      owner: null
      path: /etc/app/configuration.ini
      regexp: null
      remote_src: null
      selevel: null
      serole: null
      setype: null
      seuser: null
      src: null
      state: present
      unsafe_writes: null
      validate: null
  msg: Destination /etc/app/configuration.ini does not exist !
  rc: 257

Questo non è sicuramente l'ideale:il mio segreto è proprio lì, in bella vista. Per fortuna, Ansible fornisce un parametro no_log per le attività che proteggono i dati sensibili:

---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"
      no_log: True

Aggiungendo questo parametro all'attività che interagisce con i dati sensibili, l'output dell'attività non riuscita viene soppresso e viene preservata la riservatezza del mio segreto:

TASK [Ensure API key is present in config file] ***********************************************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  censored: 'the output has been hidden due to the fact that ''no_log: true'' was specified for this result'

È una buona idea usare no_log su qualsiasi attività che interagisce con dati sensibili. Dovresti anche essere consapevole dei suoi limiti:non impedirà la registrazione se il debug di Ansible è attivato.

[ Cerchi ulteriori informazioni sull'automazione dei sistemi? Inizia con The Automated Enterprise, un libro gratuito di Red Hat. ] 

Pensieri finali

La corretta gestione dei segreti è una delle prime sfide comuni che molti amministratori di sistema devono affrontare quando lavorano sulla distribuzione dell'automazione. In questo articolo ho descritto e dimostrato tre diversi metodi che puoi usare per proteggere i dati sensibili quando usi Ansible nel tuo ambiente. Questo articolo ha solo scalfito la superficie delle possibilità, quindi assicurati di rivedere la documentazione che ho collegato durante questa discussione. La sicurezza è compito di tutti. Puoi fare la tua parte come amministratore di sistema assicurandoti di trattare i dati privati ​​con la sensibilità che merita nelle tue pipeline di automazione.


Linux
  1. Guida di Ansible:gestisci i file utilizzando Ansible

  2. Configura il tuo demone Chrony con un playbook Ansible

  3. Come modificare il file dei tuoi host in Windows 10

  4. Portare il tuo sito offline

  5. Ansible decommentare la riga nel file

Guida introduttiva ai comandi ad hoc di Ansible

Inventario Ansible e file di configurazione

Una breve introduzione ad Ansible Vault

Scegli il miglior file system per il tuo Linux

RHCE Ansible Series #3:Ansible Playbook

RHCE Ansible Series #12:Risoluzione dei problemi di Ansible