2010-12-07 73 views
1

我想从本地机器连接到远程MySql服务器。 我想在DEBUG常量设置为true时运行它。当django启动时使用paramiko来隧道MySql端口

这里的脚本:

import select 
import SocketServer 
import sys 
import threading 
import paramiko 

SSH_PORT = 22 
DEFAULT_PORT = 4000 

g_verbose = True 


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: 
      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))) 
     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() 
     verbose('Tunnel closed from %r' % (self.request.getpeername(),)) 


def forward_tunnel(local_port, remote_host, remote_port, transport): 
    # this is a little convoluted, but lets me configure things for the Handler 
    # object. (SocketServer doesn't give Handlers any way to access the outer 
    # server normally.) 
    class SubHander (Handler): 
     chain_host = remote_host 
     chain_port = remote_port 
     ssh_transport = transport 
    ForwardServer(('', local_port), SubHander).serve_forever() 


def verbose(s): 
    if g_verbose: 
     print s 


HELP = """\ 
Set up a forward tunnel across an SSH server, using paramiko. A local port 
(given with -p) is forwarded across an SSH session to an address:port from 
the SSH server. This is similar to the openssh -L option. 
""" 

def forward(): 
    client = paramiko.SSHClient() 
    client.load_system_host_keys() 
    client.set_missing_host_key_policy(paramiko.WarningPolicy()) 

    try: 
     print 'connecting' 

     client.connect('*******', username='***', password='****!') 

     print 'connected' 
    except Exception, e: 
     print '*** Failed to connect to %s:%d: %r' % ('*****', 22, e) 
     sys.exit(1) 

    try: 
     forward_tunnel(3306, '127.0.0.1', 3306, client.get_transport()) 
    except SystemExit: 
     print 'C-c: Port forwarding stopped.' 
     sys.exit(0) 

我这里有两个问题:
1)我不知道如何和何时打电话给我转发功能时,Django的提高。
2)当我访问本地Django和运行从控制台我得到下面的异常脚本:

exception happened during processing of request from ('127.0.0.1', 41872) Traceback (most recent call last): File "/usr/lib/python2.6/SocketServer.py", line 558, in process_request_thread self.finish_request(request, client_address) File "/usr/lib/python2.6/SocketServer.py", line 320, in finish_request self.RequestHandlerClass(request, client_address, self) File "/usr/lib/python2.6/SocketServer.py", line 615, in init self.handle() File "/home/omer/Aptana Studio 3 Workspace/Website/src/ssh_tunnel/tunnel.py", line 51, in handle verbose('Tunnel closed from %r' % (self.request.getpeername(),)) File "", line 1, in getpeername
File "/usr/lib/python2.6/socket.py", line 165, in _dummy raise error(EBADF, 'Bad file descriptor') error: [Errno 9] Bad file descriptor

这是一个坏主意,开始?
我应该每次都手动做这个吗?

+0

当你启动服务器,而不是创建一个SSH会话。使用shell脚本。看看使用SSH主机密钥认证。这使您可以让脚本连接ssh会话而不要求输入用户名和密码。 – kevpie 2010-12-07 11:33:37

+0

@kevpie:为什么我做了一个坏主意? – 2010-12-07 13:04:20

回答

2

我不认为这是一个坏主意。

我不认为你需要手动完成。

异常是paramiko的正向代码示例中的一个错误。这已经通过jhalcrow在拉要求在此解决:

https://github.com/paramiko/paramiko/pull/36

这个职位有一些代码,做一个更加事件驱动的方式,也就是说,如果你想通过一些网络事件挂钩来调用它的Django的代码或类似:

Paramiko SSH Tunnel Shutdown Issue

1

姆,我没有尝试,但如果你是在Linux上,你可以通过Python的系统调用运行

ssh -L 3306:localhost:3306 remote.host.ip 

当DEBUG设置?

另外,如果你在Windows上,尝试用腻子端口转发