Làm thế nào để chuyển mật khẩu vào pg_dump?


294

Tôi đang cố gắng tạo một cronjob để sao lưu cơ sở dữ liệu của mình mỗi đêm trước khi điều gì đó thảm khốc xảy ra. Có vẻ như lệnh này sẽ đáp ứng nhu cầu của tôi:

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

Ngoại trừ sau khi chạy nó, nó hy vọng tôi nhập mật khẩu. Tôi không thể làm điều đó nếu tôi chạy nó từ cron. Làm thế nào tôi có thể vượt qua một trong tự động?


có thể bài viết hữu ích tôi đã viết về tự động hóa pg_restore! Medium.com/@trinity/ từ
kittyminky

trả lời bằng một chuỗi kết nối ở đây: stackoverflow.com/a/29101292/1579667
Benj

Câu trả lời:


304

Tạo một .pgpasstệp trong thư mục chính của tài khoản pg_dumpsẽ chạy như. Xem libpq-pgpass của tài liệu Postgresql để biết chi tiết về định dạng (bao gồm cả đoạn cuối giải thích nó sẽ bị bỏ qua nếu bạn không đặt chế độ thành 0600).


99
Tạo ~ / .pgpass với localhost: 5432: mydbname: postgres: mypass Sau đó chmod 600 ~ / .pgpass
Mircea Stanciu

6
Có thể hữu ích: Trên Ubuntu, "sudo su postgres" để chuyển sang người dùng "postgres", sau đó tạo tệp .pgpass và thực hiện kết xuất.
fiveogit

1
Tôi đã làm theo câu trả lời của bạn nhưng vẫn không thể thành công tạo tập tin sao lưu của tôi. Vui lòng xem liên kết của tôi: unix.stackexchange.com/questions/257898/ . Cảm ơn bạn.
alyssaeliyah

Hoạt động vào ngày 9.6.2: o)
Andrew

2
Lưu ý về sudo su postgres: người dùng Unix không nhất thiết phải tồn tại. Nó không cần. Nhưng người dùng DB nên.
Fabien Haddadi

216

Hoặc bạn có thể thiết lập crontab để chạy tập lệnh. Trong tập lệnh đó, bạn có thể đặt một biến môi trường như thế này: export PGPASSWORD="$put_here_the_password"

Bằng cách này nếu bạn có nhiều lệnh yêu cầu mật khẩu, bạn có thể đặt tất cả chúng trong tập lệnh. Nếu mật khẩu thay đổi, bạn chỉ phải thay đổi nó ở một nơi (tập lệnh).

Và tôi đồng ý với Joshua, sử dụng pg_dump -Fctạo định dạng xuất linh hoạt nhất và đã được nén. Để biết thêm thông tin xem: tài liệu pg_dump

Ví dụ

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

# restore the database
pg_restore -d newdb db.dump

3
Điều này không lý tưởng. ném nó vào .pgpasssẽ giữ mọi thứ ở một nơi, mà không cần thêm một lớp cảm ứng. cộng với, nếu tất cả những gì tôi muốn làm với xuất một biến, tôi sẽ làm điều đó trong .bashrctệp của mình hoặc bất cứ điều gì.
mở

9
Tôi có thể thấy tại sao các .pgpasstập tin sẽ là một giải pháp tốt hơn. Tôi chỉ đưa ra một giải pháp thay thế, không chắc nó có xứng đáng với một downvote không :)
Tối đa

13
Tôi đã không downvote. Đó là một người khác; Tôi cũng không nghĩ rằng nó bảo đảm một downvote. Có +1 để bù cho nó.
mở

7
Rất nhiều người ghét. Tôi đánh giá cao câu trả lời này và đang áp dụng nó cho ứng dụng của riêng tôi.
James T Snell

8
Đặt tài liệu biến môi trường PGPASSWORD không phải là một cách thực hành được đề xuất bởi tài liệu ( postgresql.org/docs/civerse/static/libpq-envars.html ): Không nên sử dụng biến môi trường này vì lý do bảo mật, vì một số hệ điều hành cho phép không người dùng root để xem các biến môi trường quá trình thông qua ps; thay vì xem xét sử dụng tệp ~ / .pgpass
bouchon

175

Nếu bạn muốn làm điều đó trong một lệnh:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

