从Python创建SSH隧道的问题
目标是建立多个SSH隧道,连接卫星服务器和一个集中式的注册数据库。我已经在服务器之间设置了公钥认证,这样它们就可以直接登录,而不需要输入密码。接下来该怎么做呢?我试过Paramiko,这个工具看起来还不错,但设置一个基本的隧道就变得相当复杂,虽然如果有代码示例就更好了。我还试过Autossh,但在建立一个有效的隧道后,它两分钟就死掉了,真是奇怪!希望有人能给我一个简单的代码片段,这样我可以把它变成后台运行,并用supervisord或monit来监控。
2 个回答
2
(ssh -L <localport>:localhost:<remoteport> <remotehost>)
有没有什么特别的原因不直接用 ssh
,也就是通常的做法呢?不管怎样,这个脚本 是一个本地端口转发(也叫做隧道)的例子。
5
这是一个简化版的脚本,是Alex推荐给你的。
这个脚本的功能很简单,它连接到192.168.0.8,并把192.168.0.6上的3389端口转发到本地电脑上。
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()