Nascondere la password negli script Shell


23

Come posso nascondere una password negli script della shell? Esistono numerosi script che accedono al database. Se apriamo lo script, anche altri sono a conoscenza del nome utente e della password. Quindi, se qualcuno sa come nascondere, per favore fatemelo sapere.

Ho un modo: inserire la password in un file e rendere il file nascosto e nessuno accederà al file (modificare le autorizzazioni e utilizzare il file nello script mentre si accede al database).

Risposte:


35

Innanzitutto , come hanno già detto diverse persone, è essenziale mantenere le credenziali separate dalla sceneggiatura. (Oltre a una maggiore sicurezza, significa anche che è possibile riutilizzare lo stesso script per diversi sistemi con credenziali diverse.)

In secondo luogo , è necessario considerare non solo la sicurezza delle credenziali, ma anche l'impatto se / quando tali credenziali sono compromesse. Non dovresti avere una sola password per tutti gli accessi al database, dovresti avere credenziali diverse con diversi livelli di accesso. Ad esempio, potresti avere un utente DB che ha la capacità di eseguire una ricerca nel database: quell'utente dovrebbe avere accesso in sola lettura. Un altro utente può disporre dell'autorizzazione per inserire nuovi record, ma non per eliminarli. Un terzo potrebbe avere l'autorizzazione per eliminare i record.

Oltre a limitare le autorizzazioni per ciascun account, dovresti anche avere delle restrizioni sulla provenienza di ciascun account. Ad esempio, l'account utilizzato dal server Web non deve essere autorizzato a connettersi da un indirizzo IP diverso da quello del server Web. Un account con permessi di root completi per il database dovrebbe essere molto limitato in termini di provenienza e non dovrebbe mai essere usato se non interattivamente. Considera anche di utilizzare le procedure memorizzate nel database per limitare esattamente ciò che può essere fatto da ciascun account.

Queste restrizioni devono essere implementate sul lato DB-server del sistema, in modo che anche se il lato client è compromesso, le restrizioni non possono essere modificate da esso. (E, ovviamente, il server DB deve essere protetto con firewall ecc. Oltre alla configurazione del DB ...)

Nel caso di un account DB a cui è consentito solo un accesso di sola lettura limitato e solo da un determinato indirizzo IP, potrebbe non essere necessario disporre di ulteriori credenziali oltre a quello, a seconda della sensibilità dei dati e della sicurezza dell'host dello script viene eseguito da. Un esempio potrebbe essere un modulo di ricerca sul tuo sito Web, che può essere eseguito con un utente a cui è consentito utilizzare solo una procedura memorizzata che estrae solo le informazioni che verranno presentate sulla pagina Web. In questo caso, l'aggiunta di una password non conferisce in realtà alcuna sicurezza aggiuntiva, poiché tali informazioni sono già destinate a essere pubbliche e l'utente non può accedere ad altri dati che sarebbero più sensibili.

Assicurati inoltre che la connessione al database venga stabilita tramite TLS, altrimenti chiunque sia in ascolto sulla rete può ottenere le tue credenziali.

In terzo luogo , considera quale tipo di credenziali utilizzare. Le password sono solo una forma e non la più sicura. È possibile invece utilizzare una qualche forma di coppia di chiavi pubblica / privata o AD / PAM o simili.

In quarto luogo , considerare le condizioni in cui verrà eseguito lo script:

Se viene eseguito in modo interattivo, è necessario immettere la password o la password per la chiave privata o la chiave privata o essere connessi con un ticket Kerberos valido, quando lo si esegue - in altre parole, lo script dovrebbe ottenere il suo credenziali direttamente da te al momento dell'esecuzione, invece di leggerle da alcuni file.

