Quali sono i vantaggi di mettere i valori segreti di un sito Web come variabili d'ambiente?


24

Le linee guida devops su https://12factor.net/config suggeriscono di inserire i segreti del sito Web (password del database, chiavi API, ecc.) In variabili d'ambiente. Quali vantaggi presenta invece di utilizzare file di testo (JSON, XML, YAML, INI o simili) ignorati dal controllo versione?

Trovo molto più semplice copiare un file di configurazione con segreti piuttosto che gestire le variabili di ambiente in .bash_profile e nella configurazione del server web. Mi manca qualcosa?


1
In teoria è più semplice leggere un file che memoria, in modo da poter considerare la superficie di attacco più grande e la complessità più piccola.
Florin Asăvoaie,

La mia regola empirica per i miei sviluppatori è che la memorizzazione delle impostazioni nelle variabili di ambiente è la cosa migliore da fare solo in ambienti simili a docker. Al di fuori delle VM container, approva / preferisce tutti gli altri punti di 12factor.net e l'uso dei file di configurazione. A nessuno di noi è piaciuta la natura insicura delle variabili di ambiente nelle normali distribuzioni di server.
Corey Ogburn,

Risposte:


21

L'autore elenca il loro ragionamento, sebbene sia un po 'disgiunto. Il loro argomento principale è che è facile controllare accidentalmente un file di configurazione e che i file di configurazione hanno formati diversi e possono essere sparsi nel sistema (tutti e tre sono argomenti mediocri per la configurazione relativa alla sicurezza come token di autenticazione e credenziali).

Data la mia esperienza, hai essenzialmente le seguenti tre opzioni, con vantaggi e svantaggi associati:

Archivia i dati in file di configurazione.

Quando si adotta questo approccio, è consigliabile isolarli idealmente dal repository stesso e assicurarsi che siano al di fuori dell'area in cui l'app memorizza il contenuto.

vantaggi:

  • Molto facile da isolare e controllare l'accesso, soprattutto se si utilizzano cose come SELinux o AppArmor per migliorare la sicurezza generale del sistema.
  • Generalmente facile da modificare per utenti non tecnici (questo è un vantaggio per i software pubblicati, ma non necessariamente per i software specifici della propria organizzazione).
  • Facile da gestire su grandi gruppi di server. Esistono tutti i tipi di strumenti per la distribuzione della configurazione.
  • Ragionevolmente facile da verificare quale sia la configurazione esatta utilizzata.
  • Per un'app ben scritta, di solito è possibile modificare la configurazione senza interrompere il servizio aggiornando il file di configurazione e quindi inviando un segnale particolare all'app (di solito SIGHUP).

