【问题标题】:How to pass in password to pg_dump?如何将密码传递给 pg_dump?
【发布时间】:2011-02-23 01:12:53
【问题描述】:

我正在尝试创建一个 cronjob 来在每晚发生灾难性事件之前备份我的数据库。看起来这个命令应该可以满足我的需求:

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

除了运行之后,它希望我输入密码。如果我从 cron 运行它,我不能这样做。如何自动传递一个?

【问题讨论】:

标签: bash postgresql shell crontab


【解决方案1】:

在pg_dump 将运行的帐户的主目录中创建一个.pgpass 文件。

格式为:

hostname:port:database:username:password

然后,将文件的模式设置为0600。否则会被忽略。

chmod 600 ~/.pgpass

有关详细信息,请参阅 Postgresql 文档libpq-pgpass。

【讨论】:

  • 使用 localhost:5432:mydbname:postgres:mypass 创建 ~/.pgpass 然后 chmod 600 ~/.pgpass
  • 可能有帮助:在 Ubuntu 上,“sudo su postgres”切换到“postgres”用户,然后创建 .pgpass 文件并执行转储。
  • 我按照您的回答,但仍然无法成功创建我的备份文件。请看我的链接:unix.stackexchange.com/questions/257898/…。谢谢。
  • 适用于 9.6.2 :o)
  • 注意sudo su postgres:Unix 用户不一定存在。它不需要。但是数据库用户应该。
【解决方案2】:

或者您可以设置 crontab 来运行脚本。在该脚本中,您可以像这样设置环境变量: export PGPASSWORD="$put_here_the_password"

这样,如果您有多个需要密码的命令,您可以将它们全部放入脚本中。如果密码更改,您只需在一处(脚本)更改。

我同意 Joshua 的观点,使用 pg_dump -Fc 生成最灵活的导出格式并且已经被压缩。欲了解更多信息,请参阅:pg_dump documentation

例如

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

# restore the database
pg_restore -d newdb db.dump

【讨论】:

  • 我明白为什么.pgpass 文件会是一个更好的解决方案。我只是给出了一个替代方案,但不确定它是否值得一票否决:)
  • 我没有投反对票。那是别人;我也不认为它值得投反对票。有一个 +1 来弥补它。
  • 讨厌的人太多了。我很欣赏这个答案,并在我自己的应用程序中采用它。
  • 文档不建议设置 PGPASSWORD 环境变量 (postgresql.org/docs/current/static/libpq-envars.html):出于安全原因,不建议使用此环境变量,因为一些操作系统允许非root用户通过ps查看进程环境变量;而是考虑使用 ~/.pgpass 文件
  • 这实际上是 docker 容器的首选方式。
【解决方案3】:

如果你想在一个命令中完成:

PGPASSWORD="mypass" pg_dump mydb > mydb.dump

【讨论】:

  • 不建议设置 PGPASSWORD 环境变量,文档 (postgresql.org/docs/current/static/libpq-envars.html) :出于安全原因,不建议使用此环境变量,因为一些操作系统允许非root用户通过ps查看进程环境变量;而是考虑使用 ~/.pgpass 文件
  • 这仍然是一个有用的评论。有很多部署案例仍然有用。
  • 我总是收到错误消息“用户“用户名”的对等身份验证失败”。解决方案是:PGPASSWORD="mypass" pg_dump -U username -h localhost > mydb.dump
  • 我的意见是,最好设置一个环境变量(你可以控制的地方,where 和 how 密码将被存储) 在一个已知的、未加密的位置。 postgresql doc的这一部分有问题,这个答案很好。
  • 我的密码中有一个“@”。这行得通。我不知道如何使它与postgres:// 语法一起工作。没有尝试.pgpass,因为我的 postgress 用户没有主目录。
【解决方案4】:

对于单线,如迁移数据库,您可以使用--dbname 后跟一个连接字符串(包括密码),如pg_dump manual 中所述

本质上。

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

注意:确保使用选项--dbname 而不是较短的-d,并使用有效的URI 前缀postgresql:// 或postgres://。

一般的URI形式是:

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

在您的情况下的最佳实践(cron 中的重复任务)由于安全问题,不应该这样做。如果不是 .pgpass 文件,我会将连接字符串保存为环境变量。

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

然后在你的 crontab 中添加

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

【讨论】:

  • Postgre 9.1 版输出 dbname 的未知选项
  • 这分别在 arch 和 RHEL 上使用 9.4 和 9.3 版本进行了测试。你可以发布你的连接字符串吗?当然是匿名的。
  • 谢谢,@JosueIbarra。在 PostgreSQL 9.3、Ubuntu 14.04 上测试成功。
  • @EntryLevelR 您需要将输出通过管道传输到文件以便保存。看到这个相关问题askubuntu.com/questions/420981/…
  • 这应该是公认的答案。一个衬里,透明的。
【解决方案5】:

在创建单个数据库的转储时,这一行可以帮助我。

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

【讨论】:

  • 帮了很多忙...thnxxx
【解决方案6】:
$ PGPASSWORD="mypass" pg_dump -i -h localhost -p 5432 -U username -F c -b -v -f dumpfilename.dump databasename

【讨论】:

  • 很好,但很遗憾对我不起作用,我收到“查询失败:错误:关系方向查找权限被拒绝”
  • @Doc 你试过给 pg 用户必要的权限吗?
【解决方案7】:

您可以使用以下命令直接将密码传递给 pg_dump:

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

【讨论】:

  • 欢迎来到 Stack Overflow!虽然您的答案可能有效,但它具有严重的安全隐患。 命令的参数在 ps(1) 中可见,因此如果一个进程监视 ps(1),那么密码就会被泄露。
  • 是的,@JonathanRosa,你是对的。但拉里·斯宾塞刚刚回答了这个问题。因此,例如,如果在 docker 中完成,则安全问题不是问题。
