Passa al contenuto principale

Chiavi da variabili d'ambiente e file

Oltre ad archiviare un segreto nel database, una voce del Key Store può leggere il proprio valore al momento dell'esecuzione del task da un file sul server Semaphore oppure da una variabile d'ambiente del processo del server Semaphore. Questo è utile quando la credenziale è già provisionata al di fuori di Semaphore, ad esempio:

  • una chiave SSH montata nel container di Semaphore come secret di Docker o Kubernetes;
  • un token scritto su disco da un agent (HashiCorp Vault Agent, cert-manager, ecc.) e ruotato regolarmente;
  • una password iniettata nell'ambiente del container dall'orchestratore.

Semaphore non copia il valore nel proprio database. Ogni volta che un task ha bisogno della chiave, il server legge nuovamente il file o la variabile, quindi la rotazione della credenziale su disco ha effetto a partire dal task successivo.

informazioni

Il file o la variabile viene letto dal server Semaphore, non da un runner. Quando si utilizzano runner remoti, montare il file sull'host del server; il server risolve il segreto e lo consegna al runner.

Scelta della sorgente

Quando si crea o si modifica una chiave (Key Store → New Key), nella parte superiore del modulo sono presenti le schede della sorgente:

SchedaDa dove proviene il valoreCosa inserire
LocalDatabase di Semaphore (cifrato)Il login, la password o la chiave privata nel modulo
Storage ProUn archivio di segreti esterno come HashiCorp VaultL'archivio e il percorso del segreto
EnvUna variabile d'ambiente del processo del server SemaphoreIl nome della variabile, ad esempio PROD_SSH_KEY
FileUn file sul server SemaphoreIl percorso assoluto del file, ad esempio /var/lib/semaphore/secrets/prod.json

Con Env o File selezionati, i campi login, password e chiave privata scompaiono. L'intera credenziale, incluso il login per le chiavi SSH e Accesso con password, deve trovarsi nel file o nella variabile.

1. Consentire la directory

Per motivi di sicurezza, Semaphore legge solo i file di chiave che si trovano all'interno della propria directory dei segreti. Qualsiasi altro percorso viene rifiutato all'avvio di un task:

Failed to install inventory: file path must be inside secrets path

La directory dei segreti predefinita è /tmp/semaphore. Impostarla sulla directory in cui si trovano i file di chiave tramite dirs.secrets in config.json oppure la variabile d'ambiente SEMAPHORE_SECRETS_PATH. Consultare Directory dei segreti per le regole di precedenza.

Esempio con Docker Compose che monta una directory dell'host e la consente:

services:
semaphore:
image: semaphoreui/semaphore:latest
environment:
SEMAPHORE_SECRETS_PATH: /var/lib/semaphore/secrets
volumes:
- /srv/semaphore/secrets:/var/lib/semaphore/secrets:ro

Frammento equivalente di config.json:

{
"dirs": {
"secrets": "/var/lib/semaphore/secrets"
}
}

Regole per il percorso inserito nella scheda File:

  • deve essere assoluto (/var/lib/semaphore/secrets/prod.json, non prod.json);
  • non deve contenere segmenti ..;
  • deve risolversi in una posizione all'interno della directory dei segreti (le sottodirectory sono ammesse);
  • il file deve essere leggibile dall'utente con cui viene eseguito Semaphore (nell'immagine Docker ufficiale è semaphore, UID 1001).

Le variabili d'ambiente non hanno alcuna restrizione di questo tipo; il server legge semplicemente la variabile indicata dal proprio ambiente.

2. Formattare il valore

Il contenuto del file (o il valore della variabile) dipende dal tipo di chiave. Un singolo carattere di fine riga alla fine di un file viene ignorato; tutto il resto viene utilizzato così com'è.

Chiave SSH

Semaphore si aspetta un documento JSON, non un file di chiave privata PEM o OpenSSH grezzo:

{
"login": "deploy",
"passphrase": "",
"private_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----\n"
}
  • login — il nome utente SSH, passato ad Ansible come --user. Lasciarlo vuoto per lasciare che sia l'inventory a decidere (ansible_user). Per i repository Git un login vuoto corrisponde per impostazione predefinita a git.
  • passphrase — la passphrase della chiave privata, oppure una stringa vuota.
  • private_key — la chiave privata con le interruzioni di riga codificate come \n.

Generare il documento a partire da una chiave esistente con jq, che si occupa dell'escaping:

jq -n --arg login deploy --rawfile key ~/.ssh/id_ed25519 \
'{login: $login, passphrase: "", private_key: $key}' \
> /srv/semaphore/secrets/prod_ssh.json
chmod 0400 /srv/semaphore/secrets/prod_ssh.json

Quindi creare una chiave di tipo SSH, aprire la scheda File e inserire /var/lib/semaphore/secrets/prod_ssh.json (il percorso come visto all'interno del container).

avvertimento

Far puntare la scheda File a una chiave privata grezza come ~/.ssh/id_ed25519 non funziona. Il file viene interpretato come JSON e il task non riesce a caricare l'inventory.

Accesso con password

Anche in questo caso un documento JSON:

{
"login": "svc-ansible",
"password": "s3cr3t"
}

Lasciare login vuoto per utilizzare la chiave come semplice token o password, ad esempio come password di Ansible Vault.

Esempio con variabile d'ambiente

Lo stesso formato JSON si applica alla scheda Env. In Docker Compose:

services:
semaphore:
image: semaphoreui/semaphore:latest
environment:
PROD_SSH_KEY: '{"login":"deploy","passphrase":"","private_key":"-----BEGIN OPENSSH PRIVATE KEY-----\n...\n-----END OPENSSH PRIVATE KEY-----\n"}'

Creare una chiave SSH, selezionare la scheda Env e inserire PROD_SSH_KEY come nome della variabile.

suggerimento

Le variabili d'ambiente sono visibili a tutti i processi del container e spesso finiscono nei metadati e nei log dell'orchestratore. Quando possibile, preferire la scheda File con un secret montato.

Risoluzione dei problemi

ErroreCausaSoluzione
file path must be absoluteÈ stato inserito un percorso relativoInserire il percorso completo che inizia con /
file path must not contain traversal segmentsIl percorso contiene ..Inserire il percorso risolto
file path must be inside secrets pathIl file si trova al di fuori di dirs.secretsImpostare SEMAPHORE_SECRETS_PATH sulla directory del file, oppure spostare il file
no such file or directoryIl percorso è errato oppure non è montato nel containerVerificare il mount del volume e utilizzare il percorso interno al container
permission deniedIl processo di Semaphore non può leggere il fileCorreggere il proprietario o i permessi del file
invalid character '-' looking for beginning of valueÈ stata fornita una chiave privata grezza al posto del documento JSONIncapsulare la chiave come mostrato sopra