Jak przekazać hasło do pg_dump?


294

Próbuję utworzyć cronjob do tworzenia kopii zapasowych mojej bazy danych każdej nocy, zanim wydarzy się coś katastrofalnego. Wygląda na to, że to polecenie powinno spełniać moje potrzeby:

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

Z wyjątkiem tego, że po uruchomieniu tego wymaga ode mnie wpisania hasła. Nie mogę tego zrobić, jeśli uruchomię go z crona. Jak mogę przekazać je automatycznie?


prawdopodobnie pomocny post, który napisałem o automatyzacji pg_restore! medium.com/@trinity/…
kittyminky

odpowiedz za pomocą ciągu połączenia tutaj: stackoverflow.com/a/29101292/1579667
Benj

Odpowiedzi:


304

Utwórz .pgpassplik w katalogu głównym konta, które pg_dumpbędzie działać jako. Zobacz dokumentację Postgresql libpq-pgpass, aby uzyskać szczegółowe informacje na temat formatu (w tym ostatni akapit, w którym wyjaśniono, że zostanie zignorowany, jeśli nie ustawisz trybu na 0600).


99
Utwórz ~ / .pgpass z localhost: 5432: moja_nazwa: postgres: mypass Następnie chmod 600 ~ / .pgpass
Mircea Stanciu

6
Prawdopodobnie pomocne: w systemie Ubuntu „sudo su postgres”, aby przełączyć się na użytkownika „postgres”, a następnie utworzyć plik .pgpass i wykonać zrzut.
fivedogit

1
Postąpiłem zgodnie z odpowiedzią, ale nadal nie mogę pomyślnie utworzyć pliku kopii zapasowej. Proszę zobaczyć mój link: unix.stackexchange.com/questions/257898/... . Dziękuję Ci.
alyssaeliyah

Działa z 9.6.2: o)
Andrew

2
Uwaga na temat sudo su postgres: ten użytkownik systemu Unix niekoniecznie istnieje. Nie musi. Ale użytkownik DB powinien.
Fabien Haddadi,

216

Lub możesz skonfigurować crontab do uruchamiania skryptu. Wewnątrz tego skryptu możesz ustawić zmienną środowiskową taką jak ta: export PGPASSWORD="$put_here_the_password"

W ten sposób, jeśli masz wiele poleceń wymagających hasła, możesz umieścić je wszystkie w skrypcie. Jeśli hasło się zmieni, musisz je zmienić tylko w jednym miejscu (skrypt).

I zgadzam się z Joshua, użycie pg_dump -Fcgeneruje najbardziej elastyczny format eksportu i jest już skompresowany. Aby uzyskać więcej informacji, zobacz: dokumentacja pg_dump

Na przykład

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

# restore the database
pg_restore -d newdb db.dump

3
to nie jest idealne. wrzucenie go .pgpasszatrzyma wszystko w jednym miejscu, bez dodawania dodatkowej warstwy pośredniej. ponadto, jeśli wszystko, co chciałem zrobić z eksportem zmiennej, zrobiłbym to w moim .bashrcpliku lub czymkolwiek innym .
mpen 15.11.11

9
Rozumiem, dlaczego .pgpassplik byłby lepszym rozwiązaniem. Dałem tylko alternatywę, nie jestem pewien, czy zasługuje ona na głosowanie :)
Max

13
Nie przegłosowałem. To był ktoś inny; Nie sądziłem też, że uzasadnia to głosowanie negatywne. Masz +1, aby to nadrobić.
mpen 15.11. O

7
Tyle hejterów. Doceniam tę odpowiedź i przyjmuję ją do własnego wniosku.
James T Snell

8
Ustawienie zmiennej środowiskowej PGPASSWORD nie jest zalecaną praktyką w dokumentacji ( postgresql.org/docs/current/static/libpq-envars.html ): Używanie tej zmiennej środowiskowej nie jest zalecane ze względów bezpieczeństwa, ponieważ niektóre systemy operacyjne zezwalają na root użytkowników, aby zobaczyć zmienne środowiskowe procesu za pomocą ps; zamiast tego rozważ użycie pliku ~ / .pgpass
bouchon

175

Jeśli chcesz to zrobić za pomocą jednego polecenia:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

