Туннелирование TCP портов через ssh без блокировки - PullRequest
3 голосов
/ 22 июня 2011

Я пытаюсь настроить ssh-туннель через pexpect с помощью следующего кода:

#!/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 завершается, чтобы я мог продолжить обработку с другой бизнес-логикой.

Но код выше блокирует время ожидания (около 30 секунд), если установлен ssh-туннель.

Может ли кто-нибудь дать мне совет, как избежать блока?

1 Ответ

3 голосов
/ 22 июня 2011

Я думаю, что самое простое решение - использовать 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"

Наконец, если у вас еще нет ServerAliveInterval в вашем ssh_config, рассмотрите возможность вызова ssh как ssh -o ServerAliveInterval=30 <other_options_and_args>, чтобы убедиться, что вы обнаружили потерю туннеля как можно скорее, и чтобы предотвратить его старение. из любых реализаций NAT в пути (во время бездействия).

...