本博客地址:https://blog.csdn.net/wutianxu123/article/details/125397313

一、场景

当可以远程访问内网中的某台SSH服务器时,如果此时的目的是内网中一台web服务器,当无法访问那台web服务器,而这台可以访问的SSH服务器又没有安装一些工具,我们就可以配置一条反向SSH隧道连接(如果没有SSH服务的话)。

要搭建这种隧道,必须先像往常一样,从内网的Windows客户端连到外网的SSH服务器上。通过这条SSH连接,我们可以在服务器上的某个远程端口和本地端口之间建立一条隧道。通过这个本地端口,我们可以暴露某个内部系统的3389端口并通过远程桌面协议访问,或者访问这台Windows设备能访问的任何系统。

二、代码

Paramiko的官方示例中有个rforward.py程序,位置在:paramiko-main\demos\rforward.py,可以直接使用。

已经对核心部分做了中文注释。代码如下:

#!/usr/bin/python
#-*- coding:utf8 -*-import getpass
import os
import socket
import select
import sys
import threading
from optparse import OptionParser
import paramikoSSH_PORT = 22
DEFAULT_PORT = 4000
g_verbose = True# 管理每个线程的通信
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))returnverbose("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:breakchan.send(data)if chan in r:data = chan.recv(1024)if len(data) == 0:breaksock.send(data)chan.close()sock.close()verbose("Tunnel closed from %r" % (chan.origin_addr,))def reverse_forward_tunnel(server_port, remote_host, remote_port, transport):# transport负责建立和维持加密通信# request_port_forward将服务器上某个端口的TCP连接全部转发过来transport.request_port_forward("", server_port)while True:# channel加密transport会话中收发的数据# 建立一个新的channelchan = transport.accept(1000)if chan is None:continue# 调用handler函数处理这个channelthr = threading.Thread(target=handler, args=(chan, remote_host, remote_port))thr.setDaemon(True)thr.start()def verbose(s):if g_verbose:print(s)HELP = """\
Set up a reverse forwarding tunnel across an SSH server, using paramiko. A
port on the SSH server (given with -p) is forwarded across an SSH session
back to the local machine, and out to a remote site reachable from this
network. This is similar to the openssh -R option.
"""def get_host_port(spec, default_port):"parse 'hostname:22' into a host and port, with the port optional"args = (spec.split(":", 1) + [default_port])[:2]args[1] = int(args[1])return args[0], args[1]# 参数声明
def parse_options():global g_verboseparser = OptionParser(usage="usage: %prog [options] <ssh-server>[:<server-port>]",version="%prog 1.0",description=HELP,)parser.add_option("-q","--quiet",action="store_false",dest="verbose",default=True,help="squelch all informational output",)parser.add_option("-p","--remote-port",action="store",type="int",dest="port",default=DEFAULT_PORT,help="port on server to forward (default: %d)" % DEFAULT_PORT,)parser.add_option("-u","--user",action="store",type="string",dest="user",default=getpass.getuser(),help="username for SSH authentication (default: %s)"% getpass.getuser(),)parser.add_option("-K","--key",action="store",type="string",dest="keyfile",default=None,help="private key file to use for SSH authentication",)parser.add_option("","--no-key",action="store_false",dest="look_for_keys",default=True,help="don't look for or use a private key file",)parser.add_option("-P","--password",action="store_true",dest="readpass",default=False,help="read password (for key or password auth) from stdin",)parser.add_option("-r","--remote",action="store",type="string",dest="remote",default=None,metavar="host:port",help="remote host and port to forward to",)options, args = parser.parse_args()if len(args) != 1:parser.error("Incorrect number of arguments.")if options.remote is None:parser.error("Remote address required (-r).")g_verbose = options.verboseserver_host, server_port = get_host_port(args[0], SSH_PORT)remote_host, remote_port = get_host_port(options.remote, SSH_PORT)return options, (server_host, server_port), (remote_host, remote_port)def main():# 会检查必需的几个参数是否都传进来了options, server, remote = parse_options()password = Noneif options.readpass:password = getpass.getpass("Enter SSH password: ")# 创建一个Paramiko的SSH客户端连接client = paramiko.SSHClient()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)if __name__ == "__main__":main()

三、运行

命令:

python rforward.py 192.168.153.141 -p 8081 -r 192.168.153.140:3000 --user=kali --password备注:
192.168.153.141,是SSH服务器的IP
192.168.153.140,是web服务器的IP
--user,是SSH服务器的用户名
--password,是SSH服务器的密码

运行效果:


我们连接了SSH服务器,并在上面打开了8081端口,这个端口会将流量都转发到web服务器的3000端口上,现在在SSH服务器上访问http://127.0.0.1:8081,会通过SSH隧道连接到位于web服务器上的3000端口上的web服务。

安全开发--7--SSH隧道工具开发相关推荐

  1. 动态网站开发(手动开发、使用myeclipse工具开发)

    一.使用Servlet技术开发动态网页 (1)servlet是一个普通的Java类,继承HttpServlet (2)可以接收http请求,发送http响应 (3) sevlet 交给tomcat服务 ...

  2. python测试开发教程_python3测试工具开发快速入门教程

    现有的优秀python教程大多来自国外,但是翻译过来文章,有些丧失了原意.且现有的python3教程,很少有结合项目能快速上手.为此我们退出为零基础的初学者提供python入门教程(资深python使 ...

  3. shell编程系列26--大型脚本工具开发实战

    shell编程系列26--大型脚本工具开发实战大型脚本工具开发实战拆分脚本功能,抽象函数1.function get_all_group 返回进程组列表字符串2.function get_all_pr ...

  4. 基于Qt开发的网络诊断工具

    导语: 项目名称:基于Qt开发的网络诊断工具 开发环境:VS2008 QT版本:4.7 数据读入:用户自行选中的.ini配置文件 功能实现:解析.ini文件,实时检测相关的域名连通性以及DNS解析的结 ...

  5. PHP漏洞利用工具开发,PHPcms二次开发,PHPcms,DEDEcms简单代码审计

    PHP工具开发 文章目录 PHP工具开发 PHP小马 一句话木马 PHP大马分析 实现大马后门 编写大马 PHP的cms二次开发 PHP常见CMS的漏洞分析 PHPstorm调试模式 PHPCMSv9 ...

  6. ssh远程工具_良心国产工具,比Xshell好用还免费!

    使用或维护Linux系统的都知道,我们日常对服务器的操作,一般都会借助SSH工具远程登录到服务器之后进行操作.常用的SSH工具有不少,比如:Xshell.Putty.SSH Secure Shell ...

  7. java 建立ssh隧道_如何使用IntelliJ和JDBC SSH隧道并连接到数据库?

    我在使用IntelliJ和JDBC连接到服务器上托管的数据库时遇到问题.使用命令行,命令: ssh username@server -L 11100:ct1:28017 -N 成功创建隧道并执行命令: ...

  8. 服务端开发——云服务器的端口转发设置(SSH隧道)

    引言 本篇博客介绍端口转发的知识,并详细阐述操作和设置步骤.这是因为在实际工作中,会有很多企业从安全的角度考虑,为线上或重要的服务器设置一个跳板机(堡垒机),避免远程开发人员直接操作,是企业应用开发中 ...

  9. 如何用node开发自己的cli工具

    如何用node开发自己的cli工具 灵感 写这个工具的灵感以及场景源于youtube的一次闲聊 github 地址 blog首发 使用场景 原本我们写博客展示shell,例如:安装运转docker,一 ...

最新文章

  1. ACM《数据结构》顺序表
  2. 141. Sqrt(x)【牛顿迭代法求平方根 by java】
  3. 科技发烧友之单反佳能700d中高端
  4. url映射 ccf (Java正则表达式80分解法)
  5. [Array]Majority Element
  6. 【转载】python两个列表获取交集,并集,差集
  7. (转)javascript异步编程的四种方法
  8. hibernate 读取mysql表结构_为什么要用hibernate 与基于数据库表结构的项目开发
  9. 音视频实时交互/语音通话/即时通话/连麦,EasyRTC即时通讯系统全方位服务
  10. Eclipse PHPEclipse 配置
  11. PLSQL使用常用技巧
  12. 在Android上将实时摄像头与AI危害检测配合使用
  13. java错误报告过滤_vue 过滤器filters的使用以及常见报错小坑(Failed to resolve filter)...
  14. Excel——从文本中提取数字
  15. 2019年安徽省程序设计大赛题解
  16. 台式电脑 在哪找到计算机名,win7电脑的投屏功能在哪?教你找到!
  17. 调用百度h5活体检测
  18. 用 Electron 打造 Win/Mac 应用,从「代码」到可下载的「安装包」,可能比你想得麻烦一点...
  19. ORA-00257: archiver error. Connect internal only, until freed 处理方法
  20. Spring系列:代理(jdk动态代理,cglib代理)

热门文章

  1. 钱岭:别担心“35岁危机”,要成为“老专家”
  2. 2017最新微信公众号导航系统源码_ 带会员系统和推广系统
  3. wpa_supplicant.conf 配置文件解析(一)
  4. Incorrect string value: '\xF0\x9F\x92\x98\xF0\x9F...'
  5. 游戏小程序之变化彩球
  6. ASO优化之如何更新APP
  7. 第八届“图灵杯”NEUQ-ACM程序设计竞赛个人赛 全题解
  8. 手写Spring-第三章-来填坑吧!有参bean的实例化策略
  9. VBA编辑器输入中文乱码解决
  10. 解决桌面右键文件夹卡死的问题