【解决方案8】:

@Josue Alexander Ibarra 答案适用于 centos 7 和 9.5 版 如果 --dbname 没有通过。

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

【讨论】:

  • 你是对的,这就是它应该看起来的样子,我认为几年前的问题是我的 shell 配置。这就是为什么我必须使用--dbname
【解决方案9】:

请注意,在 Windows 中,pgpass.conf 文件必须位于以下文件夹中:

%APPDATA%\postgresql\pgpass.conf

如果%APPDATA% 文件夹中没有postgresql 文件夹,请创建它。

pgpass.conf 文件内容类似于:

localhost:5432:dbname:dbusername:dbpassword

干杯

【讨论】:

    【解决方案10】:

    如this blog post 中所述,有两种方法可以非交互方式向 PostgreSQL 实用程序(例如“pg_dump”命令)提供密码:使用 ".pgpass" 文件或使用 >“PGPASSWORD” 环境变量。

    【讨论】:

      【解决方案11】:

      如果我错了,请纠正我,但如果系统用户与数据库用户相同,PostgreSQL 不会要求输入密码 - 它依赖于系统进行身份验证。这可能是配置问题。

      因此,当我希望数据库所有者postgres 每晚备份他的数据库时,我可以为其创建一个 crontab:crontab -e -u postgres。当然,postgres 需要被允许执行 cron 作业;因此它必须在/etc/cron.allow 中列出,或者/etc/cron.deny 必须为空。

      【讨论】:

      • 你就在这里。默认 Postgres 配置对本地系统帐户使用 TRUST 身份验证。然而,大多数生产设置在安装 RDBMS 后立即摆脱了这个块。
      【解决方案12】:

      使用临时 .pgpass 凭据通过 ssh 备份并推送到 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
      

      只需用您需要的任何内容替换前几个配置行 - 显然。 对于那些对 S3 备份部分不感兴趣的人,把它拿出来 - 很明显。

      此脚本随后会删除 .pgpass 中的凭据,因为在某些环境中,默认 SSH 用户可以在没有密码的情况下执行 sudo,例如具有 ubuntu 用户的 EC2 实例,因此使用具有不同主机帐户的 .pgpass为了获得这些凭证,可能毫无意义。

      【讨论】:

      • 密码会以这种方式登录到终端history,不是吗?
      • @mpen 在本地,是的。远程,没有。在我的情况下,可以在我的本地历史记录中拥有它,因为它是一个不允许远程访问的安全 VM。如果在您的情况下不行,请执行history -c。与 Jenkins 一起使用时,请使用 Inject passwords to the build as environment variables 选项以隐藏密码
      【解决方案13】:

      对于 Windows,pgpass.conf 文件应存在于路径中:

      %APPDATA%\postgresql\pgpass.conf
      

      在我的 Windows 10 绝对路径上是:

      C:\Users\Ognjen\AppData\Roaming\postgresql\pgpass.conf
      

      Note: 如果%APPDATA% 中没有postgresql 文件夹,则创建一个包含pgpass.conf 文件的文件夹。

      pgpass.conf 的内容可能是:

      *:5432:*:*:myDbPassword
      

      或者更具体的内容可以是:

      localhost:5432:dbName:username:password
      

      Note:pgpass.conf 的内容不能以空格结尾(密码后),否则会发生错误。

      【讨论】:

        【解决方案14】:

        传递密码的安全方法是将其存储在.pgpass 文件中

        .pgpass 文件的内容将采用以下格式:

        db_host:db_port:db_name:db_user:db_pass
        
        #Eg
        localhost:5432:db1:admin:tiger
        localhost:5432:db2:admin:tiger
        
        

        现在,将此文件存储在具有权限u=rw (0600) or less 的用户的主目录中

        要查找用户的主目录,请使用 echo $HOME

        限制文件的权限 chmod 0600 /home/ubuntu/.pgpass

        【讨论】:

          【解决方案15】:

          您只需要打开 pg_hba.conf 并设置信任所有方法。这对我有用。因此安全性为空。

          【讨论】:

            【解决方案16】:

            另一种(可能不安全)传递密码的方法是使用输入重定向,即调用

            pg_dump [params] &lt; [path to file containing password]

            【讨论】:

            • 关于安全性 - 此文件只需要目标用户可读;但是,任何具有 root 权限的人都可以更改安全设置,从而读取未加密的密码。所以是的,这是不安全的......
            • @Tobias 还有其他选择吗?似乎任何具有 root 权限的人都可以看到密码,无论使用什么技术,除了交互式输入密码(问题是关于 cron 的)。 postgresql.org/docs/9.3/static/auth-methods.html#GSSAPI-AUTH 提到 GSSAPI 支持单点登录,但没有提及它是否以非交互方式工作。
            • 任何拥有root权限的人也可以阅读.pgpass,这是推荐的方式。因此,我不会认为 root 访问存在安全风险。
            【解决方案17】:

            我认为最简单的方法是: 你编辑你的主要 postgres 配置文件:pg_hba.conf 在那里你必须添加以下行:

            host &lt;you_db_name&gt; &lt;you_db_owner&gt; 127.0.0.1/32 trust

            在此之后你需要启动你的cron:

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

            不用密码也能正常工作

            【讨论】:

            • 而你刚刚破坏了系统安全性。适合开发盒,但没有别的。
            猜你喜欢
            • 2022-01-12
            • 2013-06-23
            • 1970-01-01
            • 1970-01-01
            • 2020-11-02
            • 1970-01-01
            • 2021-02-11
            • 1970-01-01
            相关资源
            最近更新 更多