Bagaimana cara memasukkan kata sandi ke pg_dump?

294

Saya mencoba untuk membuat cronjob untuk membuat cadangan basis data saya setiap malam sebelum sesuatu bencana terjadi. Sepertinya perintah ini harus memenuhi kebutuhan saya:

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

Kecuali setelah menjalankan itu, saya mengharapkan untuk mengetikkan kata sandi. Saya tidak bisa melakukan itu jika saya menjalankannya dari cron. Bagaimana saya bisa memasukkan satu secara otomatis?

Mpen
sumber
mungkin posting bermanfaat yang saya tulis di pg_restore otomatis! medium.com/@trinity/…
kittyminky
jawab menggunakan string koneksi di sini: stackoverflow.com/a/29101292/1579667
Benj

Jawaban:

304

Buat .pgpassfile di direktori home dari akun yang pg_dumpakan dijalankan sebagai. Lihat dokumentasi Postgresql libpq-pgpass untuk rincian format (termasuk paragraf terakhir yang menjelaskannya akan diabaikan jika Anda tidak mengatur mode ke 0600).

araqnid
sumber
99
Buat ~ / .pgpass dengan localhost: 5432: mydbname: postgres: mypass Lalu chmod 600 ~ / .pgpass
Mircea Stanciu
6
Mungkin bermanfaat: Di Ubuntu, "sudo su postgres" untuk beralih ke pengguna "postgres", lalu buat file .pgpass dan jalankan dump.
fivedogit
1
Saya mengikuti jawaban Anda tetapi masih tidak berhasil membuat file cadangan saya. Silakan lihat tautan saya: unix.stackexchange.com/questions/257898/… . Terima kasih.
alyssaeliyah
Bekerja pada 9.6.2: o)
Andrew
2
Catatan tentang sudo su postgres: bahwa pengguna Unix belum tentu ada. Tidak perlu. Tetapi pengguna DB harus.
Fabien Haddadi
216

Atau Anda dapat mengatur crontab untuk menjalankan skrip. Di dalam skrip itu Anda dapat mengatur variabel lingkungan seperti ini: export PGPASSWORD="$put_here_the_password"

Dengan cara ini jika Anda memiliki banyak perintah yang memerlukan kata sandi, Anda dapat memasukkan semuanya ke dalam skrip. Jika kata sandi berubah, Anda hanya perlu mengubahnya di satu tempat (skrip).

Dan saya setuju dengan Joshua, menggunakan pg_dump -Fcmenghasilkan format ekspor paling fleksibel dan sudah dikompresi. Untuk info lebih lanjut, lihat: dokumentasi pg_dump

Misalnya

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

# restore the database
pg_restore -d newdb db.dump
Maks
sumber
3
ini tidak ideal. melemparkannya .pgpassakan membuat semuanya tetap di satu tempat juga, tanpa menambahkan lapisan tipuan tambahan. ditambah, jika semua yang ingin saya lakukan dengan mengekspor variabel, saya akan melakukannya di .bashrcfile saya , atau apa pun itu.
mpen
9
Saya bisa melihat mengapa .pgpassfile tersebut menjadi solusi yang lebih baik. Saya hanya memberikan alternatif, tidak yakin apakah itu layak untuk downvote :)
Max
13
Saya tidak downvote. Itu orang lain; Saya juga tidak berpikir itu menuntut downvote. Miliki +1 untuk menebusnya.
mpen
7
Begitu banyak pembenci. Saya menghargai jawaban ini dan saya mengadopsinya untuk aplikasi saya sendiri.
James T Snell
8
Mengatur variabel lingkungan PGPASSWORD bukan praktik yang disarankan oleh dokumentasi ( postgresql.org/docs/current/static/libpq-envars.html ): Penggunaan variabel lingkungan ini tidak disarankan untuk alasan keamanan, karena beberapa sistem operasi memungkinkan non- root pengguna untuk melihat variabel lingkungan proses melalui ps; alih-alih pertimbangkan untuk menggunakan file ~ / .pgpass
bouchon
175

