SSH隧道用于PostgreSQL - 连接被拒绝

3
我第一次尝试在远程/云VPS上设置应用程序(我使用的是Digital Ocean)。我试图从我的客户端创建一个SSH隧道到远程数据库。由于我以前没有尝试过这种操作,因此我参考了这篇文章这篇文章这篇文章
阅读完文章后,我在自己的客户端/本地机器上运行了以下命令:
 ssh -L 5433:localhost:5432 user@REMOTE_IP

然后我尝试连接:

 psql -h localhost -p 5433 postgres;

然而,我收到了以下错误信息:
psql: could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5433?

据我所知,我远程服务器上的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

我把postgresql.conf文件中的"listen_addresses"改成了*。
    # - Connection Settings -

listen_addresses = '*'          # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
port = 5432                             # (change requires restart)
max_connections = 100                   # (change requires restart)

我曾试过将127.0.0.1替换为localhost,但没有成功。

欢迎提出任何建议。我不熟悉SSH隧道等技术。

谢谢。 编辑:

根据@drdaeman的建议,我运行了以下命令:

sudo ssh -N -vvv -L 5433:localhost:5432 user@host

最后几条调试信息如下:

    debug1: Local forwarding listening on 127.0.0.1 port 5433.
debug2: fd 5 setting O_NONBLOCK
debug3: fd 5 is O_NONBLOCK
debug1: channel 1: new [port listener]
debug2: fd 3 setting TCP_NODELAY
debug3: ssh_packet_set_tos: set IP_TOS 0x10
debug1: Requesting no-more-sessions@openssh.com
debug3: send packet: type 80
debug1: Entering interactive session.
debug1: pledge: network
debug3: receive packet: type 80
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0

请输出以下命令sudo netstat -ltpn | grep 5432的结果:

tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      5835/postgres 

它停在那里,不响应任何命令。
感谢您的任何指导。

重启服务器? - sibert
谢谢sibert。我尝试重新启动PostgreSQL和服务器本身,但没有变化。 - KellyM
1个回答

4
根据您的描述,我认为一切都很正常 - 我没有看到问题出在哪里,但是您运行的命令和配置看起来正确。以下是您可以采取的一般步骤来诊断此问题:
首先,请检查您的PostgreSQL服务器是否正在侦听。在您的服务器上运行以下命令:
$ sudo netstat -ltpn | grep 5432

(或者您可以使用iproute2中的ss -ltpn代替旧版的netstat
如果您没有看到任何内容,这意味着没有进程在tcp/5432上监听。您可以尝试查看PostgreSQL是否在任何地方监听:
$ sudo netstat -lpn | grep postgre

如果不行的话,请检查你的服务器是否实际在运行(这取决于操作系统和分发版,但首先检查ps aux输出),并检查你的服务器日志(可能在/var/log中)是否有任何问题。
然后,请确保你没有意外在服务器上运行psql(当你SSH时,它也会打开shell会话,除非你指定了-N标志)。你需要在本地机器上运行它;)
接下来,你还可以考虑将-v(甚至是-vvv)添加到你的ssh命令中——它会产生大量有用的调试信息,例如正常操作看起来像这样:
debug1: Connection to port 5433 forwarding to localhost port 5432 requested.
debug1: channel 3: new [direct-tcpip]
debug1: channel 3: free: direct-tcpip: listening port 5433 for localhost port 5432, connect from ::1 port 60039 to ::1 port 5433, nchannels 4

如果你看到类似于channel 3: open failed: connect failed: Connection refused的信息,这意味着PostgreSQL拒绝了连接 - 你需要检查其日志以了解其原因 - 可能是在配置中启用了log_connectionslog_disconnections之后(不要忘记重新加载配置)。

2
哦,别忘了重新配置listen_addresses,这样你的PostgreSQL实例就不会暴露在世界上了。如果你使用SSH隧道,你不需要它监听0.0.0.0和/或[::]。它只需要监听127.0.0.1和/或::1即可。 - drdaeman
非常感谢。建议非常好。我已经添加了调试输出。 - KellyM
1
@KellyMarchewa 有两个问题需要进一步诊断:1)您是否检查了服务器是否正在正确监听?2)您显示的ssh输出是正常的(是的,它会像这样卡住 - 当您不再需要它时,可以使用ctrl+c终止它),但是当您运行psql时,ssh输出是否发生任何变化?当您这样做时,它应该说例如debug1: Connection to port 5433 forwarding to localhost port 5432 requested.。端口转发连接仅在请求时建立,而不是在运行ssh并连接时建立。 - drdaeman
1
好的,你的Postgres正在监听,ssh -vvv -N -L 5433:127.0.0.1:5432 your.server.example.org 应该可以工作。你可以尝试使用 telnet localhost 5433 而不是 psql -h 127.0.0.1 -p 5433 postgres 来查看是否连接成功。注意ssh输出 - 如果有任何连接尝试,它必须显示一些内容。如果没有,则表示没有连接(或者出现了某些问题)。既然你已经将答案标记为接受,我希望你已经找到了确切的原因。我怀疑这可能与 psql 调用有关,或者是IPv4/IPv6混合问题(例如,ssh尝试连接到 ::1 而不是 127.0.0.1)。 - drdaeman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接