如何通过多跳 SSH 隧道转发 TCP 连接(特别是 MyQSL 客户端-->服务器)?

如何通过多跳 SSH 隧道转发 TCP 连接(特别是 MyQSL 客户端-->服务器)?

我想打开与远程 MySQL 数据库的连接。此数据库位于不同网络上的私有子网中,因此我无法直接打开与它的连接。MySQL 服务器上的远程 SSH 访问也已完全禁用。

我当前的流程是这样的:

我通过公共服务器 HOST_1 打开 SSH 隧道。从该隧道,我打开与 MySQL 服务器 (MYSQL_HOST) 位于同一子网的服务器 (HOST_2) 的 SSH 连接。使用我当时打开的 SSH 会话(在 HOST_2 上),我使用 MySQL 客户端打开与 MYSQL_HOST 的连接。

下面是当前所做工作的非常粗略的图表:

当前连接图

要做的就是使用我本地计算机的 MySQL 客户端连接到 127.0.0.1:3306,并让连接从 HOST_1 一直通过隧道传输到 HOST_2,然后到 MYSQL_HOST,就好像我首先从 127.0.0.1 运行 MySQL 服务器一样。

同样,我无法从 HOST_2 打开通往 MYSQL_HOST 的 SSH 隧道,因此无法从那里建立隧道。我需要弄清楚如何通过 SSH 隧道将 MySQL 客户端连接转发到 HOST_2,然后让 HOST_2 将 MySQL 客户端连接转发到 MYSQL_HOST。

我想我可以使用redirnc来实现这一点。但我不确定如何做。

我读过几个问题,但对它们了解不够多,无法将这些信息整合在一起来得到我想要的答案:

  1. 通过多跳的 SSH 隧道
  2. 通过 SSH 隧道的 UDP 流量
  3. https://unix.stackexchange.com/questions/267090/reroute-mysql-connection-through-external-machine

我知道此页面上再次包含信息,这会对我有帮助,但我不知道如何使用它:http://sshmenu.sourceforge.net/articles/transparent-mulithop.html

谢谢!

答案1

该答案假设 sshd 配置为允许在 HOST_1 和 HOST_2 上进行端口转发。

您已经找到了您需要的大部分内容(第一个链接中 Mika Fischer 的回答中的第二个选项)。

从 localhost 到 host1 以及从 host1 到 host2 的隧道:

ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2 这将打开从 localhost 到 host1 的隧道和从 host1 到 host2 的另一条隧道。但是 host1 上的任何人都可以使用到 host2:1234 的端口 9999。这可能是问题,也可能不是问题。

这个想法是将端口转发串联在一起(即,将本地端口转发到远程端口,然后将其转发到更远程的端口)。

对于你的例子,命令将是

ssh -tt -L 3306:localhost:XXXX [user@]HOST_1 ssh -L XXXX:MYSQL_HOST:3306 [user@]HOST_2其中 XXXX 是任何大于 1024 且尚未使用的端口(使用相同的数字来替换两个实例)

执行后,除非您使用 SSH 密钥进行无密码登录,否则系统会要求您输入两次密码(一次输入 HOST_1,一次输入 HOST_2)。只要您通过 HOST_1 保持与 HOST_2 的连接,隧道就会一直有效。

具体细节如下:

ssh你正在执行的是本地 ssh 客户端吗

-tt强制分配伪 tty(参见由于 stdin 不是终端,因此不会分配伪终端为什么可能需要这样做)

-L 3306:localhost:XXXX [user@]HOST_1告诉您的本地 ssh 客户端将本地系统上的 3306 转发到 SSH 连接另一端的“localhost”上的端口 XXXX。您只需指定user@本地计算机上的用户是否与您在 HOST_1 上连接的用户不同。更一般地,您可以指定 3306 以外的本地端口,但您需要将 mysql 客户端指向 127.0.0.1:[您选择的端口]。

ssh(第二个)您可能知道,ssh 有一个选项可以运行单个命令,而不是启动 shell。您将使用该选项在 HOST_1 上执行另一个 SSH 会话,这将创建端口转发链中的下一个链接。

-L XXXX:MYSQL_HOST:3306 [user@]HOST_2由于此 ssh 会话在 HOST_1 上执行,因此会将本地端 (HOST_1) 上的 XXXX(从客户端上的 3306 转发)转发到远程端 (HOST_2) 上的 MYSQL_HOST 上的端口 3306。您只需指定user@HOST_1 上的用户是否与您在 HOST_2 上连接的用户不同。

如果需要额外的跳数,则ssh -L XXXX:localhost:XXXX hostX在中间为每个跳数添加实例,只要 XXXX 是路径中每个服务器上的可用端口即可。

答案2

由于您通过 HOST_1 代理与 HOST_2 的 SSH 连接,因此您只需一个-L端口转发即可完成此操作:

ssh -A -o'ProxyCommand=ssh -q 用户@HOST_1 nc %h %p' 用户@HOST_2 -L 3306:MYSQL_HOST:3306

这基本上就是您现在正在做的事情:通过与 HOST_1 的 ssh 连接打开与 HOST_2 的 ssh 连接,然后将来自本地主机 3306 的连接转发到 MYSQL_HOST:3306。请注意,MYSQL_HOST 将看到来自 HOST_2 的连接,因为这是它退出隧道并返回正常 TCP 连接的地方。

顺便说一句,如果你在本地计算机和 HOST_1 上都安装了 OpenSSH 7.3 或更高版本,则可以使用-J选项(或ProxyJumpssh 配置文件中的指令)

ssh -A -J 用户@HOST_1 用户@HOST_2 -L 3306:MYSQL_HOST:3306

这也使得通过多个 SSH 代理变得更加容易:

ssh -A -J 用户@HOST_1,用户@HOST_3,用户@HOST_3 用户@HOST_4 -L 3306:MYSQL_HOST:3306

相关内容