Wie übergebe ich ein Passwort an pg_dump?

294

Ich versuche jeden Abend einen Cronjob zu erstellen, um meine Datenbank zu sichern, bevor etwas Katastrophales passiert. Es sieht so aus, als ob dieser Befehl meine Anforderungen erfüllen sollte:

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

Außer nachdem ich das ausgeführt habe, wird erwartet, dass ich ein Passwort eingebe. Ich kann das nicht tun, wenn ich es von Cron aus laufen lasse. Wie kann ich eine automatisch übergeben?

mpen
quelle
Möglicherweise hilfreicher Beitrag, den ich über die Automatisierung von pg_restore geschrieben habe! medium.com/@trinity/…
kittyminky
Antworten Sie hier mit einer Verbindungszeichenfolge: stackoverflow.com/a/29101292/1579667
Benj

Antworten:

304

Erstellen Sie eine .pgpassDatei im Ausgangsverzeichnis des Kontos, pg_dumpdas als ausgeführt wird. Weitere Informationen zum Format finden Sie in der Postgresql-Dokumentation libpq-pgpass (einschließlich des letzten Absatzes, in dem erklärt wird, dass es ignoriert wird, wenn Sie den Modus nicht auf einstellen 0600).

araqnid
quelle
99
Erstellen Sie ~ / .pgpass mit localhost: 5432: mydbname: postgres: mypass Dann chmod 600 ~ / .pgpass
Mircea Stanciu
6
Möglicherweise hilfreich: Unter Ubuntu "sudo su postgres", um zum Benutzer "postgres" zu wechseln, dann die .pgpass-Datei erstellen und den Speicherauszug ausführen.
Fivedogit
1
Ich bin Ihrer Antwort gefolgt, konnte meine Sicherungsdatei jedoch immer noch nicht erfolgreich erstellen. Bitte beachten Sie meinen Link: unix.stackexchange.com/questions/257898/… . Danke dir.
alyssaeliyah
Arbeitet am 9.6.2: o)
Andrew
2
Hinweis sudo su postgres: Dieser Unix-Benutzer muss nicht unbedingt vorhanden sein. Das muss nicht sein. Aber der DB-Benutzer sollte.
Fabien Haddadi
216

Oder Sie können crontab so einrichten, dass ein Skript ausgeführt wird. In diesem Skript können Sie eine Umgebungsvariable wie folgt festlegen: export PGPASSWORD="$put_here_the_password"

Auf diese Weise können Sie alle Befehle, für die ein Kennwort erforderlich ist, alle in das Skript einfügen. Wenn sich das Passwort ändert, müssen Sie es nur an einer Stelle ändern (im Skript).

Und ich stimme Joshua zu, dass die Verwendung pg_dump -Fcdas flexibelste Exportformat generiert und bereits komprimiert ist. Weitere Informationen finden Sie unter: pg_dump-Dokumentation

Z.B

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

# restore the database
pg_restore -d newdb db.dump
Max
quelle
3
das ist nicht ideal. Wenn Sie es hineinwerfen, .pgpassbleibt auch alles an einem Ort, ohne dass eine zusätzliche Indirektionsebene hinzugefügt wird. Wenn ich nur eine Variable exportieren wollte, würde ich das in meiner .bashrcDatei tun , oder was auch immer es ist.
Mpen
9
Ich kann sehen, warum die .pgpassDatei eine bessere Lösung wäre. Ich gab nur eine Alternative, nicht sicher, ob es eine Ablehnung verdient :)
Max
13
Ich habe nicht abgelehnt. Das war jemand anderes; Ich dachte auch nicht, dass dies eine Ablehnung rechtfertigt. Haben Sie eine +1, um das auszugleichen.
Mpen
7
So viele Hasser. Ich schätze diese Antwort und übernehme sie für meine eigene Bewerbung.
James T Snell
8
Das Festlegen der Umgebungsvariablen PGPASSWORD wird in der Dokumentation nicht empfohlen ( postgresql.org/docs/current/static/libpq-envars.html ): Die Verwendung dieser Umgebungsvariablen wird aus Sicherheitsgründen nicht empfohlen, da einige Betriebssysteme dies nicht zulassen Root-Benutzer, um Prozessumgebungsvariablen über ps anzuzeigen; Verwenden Sie stattdessen die Datei ~ / .pgpass
bouchon
175

