2010-02-24 3 views
2

Целью является создание n числа туннелей ssh ​​между спутниковыми серверами и централизованной базы данных реестра. Я уже установил аутентификацию открытого ключа между моими серверами, чтобы они просто вошли в систему без подсказок с паролем. Что теперь ? Я пробовал Парамико. Это кажется приличным, но довольно сложно просто настроить базовый туннель, хотя код exmplaes будет оценен. Я пробовал Autossh, и он умирает через 2 минуты после создания рабочего туннеля, причудливого! Надеюсь, кто-то может помочь мне с простым фрагментом кода, который я могу демонизировать и контролировать с помощью супервизора или monit.Проблема, связанная с туннелями SSH от python

ответ

2

Есть особая причина, чтобы не только сделать это с ssh, обычная

(ssh -L <localport>:localhost:<remoteport> <remotehost>) 

менуэт? Во всяком случае, this script является примером локальной переадресации портов (туннелирование АКА).

+0

Alex Я получил эту часть вниз. Просто туннели создаются «на лету» на основе изменений состояния клиентской стороны. Поэтому его нужно как-то открыть и закрыть python. – jaycee

+0

ОК, так что случилось с примером, на который я указал (изнутри самого парамико)? –

5

Вот вырезанная версия script, которую Алекс указал на вас.

Он просто подключается к 192.168.0.8 и вперед порт от 192.168.0.6 на локальный

import select 
import SocketServer 
import sys 
import paramiko 

class ForwardServer(SocketServer.ThreadingTCPServer): 
    daemon_threads = True 
    allow_reuse_address = True 

class Handler (SocketServer.BaseRequestHandler): 
    def handle(self): 
     try: 
      chan = self.ssh_transport.open_channel('direct-tcpip', (self.chain_host, self.chain_port), self.request.getpeername()) 
     except Exception, e: 
      print('Incoming request to %s:%d failed: %s' % (self.chain_host, self.chain_port, repr(e))) 
      return 
     if chan is None: 
      print('Incoming request to %s:%d was rejected by the SSH server.' % (self.chain_host, self.chain_port)) 
      return 

     print('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port))) 
     while True: 
      r, w, x = select.select([self.request, chan], [], []) 
      if self.request in r: 
       data = self.request.recv(1024) 
       if len(data) == 0: 
        break 
       chan.send(data) 
      if chan in r: 
       data = chan.recv(1024) 
       if len(data) == 0: 
        break 
       self.request.send(data) 
     chan.close() 
     self.request.close() 
     print('Tunnel closed from %r' % (self.request.getpeername(),)) 

def main(): 
    client = paramiko.SSHClient() 
    client.load_system_host_keys() 
    client.set_missing_host_key_policy(paramiko.WarningPolicy()) 
    client.connect("192.168.0.8") 

    class SubHandler(Handler): 
     chain_host = "192.168.0.6" 
     chain_port = 3389 
     ssh_transport = client.get_transport() 

    try: 
     ForwardServer(('', 3389), SubHandler).serve_forever() 
    except KeyboardInterrupt: 
     sys.exit(0) 

if __name__ == '__main__': 
    main() 
+0

gnibbler спасибо. Я попробую. Это больше похоже на то, что я искал. Спасибо Алексу! – jaycee