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")
或者,如果需要引号,则可能表示您使用了一些需要转义的特殊字符。您也可以尝试使用更简单的密码进行调试,然后再使用更强大的密码。
我正在尝试通过 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")
或者,如果需要引号,则可能表示您使用了一些需要转义的特殊字符。您也可以尝试使用更简单的密码进行调试,然后再使用更强大的密码。