Wenn Sie es in einem Befehl tun möchten:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump
Gitaarik
quelle
27
Das Festlegen der Umgebungsvariablen PGPASSWORD wird in der Dokumentation nicht empfohlen ( postgresql.org/docs/current/static/libpq-envars.html ): Die Verwendung dieser Umgebungsvariablen wird aus Sicherheitsgründen nicht empfohlen, da einige Betriebssysteme dies nicht zulassen Root-Benutzer, um Prozessumgebungsvariablen über ps anzuzeigen; Verwenden Sie stattdessen die Datei ~ / .pgpass
bouchon
18
Es ist immer noch ein nützlicher Kommentar. Es gibt viele Bereitstellungsfälle, in denen dies immer noch hilfreich ist.
Iain Duncan
1
Ich habe immer die Fehlermeldung "Peer-Authentifizierung für Benutzer" Benutzername "fehlgeschlagen" erhalten. Die Lösung war: PGPASSWORD = "mypass" pg_dump -U Benutzername -h localhost> mydb.dump
Martin Pabst
4
Meiner Meinung nach ist es weitaus besser, eine Umgebungsvariable (wo Sie die Kontrolle haben, wo und wie das Passwort gespeichert wird) als an einem bekannten, unverschlüsselten Ort einzurichten . Dieser Teil des postgresql-Dokuments ist fehlerhaft, und diese Antwort ist gut.
Peterh - Wiedereinsetzung Monica
1
Mein Passwort hatte ein '@'. Das hat funktioniert. Ich konnte nicht herausfinden, wie es mit der postgres://Syntax funktioniert . Habe das nicht ausprobiert, .pgpassweil mein Postgress-Benutzer kein Home-Verzeichnis hat.
Jmathew
136

Für einen Einzeiler wie das Migrieren einer Datenbank können Sie --dbnameeine Verbindungszeichenfolge (einschließlich des Kennworts) verwenden, wie im Handbuch pg_dump angegeben

Im Wesentlichen.

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

Hinweis: Stellen Sie sicher, dass Sie die Option --dbnameanstelle der kürzeren verwenden -dund ein gültiges URI-Präfix verwenden, postgresql://oder postgres://.

Das allgemeine URI-Formular lautet:

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

Best Practice in Ihrem Fall (sich wiederholende Aufgabe in Cron) Dies sollte aus Sicherheitsgründen nicht durchgeführt werden. Ohne .pgpassDatei würde ich die Verbindungszeichenfolge als Umgebungsvariable speichern.

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

dann haben in Ihrem crontab

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

Josue Alexander Ibarra
quelle
Version 9.1 von Postgre gibt eine unbekannte Option für dbname aus
akohout
Dies wurde mit den Versionen 9.4 und 9.3 auf Arch bzw. RHEL getestet. Kannst du deine Verbindungszeichenfolge posten? natürlich anonymisiert.
Josue Alexander Ibarra
Danke, @JosueIbarra. Erfolgreich getestet unter PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu
1
@EntryLevelR Sie müssen die Ausgabe in eine Datei leiten, um sie zu speichern. siehe diese relevante Frage askubuntu.com/questions/420981/…
Josue Alexander Ibarra
4
Dies sollte die akzeptierte Antwort sein. Ein Liner, klar.
Swdev
48
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename
Francisco Luz
quelle
Schön, aber funktioniert leider nicht für mich, ich bekomme "Abfrage fehlgeschlagen: FEHLER: Berechtigung für Beziehung direction_lookup verweigert"
James T Snell
@Doc haben Sie versucht, dem pg-Benutzer die erforderlichen Berechtigungen zu erteilen?
Francisco Luz
33

Dieser eine Liner hilft mir beim Erstellen eines Dumps einer einzelnen Datenbank.

PGPASSWORD="yourpassword" pg_dump -U postgres -h localhost mydb > mydb.pgsql
Aarvy
quelle
1
hat sehr geholfen ... thnxxx
ronit
19

@Josue Alexander Ibarra Antwort funktioniert auf Centos 7 und Version 9.5, wenn --dbname nicht übergeben wird.

pg_dump postgresql://username:[email protected]:5432/mydatabase 
Jauyzed
quelle
1
Du hast recht, so soll es aussehen. Ich denke, was vor ein paar Jahren falsch war, war meine Shell-Konfiguration. Deshalb war es für mich wichtig zu verwenden--dbname
Josue Alexander Ibarra
7

Beachten Sie, dass sich die pgpass.confDatei in Windows im folgenden Ordner befinden muss:

%APPDATA%\postgresql\pgpass.conf

Wenn sich kein postgresqlOrdner im %APPDATA%Ordner befindet, erstellen Sie ihn.

Der pgpass.confDateiinhalt ist ungefähr so:

localhost:5432:dbname:dbusername:dbpassword

Prost

Fernando Meneses Gomes
quelle
4

Korrigieren Sie mich, wenn ich falsch liege, aber wenn der Systembenutzer mit dem Datenbankbenutzer identisch ist, fragt PostgreSQL nicht nach dem Kennwort - es ist für die Authentifizierung auf das System angewiesen. Dies kann eine Frage der Konfiguration sein.

