RPyC 通过代理连接

时间:2021-07-26 18:23:34

标签: python ssl ssh rpyc

上下文

我有一个私人服务器,可以使用公共服务器作为代理访问

|------|       |------|       |-------|
|Remote|  ->   |Public|  ->   |Private|
|------|       |------|       |-------|

我可以使用

连接到私有服务器(正确设置了 ssh 密钥)
user@remote:$ ssh user@public
user@public:$ ssh user@private
user@private:$

或在一行中:

user@remote:$ ssh -o ProxyCommand='ssh -W %h:%p user@public' user@private

问题:

现在,我希望能够将 RPyC 请求从远程机器直接发送到专用服务器。

作为我为什么需要它的洞察力:远程机器有一个摄像头,而私人服务器有 gpus(两者之间有良好的连接)

到目前为止我尝试过的

我设法像 RPyC SSH connection 一样运行 SSL 连接

conn = rpyc.ssl_connect("private", port = 12345, keyfile="/path/to/my.key", certfile="/path/to/my.cert")

使用诸如 Create a self signed X509 certificate in Python 之类的东西获得的密钥和证书。

现在,如果客户端已经从公共服务器启动,它就可以工作了。我不知道如何从远程机器重定向 SSL 连接。

我尝试过的其他方法是将 Plumbum SshMachine 声明为零部署教程指出的 (https://rpyc.readthedocs.io/en/latest/docs/zerodeploy.html)

mach = SshMachine("user@private", ssh_opts=["-o ProxyCommand='ssh -W %h:%p user@public'"]

我可以使用它启动零部署服务器,但这并不令人满意,因为它使用了全新的(临时)python 副本,并且我需要使用从私有服务器(例如 cuda 设置)安装的库。

当然,我不能将这两种方法结合起来,因为 ssl_connect 需要一个字符串作为主机名,如果给定 SshMachine,则会引发异常。

约束

我既没有私人服务器也没有公共服务器的 root 访问权限,但是任何可以用 pip 安装的库都可以。我试过寻找例如在 paramiko 但我不知道从哪里开始...

更新

我找到了一个解决方案(参见答案 https://stackoverflow.com/a/68535406/6068769),但我还有一些问题,所以我还没有接受:

  • 我必须从线程服务器中删除身份验证器参数。使用 ssh 连接管道添加一个的语法(客户端+服务器)是什么?
  • 要使解决方案起作用,我需要在另一个终端 (ssh -o ....) 中的远程服务器和专用服务器之间打开 ssh 连接。否则,SshMachine 拒绝连接并出现以下错误:
plumbum.machine.session.SSHCommsError: SSH communication failed
Return code:   | 255
Command line:  | 'true '
stderr:        | /bin/bash: line 0 : exec: ssh -W private:22 user@public : not found

我可以接受事先打开连接,但如果我不需要它会更干净。

  • 是否有其他使用 SSL 协议的解决方案?

1 个答案:

答案 0 :(得分:0)

好吧,我离得不远,我只是错过了方法rpyc.ssh_connect

这是 MWE:

## Server
import rpyc

class MyService(rpyc.Service):
    def on_connect(self, conn):
        pass

    def on_disconnect(self, conn):
        pass

    def exposed_some_computations(self, input):
        return 2*input

if __name__ == "__main__":
        from rpyc.utils.server import ThreadedServer
        server = ThreadedServer(MyService, port=12345)
        server.start()
## Client
from plumbum import SshMachine
import rpyc

mach = SshMachine("user@private", ssh_opts=["-o ProxyCommand='ssh -W %h:%p user@public'"])

conn = rpyc.ssh_connect(mach, 12345)
result = conn.root.exposed_some_computations(18)