通过 ssh 建立 TCP 端口隧道而不阻塞

发布于 2024-11-16 19:53:06 字数 873 浏览 8 评论 0原文

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

#!/bin/env python2.4

import pexpect, sys
child = pexpect.spawn('ssh -CfNL 0.0.0.0:3306:127.0.0.1:3306 [email protected]')
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 秒)。

有人可以给我一些关于如何避免阻塞的建议吗?

I'm trying setup a ssh tunnel via pexpect with following code:

#!/bin/env python2.4

import pexpect, sys
child = pexpect.spawn('ssh -CfNL 0.0.0.0:3306:127.0.0.1:3306 [email protected]')
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

What I expect is after password was sent and ssh tunnel established, the while loop exits so that I can continue processing with other business logic.

But the code above block util timeout (about 30 seconds) if ssh tunnel established.

Could anyone please give me some advice on how to avoid the block?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝影如岚 2024-11-23 19:53:06

我认为最简单的解决方案是使用 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 ssh -o ServerAliveInterval=30 < other_options_and_args> 确保尽快检测到隧道丢失,并防止其因路径中的任何 NAT 实现而老化(在不活动期间)。

I think the simplest solution is to use ssh host-key authentication, combined with backgrounding ssh with &... this is a very basic implementation, but you could enhance it to kill the process after you're done... also, note that I added -n to your ssh args, since we're backgrounding the process.

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"

Finally, if you don't already have ServerAliveInterval in your ssh_config, consider calling ssh as ssh -o ServerAliveInterval=30 <other_options_and_args> to make sure you detect loss of the tunnel as soon as possible, and to keep it from aging out of any NAT implementations in the path (during inactivity).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文