通过 ssh 隧道使用套接字进行双向通信

Posted

技术标签:

【中文标题】通过 ssh 隧道使用套接字进行双向通信【英文标题】:Bi-directional communication using sockets via ssh tunnel 【发布时间】:2018-04-26 08:18:13 【问题描述】:

我有一个服务器主机 (S) 和一堆客户端 (C1, C2, C3, ...)。我想分别打开 S 和 C1、C2、C3 之间的连接以进行双向通信。理想情况下使用套接字。用于授权目的的 SSH 是首选。

理想情况下:

    客户端 C1 创建到 S 的 SSH 反向隧道,转发 C1 的端口,因此它可以在 S 上作为自己的端口访问。 在 C1 上运行的客户端程序创建一个套接字并绑定到转发端口。 在 S 上运行的服务器程序创建一个套接字并绑定到转发端口。 客户端和服务器可以交换数据。

这样的事情可能吗?我尝试使用 Python 编写草稿,但无济于事:

首先,我在 C1 上运行:ssh -N -R 9999:localhost:15432 root@example.com - OK

其次,在我运行的服务器上:

import socket

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 9999))
serversocket.listen(5)

while True:
    connection, address = serversocket.accept()
    buf = connection.recv(64)
    if len(buf) > 0:
        print buf
        break

第三,我在客户端运行:

import socket

clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 15432))
clientsocket.send('hello')

但我在客户端收到socket.error: [Errno 111] Connection refused。另外,如果我先设置隧道然后启动服务器程序,我会得到[Errno 98] Address already in use。它只在我第一次启动程序,然后设置隧道时才有效。

如果上述概念没有意义,您建议创建一种同步工具,以便任何客户端侦听来自服务器的查询并可以响应数据? (最好在 Python 中)。

提前致谢。

【问题讨论】:

【参考方案1】:

-N 并没有像您认为的那样做:它旨在让 ssh-destination 能够连接回发起者。但这会使发​​起方成为服务器。

听起来您应该使用-L 来简单地创建从客户端通过 ssh 隧道到服务器的连接。

为了演示:我有一个名为“bree”的本地服务器。在那台机器上,我执行(这也可能是你的 python 服务器在端口 9999 上监听):

nc -l 9999

现在在我的客户端计算机上,我在一个窗口中执行此操作(或者可以将其置于后台):

ssh -N -L 9999:bree:9999 bree

这表示:在本地(客户端)机器上监听 9999 端口,当与它建立连接时,通过隧道转发请求,并连接到 bree 上的 9999 端口。

现在,在客户端机器上的第二个窗口中,我执行:

nc localhost 9999

两个nc 实例已连接。

【讨论】:

以上是关于通过 ssh 隧道使用套接字进行双向通信的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python中使用套接字建立双向通信?

使用 socketpair 进行双向通信:挂起子进程的读取输出

Java:加密的服务器/客户端双向通信?

C#Socket通信

C#Socket通信

简述Socket(套接字)通信