问题描述
我正在尝试在host1和host3之间打开一条双向隧道,中间是host2。
host1 <--> host2 <--> host3
这是我在host1上运行的(阻塞)bash命令,以转发端口51672。
ssh -g -L 51672:host2:51672 host2_username@host2 \'/tmp/sshpass -p host3_pass ssh -g -L 51672:host3:51672 host3_username@host3 \'\'"while true; do : ; sleep 5; done"\'\'\'
我有一个脚本在host3
上运行,侦听端口51672。当我在host1
上创建TCP套接字并连接到host2:51672
时,我可以通过该主机名与host3上的脚本进行通信套接字。
在下一步中,我尝试将其移植到python中并使用sshtunnel
包。我有些困惑,here中的哪个选项等效于我的情况。
这是我的第一次尝试:
import paramiko
import sshtunnel
with sshtunnel.open_tunnel(
ssh_address_or_host=(host2,22),ssh_username=host2_username,ssh_password=host2_pass,local_bind_address=('0.0.0.0',51672),remote_bind_address=(host3,block_on_close=False
) as tunnel1:
log.info('Tunnel to host2 is established.')
with sshtunnel.open_tunnel(
ssh_address_or_host=('localhost',tunnel1.local_bind_port),ssh_username=host3_username,ssh_password=host3_password,block_on_close=False
) as tunnel2:
log.info('Tunnel to host3 is established.')
while True:
time.sleep(1)
我可以确认从host1到host2的隧道是打开的,因为以下命令在host1上返回0。
nc -z localhost 51672
但是,host2和host3之间的隧道似乎不起作用。
解决方法
第一步是建立SSH隧道。然后,您将使用自定义端口。
更简单的方法(虽然不是最佳方法)是:
- 打开与
host2
的直接SSH连接。 - 通过
host1:A
连接将本地host2
端口转发到host3:22
- 使用转发的端口
host3
打开到host1:A
的SSH连接。 - 通过
host1:B
将另一个本地host3
端口转发到host3:51672
。 - 连接到
host1:B
进入host3:51672
。
但是实际上您不需要进行第一次物理端口转发,可以使用Nested SSH using Python Paramiko中所示的sock
方法。
(我相信,即使是您原来的ssh
方法,由于具有两次转发功能,也不必要地变得复杂)