The object is to set up n number of ssh tunnels between satellite servers and a centralized registry database. I have already set up public key authentication between my servers so they just log 开发者_高级运维right in without password prompts. Now what ? I've tried Paramiko. It seems decent but gets pretty complicated just to set up a basic tunnel, although code exmplaes would be aprreciated. I've tried Autossh and it dies 2 minutes after setting up a working tunnel, bizarre! Hopefully someone can help me with a simple code snippet that I can daemonize and monitor with supervisord or monit.
Here is a cutdown version of the script that Alex pointed you to.
It simply connects to 192.168.0.8 and forwards port 3389 from 192.168.0.6 to localhost
import select
import SocketServer
import sys
import paramiko
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:
print('Incoming request to %s:%d failed: %s' % (self.chain_host, self.chain_port, repr(e)))
return
if chan is None:
print('Incoming request to %s:%d was rejected by the SSH server.' % (self.chain_host, self.chain_port))
return
print('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()
print('Tunnel closed from %r' % (self.request.getpeername(),))
def main():
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
client.connect("192.168.0.8")
class SubHandler(Handler):
chain_host = "192.168.0.6"
chain_port = 3389
ssh_transport = client.get_transport()
try:
ForwardServer(('', 3389), SubHandler).serve_forever()
except KeyboardInterrupt:
sys.exit(0)
if __name__ == '__main__':
main()
Is there a special reason not to just do it with ssh
, the usual
(ssh -L <localport>:localhost:<remoteport> <remotehost>)
minuet? Anyway, this script is an example of local port forwarding (AKA tunneling).
精彩评论