Comment passer le mot de passe à pg_dump?

294

J'essaie de créer un cronjob pour sauvegarder ma base de données tous les soirs avant que quelque chose de catastrophique ne se produise. Il semble que cette commande devrait répondre à mes besoins:

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

Sauf après avoir exécuté cela, il s'attend à ce que je tape un mot de passe. Je ne peux pas faire ça si je le lance depuis cron. Comment puis-je en transmettre un automatiquement?

mpen
la source
article peut-être utile que j'ai écrit sur l'automatisation de pg_restore! medium.com/@trinity/…
kittyminky
répondez en utilisant une chaîne de connexion ici: stackoverflow.com/a/29101292/1579667
Benj

Réponses:

304

Créez un .pgpassfichier dans le répertoire personnel du compte qui pg_dumps'exécutera en tant que. Voir la documentation de Postgresql libpq-pgpass pour plus de détails sur le format (y compris le dernier paragraphe où il explique qu'il sera ignoré si vous ne définissez pas le mode sur 0600).

araqnid
la source
99
Créez ~ / .pgpass avec localhost: 5432: mydbname: postgres: mypass Puis chmod 600 ~ / .pgpass
Mircea Stanciu
6
Peut-être utile: sur Ubuntu, "sudo su postgres" pour basculer vers l'utilisateur "postgres", puis créez le fichier .pgpass et exécutez le vidage.
fivedogit
1
J'ai suivi votre réponse, mais je n'ai toujours pas réussi à créer mon fichier de sauvegarde. Veuillez consulter mon lien: unix.stackexchange.com/questions/257898/… . Je vous remercie.
alyssaeliyah
Fonctionne le 9.6.2: o)
Andrew
2
Remarque sudo su postgres: cet utilisateur Unix n'existe pas nécessairement. Il n'en a pas besoin. Mais l'utilisateur DB devrait.
Fabien Haddadi
217

Ou vous pouvez configurer crontab pour exécuter un script. À l'intérieur de ce script, vous pouvez définir une variable d'environnement comme celle-ci: export PGPASSWORD="$put_here_the_password"

De cette façon, si vous avez plusieurs commandes nécessitant un mot de passe, vous pouvez toutes les mettre dans le script. Si le mot de passe change, vous n'avez qu'à le changer en un seul endroit (le script).

Et je suis d'accord avec Joshua, l'utilisation pg_dump -Fcgénère le format d'exportation le plus flexible et est déjà compressé. Pour plus d'informations, voir: documentation pg_dump

Par exemple

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

# restore the database
pg_restore -d newdb db.dump
Max
la source
3
ce n'est pas l'idéal. le jeter .pgpassgardera tout au même endroit, sans ajouter une couche supplémentaire d'indirection. De plus, si tout ce que je voulais faire avec l'exportation d'une variable, je le ferais dans mon .bashrcfichier, ou quoi que ce soit.
mpen
9
Je peux voir pourquoi le .pgpassfichier serait une meilleure solution. Je donnais juste une alternative, je ne sais pas si elle mérite un downvote cependant :)
Max
13
Je n'ai pas downvote. C'était quelqu'un d'autre; Je ne pensais pas non plus que cela méritait un downvote. Ayez un +1 pour compenser cela.
mpen
7
Tant de haineux. J'apprécie cette réponse et je l'adopte pour ma propre candidature.
James T Snell
8
La définition de la variable d'environnement PGPASSWORD n'est pas une pratique recommandée par la documentation ( postgresql.org/docs/current/static/libpq-envars.html ): l' utilisation de cette variable d'environnement n'est pas recommandée pour des raisons de sécurité, car certains systèmes d'exploitation autorisent les utilisateurs root pour voir les variables d'environnement de processus via ps; pensez plutôt à utiliser le fichier ~ / .pgpass
bouchon
175