Se viene eseguito da un server Web, prendere in considerazione l'impostazione delle credenziali nel momento in cui si avvia il server Web. Un buon esempio qui sono i certificati SSL: hanno un certificato pubblico e una chiave privata e la chiave privata ha una password. È possibile memorizzare la chiave privata sul server Web, ma è comunque necessario immettere la password quando si avvia Apache. È inoltre possibile disporre delle credenziali su un tipo di hardware, ad esempio una scheda fisica o un HSM, che può essere rimosso o bloccato all'avvio del server. (Ovviamente, l'aspetto negativo di questo metodo è che il server non può riavviarsi da solo se succede qualcosa. Preferirei questo al rischio di compromettere il mio sistema, ma il tuo chilometraggio può variare ...)

Se lo script viene eseguito da cron, questa è la parte difficile. Non vuoi avere le credenziali ovunque nel tuo sistema dove qualcuno possa accedervi - ma vuoi averle in giro in modo che il tuo script possa accedervi, giusto? Bene, non proprio. Considera esattamente cosa sta facendo la sceneggiatura. Di quali autorizzazioni ha bisogno sul database? Può essere limitato in modo che non importa se la persona sbagliata si connette con tali autorizzazioni? Puoi invece eseguire lo script direttamente sul server DB a cui nessun altro ha accesso, anziché dal server che ha altri utenti? Se, per qualche ragione che non riesco a pensare, è assolutamente necessario avere lo script in esecuzione su un server non sicuro e deve essere in grado di fare qualcosa di pericoloso / distruttivo ... ora è un buon momento per ripensare la tua architettura.

In quinto luogo , se apprezzi la sicurezza del tuo database, non dovresti eseguire questi script su server a cui altre persone hanno accesso. Se qualcuno ha effettuato l'accesso al tuo sistema, avrà la possibilità di ottenere le tue credenziali. Ad esempio, nel caso di un server Web con un certificato SSL, esiste almeno una possibilità teorica che qualcuno sia in grado di ottenere il root e accedere all'area di memoria del processo httpd ed estrarre le credenziali. Negli ultimi tempi c'è stato almeno un exploit in cui questo poteva essere fatto su SSL, senza nemmeno aver bisogno che l'attaccante avesse effettuato l'accesso.

Considera anche l'uso di SELinux o apparmor o qualsiasi altra cosa disponibile per il tuo sistema per limitare quali utenti possono fare cosa. Ti permetteranno di impedire agli utenti di provare a connettersi al database, anche se riescono ad accedere alle credenziali.

Se tutto ciò ti sembra eccessivo e non puoi permetterti o non hai il tempo di farlo - quindi, secondo la mia opinione (arrogante ed elitaria), non dovresti archiviare nulla di importante o sensibile nel tuo database. E se non stai memorizzando nulla di importante o sensibile, anche dove archiviare le tue credenziali non è importante - nel qual caso, perché usare una password?

Infine , se non puoi assolutamente evitare di archiviare un qualche tipo di credenziali, potresti avere le credenziali di sola lettura e di proprietà di root e root che potrebbero garantire la proprietà su una base estremamente temporanea quando richiesto da uno script (perché il tuo script non dovrebbe essere eseguito come root a meno che non sia assolutamente necessario e la connessione a un database non lo rende necessario). Ma non è ancora una buona idea.


9
Non arrogante ed elitario affatto. Oppure lo sono anch'io. "Come posso proteggere i miei gioielli in caso di furto con scasso?" "Mettilo in una cassaforte imbullonata / saldata in posizione." "Troppi problemi, prenderò solo una cassaforte portatile e appenderò la chiave a un gancio." "Allora non preoccuparti di usare una cassaforte." Consiglio eminentemente sensato.
Wildcard

12

Prima di tutto, se c'è qualche modo in cui puoi cambiare le cose per evitare di dover memorizzare una password all'interno o accanto a uno script in primo luogo, dovresti fare ogni sforzo per farlo. La risposta di Jenny D contiene molti buoni consigli in tal senso.

Altrimenti, la tua idea di mettere la password in un file separato con autorizzazioni limitate è praticamente così. Ad esempio, puoi sorgente quel file dallo script principale:

. /usr/local/etc/secret-password-here

Potresti anche limitare le autorizzazioni dello script principale in modo che solo le persone autorizzate possano eseguirlo, ma è probabilmente meglio fare come suggerisci e archiviare solo la password stessa in un file con restrizioni. In questo modo è possibile consentire l'ispezione del codice stesso (senza segreti sensibili), il controllo della versione e la copia dello script più facilmente, ecc ...


@BasileStarynkevitch ah ma vedo che dice anche " /usr/local/etcpotrebbe essere un collegamento simbolico a /etc/local". Ho perso questo. Quindi hai anche ragione, ma è un MAGGIO quindi è facoltativo. Ma sì, non importa molto e preferenze personali.
Celada,

1
Tranne che sto eseguendo il backup /etc/ ma non /usr/local/ (che presumo possa essere ricostruito dopo l'arresto del disco)
Basile Starynkevitch,

giusto punto sui backup
Celada,

3

Altre risposte hanno affrontato il come , ma considererò il se . A seconda del tipo di database a cui si connettono i tuoi utenti, potresti già avere un meccanismo adatto che è già utilizzato da quei programmi client, nel qual caso assicurati di usarli (sto pensando a ~/.mysqlrco ~/.pgpass).

Se stai offrendo a più utenti la possibilità di accedere al database per eseguire query specifiche utilizzando un account condiviso, probabilmente non dovresti. Assicurati invece di avere account nel database e che tali account non abbiano più autorizzazioni di quelle di cui hanno bisogno (probabilmente leggono su gran parte di esso e molto poco accesso in scrittura). Se devono eseguire query specifiche su determinate tabelle a cui non possono accedere in altro modo, fornire le procedure memorizzate SECURTY DEFINERper consentire loro di farlo.

Se nessuno dei evita sopra di voi che hanno bisogno di credenziali di memorizzare, quindi leggere le altre risposte qui.


1

L'idea di nascondere la password in un luogo inaccessibile potrebbe essere OK a seconda delle circostanze.

Se le informazioni sono separate, ciò significa che la semplice modifica del file, ad esempio durante una revisione del codice con un collega, non lo mostrerà. Ma renditi conto che chiunque abbia accesso al tuo account può facilmente trovare un tale file. Ho usato una sottodirectory di ~/.sshtali scopi, per la semplice ragione che si sshlamenta se i diritti di accesso per ~/.sshnon sono abbastanza limitati.

Vi sono tuttavia altre cose che puoi fare per impedire un simile sguardo di nome utente e / o password.

Offuscante : se non si desidera che nessuno legga il nome utente o la password mentre si modifica uno script, è possibile inserirlo nel testo ma non come testo normale, ma offuscato. Se la versione offuscata è abbastanza lunga da impedirne la memorizzazione da parte di qualcuno che la guarda, non può essere conosciuta anche se il metodo e la chiave di decrittazione sono in bella vista. Questo sarebbe ovviamente ancora banalmente eluso da qualcuno che ha accesso al tuo account.

Utilizzando GPG :

Leggermente meglio, ma ancora non completa prova contro gli attacchi dell'utente root sul tuo sistema, è crittografare le coppie nome utente / password in un file il tuo gpgpubblico e fare in modo che lo script recuperi il contenuto sul file (eventualmente richiedendoti una password, in caso contrario cache / scaduti). Uso la ggp-card in modo tale che quando lascio il mio portatile in giro ma estraggo la scheda, non è possibile accedere anche se il pin sarebbe ancora memorizzato nella cache. Almeno se eseguo la cosa 20 volte in pochi minuti, devo fornire il pin solo una volta.

La sicurezza sembra sempre inversamente proporzionale alla convenienza (impostazione e utilizzo).


0

C'è un modo per archiviare le password in uno script bash ma devi crittografare e offuscare lo script in modo che nessuno possa effettivamente leggerlo o eseguire qualsiasi tipo di debugger su di esso per vedere esattamente cosa sta facendo. Per crittografare e offuscare uno script bash / shell e renderlo effettivamente eseguibile, prova a copiarlo e incollarlo qui:

http://www.kinglazy.com/shell-script-encryption-kinglazy-shieldx.htm

Nella pagina sopra, tutto ciò che devi fare è inviare il tuo script (puoi prima inviare uno script di esempio per la tua tranquillità). Un file zip verrà generato per te. Fare clic con il tasto destro sul collegamento per il download e copiare l'URL fornito. Quindi, vai alla casella UNIX ed esegui i seguenti passaggi.

Installazione:

  1. wget link-to-the-zip-file

  2. decomprimere il file zip appena scaricato

  3. cd / tmp / KingLazySHIELD

  4. ./install.sh / var / tmp / KINGLAZY / SHIELDX- (your-script-name) / home / (your-username) -force

Quello che il comando di installazione sopra farà per te è:

  1. Installerà la versione crittografata del tuo script nella directory / var / tmp / KINGLAZY / SHIELDX- (nome-tuo-script).

  2. Inserirà un collegamento a questo script crittografato in qualsiasi directory specificata in sostituzione di / home / (nome utente); in questo modo, consente di accedere facilmente allo script senza dover digitare il percorso assoluto.

  3. Assicura che NESSUNO possa modificare lo script - Qualsiasi tentativo di modificare lo script crittografato lo renderà inutilizzabile ... fino a quando tali tentativi non verranno interrotti o rimossi. Può anche essere configurato per avvisarti ogni volta che qualcuno prova a fare qualcosa con lo script diverso da eseguirlo ... cioè hacking o tentativi di modifica.

  4. Assicura assolutamente che NESSUNO possa farne copie. Nessuno può copiare il tuo script in una posizione isolata e provare a rovinarlo per vedere come funziona. Tutte le copie dello script devono essere collegamenti alla posizione originale specificata durante l'installazione (passaggio 4).

NOTA:

Non credo che questo funzioni per gli script interattivi che richiedono all'utente una risposta. I valori devono essere codificati nello script. La crittografia garantisce che nessuno possa effettivamente vedere quei valori, quindi non devi preoccuparti di questo.


0

Un'altra soluzione, indipendentemente dalla sicurezza (penso anche che sia meglio conservare le credenziali in un altro file o in un database) è crittografare la password con gpg e inserirla nello script.

Uso una coppia di chiavi gpg senza password che conservo in un dispositivo USB. (Nota: quando si esporta questa coppia di chiavi non utilizzare --armor, esportarli in formato binario).

Prima crittografa la tua password:

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient someone@mail.com --encrypt

Verrà stampata la password crittografata gpg nell'output standard. Copia l'intero messaggio e aggiungilo allo script:

password=$(gpg --batch --quiet --no-default-keyring --secret-keyring /media/usb/key.priv --decrypt <<EOF 
-----BEGIN PGP MESSAGE-----

hQEMA0CjbyauRLJ8AQgAkZT5gK8TrdH6cZEy+Ufl0PObGZJ1YEbshacZb88RlRB9
h2z+s/Bso5HQxNd5tzkwulvhmoGu6K6hpMXM3mbYl07jHF4qr+oWijDkdjHBVcn5
0mkpYO1riUf0HXIYnvCZq/4k/ajGZRm8EdDy2JIWuwiidQ18irp07UUNO+AB9mq8
5VXUjUN3tLTexg4sLZDKFYGRi4fyVrYKGsi0i5AEHKwn5SmTb3f1pa5yXbv68eYE
lCVfy51rBbG87UTycZ3gFQjf1UkNVbp0WV+RPEM9JR7dgR+9I8bKCuKLFLnGaqvc
beA3A6eMpzXQqsAg6GGo3PW6fMHqe1ZCvidi6e4a/dJDAbHq0XWp93qcwygnWeQW
Ozr1hr5mCa+QkUSymxiUrRncRhyqSP0ok5j4rjwSJu9vmHTEUapiyQMQaEIF2e2S
/NIWGg==
=uriR
-----END PGP MESSAGE-----
EOF)

In questo modo solo se l'USB è montato nel sistema la password può essere decifrata. Ovviamente puoi anche importare le chiavi nel sistema (meno sicuro o niente sicurezza) o puoi proteggere la chiave privata con password (quindi non può essere automatizzata).


-2
#!/bin/bash
unset username
unset password
unset dbname
echo -n "username:"
read username
echo -n "dbname:"
read dbname
prompt="password:"

    while IFS= read -p "$prompt" -r -s -n 1 char
            do
                    if [[ $char == $'\0' ]]
                            then
                                    break
                    fi
                    prompt='*'
                    password+="$char"
            #       read -s -p "Enter Password: "  pswd
            #       echo -e "\nYour password is: " $pswd
            done

3
Ho indentato il tuo codice, forse potresti spiegare cosa stai cercando di fare?
Archemar,

-6

Non credo che dovresti mai memorizzare la password. Non riesco a pensare a una sola buona ragione per questo. Piuttosto, dovresti archiviare un hash salato di quella password - una stringa che viene prodotta in modo affidabile da una funzione quando la password originale viene passata come input, ma mai la password .


5
Non sono chiaro su come questo risolverà il problema di a) essere in grado di connettersi a un servizio che richiede una password eb) gli utenti siano in grado di vedere lo script e quindi di riuscire a capire i dettagli di autenticazione, se si tratta di password o no
Jenny D,

