PostgreSQL/psycopg2 使用 SSH 隧道的密码验证

PostgreSQL/psycopg2 Password Authentication using SSH Tunneling

我正在尝试通过 ssh 隧道连接到 PostgreSQL 数据库。它设置为侦听端口 3333 并转发到具有数据库的计算机上的端口 5432。我可以通过隧道使用带有密码身份验证的 psql 命令进行连接,但是由于某种原因,当我尝试通过隧道使用 psycopg2 进行连接时,我收到错误 FATAL: password authentication failed for user database_user。我试过在用户名和密码周围加上引号,但没有用。

成功psql命令:

psql -h localhost -p 3333 -U database_name database_user 
#This command brings up password prompt

pscyopg2 命令失败:

psycopg2.connect("dbname='database_name' user='database_user' host='localhost' password='database_password' port=3333")

输出:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/database_user/.local/share/virtualenvs/project-QNhT-Vzg/lib/python3.7/site-packages/psycopg2/__init__.py", line 126, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: FATAL:  password authentication failed for user "database_user"
FATAL:  password authentication failed for user "database_user"

这里是我的pg_hba.conf的一部分供参考:

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5

在调试连接问题时,记住我们在到达服务之前必须经过哪些层总是值得的。当您连接 PostgreSQL 服务时,至少会有三层:

  • 网络:防火墙、NAT、端口转发
  • PostgreSQL ACL
  • PostgreSQL 登录

了解导致问题的层很重要,PostgreSQL 客户端(在您的场景中包含在 psycopg2 中)错误将通过发出临时错误消息来帮助您解决此问题:

  • 网络问题一般会出现典型的:Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?也就是说你根本没有连接PostgreSQL服务,问题出在服务之前;
  • ACL 问题通常会引发一个典型的问题:No pg_hba.conf entry for host <hostname>, user <username>, database <database> 这意味着您确实连接了 PostgreSQL 服务,但该连接在 ACL 中未被引用为有效;
  • 登录问题通常会引发您遇到的错误:password authentication failed for user "<user>" 这意味着您确实连接了 PostgreSQL 服务并且连接符合 ACL 条目但身份验证失败。

在后面的场景中,知道触发的条目很重要,因为它定义了身份验证模式。在你的例子中,它是一个 md5 条目(因为在 peer 模式下没有密码并且你的 SSH 隧道应该映射本地主机所以你被视为 host 而不是 local 对于 postgreSQL 的观点):

host    all             all             127.0.0.1/32            md5

显然您的密码与您期望的不同。要解决此问题,请确保:

  • 你设置了postgreSQL用户的密码,并检查了LOGIN权限(不是unix/SSH用户,有不同的概念);
  • 您在 psycopg2 连接中使用了相同的密码,那么您一定能够连接;

阅读您的评论,您的密码中似乎也有 ' 引号。所以你的连接密码可能是:

psycopg2.connect("dbname='database_name' user='database_user' host='localhost' password="'database_password'" port=3333")

或者,如果需要引号,则可能表示您使用了一些需要转义的特殊字符。您也可以尝试使用更简单的密码进行调试,然后再使用更强大的密码。