Wenn ich also wollte, dass der Datenbankbesitzer postgresjede Nacht seine Datenbanken sichert, könnte ich eine Crontab dafür erstellen : crontab -e -u postgres. Natürlich postgresmüsste es erlaubt sein, Cron-Jobs auszuführen; Daher muss es in aufgeführt sein /etc/cron.allowoder /etc/cron.denyleer sein.

Tobias
quelle
Du bist irgendwie hier richtig. Die Standardkonfiguration von Postgres verwendet die TRUST-Authentifizierung für lokale Systemkonten. Die meisten Produktions-Setups entfernen diesen Block jedoch direkt nach der Installation von RDBMS.
Jacek Prucia
4

Sichern Sie über ssh mit einem Kennwort unter Verwendung temporärer .pgpass-Anmeldeinformationen und drücken Sie auf 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

Ersetzen Sie einfach die ersten paar Konfigurationszeilen durch alles, was Sie brauchen - natürlich. Für diejenigen, die nicht am S3-Backup-Teil interessiert sind, nehmen Sie es heraus - offensichtlich.

Dieses Skript löscht die Anmeldeinformationen .pgpassanschließend, da in einigen Umgebungen der Standard-SSH-Benutzer ohne Kennwort sudo kann, z. B. eine EC2-Instanz mit dem ubuntuBenutzer. Daher ist die Verwendung .pgpassmit einem anderen Hostkonto zur Sicherung dieser Anmeldeinformationen möglicherweise sinnlos.

MikeM
quelle
Das Passwort wird auf historydiese Weise am Terminal protokolliert , nein?
Mpen
1
@mpen Vor Ort, ja. Aus der Ferne, nein. In meinem Fall ist es in Ordnung, dies in meinem lokalen Verlauf zu haben, da es sich um eine sichere VM handelt, die keinen Remotezugriff zulässt. Wenn dies in Ihrem Fall nicht in Ordnung ist, tun Sie es einfach history -c. Verwenden Sie bei der Verwendung mit Jenkins die Inject passwords to the build as environment variablesOption, damit das Passwort maskiert wird
MikeM
4

Wie in diesem Blogbeitrag beschrieben , gibt es zwei Möglichkeiten, PostgreSQL-Dienstprogrammen wie dem Befehl "pg_dump" nicht interaktiv ein Kennwort bereitzustellen: Verwenden der Datei ".pgpass" oder der Umgebungsvariablen "PGPASSWORD" .

manfall19
quelle
-1

Eine andere (wahrscheinlich nicht sichere) Möglichkeit, ein Passwort zu übergeben, ist die Umleitung von Eingaben, dh das Aufrufen

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

szymond
quelle
In Bezug auf die Sicherheit - Diese Datei muss nur von den beabsichtigten Benutzern gelesen werden können. Jeder mit Root-Rechten kann jedoch die Sicherheitseinstellungen ändern und somit das unverschlüsselte Kennwort lesen. Also ja, das ist unsicher ...
Tobias
3
@Tobias gibt es eine Alternative? Es scheint, dass jeder mit Root-Rechten das Passwort immer sehen kann, egal welche Technik außer der interaktiven Eingabe des Passworts (und die Frage bezieht sich auf cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH erwähnt, dass GSSAPI Single Sign-On unterstützt, erwähnt jedoch nicht, ob dies nicht interaktiv funktioniert.
Ross Bradbury
4
Jeder mit Root-Rechten kann auch den empfohlenen .pgpass lesen. Daher würde ich den Root-Zugriff nicht als Sicherheitsrisiko betrachten.
Max
-1

Sie können ein Passwort direkt an pg_dump übergeben, indem Sie Folgendes verwenden:

pg_dump "host=localhost port=5432 dbname=mydb user=myuser password=mypass" > mydb_export.sql
Larry Spence
quelle
Willkommen bei Stack Overflow! Ihre Antwort mag zwar funktionieren, hat jedoch schwerwiegende Auswirkungen auf die Sicherheit. Argumente eines Befehls sind in ps (1) sichtbar. Wenn also ein Prozess ps (1) überwacht, ist das Kennwort gefährdet.
Jonathan Rosa
-4

Meiner Meinung nach ist dies der einfachste Weg: Sie bearbeiten Ihre Haupt-Postgres-Konfigurationsdatei: pg_hba.conf Dort müssen Sie die folgende Zeile hinzufügen:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

und danach musst du anfangen cron so:

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

und es funktionierte ohne Passwort

Dofri
quelle
Und Sie haben gerade die Systemsicherheit zerstört. OK für eine Entwicklungsbox, aber sonst nichts.
Theodore R. Smith