1
Stai sostenendo di conoscere la mia risposta prima di scriverla.
Jenny D,

1
Ho scritto la mia risposta ora. Quello che stavo cercando di ottenere da te era in parte il mio quinto punto: una volta che le credenziali sono archiviate in memoria, non sono completamente sicure da un utente malintenzionato con accesso al server. Inoltre, la tua risposta concisa non è stata molto utile, anche se non errata. Sto pensando di indicarlo la prossima volta che qualcuno si lamenta che noi di ServerFault non siamo così carini come le persone di Unix / Linux :-)
Jenny D,

2
@JennyD - una volta che il credito è nella memoria - sicuramente non ha bisogno di rimanere lì - e questa è un'ottima ragione per trattare con gli hash invece. Tuttavia, rappresenterò felicemente gli standard di cortesia della comunità come il suo esempio in generale - in realtà sono molto noto per quel tratto.
Mikeserv,

4
Dopo la tua grande discussione, vorrei solo menzionare nel caso in cui ci fosse qualche malinteso sul fatto che fossi io a declassare, non Jenny. E il motivo non era un'opinione sull'opportunità o meno di utilizzare un certificato e una chiave privata o una password inserita in modo interattivo o fare ciò che l'OP desiderava o altro. È perché la risposta così com'è è sbagliata: archiviare un hash salato della password come credenziale del client non è una cosa: gli hash salati sono una cosa che mantieni alla fine della connessione che sta verificando l'autent, non sul lato che lo sta inviando.
Celada,
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.