19.11. 使用SSH隧道的安全 TCP/IP 连接

可以使用SSH来加密客户端和PostgreSQL服务器之间的网络连接。如果处理得当,这将提供一个足够安全的网络连接,即使是对那些无 SSL 能力的客户端。

首先确认在PostgreSQL服务器的同一台机器上正确运行着一个SSH服务器,并且你可以使用ssh作为某个用户登入;然后,您可以建立到远程服务器的安全隧道。 安全隧道侦听本地端口并将所有流量转发到远程机器上的端口。 发送到远程端口的流量可以到达其 localhost 地址,或者如果需要,可以到达不同的绑定地址; 它似乎不是来自您的本地机器。 此命令创建从客户端机器到远程机器 foo.com 的安全隧道:

ssh -L 63333:localhost:5432 joe@foo.com

-L 参数中的第一个数字 63333 是隧道的本地端口号; 它可以是任何未使用的端口。 (IANA 保留端口 49152 到 65535 供私人使用。)此后的名称或 IP 地址是您要连接到的远程绑定地址,即 localhost,这是默认值。 第二个数字 5432 是隧道的远端,例如,您的数据库服务器正在使用的端口号。 为了使用此隧道连接到数据库服务器,您需要连接到本地机器上的端口 63333:

psql -h localhost -p 63333 postgres

对于数据库服务器,它将把你看做是连接到localhost绑定地址的主机foo.com上的用户joe,并且它将使用为该用户到该绑定地址的连接配置的任何身份验证程序。注意服务器将不会认为连接是 SSL 加密的,因为事实上SSH服务器和PostgreSQL服务器之间没有加密。这不应该造成任何额外的安全风险,因为它们在同一台机器上。

为了让隧道设置成功,你必须允许通过ssh作为joe@foo.com连接,就像你已经尝试使用ssh来创建一个终端会话。

你应当也已经设定好了端口转发:

ssh -L 63333:foo.com:5432 joe@foo.com

但是数据库服务器则将会看到连接从它的foo.com绑定地址进来,它没有被默认设置listen_addresses = 'localhost'所打开。这通常不是你想要的。

如果你必须通过某个登录主机到数据库服务器,一个可能的设置看起来像:

ssh -L 63333:db.foo.com:5432 joe@shell.foo.com

注意这种从shell.foo.comdb.foo.com的连接的方法将不会被 SSH 隧道加密。当网络被限制于各种方法时,SSH 提供了相当多的配置可能性。详情请参考 SSH 的文档。

提示

一些其他的应用可以提供安全隧道,它们使用和刚刚描述的 SSH 概念上相似的过程。