Si vous voulez le faire en une seule commande:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump
gitaarik
la source
27
La définition de la variable d'environnement PGPASSWORD n'est pas une pratique recommandée par la documentation ( postgresql.org/docs/current/static/libpq-envars.html ): l' utilisation de cette variable d'environnement n'est pas recommandée pour des raisons de sécurité, car certains systèmes d'exploitation autorisent les utilisateurs root pour voir les variables d'environnement de processus via ps; envisagez plutôt d'utiliser le fichier ~ / .pgpass
bouchon
18
C'est toujours un commentaire utile. Il existe de nombreux cas de déploiement où cela est toujours utile.
Iain Duncan
1
J'ai toujours eu l'erreur «L'authentification par les pairs a échoué pour l'utilisateur« nom d'utilisateur »». La solution était: PGPASSWORD = "mypass" pg_dump -U nom d'utilisateur -h localhost> mydb.dump
Martin Pabst
4
À mon avis, il est bien préférable de configurer une variable d'environnement (où vous avez le contrôle, et comment le mot de passe sera stocké) comme dans un emplacement connu et non chiffré. Cette partie du document postgresql est défectueuse, et cette réponse est bonne.
peterh
1
Mon mot de passe contenait un «@». Cela a fonctionné. Je ne pouvais pas comprendre comment le faire fonctionner avec la postgres://syntaxe. N'a pas essayé .pgpasscar mon utilisateur postgress n'a pas de répertoire personnel.
jmathew
136

Pour une ligne unique, comme la migration d'une base de données, vous pouvez utiliser --dbnamesuivi d'une chaîne de connexion (y compris le mot de passe) comme indiqué dans le manuel pg_dump

En substance.

pg_dump --dbname=postgresql://username:[email protected]:5432/mydatabase

Remarque: assurez-vous que vous utilisez l'option --dbnameau lieu de la plus courte -det utilisez un préfixe URI valide, postgresql://ou postgres://.

Le formulaire URI général est:

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

Meilleure pratique dans votre cas (tâche répétitive dans cron), cela ne devrait pas être fait en raison de problèmes de sécurité. Si ce n'était pas pour le .pgpassfichier, je sauvegarderais la chaîne de connexion en tant que variable d'environnement.

export MYDB=postgresql://username:[email protected]:5432/mydatabase

alors ayez dans votre crontab

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

Josue Alexander Ibarra
la source
La version 9.1 de Postgre affiche une option inconnue pour
dbname
Cela a été testé avec les versions 9.4 et 9.3 sur arch et RHEL respectivement. pouvez-vous publier votre chaîne de connexion? anonymisé bien sûr.
Josue Alexander Ibarra
Merci, @JosueIbarra. Testé avec succès sur PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu
1
@EntryLevelR vous devez diriger la sortie vers un fichier afin de l'enregistrer. voir cette question pertinente askubuntu.com/questions/420981/…
Josue Alexander Ibarra
4
ce devrait être la réponse acceptée. Un liner, clair.
swdev
48
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename
Francisco Luz
la source
Bien, mais malheureusement ça ne marche pas pour moi, je reçois "la requête a échoué: ERREUR: autorisation refusée pour la relation direction_lookup"
James T Snell
@Doc avez-vous essayé de donner les autorisations nécessaires à l'utilisateur pg?
Francisco Luz
33

Cette doublure m'aide tout en créant le vidage d'une seule base de données.

PGPASSWORD="yourpassword" pg_dump -U postgres -h localhost mydb > mydb.pgsql
Aarvy
la source
1
a beaucoup aidé ... thnxxx
ronit
19

La réponse @Josue Alexander Ibarra fonctionne sur centos 7 et la version 9.5 si --dbname n'est pas transmis.

pg_dump postgresql://username:[email protected]:5432/mydatabase 
Jauyzed
la source
1
Vous avez raison, c'est à ça que ça doit ressembler, je pense que ce qui n'allait pas il y a quelques années était ma configuration de shell. C'est pourquoi il était essentiel pour moi d'utiliser--dbname
Josue Alexander Ibarra
7

Notez que, dans Windows, le pgpass.conffichier doit se trouver dans le dossier suivant:

%APPDATA%\postgresql\pgpass.conf

s'il n'y a pas de postgresqldossier à l'intérieur du %APPDATA%dossier, créez-le.

le pgpass.confcontenu du fichier est quelque chose comme:

localhost:5432:dbname:dbusername:dbpassword

à votre santé

Fernando Meneses Gomes
la source
4

Corrigez-moi si je me trompe, mais si l'utilisateur du système est le même que l'utilisateur de la base de données, PostgreSQL ne demandera pas le mot de passe - il s'appuie sur le système pour l'authentification. Cela peut être une question de configuration.