27
Ustawienie zmiennej środowiskowej PGPASSWORD nie jest zalecaną praktyką w dokumentacji ( postgresql.org/docs/current/static/libpq-envars.html ): Używanie tej zmiennej środowiskowej nie jest zalecane ze względów bezpieczeństwa, ponieważ niektóre systemy operacyjne zezwalają na root użytkowników, aby zobaczyć zmienne środowiskowe procesu za pomocą ps; zamiast tego rozważ użycie pliku ~ / .pgpass
bouchon,

18
To wciąż przydatny komentarz. Istnieje wiele przypadków wdrażania, w których jest to nadal pomocne.
Iain Duncan

1
Zawsze pojawia się błąd „Uwierzytelnianie elementu równorzędnego nie powiodło się dla użytkownika„ nazwa użytkownika ””. Rozwiązaniem było: PGPASSWORD = "mypass" pg_dump -U nazwa użytkownika -h localhost> mydb.dump
Martin Pabst

4
Uważam, że o wiele lepiej jest skonfigurować zmienną środowiskową (gdzie masz kontrolę, gdzie i jak hasło będzie przechowywane), jak w znanej, niezaszyfrowanej lokalizacji. Ta część dokumentu postgresql jest wadliwa i ta odpowiedź jest dobra.
peterh - Przywróć Monikę

1
Moje hasło zawierało „@”. To zadziałało. Nie mogłem wymyślić, jak to zrobić ze postgres://składnią. Nie próbowałem, .pgpassponieważ mój użytkownik postgress nie ma katalogu domowego.
jmathew

136

W przypadku jednowierszowego, takiego jak migracja bazy danych, można użyć --dbnamełańcucha połączenia (w tym hasła), zgodnie z instrukcją pg_dump

W istocie.

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

Uwaga: Upewnij się, że używasz opcji --dbnamezamiast krótszej -di używasz poprawnego prefiksu URI, postgresql://lub postgres://.

Ogólny formularz URI to:

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

Najlepsza praktyka w twoim przypadku (powtarzalne zadanie w cronie) nie powinno się tego robić z powodu problemów z bezpieczeństwem. Gdyby nie .pgpassplik, zapisałbym ciąg połączenia jako zmienną środowiskową.

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

więc miejcie w swoim crontabie

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


Wersja 9.1 Postgre wyświetla nieznaną opcję dla dbname
podobnie

Zostało to przetestowane w wersjach 9.4 i 9.3 odpowiednio na arch i RHEL. czy możesz opublikować ciąg połączenia? oczywiście anonimowe.
Josue Alexander Ibarra

Dzięki, @JosueIbarra. Testy zakończyły się powodzeniem na PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu

1
@EntryLevelR musisz potokować wyjście do pliku, aby go zapisać. zobacz to istotne pytanie askubuntu.com/questions/420981/...
Josue Alexander Ibarra

4
to powinna być zaakceptowana odpowiedź. Jedna wkładka, przezroczysta.
swdev,

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

Ładne, ale niestety nie działa na mnie, mam „query failed: BŁĄD: brak dostępu do relacji direction_lookup”
James T Snell

@Doc próbowałeś dać niezbędne uprawnienia użytkownikowi pg?
Francisco Luz

33

Ta jedna linijka pomaga mi podczas tworzenia zrzutu pojedynczej bazy danych.

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

1
bardzo pomógł ... thnxxx
ronit

19

@Josue Alexander Ibarra odpowiedź działa na centos 7 i wersji 9.5, jeśli --dbname nie zostanie przekazane.

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

1
Masz rację, tak to powinno wyglądać. Myślę, że kilka lat temu nie tak było z moją konfiguracją powłoki. Dlatego tak ważne było dla mnie użycie--dbname
Josue Alexander Ibarra

7

Pamiętaj, że w systemie Windows pgpass.confplik musi znajdować się w następującym folderze:

%APPDATA%\postgresql\pgpass.conf

jeśli w postgresqlfolderze nie ma %APPDATA%folderu, utwórz go.

pgpass.confzawartość pliku jest coś takiego:

localhost:5432:dbname:dbusername:dbpassword

Twoje zdrowie


4

