Come passare la password a pg_dump?


294

Sto cercando di creare un cronjob per eseguire il backup del mio database ogni notte prima che accada qualcosa di catastrofico. Sembra che questo comando dovrebbe soddisfare le mie esigenze:

0 3 * * * pg_dump dbname | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz

Tranne che dopo averlo eseguito, mi aspetto di digitare una password. Non posso farlo se lo eseguo da cron. Come posso passarne uno automaticamente?


possibilmente utile post che ho scritto sull'automazione di pg_restore! medium.com/@trinity/...
kittyminky

risposta usando una stringa di connessione qui: stackoverflow.com/a/29101292/1579667
Benj

Risposte:


304

Crea un .pgpassfile nella home directory dell'account che pg_dumpverrà eseguito come. Vedere la documentazione di Postgresql libpq-pgpass per i dettagli del formato (incluso l'ultimo paragrafo in cui spiega che verrà ignorato se non si imposta la modalità su 0600).


99
Crea ~ / .pgpass con localhost: 5432: mydbname: postgres: mypass Quindi chmod 600 ~ / .pgpass
Mircea Stanciu

6
Forse utile: su Ubuntu, "sudo su postgres" per passare all'utente "postgres", quindi creare il file .pgpass ed eseguire il dump.
fivedogit,

1
Ho seguito la tua risposta ma non riesco ancora a creare correttamente il mio file di backup. Si prega di consultare il mio link: unix.stackexchange.com/questions/257898/… . Grazie.
alyssaeliyah,

Funziona il 9.6.2: o)
Andrew

2
Nota sudo su postgres: l'utente Unix non esiste necessariamente. Non è necessario. Ma l'utente DB dovrebbe.
Fabien Haddadi,

216

Oppure puoi configurare crontab per eseguire uno script. All'interno di quello script puoi impostare una variabile d'ambiente come questa: export PGPASSWORD="$put_here_the_password"

In questo modo, se si dispone di più comandi che richiedono una password, è possibile inserirli tutti nello script. Se la password cambia, devi solo cambiarla in un posto (lo script).

E sono d'accordo con Joshua, l'utilizzo pg_dump -Fcgenera il formato di esportazione più flessibile ed è già compresso. Per maggiori informazioni, consultare: documentazione pg_dump

Per esempio

# dump the database in custom-format archive
pg_dump -Fc mydb > db.dump

# restore the database
pg_restore -d newdb db.dump

3
questo non è l'ideale. lanciandolo .pgpassmanterrai tutto in un unico posto, senza aggiungere un ulteriore livello di indiretta. inoltre, se tutto ciò che volevo fare con l'esportazione di una variabile, lo farei nel mio .bashrcfile o qualunque cosa sia.
Aprire il

9
Vedo perché il .pgpassfile sarebbe una soluzione migliore. Stavo solo dando un'alternativa, non sono sicuro se merita un downvote però :)
Max

13
Non ho votato a fondo. Quello era qualcun altro; Non pensavo nemmeno che giustificasse un downvote. Hai un +1 per compensarlo.
Aprire il

7
Così tanti odiatori. Apprezzo questa risposta e la sto adottando per la mia domanda.
James T Snell,

8
L'impostazione della variabile d'ambiente PGPASSWORD non è una pratica raccomandata dalla documentazione ( postgresql.org/docs/current/static/libpq-envars.html ): l' uso di questa variabile d'ambiente non è raccomandato per motivi di sicurezza, poiché alcuni sistemi operativi consentono non gli utenti root possono vedere le variabili di ambiente di processo tramite ps; invece considera l'utilizzo del file ~ / .pgpass
bouchon il

175

Se vuoi farlo in un solo comando:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

27
L'impostazione della variabile d'ambiente PGPASSWORD non è consigliata dalla documentazione ( postgresql.org/docs/current/static/libpq-envars.html ): l' uso di questa variabile d'ambiente non è raccomandato per motivi di sicurezza, poiché alcuni sistemi operativi consentono non gli utenti root possono vedere le variabili di ambiente di processo tramite ps; invece considera l'utilizzo del file ~ / .pgpass
bouchon il

18
È ancora un commento utile. Ci sono molti casi di distribuzione in cui questo è ancora utile.
Iain Duncan,

1
Ho sempre ricevuto l'errore "Autenticazione peer non riuscita per l'utente" nome utente "'. La soluzione era: PGPASSWORD = "mypass" pg_dump -U username -h localhost> mydb.dump
Martin Pabst

4
La mia opinione è che è molto meglio impostare una variabile d'ambiente (dove si ha il controllo, dove e come verrà memorizzata la password) come in una posizione nota e non crittografata. Questa parte del documento postgresql è difettosa e questa risposta è buona.
Peter - Ripristina Monica il

1
La mia password conteneva un "@". Questo ha funzionato. Non sono riuscito a capire come farlo funzionare con la postgres://sintassi. Non ho provato .pgpassperché il mio utente postgress non ha home directory.
jmathew,

