使用CA签名密钥实现SSH端口转发:Paramiko问题及解决
如何在Paramiko中正确使用request_port_forward实现带CA签名的SSH端口转发?
我之前用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)
不过尝试使用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()
请问如何正确使用request_port_forward方法?
解决方案
感谢@Martin Prikryl的帮助。之前使用Transport.open_channel时误以为需要用forwarded-tcpip,尝试正确方法后终于成功,代码如下:
def forward_tunnel(local_port, remote_host, remote_port, transport: Transport): channel = transport.open_channel("direct-tcpip",(remote_host,remote_port),("127.0.0.1",local_port)) local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) local_socket.bind(("127.0.0.1", local_port)) local_socket.listen(1) conn, addr = local_socket.accept() timeout = 5 try: while True: r, w, x = select.select([channel, conn], [], [], timeout) if channel in r: data = channel.recv(1024) if len(data) > 0: conn.sendall(data) else: break if conn in r: data = conn.recv(1024) if len(data) > 0: channel.sendall(data) else: break finally: channel.close() conn.close() local_socket.close()
内容的提问来源于stack exchange,提问作者domagaja
相关产品推荐
相关产品推荐