Jika Anda ingin melakukannya dalam satu perintah:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump
gitaarik
sumber
27
Mengatur variabel lingkungan PGPASSWORD bukan praktik yang disarankan oleh dokumentasi ( postgresql.org/docs/current/static/libpq-envars.html ): Penggunaan variabel lingkungan ini tidak disarankan untuk alasan keamanan, karena beberapa sistem operasi memungkinkan non- root pengguna untuk melihat variabel lingkungan proses melalui ps; alih-alih pertimbangkan untuk menggunakan file ~ / .pgpass
bouchon
18
Itu masih komentar yang berguna. Ada banyak kasus penempatan yang masih membantu.
Iain Duncan
1
Saya selalu mendapat kesalahan 'Otentikasi rekan gagal untuk pengguna "nama pengguna"'. Solusinya adalah: PGPASSWORD = "mypass" pg_dump -U nama pengguna -h localhost> mydb.dump
Martin Pabst
4
Pendapat saya adalah bahwa jauh lebih baik untuk mengatur variabel lingkungan (di mana Anda memiliki kontrol, di mana dan bagaimana kata sandi akan disimpan) seperti di lokasi yang diketahui dan tidak terenkripsi. Bagian dari postgresql doc ini salah, dan jawaban ini bagus.
peterh
1
Kata sandi saya memiliki '@' di dalamnya. Ini berhasil. Saya tidak tahu bagaimana cara membuatnya bekerja dengan postgres://sintaks. Tidak mencoba .pgpasskarena pengguna postgress saya tidak memiliki direktori home.
jmathew
136

Untuk one-liner, seperti memigrasikan basis data yang dapat Anda gunakan --dbnamediikuti oleh koneksi string (termasuk kata sandi) seperti yang dinyatakan dalam manual pg_dump

Intinya.

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

Catatan: Pastikan Anda menggunakan opsi --dbnamealih-alih yang lebih pendek -ddan menggunakan awalan URI yang valid, postgresql://atau postgres://.

Bentuk URI umum adalah:

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

Praktik terbaik dalam kasus Anda (tugas berulang di cron) ini tidak boleh dilakukan karena masalah keamanan. Jika bukan karena .pgpassfile saya akan menyimpan string koneksi sebagai variabel lingkungan.

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

kemudian miliki di crontab Anda

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

Josue Alexander Ibarra
sumber
Versi 9.1 dari Postgre menampilkan opsi yang tidak diketahui untuk dbname
akohout
Ini diuji dengan versi 9.4 dan 9.3 masing-masing pada arch dan RHEL. dapatkah Anda memposting string koneksi Anda? dianonimkan tentu saja.
Josue Alexander Ibarra
Terima kasih, @JosueIbarra. Diuji berhasil pada PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu
1
@EntryLevelR Anda perlu mem-pipe output ke file untuk menyimpannya lihat pertanyaan yang relevan ini askubuntu.com/questions/420981/…
Josue Alexander Ibarra
4
ini harus menjadi jawaban yang diterima. Satu liner, jelas.
swdev
48
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename
Francisco Luz
sumber
Bagus, tetapi sayangnya tidak bekerja untuk saya, saya mendapatkan "permintaan gagal: ERROR: izin ditolak untuk hubungan direction_lookup"
James T Snell
@ Doc sudahkah Anda mencoba memberikan izin yang diperlukan kepada pengguna pg?
Francisco Luz
33

Liner satu ini membantu saya saat membuat dump dari satu basis data.

PGPASSWORD="yourpassword" pg_dump -U postgres -h localhost mydb > mydb.pgsql
Aarvy
sumber
1
banyak membantu ... thnxxx
ronit
19

@Josue Alexander Ibarra menjawab berfungsi pada centos 7 dan versi 9.5 jika --dbname tidak disahkan.

pg_dump postgresql://username:[email protected]:5432/mydatabase 
Jauyzed
sumber
1
Anda benar, begitulah seharusnya terlihat, saya pikir apa yang salah beberapa tahun yang lalu adalah konfigurasi shell saya. Itulah mengapa sangat penting bagi saya untuk menggunakan--dbname
Josue Alexander Ibarra
7

Perhatikan bahwa, di windows, pgpass.conffile tersebut harus berada di folder berikut:

%APPDATA%\postgresql\pgpass.conf

jika tidak ada postgresqlfolder di dalam %APPDATA%folder, buatlah.

yang pgpass.confisi file adalah sesuatu seperti:

localhost:5432:dbname:dbusername:dbpassword

Bersulang

Fernando Meneses Gomes
sumber
4

Perbaiki saya jika saya salah, tetapi jika pengguna sistem sama dengan pengguna basis data, PostgreSQL tidak akan meminta kata sandi - itu bergantung pada sistem untuk otentikasi. Ini mungkin masalah konfigurasi.