27
Đặt tài liệu biến môi trường PGPASSWORD không phải là một cách thực hành được đề xuất bởi tài liệu ( postgresql.org/docs/civerse/static/libpq-envars.html ): Không nên sử dụng biến môi trường này vì lý do bảo mật, vì một số hệ điều hành cho phép không người dùng root để xem các biến môi trường quá trình thông qua ps; thay vì xem xét sử dụng tệp ~ / .pgpass
bouchon

18
Nó vẫn là một bình luận hữu ích. Có rất nhiều trường hợp triển khai trong đó điều này vẫn hữu ích.
Iain Duncan

1
Tôi luôn gặp lỗi 'Xác thực ngang hàng không thành công cho "tên người dùng"'. Giải pháp là: PGPASSWORD = "mypass" pg_dump -U tên người dùng -h localhost> mydb.dump
Martin Pabst

4
Ý kiến của tôi là nó là tốt hơn để thiết lập một biến môi trường (nơi bạn có quyền kiểm soát, nơicách mật khẩu sẽ được lưu trữ) như trong một tiếng, vị trí không được mã hóa. Phần này của tài liệu postgresql bị lỗi và câu trả lời này là một câu hỏi hay.
peterh - Phục hồi Monica

1
Mật khẩu của tôi có '@' trong đó. Điều này đã làm việc. Tôi không thể tìm ra cách làm cho nó hoạt động với postgres://cú pháp. Không thử .pgpassvì người dùng truy cập của tôi không có thư mục chính.
jmathew

136

Đối với một lớp lót, như di chuyển cơ sở dữ liệu, bạn có thể sử dụng --dbnametheo sau là chuỗi kết nối (bao gồm cả mật khẩu) như được nêu trong hướng dẫn pg_dump

Về bản chất.

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

Lưu ý: Đảm bảo rằng bạn sử dụng tùy chọn --dbnamethay vì ngắn hơn -dvà sử dụng tiền tố URI hợp lệ postgresql://hoặc postgres://.

Biểu mẫu URI chung là:

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

Thực hành tốt nhất trong trường hợp của bạn (nhiệm vụ lặp đi lặp lại trong cron) điều này không nên được thực hiện vì vấn đề bảo mật. Nếu không có .pgpasstệp, tôi sẽ lưu chuỗi kết nối dưới dạng biến môi trường.

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

sau đó có trong crontab của bạn

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


Phiên bản 9.1 của Postgre xuất ra một tùy chọn không xác định cho dbname
akohout

Điều này đã được thử nghiệm với các phiên bản 9,4 và 9,3 trên vòm và RHEL tương ứng. bạn có thể gửi chuỗi kết nối của bạn? tất nhiên là ẩn danh.
Josue Alexander Ibarra

Cảm ơn, @JosueIbarra. Đã thử nghiệm thành công trên PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Từ

1
@EntryLevelR bạn cần chuyển đầu ra thành một tệp để lưu nó. xem câu hỏi này liên quan askubuntu.com/questions/420981/...
Josue Alexander Ibarra

4
đây sẽ là câu trả lời được chấp nhận Một lớp lót, rõ ràng.
swdev

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

Đẹp, nhưng đáng buồn là nó không hoạt động với tôi, tôi nhận được "truy vấn thất bại: LRI: quyền bị từ chối cho mối quan hệ direction_lookup"
James T Snell

@Doc bạn đã thử cung cấp các quyền cần thiết cho người dùng pg chưa?
Francisco Luz

33

Điều này giúp tôi trong khi tạo kết xuất của một cơ sở dữ liệu.

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

1
đã giúp rất nhiều ... thnxxx
ronit

19

@Josue Alexander Ibarra trả lời hoạt động trên centos 7 và phiên bản 9.5 nếu --dbname không được thông qua.

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

1
Bạn nói đúng, đó là vẻ ngoài của nó, tôi nghĩ cái sai vài năm trước là cấu hình vỏ của tôi. Đó là lý do tại sao nó rất cần thiết cho tôi sử dụng--dbname
Josue Alexander Ibarra

7

Lưu ý rằng, trong windows, pgpass.conftệp phải nằm trong thư mục sau:

%APPDATA%\postgresql\pgpass.conf

nếu không có postgresqlthư mục trong %APPDATA%thư mục, hãy tạo nó.

các pgpass.confnội dung tập tin là một cái gì đó như:

localhost:5432:dbname:dbusername:dbpassword

chúc mừng


4

Sửa lỗi cho tôi nếu tôi sai, nhưng nếu người dùng hệ thống giống với người dùng cơ sở dữ liệu, PostgreQuery sẽ không yêu cầu mật khẩu - nó phụ thuộc vào hệ thống để xác thực. Đây có thể là một vấn đề về cấu hình.

