我有一个使用 sshtunnel 库的工作 SSH 隧道转发器。
ssh_tunnel_server = {
'ssh_address_or_host': (remote_host, 22),
'ssh_username': ssh_user,
'ssh_pkey': ssh_key_path,
'remote_bind_address': ("localhost", 5900),
'local_bind_address': ('127.0.0.1', 0),
}
tunnel = SSHTunnelForwarder(**ssh_tunnel_server)
tunnel.start()
不幸的是,我现在还需要涵盖 CA 签名的 ssh 连接。
直接使用 paramiko 我发现只需提供 CA 公钥作为 key_filename 参数即可与 CA 建立简单的 ssh 连接。使用 open_session() 我还可以执行命令。
client.connect(ssh_host, port=ssh_port, username=ssh_user, pkey=private_key, key_filename=ssh_cert_path)
我尝试在IP地址和端口的任意组合中使用transport.request_port_forward函数,但失败了。
transport.request_port_forward("localhost", local_port,handler(channel, "127.0.0.1",remote_port))
它挂在 chan = Transport.accept(1000) 处。
代码是:
def forward_tunnel(local_port, remote_host, remote_port, transport: Transport):
transport.request_port_forward("", local_port)
while True:
chan = transport.accept(1000)
if chan is None:
continue
thr = threading.Thread(target=handler, args=(chan, remote_host, remote_port))
thr.setDaemon(True)
thr.start()
如何正确使用请求端口转发方法?
Transport.request_port_forward
用于远程端口转发。
您原来的 sshtunnel 代码正在实现 local 端口转发。在实现 local 端口转发时,您需要监听(接受)local 连接。接受连接后,需要调用
Transport.open_channel
创建 direct-tcpip
通道。并将所有本地连接数据转发到通道或从通道转发所有本地连接数据。检查 sshtunnel 中的 _ForwardHandler
类(您也许可以重用它或至少重用它的代码)。