Popraw mnie, jeśli się mylę, ale jeśli użytkownik systemu jest taki sam jak użytkownik bazy danych, PostgreSQL nie poprosi o hasło - polega na systemie do uwierzytelnienia. Może to być kwestia konfiguracji.

Tak więc, gdy chciałem właściciela bazy danych postgresdo tworzenia kopii zapasowych swoich bazach danych każdej nocy, mogę stworzyć crontab dla niego: crontab -e -u postgres. Oczywiście postgresnależałoby zezwolić na wykonywanie zadań crona; dlatego musi być wymieniony w /etc/cron.allowlub /etc/cron.denymusi być pusty.


W pewnym sensie jesteś tutaj. Domyślna konfiguracja Postgres używa uwierzytelnienia TRUST dla lokalnych kont systemowych. Jednak większość konfiguracji produkcyjnych pozbywa się tego bloku zaraz po zainstalowaniu RDBMS.
Jacek Prucia,

4

Wykonaj kopię zapasową przez ssh za pomocą hasła przy użyciu tymczasowych poświadczeń .pgpass i przekaż do 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

Wystarczy zastąpić pierwszą parę linii konfiguracji tym, czego potrzebujesz - oczywiście. Dla tych, którzy nie są zainteresowani częścią zapasową S3, wyjmij ją - oczywiście.

Skrypt ten usuwa później poświadczenia, .pgpassponieważ w niektórych środowiskach domyślny użytkownik SSH może sudo bez hasła, na przykład wystąpienie EC2 z ubuntuużytkownikiem, więc używanie .pgpassinnego konta hosta w celu zabezpieczenia tych poświadczeń może być bezcelowe.


Hasło zostanie zalogowane do terminala w historyten sposób, nie?
mpen

1
@mpen Lokalnie, tak. Zdalnie, nie. W moim przypadku jest OK mieć w mojej lokalnej historii, ponieważ jest to bezpieczna maszyna wirtualna, która nie pozwala na zdalny dostęp. Jeśli w twoim przypadku nie jest OK, po prostu zrób history -c. Korzystając z Jenkins, użyj Inject passwords to the build as environment variablesopcji, aby hasło było maskowane
MikeM

4

Jak szczegółowo opisano w tym poście na blogu , istnieją dwa sposoby nieinteraktywnego podania hasła do narzędzi PostgreSQL, takich jak polecenie „pg_dump”: użycie pliku „.pgpass” lub użycie zmiennej środowiskowej „PGPASSWORD” .


-1

Innym (prawdopodobnie nie bezpiecznym) sposobem na podanie hasła jest przekierowanie wejściowe, tj. Wywołanie

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


W kwestii bezpieczeństwa - plik ten musiałby być czytelny tylko dla zamierzonego użytkownika (użytkowników); jednak każdy z prawami root może zmienić ustawienia bezpieczeństwa, a tym samym odczytać niezaszyfrowane hasło. Więc tak, to niepewne ...
Tobias

3
@Tobias czy jest jakaś alternatywa? Wydawałoby się, że każdy z prawami roota zawsze może zobaczyć hasło bez względu na technikę inną niż interaktywne wprowadzanie hasła (pytanie dotyczy crona). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH wspomina o GSSAPI obsługującym logowanie jednokrotne, ale nie ma wzmianki, czy to działa nieinteraktywnie.
Ross Bradbury,

4
Każdy z prawami root może również przeczytać .pgpass, który jest zalecanym sposobem. Dlatego nie uważałbym dostępu do konta root za zagrożenie bezpieczeństwa.
maks.

-1

Możesz przekazać hasło bezpośrednio do pg_dump, używając następujących poleceń:

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

Witamy w Stack Overflow! Twoja odpowiedź może zadziałać, ale ma poważne konsekwencje dla bezpieczeństwa. Argumenty polecenia są widoczne w ps (1) , więc jeśli proces monitoruje ps (1), hasło jest zagrożone.
Jonathan Rosa

-4

według mnie najłatwiejszy sposób: edytujesz główny plik konfiguracyjny postgres: pg_hba.conf tam musisz dodać następujący wiersz:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

a potem musisz zacząć cron w ten sposób:

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

i działało bez hasła


Właśnie zniszczyłeś bezpieczeństwo systemu. OK jak na dev box, ale nic więcej.
Theodore R. Smith
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.