使用 SSH 隧道的 PostgreSQL/psycopg2 密码验证
Posted
技术标签:
【中文标题】使用 SSH 隧道的 PostgreSQL/psycopg2 密码验证【英文标题】:PostgreSQL/psycopg2 Password Authentication using SSH Tunneling 【发布时间】:2020-05-31 19:27:19 【问题描述】:我正在尝试通过 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
【问题讨论】:
这不足以找出您的问题。有防火墙吗? postgres 是否在监听接口?您能否解决这些问题并添加特定的 Python 代码和错误跟踪,因为它肯定包含有关问题所在的信息。 看来您的密码不是您想的那样。您可以访问 postgres,并且 ACL (pg_hba) 是正确的。错误很典型:密码不匹配。你确定没有错别字?你设置了这个密码吗?当您尝试使用 psql 时,您是处于本地模式还是主机模式? 不知何故它最终通过使用单引号中的密码创建一个环境变量来工作。如果您回答有关检查密码的问题,我会将其标记为已接受的答案。谢谢你的帮助! @jlandercy 您好 Gunnar,添加了包含更多详细信息和检查清单的答案。干杯 【参考方案1】:在调试连接问题时,总是值得记住在到达服务之前我们必须经过哪些层。当你连接 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")
或者如果需要引号,它可能表明您使用了一些需要转义的特殊字符。您还可以尝试使用更简单的密码进行调试,然后使用更强的密码。
【讨论】:
以上是关于使用 SSH 隧道的 PostgreSQL/psycopg2 密码验证的主要内容,如果未能解决你的问题,请参考以下文章
PyCharm SSH 隧道通过本地 ssh 配置 (~/.ssh/config)