当 django 启动时使用 paramiko 隧道 MySql 端口

发布于 2024-10-06 19:55:57 字数 4043 浏览 4 评论 0原文

我正在尝试从本地计算机连接到远程 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)我不知道当 django 引发时如何以及何时调用我的转发函数。
2)当我在本地访问 django 并从控制台运行脚本时,出现以下异常:

异常发生在 处理请求来自 ('127.0.0.1', 41872) 回溯(大多数 最近通话最后):文件 “/usr/lib/python2.6/SocketServer.py”, 第 558 行,在 process_request_thread 中 self.finish_request(请求, client_address) 文件 “/usr/lib/python2.6/SocketServer.py”, 第 320 行,在 finish_request 中 self.RequestHandlerClass(请求, client_address, 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(),)) 文件 getpeername 中的“”,第 1 行
文件“/usr/lib/python2.6/socket.py”, 第 165 行,在 _dummy 中 引发错误(EBADF,'错误文件描述符')错误:[Errno 9] 错误文件 描述符

这是一个坏主意吗?
我应该每次都手动执行此操作吗?

I am trying to connect to a remote MySql server from my local machine.
I want to run it whenever the DEBUG constant is set to true.

Here's the script:

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)

I have two problems here:
1) I don't know how and when to call my forward function when django raises.
2) When I access django locally and run the script from the console I get the following exception:

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

Was this a bad idea to begin with?
Should I do this manually every time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一杯敬自由 2024-10-13 19:55:57

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

我认为您不需要手动执行此操作。

例外是 paramiko 的前向代码示例中的错误。 jhalcrow 在此处的拉取请求中已解决此问题:

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

这篇文章有一些代码可以以更多事件驱动的方式来完成它,即如果你想通过 django 代码中的一些 Web 事件挂钩来调用它或类似的:

Paramiko SSH 隧道关闭问题

I don't think it's a bad idea.

I don't think you need to do it manually.

The exception is a bug in paramiko's forward code sample. This has been addressed by jhalcrow in the pull request here:

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

This post has some code to do it in a more event driven way, i.e if you wanted to call it via some web event hooks in your django code or the like:

Paramiko SSH Tunnel Shutdown Issue

眼眸印温柔 2024-10-13 19:55:57

嗯,我没有尝试这个,但是如果你在linux上,你可以

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

在设置DEBUG时运行python系统调用吗?

另外,如果您使用的是 Windows,请尝试使用 putty 进行端口转发

humm, i didn't try this, but if you are on linux, could you run

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

through python system call when DEBUG is set?

also if you are on Windows, try putty with port forwarding

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文