Ainsi, quand je voulais que le propriétaire de la base postgresde ses bases de données de sauvegarde tous les soirs, je pouvais créer un crontab pour elle: crontab -e -u postgres. Bien sûr, postgresil faudrait être autorisé à exécuter des tâches cron; il doit donc être répertorié dans /etc/cron.allow, ou /etc/cron.denydoit être vide.

Tobias
la source
Vous êtes en quelque sorte ici. La configuration Postgres par défaut utilise l'authentification TRUST pour les comptes système locaux. Cependant, la plupart des configurations de production se débarrassent de ce bloc juste après l'installation du SGBDR.
Jacek Prucia
4

Sauvegardez sur ssh avec mot de passe en utilisant des informations d'identification temporaires .pgpass et passez à S3:

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

DB_HOST="*******.*********.us-west-2.rds.amazonaws.com"
DB_USER="*******"
SSH_HOST="[email protected]_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

Remplacez simplement les deux premières lignes de configuration par tout ce dont vous avez besoin - évidemment. Pour ceux qui ne sont pas intéressés par la partie de sauvegarde S3, retirez-la - évidemment.

Ce script supprime les informations d'identification par la .pgpasssuite, car dans certains environnements, l'utilisateur SSH par défaut peut sudo sans mot de passe, par exemple une instance EC2 avec l' ubuntuutilisateur, donc l'utilisation .pgpassavec un compte hôte différent pour sécuriser ces informations d'identification peut être inutile.

MikeM
la source
Le mot de passe sera connecté au terminal de historycette façon, non?
mpen
1
@mpen Localement, oui. À distance, non. Dans mon cas, c'est OK d'avoir dans mon historique local car c'est une machine virtuelle sécurisée qui ne permet pas l'accès à distance. Si dans votre cas, ce n'est pas OK, faites-le history -c. Lors de l'utilisation avec Jenkins, utilisez l' Inject passwords to the build as environment variablesoption pour que le mot de passe soit masqué
MikeM
4

Comme détaillé dans cet article de blog , il existe deux façons de fournir de manière non interactive un mot de passe aux utilitaires PostgreSQL tels que la commande "pg_dump": en utilisant le fichier ".pgpass" ou en utilisant la variable d'environnement "PGPASSWORD" .

manfall19
la source
-1

Une autre façon (probablement non sécurisée) de transmettre le mot de passe consiste à utiliser la redirection d'entrée, c'est-à-dire appeler

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

Szymond
la source
Concernant la sécurité - ce fichier devrait être lisible uniquement par le ou les utilisateurs prévus; cependant, toute personne disposant de droits root pourrait modifier les paramètres de sécurité, et donc lire le mot de passe non chiffré. Alors oui, ce n'est pas sûr ...
Tobias
3
@Tobias existe-t-il une alternative? Il semblerait que toute personne disposant de droits root puisse toujours voir le mot de passe, quelle que soit la technique autre que la saisie interactive du mot de passe (et la question concerne cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH mentionne que GSSAPI prend en charge l'authentification unique, mais aucune mention si cela fonctionne de manière non interactive.
Ross Bradbury
4
Toute personne disposant de droits root peut également lire le .pgpass qui est la méthode recommandée. Par conséquent, je ne considérerais pas l'accès root comme un risque pour la sécurité.
max
-1

Vous pouvez passer un mot de passe dans pg_dump directement en utilisant ce qui suit:

pg_dump "host=localhost port=5432 dbname=mydb user=myuser password=mypass" > mydb_export.sql
Larry Spence
la source
Bienvenue dans Stack Overflow! Bien que votre réponse puisse fonctionner, elle a de sérieuses implications en termes de sécurité. Les arguments d'une commande sont visibles dans ps (1) , donc si un processus surveille ps (1) alors le mot de passe est compromis.
Jonathan Rosa
-4

la façon la plus simple à mon avis, ceci: vous éditez votre fichier de configuration principal postgres: pg_hba.conf là vous devez ajouter la ligne suivante:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

et après cela, vous devez commencer votre cron ainsi:

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

et cela a fonctionné sans mot de passe

Dofri
la source
Et vous venez de détruire la sécurité du système. OK pour une boîte de développement, mais rien d'autre.
Theodore R. Smith,