2010-02-24 93 views
2

目標是在衛星服務器和中央註冊表數據庫之間設置n個ssh隧道。我已經在我的服務器之間建立了公鑰驗證,因此他們只需登錄即可,無需密碼提示。怎麼辦 ?我試過帕拉米科。它看起來很體面,但爲了建立一個基本的隧道而變得相當複雜,儘管代碼exmplaes會被誇大。我嘗試過Autossh,它在建立工作隧道2分鐘後死亡,奇怪!希望有人可以用簡單的代碼片段來幫助我,我可以用supervisord或monit來進行守護和監視。源自python的SSH隧道的問題

回答

2

是否有特殊原因不只是ssh做到這一點,通常

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

小步舞曲?無論如何,this script是本地端口轉發(AKA隧道)的一個例子。

+0

亞歷克斯我已經得到了一部分下來。只是隧道是基於客戶端狀態變化而實時創建的。所以它需要以某種方式被python打開和關閉。 – jaycee

+0

好的,我指出的例子(來自paramiko本身)有什麼問題? –

5

這是Alex向您指出的script的簡化版本。

它只是連接到192.168.0.8並轉發端口從192.168.0.6爲localhost

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