136

Per un one-liner, come la migrazione di un database, è possibile utilizzare --dbnameseguito da una stringa di connessione (inclusa la password) come indicato nel manuale pg_dump

In sostanza.

pg_dump --dbname=postgresql://username:password@127.0.0.1:5432/mydatabase

Nota: assicurarsi di utilizzare l'opzione --dbnameanziché quella più corta -de utilizzare un prefisso URI valido postgresql://o postgres://.

Il modulo URI generale è:

postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]

Le migliori pratiche nel tuo caso (attività ripetitiva in cron) non dovrebbero essere eseguite a causa di problemi di sicurezza. Se non fosse per il .pgpassfile, salverei la stringa di connessione come variabile di ambiente.

export MYDB=postgresql://username:password@127.0.0.1:5432/mydatabase

quindi avere nel tuo crontab

0 3 * * * pg_dump --dbname=$MYDB | gzip > ~/backup/db/$(date +%Y-%m-%d).psql.gz


La versione 9.1 di Postgre produce un'opzione sconosciuta per dbname
akohout,

Questo è stato testato con le versioni 9.4 e 9.3 rispettivamente su arch e RHEL. puoi pubblicare la tua stringa di connessione? anonimizzato ovviamente.
Josue Alexander Ibarra,

Grazie, @JosueIbarra. Testato con successo su PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu,

1
@EntryLevelR è necessario reindirizzare l'output in un file per salvarlo. vedi questa domanda pertinente askubuntu.com/questions/420981/…
Josue Alexander Ibarra,

4
questa dovrebbe essere la risposta accettata. Una fodera, chiara.
swdev,

48
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename

Bello, ma purtroppo non funziona per me, ottengo "query non riuscita: ERRORE: autorizzazione negata per la relazione direction_lookup"
James T Snell

@Doc hai provato a dare le autorizzazioni necessarie all'utente pg?
Francisco Luz,

33

Questa fodera mi aiuta durante la creazione di dump di un singolo database.

PGPASSWORD="yourpassword" pg_dump -U postgres -h localhost mydb > mydb.pgsql

1
aiutato molto ... thnxxx
ronit

19

@La risposta Alexander Ibarra di Alexander funziona su centos 7 e versione 9.5 se --dbname non viene passato.

pg_dump postgresql://username:password@127.0.0.1:5432/mydatabase 

1
Hai ragione, è così che dovrebbe apparire, penso che ciò che era sbagliato qualche anno fa fosse la mia configurazione della shell. Ecco perché era essenziale per me usare--dbname
Josue Alexander Ibarra il

7

Si noti che, in Windows, il pgpass.conffile deve trovarsi nella seguente cartella:

%APPDATA%\postgresql\pgpass.conf

se non ci sono postgresqlcartelle all'interno della %APPDATA%cartella, crearla.

il pgpass.confcontenuto del file è simile a:

localhost:5432:dbname:dbusername:dbpassword

Saluti


4

Correggimi se sbaglio, ma se l'utente del sistema è uguale all'utente del database, PostgreSQL non chiederà la password, ma farà affidamento sul sistema per l'autenticazione. Questa potrebbe essere una questione di configurazione.

Così, quando ho voluto il proprietario del database postgresdi backup dei suoi database ogni notte, ho potuto creare un crontab per esso: crontab -e -u postgres. Naturalmente, postgresdovrebbe essere autorizzato a eseguire lavori cron; quindi deve essere elencato in /etc/cron.allowo /etc/cron.denydeve essere vuoto.


Sei un po 'qui. La configurazione predefinita di Postgres utilizza l'autenticazione TRUST per gli account di sistema locali. Tuttavia, la maggior parte delle configurazioni di produzione elimina questo blocco subito dopo l'installazione di RDBMS.
Jacek Prucia,

4

Esegui il backup su ssh con password usando le credenziali temporanee .pgpass e passa a S3:

#!/usr/bin/env bash
cd "$(dirname "$0")"

DB_HOST="*******.*********.us-west-2.rds.amazonaws.com"
DB_USER="*******"
SSH_HOST="my_user@host.my_domain.com"
BUCKET_PATH="bucket_name/backup"