Vì vậy, khi tôi muốn chủ sở hữu cơ sở dữ liệu postgressao lưu cơ sở dữ liệu của mình mỗi đêm, tôi có thể tạo một crontab cho nó : crontab -e -u postgres. Tất nhiên, postgressẽ cần phải được phép thực hiện các công việc định kỳ; do đó, nó phải được liệt kê trong /etc/cron.allow, hoặc /etc/cron.denyphải trống.


Bạn sắp xếp ngay tại đây. Cấu hình Postgres mặc định sử dụng xác thực TRUST cho các tài khoản hệ thống cục bộ. Tuy nhiên, hầu hết các thiết lập sản xuất thoát khỏi khối này ngay sau khi cài đặt RDBMS.
Jacek Prucia

4

Sao lưu qua ssh bằng mật khẩu bằng thông tin xác thực .pgpass tạm thời và đẩy lên 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

Chỉ cần thay thế một vài dòng cấu hình đầu tiên bằng bất cứ thứ gì bạn cần - rõ ràng. Đối với những người không quan tâm đến phần sao lưu S3, hãy lấy nó ra - rõ ràng.

Tập lệnh này sẽ xóa thông tin đăng nhập .pgpasssau đó vì trong một số môi trường, người dùng SSH mặc định có thể sudo mà không cần mật khẩu, ví dụ EC2 với ubuntungười dùng, do đó sử dụng .pgpassvới tài khoản máy chủ khác để bảo mật thông tin đăng nhập đó, có thể là vô nghĩa.


Mật khẩu sẽ được đăng nhập vào terminal historytheo cách này, phải không?
mpen

1
@mpen Ở địa phương, vâng. Từ xa, không. Trong trường hợp của tôi, nó có thể có trong lịch sử địa phương của tôi vì nó là một VM an toàn không cho phép truy cập từ xa. Nếu trong trường hợp của bạn không ổn, chỉ cần làm history -c. Khi sử dụng với Jenkins, hãy sử dụng Inject passwords to the build as environment variablestùy chọn để mật khẩu được che dấu
MikeM

4

Như chi tiết trong bài đăng trên blog này , có hai cách để không tương tác cung cấp mật khẩu cho các tiện ích PostgreQuery, chẳng hạn như lệnh "pg_dump": sử dụng tệp ".pgpass" hoặc sử dụng biến môi trường "PGPASSWORD" .


-1

Một cách khác (có thể không an toàn) để truyền mật khẩu là sử dụng chuyển hướng đầu vào tức là gọi

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


Liên quan đến bảo mật - tập tin này chỉ cần được đọc bởi người dùng dự định; tuy nhiên, bất kỳ ai có quyền root đều có thể thay đổi cài đặt bảo mật và do đó để đọc mật khẩu không được mã hóa. Vì vậy, có, điều này không an toàn ...
Tobias

3
@Tobias có cách nào khác không? Dường như bất cứ ai có quyền root luôn có thể nhìn thấy mật khẩu bất kể kỹ thuật nào khác ngoài việc nhập mật khẩu một cách tương tác (và câu hỏi là về cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH đề cập GSSAPI hỗ trợ đăng nhập một lần nhưng không đề cập nếu hoạt động không tương tác.
Ross Bradbury

4
Bất cứ ai có quyền root cũng có thể đọc .pgpass là cách được đề xuất. Do đó, tôi sẽ không coi quyền truy cập root là rủi ro bảo mật.
tối đa

-1

Bạn có thể chuyển mật khẩu vào pg_dump trực tiếp bằng cách sử dụng như sau:

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

Chào mừng bạn đến với Stack Overflow! Trong khi câu trả lời của bạn có thể hoạt động, nó có ý nghĩa bảo mật nghiêm trọng.Các đối số của một lệnh được hiển thị trong ps (1) , vì vậy nếu một quá trình theo dõi ps (1) thì mật khẩu bị xâm phạm.
Jonathan Rosa

-4

Theo cách dễ nhất theo ý kiến ​​của tôi, điều này: bạn chỉnh sửa tệp cấu hình postgres chính: pg_hba.conf ở đó bạn phải thêm dòng sau:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

và sau này, bạn cần bắt đầu bạn cron như vậy:

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

và nó hoạt động mà không cần mật khẩu


Và bạn vừa phá hủy bảo mật hệ thống. OK cho một hộp dev, nhưng không có gì khác.
Theodore R. Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.