¿Cómo pasar la contraseña a pg_dump?


294

Estoy intentando crear un cronjob para hacer una copia de seguridad de mi base de datos todas las noches antes de que ocurra algo catastrófico. Parece que este comando debería satisfacer mis necesidades:

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

Excepto después de ejecutar eso, espera que escriba una contraseña. No puedo hacer eso si lo ejecuto desde cron. ¿Cómo puedo pasar uno automáticamente?


Posiblemente útil publicación que escribí sobre la automatización de pg_restore! medium.com/@trinity/…
kittyminky

responde usando una cadena de conexión aquí: stackoverflow.com/a/29101292/1579667
Benj

Respuestas:


304

Cree un .pgpassarchivo en el directorio de inicio de la cuenta que pg_dumpse ejecutará como. Consulte la documentación de Postgresql libpq-pgpass para obtener detalles del formato (incluido el último párrafo donde explica que se ignorará si no establece el modo en 0600).


99
Cree ~ / .pgpass con localhost: 5432: mydbname: postgres: mypass Then chmod 600 ~ / .pgpass
Mircea Stanciu

66
Posiblemente útil: en Ubuntu, "sudo su postgres" para cambiar al usuario "postgres", luego cree el archivo .pgpass y ejecute el volcado.
Fivedogit

1
Seguí tu respuesta, pero aún no puedo crear con éxito mi archivo de copia de seguridad. Por favor vea mi enlace: unix.stackexchange.com/questions/257898/… . Gracias.
alyssaeliyah

Funciona en 9.6.2: o)
Andrew

2
Nota sobre sudo su postgres: que el usuario de Unix no existe necesariamente. No necesita hacerlo. Pero el usuario de la base de datos debería.
Fabien Haddadi

217

O puede configurar crontab para ejecutar un script. Dentro de ese script puede establecer una variable de entorno como esta: export PGPASSWORD="$put_here_the_password"

De esta manera, si tiene varios comandos que requieren contraseña, puede incluirlos en el script. Si la contraseña cambia, solo tiene que cambiarla en un lugar (el script).

Y estoy de acuerdo con Joshua, el uso pg_dump -Fcgenera el formato de exportación más flexible y ya está comprimido. Para obtener más información, consulte: documentación de pg_dump

P.ej

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

# restore the database
pg_restore -d newdb db.dump

3
Esto no es ideal. tirarlo también .pgpassmantendrá todo en un solo lugar, sin agregar una capa adicional de indirección. Además, si todo lo que quisiera hacer con exportar una variable, lo haría en mi .bashrcarchivo, o lo que sea.
mpen

99
Puedo ver por qué el .pgpassarchivo sería una mejor solución. Solo estaba dando una alternativa, aunque no estoy seguro de si merece un voto negativo :)
Max

13
No voté en contra. Ese era alguien más; Tampoco pensé que merecía un voto negativo. Ten un +1 para compensarlo.
mpen

77
Tantos enemigos Agradezco esta respuesta y la estoy adoptando para mi propia aplicación.
James T Snell

8
La configuración de la variable de entorno PGPASSWORD no es una práctica recomendada por la documentación ( postgresql.org/docs/current/static/libpq-envars.html ): el uso de esta variable de entorno no se recomienda por razones de seguridad, ya que algunos sistemas operativos permiten usuarios root para ver las variables de entorno del proceso a través de ps; en su lugar considere usar el archivo ~ / .pgpass
bouchon el

175

Si quieres hacerlo con un solo comando:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

27
La configuración de la variable de entorno PGPASSWORD no es una práctica recomendada por la documentación ( postgresql.org/docs/current/static/libpq-envars.html ): el uso de esta variable de entorno no se recomienda por razones de seguridad, ya que algunos sistemas operativos permiten usuarios root para ver las variables de entorno del proceso a través de ps; en lugar de considerar el uso de la .pgpass archivo ~ /
Bouchon

18
Sigue siendo un comentario útil. Hay muchos casos de implementación en los que esto sigue siendo útil.
Iain Duncan

1
Siempre recibí el error 'Error de autenticación de pares para el usuario "nombre de usuario"'. La solución fue: PGPASSWORD = "mypass" pg_dump -U nombre de usuario -h localhost> mydb.dump
Martin Pabst

44
Mi opinión es que es mucho mejor configurar una variable de entorno (dónde tiene control, dónde y cómo se almacenará la contraseña) como en una ubicación conocida, sin cifrar. Esta parte del documento postgresql es defectuosa, y esta respuesta es buena.
peterh - Restablecer Monica

1
Mi contraseña tenía una '@'. Esto funcionó. No pude averiguar cómo hacer que funcione con la postgres://sintaxis. No probé el .pgpassporque mi usuario de postgreso no tiene directorio de inicio.
jmathew

136

Para una línea, como migrar una base de datos que puede usar --dbnameseguida de una cadena de conexión (incluida la contraseña) como se indica en el manual pg_dump

En esencia.

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

Nota: Asegúrese de usar la opción en --dbnamelugar de la más corta -dy use un prefijo URI válido, postgresql://o postgres://.

La forma general de URI es:

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

La mejor práctica en su caso (tarea repetitiva en cron) no debe hacerse debido a problemas de seguridad. Si no fuera por el .pgpassarchivo, guardaría la cadena de conexión como una variable de entorno.

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

entonces ten en tu crontab

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


La versión 9.1 de Postgre genera una opción desconocida para dbname
akohout el

Esto se probó con las versiones 9.4 y 9.3 en Arch y RHEL respectivamente. ¿Puedes publicar tu cadena de conexión? anonimizado por supuesto.
Josue Alexander Ibarra

Gracias, @JosueIbarra. Probado con éxito en PostgreSQL 9.3, Ubuntu 14.04.
Cao Minh Tu

1
@EntryLevelR necesita canalizar la salida a un archivo para guardarlo. vea esta pregunta relevante askubuntu.com/questions/420981/…
Josue Alexander Ibarra

44
Esta debería ser la respuesta aceptada. Un forro, claro.
swdev

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

Agradable, pero lamentablemente no funciona para mí, recibo "error en la consulta: ERROR: permiso denegado para la relación direction_lookup"
James T Snell

@Doc, ¿has intentado otorgar los permisos necesarios al usuario de pg?
Francisco Luz

33

Este liner me ayuda al crear el volcado de una sola base de datos.

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

1
ayudó mucho ... thnxxx
ronit

19

La respuesta de @Josue Alexander Ibarra funciona en centos 7 y la versión 9.5 si no se pasa --dbname.

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

1
Tienes razón, así es como se supone que debe verse, creo que lo que estuvo mal hace unos años fue mi configuración de shell. Es por eso que era esencial para mí usar--dbname
Josue Alexander Ibarra

7

Tenga en cuenta que, en Windows, el pgpass.confarchivo debe estar en la siguiente carpeta:

%APPDATA%\postgresql\pgpass.conf

Si no hay una postgresqlcarpeta dentro de la %APPDATA%carpeta, créela.

el pgpass.confcontenido del archivo es algo así como:

localhost:5432:dbname:dbusername:dbpassword

salud


4

Corríjame si me equivoco, pero si el usuario del sistema es el mismo que el usuario de la base de datos, PostgreSQL no solicitará la contraseña; depende del sistema para la autenticación. Esto podría ser una cuestión de configuración.

Por lo tanto, cuando se quería que el propietario de la base postgresde copia de seguridad de sus bases de datos de todas las noches, podría crear un crontab para ello: crontab -e -u postgres. Por supuesto, postgressería necesario permitirle ejecutar trabajos cron; por lo tanto, debe aparecer en la lista /etc/cron.allowo /etc/cron.denydebe estar vacío.


Estás como aquí. La configuración predeterminada de Postgres utiliza la autenticación TRUST para las cuentas del sistema local. Sin embargo, la mayoría de las configuraciones de producción eliminan este bloque justo después de instalar RDBMS.
Jacek Prucia

4

Copia de seguridad sobre ssh con contraseña utilizando credenciales temporales de .pgpass y empuje a 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

Simplemente sustituya el primer par de líneas de configuración con lo que necesite, obviamente. Para aquellos que no estén interesados ​​en la parte de respaldo S3, sáquenla, obviamente.

Este script elimina las credenciales .pgpassdespués porque en algunos entornos, el usuario SSH predeterminado puede sudo sin una contraseña, por ejemplo, una instancia de EC2 con el ubuntuusuario, por lo que .pgpasspuede ser inútil usar una cuenta de host diferente para proteger esas credenciales.


La contraseña se registrará en la terminal de historyesta manera, ¿no?
mpen

1
@mpen Localmente, sí. Remotamente no. En mi caso, está bien tenerlo en mi historial local porque es una VM segura que no permite el acceso remoto. Si en su caso eso no está bien, simplemente hágalo history -c. Cuando lo use con Jenkins, use la Inject passwords to the build as environment variablesopción para que la contraseña
quede

4

Como se detalla en esta publicación de blog , hay dos formas de proporcionar una contraseña de manera no interactiva a las utilidades de PostgreSQL, como el comando "pg_dump": usando el archivo ".pgpass" o usando la variable de entorno "PGPASSWORD" .


-1

Otra forma (probablemente no segura) de pasar la contraseña es usar la redirección de entrada, es decir, llamar

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


Con respecto a la seguridad: este archivo debería ser legible solo por el usuario o usuarios previstos; sin embargo, cualquier persona con derechos de root podrá cambiar la configuración de seguridad y, por lo tanto, leer la contraseña sin cifrar. Entonces sí, esto es inseguro ...
Tobias

3
@Tobias ¿hay alguna alternativa? Parecería que cualquier persona con derechos de root siempre podría ver la contraseña, sin importar la técnica que no sea ingresar la contraseña de manera interactiva (y la pregunta es sobre cron). postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH menciona que GSSAPI admite el inicio de sesión único pero no menciona si eso funciona de manera no interactiva.
Ross Bradbury

44
Cualquier persona con derechos de root también puede leer el .pgpass, que es la forma recomendada. Por lo tanto, no consideraría el acceso a la raíz como un riesgo de seguridad.
max

-1

Puede pasar una contraseña a pg_dump directamente utilizando lo siguiente:

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

¡Bienvenido a Stack Overflow! Si bien su respuesta puede funcionar, tiene serias implicaciones de seguridad. Los argumentos de un comando son visibles en ps (1) , por lo que si un proceso monitorea ps (1), la contraseña se ve comprometida.
Jonathan Rosa

-4

la forma más fácil en mi opinión, esto: edita su archivo de configuración principal de postgres: pg_hba.conf allí debe agregar la siguiente línea:

host <you_db_name> <you_db_owner> 127.0.0.1/32 trust

y después de esto necesitas comenzar tu cron así:

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

y funcionó sin contraseña


Y acabas de destruir la seguridad del sistema. Está bien para un cuadro de desarrollo, pero nada más.
Theodore R. Smith
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.