forward.py
89 lines
| 3.4 KiB
| text/x-python
|
PythonLexer
MinRK
|
r3571 | #!/usr/bin/env python | |
# | |||
Min RK
|
r3572 | # This file is adapted from a paramiko demo, and thus licensed under LGPL 2.1. | |
MinRK
|
r3571 | # Original Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com> | |
# Edits Copyright (C) 2010 The IPython Team | |||
# | |||
# Paramiko is free software; you can redistribute it and/or modify it under the | |||
# terms of the GNU Lesser General Public License as published by the Free | |||
# Software Foundation; either version 2.1 of the License, or (at your option) | |||
# any later version. | |||
# | |||
# Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY | |||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | |||
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | |||
# details. | |||
# | |||
# You should have received a copy of the GNU Lesser General Public License | |||
# along with Paramiko; if not, write to the Free Software Foundation, Inc., | |||
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |||
""" | |||
Sample script showing how to do local port forwarding over paramiko. | |||
This script connects to the requested SSH server and sets up local port | |||
forwarding (the openssh -L option) from a local port through a tunneled | |||
connection to a destination reachable from the SSH server machine. | |||
""" | |||
from __future__ import print_function | |||
MinRK
|
r3619 | import logging | |
MinRK
|
r3571 | import select | |
import SocketServer | |||
MinRK
|
r3619 | logger = logging.getLogger('ssh') | |
MinRK
|
r3571 | ||
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: | |||
MinRK
|
r3619 | logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host, | |
MinRK
|
r3571 | self.chain_port, | |
repr(e))) | |||
return | |||
if chan is None: | |||
MinRK
|
r3619 | logger.debug('Incoming request to %s:%d was rejected by the SSH server.' % | |
MinRK
|
r3571 | (self.chain_host, self.chain_port)) | |
return | |||
MinRK
|
r3619 | logger.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(), | |
MinRK
|
r3571 | 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() | |||
MinRK
|
r3619 | logger.debug('Tunnel closed ') | |
MinRK
|
r3571 | ||
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 | |||
Min RK
|
r3572 | ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever() | |
MinRK
|
r3571 | ||
MinRK
|
r3619 | __all__ = ['forward_tunnel'] |