Jadi, ketika saya ingin pemilik database postgresuntuk backup database-nya setiap malam, saya bisa membuat crontab untuk itu: crontab -e -u postgres. Tentu saja, postgresperlu diizinkan untuk menjalankan pekerjaan cron; karena itu harus terdaftar dalam /etc/cron.allow, atau /etc/cron.denyharus kosong.

Tobias
sumber
Anda ada di sini. Konfigurasi Postgres default menggunakan otentikasi TRUST untuk akun sistem lokal. Namun sebagian besar pengaturan produksi menyingkirkan blok ini tepat setelah menginstal RDBMS.
Jacek Prucia
4

Cadangkan lewat ssh dengan kata sandi menggunakan kredensial .pgpass sementara dan tekan ke 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

Ganti saja beberapa baris konfigurasi pertama dengan apa pun yang Anda butuhkan - jelas. Bagi mereka yang tidak tertarik pada bagian cadangan S3, keluarkan - jelas.

Script ini menghapus kredensial .pgpasssetelahnya karena di beberapa lingkungan, pengguna SSH default dapat sudo tanpa kata sandi, misalnya instance EC2 dengan ubuntupengguna, jadi menggunakan .pgpassdengan akun host yang berbeda untuk mengamankan kredensial tersebut, mungkin tidak ada gunanya.

MikeM
sumber
Kata sandi akan masuk ke terminal historydengan cara ini, bukan?
buka
1
@ buka secara lokal, ya. Secara jarak jauh, tidak. Dalam kasus saya, OK untuk memiliki dalam sejarah lokal saya karena VM aman yang tidak memungkinkan akses jarak jauh. Jika dalam kasus Anda itu tidak OK, lakukan saja history -c. Saat menggunakan dengan Jenkins, gunakan Inject passwords to the build as environment variablesopsi sehingga kata sandi ditutup
MikeM
4

Sebagaimana dirinci dalam posting blog ini , ada dua cara untuk secara nonaktif memberikan kata sandi ke utilitas PostgreSQL seperti perintah "pg_dump": menggunakan file ".pgpass" atau menggunakan variabel lingkungan "PGPASSWORD" .

manfall19
sumber
-1

Cara lain (mungkin tidak aman) untuk memasukkan kata sandi adalah menggunakan pengalihan input yaitu menelepon

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

szymond
sumber
Mengenai keamanan - file ini harus dapat dibaca oleh pengguna yang dituju saja; namun, siapa pun dengan hak root akan dapat mengubah pengaturan keamanan, dan dengan demikian membaca kata sandi yang tidak dienkripsi. Jadi ya, ini tidak aman ...
Tobias
3
@Tobias apakah ada alternatif lain? Tampaknya siapa pun yang memiliki hak root selalu dapat melihat kata sandi apa pun tekniknya selain memasukkan kata sandi secara interaktif (dan pertanyaannya adalah tentang cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH menyebutkan GSSAPI mendukung sistem masuk tunggal tetapi tidak menyebutkan apakah itu berfungsi secara non-interaktif.
Ross Bradbury
4
Siapa pun yang memiliki hak root juga dapat membaca .pgpass yang merupakan cara yang disarankan. Oleh karena itu, saya tidak akan menganggap akses root sebagai risiko keamanan.
Maks
-1

Anda dapat mengirimkan kata sandi ke pg_dump secara langsung dengan menggunakan yang berikut:

pg_dump "host=localhost port=5432 dbname=mydb user=myuser password=mypass" > mydb_export.sql
Larry Spence
sumber
Selamat Datang di Stack Overflow! Sementara jawaban Anda mungkin berhasil, itu memiliki implikasi keamanan yang serius. Argumen perintah terlihat dalam ps (1) , jadi jika suatu proses memonitor ps (1) maka kata sandi dikompromikan.
Jonathan Rosa
-4

cara termudah menurut saya, ini: Anda mengedit file konfigurasi postgres utama Anda: pg_hba.conf di sana Anda harus menambahkan baris berikut:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

dan setelah ini, Anda perlu memulai Anda cron demikian:

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

dan itu bekerja tanpa kata sandi

Dofri
sumber
Dan Anda baru saja menghancurkan keamanan sistem. OK untuk kotak dev, tapi tidak ada yang lain.
Theodore R. Smith