Вопрос о запуске SSH туннеля с использованием Python - PullRequest
3 голосов
/ 26 августа 2010

У меня возникли проблемы при запуске SSH-туннеля с HTTP-сервера RPC, написанного на Python.

Существует простой HTTP-сервер RPC, написанный на Python, на основе Python BaseHTTPServer. Как часть одной из служб, я хотел бы запустить SSH-туннель от сервера RPC к удаленной машине. Я использовал os.system для запуска туннеля SSH в скрипте Python, вызываемом вызовом RPC

os.system("ssh -f -n -N -L 127.0.0.1:%d:localhost:%d user@%s" % (6800, 9000, "remote.machine"))

На первый взгляд все выглядит хорошо, поскольку туннель запущен, и я могу им воспользоваться, но я заметил одну вещь. В дополнение к прослушиванию через порт 6800 SSH также начал прослушивать порт 8001 (порт, на котором работает HTTP-сервер RPC).

Вот вывод команды lsof относительно сервера RPC и SSH:

rpc.py    27763   usern    5u  IPv4 102130428       TCP 127.0.0.1:8001 (LISTEN)
ssh        1951   usern   14u  IPv4 102149728       TCP 127.0.0.1:6800 (LISTEN)
ssh        1951   usern    5u  IPv4 102130428       TCP 127.0.0.1:8001 (LISTEN)

Все работает до перезапуска сервера RPC. Во время перезапуска сервер RPC вынужден закрыть свое соединение с прослушивающим сокетом, но соединение SSH остается открытым, и сервер RPC не может снова запуститься на том же порту.

Кажется, что SSH-туннель также каким-то образом ассоциируется с fd прослушивающего сокета RPC-сервера.

Может кто-нибудь дать подсказки, как настроить SSH-туннель из сценария, при этом он прослушивает только предполагаемый порт (6800 в этом примере).

Ответы [ 3 ]

2 голосов
/ 29 апреля 2011

Вместо os.system (), попробуйте использовать subprocess.Popen () и установить close_fds = True (доступно в Python 2.4 и выше).

import subprocess    
subprocess.Popen("ssh -f -n -N -L 127.0.0.1:%d:localhost:%d user@%s" % (6800, 9000, "remote.machine"), shell=True, close_fds=True)

Теоретически, я считаю, что вы также должны иметь возможность использовать fcntl для установки дескриптора файла прослушивающего сокета на значение close-on-exec (FD_CLOEXEC) до вызова os.system ().

1 голос
/ 31 августа 2010

Рассматривали ли вы использование paramiko для вашего SSH?(зависит от PyCrypto, но в остальном чистый Python)

Это упростит управление соединением и, в зависимости от того, как ваш сервер работает с сокетами, вы можете просто настроить канал Paramiko и затем позволитьсервер обрабатывает его так же, как и любой другой прослушивающий сокет.

(в paramiko объекты транспорта представляют основные соединения SSH2, и для каждого транспорта вы можете создать несколько объектов канала, каждый из которых выступает в качестве вставкизамена обычного сокета Python)

Вот некоторые ресурсы на случай, если вы захотите взглянуть:

0 голосов
/ 27 августа 2010

Я подозреваю, что это как-то связано с разветвлением и последующим указанием ssh отсоединиться от вызывающего процесса ("-f").

Кроме того, не уверен, поможет ли это, но вы действительно должны использоватьмодуль подпроцесса, если ваш питон достаточно современный, чтобы иметь его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...