svantaggi:

  • È necessaria una pianificazione adeguata per proteggere i dati.
  • Potrebbe essere necessario imparare formati diversi (anche se in questi giorni c'è solo una manciata di cui preoccuparsi e generalmente hanno una sintassi simile).
  • Le posizioni esatte di archiviazione possono essere codificate nell'app, il che rende la distribuzione potenzialmente problematica.
  • L'analisi dei file di configurazione può essere problematica.

Archivia i dati in variabili d'ambiente.

Di solito questo viene fatto acquistando un elenco di variabili e valori di ambiente dallo script di avvio, ma in alcuni casi potrebbe semplicemente dichiararli sulla riga di comando prima del nome del programma.

vantaggi:

  • Rispetto all'analisi di un file di configurazione, estrarre un valore da una variabile d'ambiente è banale in quasi tutti i linguaggi di programmazione.
  • Non devi preoccuparti troppo della pubblicazione accidentale della configurazione.
  • Ottieni un certo grado di sicurezza dall'oscurità perché questa pratica è rara e la maggior parte delle persone che hackerano la tua app non penserà di guardare subito le variabili di ambiente.
  • L'accesso può essere controllato dall'applicazione stessa (quando genera processi figlio, può facilmente pulire l'ambiente per rimuovere le informazioni sensibili).

svantaggi

  • Sulla maggior parte dei sistemi UNIX, è abbastanza facile accedere alle variabili di ambiente di un processo. Alcuni sistemi forniscono modi per mitigarlo (ad esempio l' hidepidopzione di mount /procsu LInux), ma non sono abilitati per impostazione predefinita e non proteggono dagli attacchi dell'utente proprietario del processo.
  • Non è banale vedere le impostazioni esatte che qualcosa sta usando se gestisci correttamente il problema di sicurezza sopra menzionato.
  • Devi fidarti dell'app per cancellare l'ambiente quando genera processi figlio, altrimenti perderanno informazioni.
  • Non è possibile modificare facilmente la configurazione senza un riavvio completo dell'app.

Utilizzare gli argomenti della riga di comando per passare i dati.

Scherzi a parte, evitatelo a tutti i costi, non è sicuro ed è un dolore nel culo da mantenere.

vantaggi:

  • Ancora più semplice da analizzare rispetto alle variabili d'ambiente nella maggior parte delle lingue.
  • I processi figlio non ereditano automaticamente i dati.
  • Fornisce un modo semplice per testare rapidamente configurazioni particolari durante lo sviluppo dell'applicazione.

svantaggi:

  • Proprio come le variabili di ambiente, è facile leggere la riga di comando di un altro processo sulla maggior parte dei sistemi.
  • Estremamente noioso per aggiornare la configurazione.
  • Pone un limite per quanto tempo può essere la configurazione (a volte fino a 1024 caratteri).

1
Un punto non irrilevante è il (ri) avvio automatico di un server, senza dover fornire manualmente alcuna password, alla fine sono da qualche parte sul disco per questo
PlasmaHH,

7
Sulla maggior parte dei sistemi UNIX, è possibile leggere praticamente tutte le variabili di ambiente dei processi senza richiedere privilegi significativi. - Puoi espanderci? Il file / proc / #### / environment è leggibile solo dal proprietario, quindi dovresti essere root o avere sudo.
rrauenza,

Penso che parte di questa tendenza di configurazione env sia nata anche da cose come docker in cui si utilizza un contenitore standard e lo si configura passando variabili env al contenitore.
rrauenza,

@rrauenza La proprietà di un processo non è un privilegio significativo a meno che tu non faccia un ottimo lavoro di segregazione delle cose per account, e in realtà hai solo bisogno della capacità CAP_SYS_ADMIN (che la radice ha implicitamente) se non sei il proprietario. Inoltre, per quanto riguarda la variabile ambientale, probabilmente hai ragione, ma è un design marginale anche con Docker.
Austin Hemmelgarn,

3
Sono d'accordo con il punto che @rrauenza fa. La risposta è abbastanza buona dappertutto, ma mi piacerebbe chiarire come esattamente puoi leggere praticamente tutte le variabili di ambiente dei processi senza bisogno di privilegi significativi . Per quanto riguarda " e in realtà hai solo bisogno della capacità CAP_SYS_ADMIN (che ha la radice implicitamente) ..." beh, se un agente maligno ha i privilegi di root, ulteriori discussioni sono ridondanti e CAP_SYS_ADMIN potrebbe anche essere il privilegio di root (vedi man7.org/linux /man-pages/man7/capabilities.7.html , CAP_SYS_ADMIN e Note per gli sviluppatori del kernel )
Nubarke,

13

Le variabili di ambiente saranno ereditate da ogni processo figlio del web server. Sono tutte le sessioni che si collegano al server e ogni programma generato da loro. I segreti verranno automaticamente rivelati a tutti questi processi.

Se si mantengono segreti nei file di testo, devono essere leggibili dal processo del server e potenzialmente anche da ogni processo figlio. Ma almeno i programmi devono andare a trovarli; non vengono forniti automaticamente. Potresti anche essere in grado di far funzionare alcuni processi figlio con account diversi e rendere i segreti leggibili solo da quegli account. Ad esempio, suEXEC lo fa in Apache.


1
"Questa è ogni sessione che si collega al server" è un'affermazione fuorviante. Non è possibile aprire una sessione http sul server e ottenere l'accesso alle sue variabili di ambiente, né è possibile accedere a una shell su quel server e ottenerli a meno che non si disponga di un accesso root o di possedere il processo del server Web.
Segfault,

Ogni processo generato dal server Web eredita il suo ambiente, a meno che non si esegua diversamente una procedura attiva. Una pagina HTML non ha la capacità di utilizzare tali informazioni, ma lo fa uno script.
Andrew Schulman,

Sebbene corretta, questa risposta potrebbe avere alcune correzioni / concessioni, in particolare per quanto riguarda il termine sessioni . In prima lettura, sembra dipingere in maniera negativa l'uso delle variabili d'ambiente quasi per suggerire possibilità di divulgazione di informazioni a un cliente esterno. Inoltre, una concessione paragonabile a suexec può essere fatta per un'impostazione limitata di env-vars, ad esempio l'impostazione di env-vars per processo (a la MYVAR=foo /path/to/some/executable) limita la propagazione a un processo e solo ai suoi figli - e dove i demoni master necessari possono scrub / reset / modifica l'ambiente dei processi figlio.
Shalomb,

2

Anche se ci sono alcuni compromessi relativi alla sicurezza da fare quando si tratta di variabili o file di ambiente, non credo che la sicurezza sia stata la principale forza trainante per questa raccomandazione. Ricorda che gli autori di 12factor.net sono anche (o erano anche?) Sviluppatori di Heroku PaaS. Far sì che tutti utilizzino le variabili di ambiente probabilmente ha semplificato un po 'il loro sviluppo. C'è così tanta varietà nei diversi formati e posizioni dei file di configurazione e sarebbe stato difficile per loro supportarli tutti. Le variabili d'ambiente sono facili in confronto.

Non ci vuole molta immaginazione per indovinare alcune delle conversazioni che si sono svolte.

Sviluppatore A: "Ah, questa IU del file di configurazione segreta è troppo ingombra! Dobbiamo davvero avere un menu a discesa che passi da json, xml e csv?"

Sviluppatore B: "Oh, la vita sarebbe così grandiosa se solo tutti usassero le variabili d'ambiente per la configurazione dell'app".

Sviluppatore A: "In realtà ci sono alcuni plausibili motivi di sicurezza per farlo. Probabilmente le variabili di ambiente non verranno controllate accidentalmente nel controllo del codice sorgente."

Sviluppatore B: "Non impostare le variabili di ambiente con uno script che avvia il daemon o un file di configurazione?"

Sviluppatore A: "Non in Heroku! Li faremo digitare nella UI."

Sviluppatore B: "Oh, guarda, il mio avviso sul nome di dominio per 12factor.net è appena andato via." 1


1 : fonte: inventato.


1

TL; DR

Esistono diversi motivi per utilizzare le variabili di ambiente anziché i file di configurazione, ma due dei più comuni da trascurare sono il valore di utilità della configurazione fuori banda e la separazione avanzata tra server, applicazioni o ruoli organizzativi. Piuttosto che presentare un elenco esaustivo di tutte le possibili ragioni, affronterò solo questi due argomenti nella mia risposta e toccerò leggermente le loro implicazioni sulla sicurezza.

Configurazione fuori banda: separazione dei segreti dal codice sorgente

Se memorizzi tutti i tuoi segreti in un file di configurazione, devi distribuirli su ciascun server. Ciò significa che è necessario controllare i segreti nel controllo di revisione insieme al codice o disporre di un repository o di un meccanismo di distribuzione completamente separati per i segreti.

Crittografare i tuoi segreti non aiuta davvero a risolverlo. Tutto ciò che fa è spingere il problema ad una rimozione, perché ora devi preoccuparti anche della gestione e della distribuzione delle chiavi!

In breve, le variabili di ambiente sono un approccio per spostare i dati per server o per applicazione fuori dal codice sorgente quando si desidera separare lo sviluppo dalle operazioni. Ciò è particolarmente importante se hai pubblicato il codice sorgente!

Migliora la separazione: server, applicazioni e ruoli

Mentre potresti sicuramente avere un file di configurazione per contenere i tuoi segreti, se li memorizzi nel codice sorgente hai un problema di specificità. Hai un ramo o un repository separato per ogni set di segreti? Come assicurate che il giusto set di segreti arrivi ai server giusti? O riduci la sicurezza avendo "segreti" che sono gli stessi ovunque (o leggibili ovunque, se li hai tutti in un unico file), e quindi costituiscono un rischio maggiore se i controlli di sicurezza di un sistema falliscono?

Se si desidera avere segreti univoci su ciascun server o per ogni applicazione, le variabili di ambiente eliminano il problema di dover gestire una moltitudine di file. Se aggiungi un nuovo server, applicazione o ruolo, non devi creare nuovi file o aggiornare quelli vecchi: aggiorni semplicemente l'ambiente del sistema in questione.

Pensieri di separazione sulla sicurezza

Mentre una completa esplorazione della sicurezza di kernel / memoria / file non rientra nell'ambito di questa risposta, vale la pena sottolineare che le variabili di ambiente per sistema correttamente implementate non sono meno sicure dei segreti "crittografati". In entrambi i casi, il sistema di destinazione deve ancora conservare il segreto decifrato in memoria ad un certo punto per poterlo utilizzare.

Vale anche la pena sottolineare che quando i valori sono memorizzati nella memoria volatile su un determinato nodo, non esiste alcun file su disco che può essere copiato e attaccato offline. Questo è generalmente considerato un vantaggio per i segreti in memoria, ma certamente non è conclusivo.

La questione delle variabili d'ambiente rispetto ad altre tecniche di gestione dei segreti è in realtà più sui compromessi di sicurezza e usabilità che non sugli assoluti. Il tuo chilometraggio può variare.


2
Questo non è convincente, perché tutti gli aspetti negativi che menzioni per i file di configurazione valgono anche per le variabili di ambiente. Le variabili di ambiente sono dati di configurazione. Non si impostano magicamente. Devono essere distribuiti su ciascun sistema e per impostarli è necessario utilizzare una sorta di meccanismo di configurazione .
jpaugh

@jpaugh Stai discutendo con un uomo di paglia e attaccando qualcosa che non ho mai detto. I problemi che risolvo sono la configurazione fuori banda e la separazione dei dati. Come spiegato chiaramente, puoi fare queste cose nel modo che preferisci. Se preferisci, puoi pubblicare i tuoi segreti insieme al tuo codice pubblicamente su GitHub, ma questo sembra certamente poco saggio nel caso generale. Tuttavia, solo tu puoi determinare i compromessi necessari affinché il tuo sistema funzioni correttamente all'interno di un determinato modello di minaccia.
CodeGnome

2
Tutti i tuoi punti sono corretti, tranne per il fatto che si applica alle variabili di ambiente tanto quanto a qualsiasi altro dato di configurazione. Se si memorizzano le variabili di ambiente in file, è possibile eseguirne il commit; e se li invii fuori banda, è più facile fare in un file che digitandoli. Ma se preferisci digitarli, perché non digitare invece un oggetto JSON e leggerlo su stdin? Questo è in realtà più sicuro della riga di comando.
jpaugh

1

Personalmente, non consiglierei di impostare le variabili ambientali in .bashrcquanto diventano visibili a tutti i processi avviati dalla shell ma di impostarle a livello di demone / supervisore (script init / rc, configurazione del sistema) in modo che il loro ambito sia limitato a dove necessario .

Laddove team separati gestiscono le operazioni, le variabili di ambiente forniscono un'interfaccia semplice per le operazioni per impostare l'ambiente per l'applicazione senza dover conoscere i file / formati di configurazione e / o ricorrere alla manipolazione del loro contenuto. Ciò è particolarmente vero nelle impostazioni multi-lingua / multi-framework in cui i team operativi possono scegliere il sistema di distribuzione (sistema operativo, processi di supervisione) in base alle esigenze operative (facilità di distribuzione, scalabilità, sicurezza, ecc.).

Un'altra considerazione sono le pipeline CI / CD, poiché il codice attraversa ambienti diversi(ad esempio sviluppo, test / qa, gestione temporanea, produzione) i dettagli ambientali (zone di distribuzione, dettagli di connessione al database, credenziali, indirizzi IP, nomi di dominio, ecc. ecc.) sono meglio impostati da strumenti / framework di gestione della configurazione dedicati e consumati dall'applicazione processi dall'ambiente (in un ambiente secco, scrivere una volta, eseguire ovunque moda). Tradizionalmente, dove gli sviluppatori tendono a gestire questi problemi operativi, tendono a archiviare file o modelli di configurazione oltre al codice, per poi aggiungere soluzioni alternative e altre complessità quando cambiano i requisiti operativi (ad es. Nuovi ambienti / distribuzione / siti, scalabilità / sicurezza peso in,

  • Env-vars semplifica la configurazione / complessità su larga scala.
  • Env-vars colloca la configurazione operativa esattamente con il team responsabile degli aspetti non correlati al codice dell'applicazione in modo uniforme (se non standard) non vincolante.
  • Env-vars supporta lo scambio dei processi master / supervisore (ad esempio god, monit, supervisord, sysvinit, systemd, ecc.) Che supportano l'applicazione - e certamente anche il sistema di distribuzione (sistemi operativi, immagini del contenitore, ecc.) O altro come requisiti operativi Evolve / cambio. Mentre ogni framework linguistico al giorno d'oggi ha una sorta di runtime di processo, questi tendono ad essere operativamente inferiori, adatti più agli ambienti di sviluppo e / o aumentano la complessità in ambienti di produzione multi-lingua / multi-framework.

Per la produzione, preferisco impostare l'applicazione env-vars in un EnvironmentFile come /etc/default/myapplication.confquello distribuito dalla gestione della configurazione e impostato leggibile solo in modo roottale che systemd(o qualsiasi altra cosa) possa generare l'applicazione sotto un utente del sistema Privato Privato in un Privato gruppo . Supportato con gruppi di utenti dedicati per opse sudo- questi file sono illeggibili dal mondo per impostazione predefinita. Questo è conforme a 12factor che supporta tutta la bontà di Dev + Ops plus ha tutti i vantaggi di una sicurezza decente, consentendo allo stesso tempo agli sviluppatori / tester di abbandonare i propri file Environment negli ambienti dev / qa / test.


0

Dal punto di vista di uno sviluppatore, l'archiviazione dei dati di configurazione nelle variabili di ambiente semplifica le distribuzioni tra diversi ambienti (sviluppo, QA e produzione) e libera gli sviluppatori dal doversi preoccupare di distribuire il file di configurazione errato.

Le app Web di Azure offrono la possibilità di usare questo modello e funziona molto bene.

Inoltre, mantiene i dati potenzialmente sensibili fuori dal controllo del codice sorgente. Ignorare quei file dal controllo del codice sorgente non è realmente fattibile (almeno in .NET) perché in questi file è presente anche la necessaria configurazione di plateplate.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.