if [ $# -ne 2 ]; then
    echo "Error: 2 arguments required"
    echo "Usage:"
    echo "  my-backup-script.sh <DB-name> <password>"
    echo "  <DB-name> = The name of the DB to backup"
    echo "  <password> = The DB password, which is also used for GPG encryption of the backup file"
    echo "Example:"
    echo "  my-backup-script.sh my_db my_password"
    exit 1
fi

DATABASE=$1
PASSWORD=$2

echo "set remote PG password .."
echo "$DB_HOST:5432:$DATABASE:$DB_USER:$PASSWORD" | ssh "$SSH_HOST" "cat > ~/.pgpass; chmod 0600 ~/.pgpass"
echo "backup over SSH and gzip the backup .."
ssh "$SSH_HOST" "pg_dump -U $DB_USER -h $DB_HOST -C --column-inserts $DATABASE" | gzip > ./tmp.gz
echo "unset remote PG password .."
echo "*********" | ssh "$SSH_HOST" "cat > ~/.pgpass"
echo "encrypt the backup .."
gpg --batch --passphrase "$PASSWORD" --cipher-algo AES256 --compression-algo BZIP2 -co "$DATABASE.sql.gz.gpg" ./tmp.gz

# Backing up to AWS obviously requires having your credentials to be set locally
# EC2 instances can use instance permissions to push files to S3
DATETIME=`date "+%Y%m%d-%H%M%S"`
aws s3 cp ./"$DATABASE.sql.gz.gpg" s3://"$BUCKET_PATH"/"$DATABASE"/db/"$DATETIME".sql.gz.gpg
# s3 is cheap, so don't worry about a little temporary duplication here
# "latest" is always good to have because it makes it easier for dev-ops to use
aws s3 cp ./"$DATABASE.sql.gz.gpg" s3://"$BUCKET_PATH"/"$DATABASE"/db/latest.sql.gz.gpg

echo "local clean-up .."
rm ./tmp.gz
rm "$DATABASE.sql.gz.gpg"

echo "-----------------------"
echo "To decrypt and extract:"
echo "-----------------------"
echo "gpg -d ./$DATABASE.sql.gz.gpg | gunzip > tmp.sql"
echo

Sostituisci semplicemente la prima coppia di linee di configurazione con tutto ciò di cui hai bisogno, ovviamente. Per coloro che non sono interessati alla parte di backup S3, eliminala - ovviamente.

Questo script elimina successivamente le credenziali .pgpassperché in alcuni ambienti, l'utente SSH predefinito può eseguire la sudo senza una password, ad esempio un'istanza EC2 con l' ubuntuutente, quindi l'utilizzo .pgpasscon un altro account host per proteggere tali credenziali potrebbe essere inutile.


La password verrà registrata sul terminale in historyquesto modo, no?
aprono il

1
@mpen A livello locale, sì. A distanza, no. Nel mio caso è OK avere nella mia cronologia locale perché è una VM sicura che non consente l'accesso remoto. Se nel tuo caso non va bene, fallo history -c. Quando si utilizza con Jenkins, utilizzare l' Inject passwords to the build as environment variablesopzione in modo che la password sia mascherata
MikeM,

4

Come dettagliato in questo post del blog , ci sono due modi per fornire in modo non interattivo una password alle utility PostgreSQL come il comando "pg_dump": usare il file ".pgpass" o usare la variabile d'ambiente "PGPASSWORD" .


-1

Un altro modo (probabilmente non sicuro) per passare la password è utilizzare il reindirizzamento dell'input, ovvero la chiamata

pg_dump [params] < [path to file containing password]


Per quanto riguarda la sicurezza - questo file dovrebbe essere leggibile solo dagli utenti previsti; tuttavia, chiunque disponga dei diritti di root sarebbe in grado di modificare le impostazioni di sicurezza e quindi di leggere la password non crittografata. Quindi sì, questo è insicuro ...
Tobias,

3
@Tobias c'è qualche alternativa? Sembrerebbe che chiunque abbia i diritti di root possa sempre vedere la password indipendentemente da quale tecnica oltre a inserire la password in modo interattivo (e la domanda riguarda cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH menziona GSSAPI che supporta il single sign-on ma nessuna menzione se funziona in modo non interattivo.
Ross Bradbury,

4
Chiunque abbia i diritti di root può anche leggere il .pgpass che è il modo raccomandato. Pertanto, non considererei l'accesso alla radice un rischio per la sicurezza.
massimo

-1

È possibile passare una password in pg_dump direttamente utilizzando quanto segue:

pg_dump "host=localhost port=5432 dbname=mydb user=myuser password=mypass" > mydb_export.sql

Benvenuto in Stack Overflow! Mentre la tua risposta potrebbe funzionare, ha serie implicazioni per la sicurezza. Gli argomenti di un comando sono visibili in ps (1) , quindi se un processo monitora ps (1) la password è compromessa.
Jonathan Rosa,

-4

il modo più semplice secondo me è questo: modifichi il tuo file di configurazione principale di postgres: pg_hba.conf lì devi aggiungere la seguente riga:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

e dopo questo è necessario avviare cron in questo modo:

pg_dump -h 127.0.0.1 -U <you_db_user> <you_db_name> | gzip > /backup/db/$(date +%Y-%m-%d).psql.gz

e ha funzionato senza password


E hai appena distrutto la sicurezza del sistema. OK per una scatola di sviluppo, ma nient'altro.
Theodore R. Smith,
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.