Использование paramiko для туннелирования порта MySql при запуске django - PullRequest
1 голос
/ 07 декабря 2010

Я пытаюсь подключиться к удаленному серверу MySql с моей локальной машины. Я хочу запускать его всякий раз, когда для константы DEBUG установлено значение true.

Вот сценарий:

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) Я не знаю, как и когда вызывать мою функцию форварда, когда рейзит Джанго.
2) Когда я получаю доступ к django локально и запускаю скрипт из консоли, я получаю следующее исключение:

исключение произошло во время обработка запроса от ('127.0.0.1', 41872) Traceback (большинство последний звонок последний): File "/Usr/lib/python2.6/SocketServer.py", строка 558, в process_request_thread Файл self.finish_request (запрос, адрес клиента) "/Usr/lib/python2.6/SocketServer.py", линия 320, в отделке по запросу Файл self.RequestHandlerClass (запрос, адрес клиента, self) "/Usr/lib/python2.6/SocketServer.py", строка 615, в init Файл self.handle () "/ home / omer / Aptana Studio 3 Рабочая область / Сайт / SRC / ssh_tunnel / tunnel.py», линия 51, в ручке verbose ('Туннель закрыт из% r'% (self.request.getpeername (),)) Файл "", строка 1, в getpeername
Файл "/usr/lib/python2.6/socket.py", строка 165, в _dummy ошибка повышения (EBADF, «Bad file descriptor») ошибка: [Errno 9] Bad file Дескриптор

Это была плохая идея для начала?
Должен ли я делать это вручную каждый раз?

Ответы [ 2 ]

2 голосов
/ 30 декабря 2011

Я не думаю, что это плохая идея.

Я не думаю, что вам нужно делать это вручную.

Исключением является ошибка в примере прямого кода Paramiko.Это было решено jhalcrow в запросе на получение ответа здесь:

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

В этом посте есть некоторый код, чтобы сделать это более управляемым событиями способом, т. Е. Если вы хотите вызвать его черезнекоторые перехваты веб-событий в вашем коде django или аналогичные:

Проблема с отключением туннеля Paramiko SSH

1 голос
/ 07 декабря 2010

хм, я не пробовал этого, но если вы работаете в Linux, не могли бы вы запустить

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

через системный вызов python, когда установлен DEBUG?

также, если выв Windows попробуйте замазку с переадресацией портов

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