本地轉寄代碼forward.py
#!/usr/bin/env pythonimport osimport socketimport selectimport SocketServerimport sysimport paramikodef verbose(s): print sclass ForwardServer (SocketServer.ThreadingTCPServer): daemon_threads = True allow_reuse_address = Trueclass 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: verbose('Incoming request to %s:%d failed: %s' % (self.chain_host, self.chain_port, repr(e))) return if chan is None: verbose('Incoming request to %s:%d was rejected by the SSH server.' % (self.chain_host, self.chain_port)) return verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), chan.getpeername(), (self.chain_host, self.chain_port))) try: 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) except Exception as e: verbose('Forward request to %s:%d was failed.' % (self.chain_host, self.chain_port)) verbose('Tunnel closed from %r' % (self.request.getpeername(),)) chan.close() self.request.close()forwardServer=None;def forward_tunnel(local_port, remote_host, remote_port, transport): class SubHander (Handler): chain_host = remote_host chain_port = remote_port ssh_transport = transport global forwardServer forwardServer=ForwardServer(('', local_port), SubHander); forwardServer.serve_forever();def stopForward(): if forwardServer: forwardServer.shutdown();def forward(local_port,ssh_host,ssh_port,username,password,remote_host,remote_port): client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.WarningPolicy()) try: client.connect(ssh_host, ssh_port, username,password) except Exception, e: print '*** Failed to connect to %s:%d: %r' % (ssh_host, ssh_port, e) sys.exit(1) verbose('Now forwarding port %d to %s:%d ...' % (local_port, remote_host, remote_port)) try: forward_tunnel(local_port, remote_host, remote_port, client.get_transport()) except KeyboardInterrupt: print 'C-c: Port forwarding stopped.' sys.exit(0)if __name__ == '__main__': forward(3306,"ssh.company.com",22,"admin","pwd","172.24.23.21",3306)
先啟動轉寄服務。
通過代理串連資料庫伺服器 test.py:
conn=MySQLdb.connect(host="127.0.0.1", port=3306, user="user", passwd="pwd", db="db", connect_timeout=1000, charset="GBK")cur=conn.cursor()cur.execute("""select * from temp limit 5""");for c in cursor: print ccur.close();conn.close()
注意,這裡是先向本地3306發送資料,本地轉寄服務接收到資料後會轉寄給SSHD服務,SSHD服務會幫我們將資料轉寄到目標伺服器,得到響應後再原路返回。