1.SSH隧道。
SSH隧道是一个不可思议又难以理解和配置的技术方法,特别是在做反向SSH隧道的时候!关于SSH隧道的具体内容可以访问这个链接学习!
https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/index.html
2.rforword.py工具。
paramiko库文件中包含了叫rforward.py的文件,他可以完美解决这个问题可以到下面的链接去去下载它!
https://github.com/paramiko/paramiko/tree/master/demos
3.代码。
main()函数
def main():
options, server, remote = parse_options() #确保必要参数传递给了脚本
password = None
if options.readpass:
password = getpass.getpass("Enter SSH password: ")
client = paramiko.SSHClient() #建立与SSH客户端的连接
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
verbose("Connecting to ssh host %s:%d ..." % (server[0], server[1]))
try:
client.connect(
server[0],
server[1],
username=options.user,
key_filename=options.keyfile,
look_for_keys=options.look_for_keys,
password=password,
)
except Exception as e: #测试代码
print("*** Failed to connect to %s:%d: %r" % (server[0], server[1], e))
sys.exit(1)
verbose(
"Now forwarding remote port %d `to` %s:%d ..."
% (options.port, remote[0], remote[1])
)
try: #调用函数
reverse_forward_tunnel(
options.port, remote[0], remote[1], client.get_transport()
)
except KeyboardInterrupt: #测试代码如果端口关闭打印消息
print("C-c: Port forwarding stopped.")
sys.exit(0)
rever_forward_tunnel函数
def reverse_forward_tunnel(server_port, remote_host, remote_port, transport):
transport.request_port_forward("", server_port) #转发SSH服务器一个端口的TCP连接
while True:
chan = transport.accept(1000) #建立新的传输通道
if chan is None:
continue
thr = threading.Thread(
target=handler, args=(chan, remote_host, remote_port) #调用handler函数处理
)
thr.setDaemon(True)
thr.start()
Paramiko中,两个主要的通信方法:transport用来处理和维护加密连接,channel加密传输会话中发送和接受数据。
handler函数
def handler(chan, host, port):
sock = socket.socket()
try:
sock.connect((host, port))
except Exception as e:
verbose("Forwarding request to %s:%d failed: %r" % (host, port, e))
return
verbose(
"Connected! Tunnel open %r -> %r -> %r"
% (chan.origin_addr, chan.getpeername(), (host, port))
)
while True: #数据的发送和接收
r, w, x = select.select([sock, chan], [], [])
if sock in r:
data = sock.recv(1024)
if len(data) == 0:
break
chan.send(data)
if chan in r:
data = chan.recv(1024)
if len(data) == 0:
break
sock.send(data)
chan.close()
sock.close()
verbose("Tunnel closed from %r" % (chan.origin_addr,))
4.测试。
我们先在Windows系统上运行rforword.py并将它设置成WEB服务器和kail SSH服务器端的中间人程序。我将WEB服务器设置成了百度。
Windows主机上可以看到,连接到了192.168.179.128的SSH服务端并且打开了8080端口,程序将数据流量导向180.97.33.108主机的80端口。现在用Linux服务器上的浏览器访问http://127.0.01:8080,通过SSH隧道连接到位于180.97.33.108的WEB服务器上。返回Windows主机,可以看到Paramiko已经建立了连接: