¿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?

mpen
fuente
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).

araqnid
fuente
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
Max
fuente
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
gitaarik
fuente
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:[email protected]: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:[email protected]:5432/mydatabase

entonces ten en tu crontab

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

Josue Alexander Ibarra
fuente
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
Francisco luz
fuente
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
Aarvy
fuente
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:[email protected]:5432/mydatabase 
Jauyzed
fuente
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

Fernando Meneses Gomes
fuente
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.

Tobias
fuente
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="[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

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.

MikeM
fuente
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" .

manfall19
fuente
-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]

szymond
fuente
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
Larry Spence
fuente
¡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

Dofri
fuente
Y acabas de destruir la seguridad del sistema. Está bien para un cuadro de desarrollo, pero nada más.
Theodore R. Smith