在没有阻塞的情况下通过ssh隧道传输TCP端口



我正在尝试使用以下代码通过pexpect设置ssh隧道:

#!/bin/env python2.4
import pexpect, sys
child = pexpect.spawn('ssh -CfNL 0.0.0.0:3306:127.0.0.1:3306 user@server.com')
child.logfile = sys.stdout
while True:
    code = child.expect([
        'Are you sure you want to continue connecting (yes/no)?',
        'password:',
        pexpect.EOF,
        pexpect.TIMEOUT
    ])
    if code == 0:
        child.sendline('yes')
    elif code == 1:
        child.sendline('passwordhere')
    elif code == 2:
        print ".. EOF"
        break
    elif code == 3:
        print ".. Timeout"
        break

我所期望的是,在发送密码并建立ssh隧道之后,while循环退出,这样我就可以继续处理其他业务逻辑了。

但是如果ssh隧道建立,上面的代码会阻止util超时(大约30秒)。

有人能给我一些如何避开街区的建议吗?

我认为最简单的解决方案是使用ssh主机密钥身份验证,并将ssh&结合起来。。。这是一个非常基本的实现,但您可以增强它以在完成后终止流程。。。另外,请注意,我将-n添加到了您的ssh参数中,因为我们正在后台处理该过程。

import subprocess
USER = 'user'
HOST = 'server.com'
cmd = r"""ssh -CfNnL 0.0.0.0:3306:127.0.0.1:3306 %s@%s &""" % (USER, HOST)
subcmd = cmd.split(' ')
retval = subprocess.Popen(subcmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stat = retval.poll()
while stat == None:
    stat = retval.poll()
print "ssh in background"

最后,如果您的ssh_config中还没有ServerAliveInterval,请考虑将ssh调用为ssh -o ServerAliveInterval=30 <other_options_and_args>,以确保尽快检测到隧道丢失,并防止它在路径中的任何NAT实现之外老化(在不活动期间)。

最新更新