茗宸博客网

  • 首页
  • 数据通信
    • 华为
    • 思科
    • 浪潮科技
    • 锐捷
  • 硬件瞎折腾
    • 电脑折腾
    • 软路由
    • 服务器
    • 私有NAS
    • FPV无人机瞎折腾
  • 网络安全
    • CTF经验
    • 实战环境
    • 渗透实战
    • 蓝队加固
    • 近期赛事
    • 漏洞分享
  • 网络技术
    • 网络基础
    • 网络技术精品
    • linux基础
    • 计算机基础
  • 编程学习
    • python
  • 运行维护
  • 服务器搭建
  • 资源分享
  • 随手笔记
    • 随手笔记之ensp
    • 随手笔记之mysql
  • 日常
    • 拍摄
茗宸博客
随手笔记
  1. 首页
  2. 数据通信
  3. 服务器搭建
  4. 正文

反向代理进行内网穿透

2024年9月19日 209点热度 1人点赞 0条评论
内容目录

背景

在开始前我们先来看一个场景。某一天你新学了一个Web框架,弄了一个HelloWorld后很兴奋,要给朋友show一下(因为只是临时show一下,所以你没有考虑将网站部署到服务器上)。这时候就比较尴尬了,你家宽带没有独占IP,公司是独占IP但是你又没权限配置路由器的转发表。你发现你的网页只有在局域网内才能访问得到,在外网的朋友是无法访问的。这时候有两个方法,一个方法是将网站部署到有公网IP的服务器上,另一个方法就是本文的主角——使用反向代理进行内网穿透。img

反向代理-Reserve Proxy

反向代理其实不是什么新鲜玩意儿,它本质上和正向代理一样,都是把流量做转发。而正向代理的最典型的例子就是大家所用的梯子。假如客户端A到服务端B中间有个防火墙,屏蔽了所有A到B的流量,而有个设备C,A到C,C到B的路由都是通的。这时候我们就可以把流量先发给C,C收到后再将流量发给B,这样我们就可以访问到B上的资源了。这就是正向代理比较直观的例子。img
如果说正向代理代理的是客户端,那么反向代理代理的就是服务端。比较直观的例子是负载均衡。比如我访问百度的域名,我的请求会首先到一个服务器C上,C会给根据我的网络情况从很多的实例服务器中给我分配一个最快的实例服务器。这里的C做的工作其实就是反向代理。从这里我们可以看出正向代理多是管理出去的流量的,而反向代理多是管理进来的流量的。
img

反向代理的作用有

  • 对客户端隐藏服务器(集群)的IP地址
  • 安全:作为应用层防火墙,为网站提供对基于Web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等
  • 为后端服务器(集群)统一提供加密和SSL加速(如SSL终端代理)
  • 负载均衡,若服务器集群中有负荷较高者,反向代理通过URL重写,根据连线请求从负荷较低者获取与所需相同的资源或备援
  • 对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务
  • 对一些内容进行压缩,以节约带宽或为网络带宽不佳的网络提供服务
  • 减速上传
  • 为在私有网络下(如局域网)的服务器集群提供NAT穿透及外网发布服务
  • 提供HTTP访问认证
  • 突破互联网封锁(不常用,因为反向代理与客户端之间的连线不一定是加密连线,非加密连线仍有遭内容审查进而遭封禁的风险;此外面对针对域名的关键字过滤、DNS缓存污染/投毒攻击乃至深度数据包检测也无能为力)

内网穿透-Intranet Penetration

在文章的开头我们举了一个例子,在外网的设备是无法直接访问到内网的资源的。因为各种路由(运营商的、自己的)将我们的内网的设备给屏蔽了。就像你无法直接访问到百度最下层的实例服务器一样。这时候我们就可以利用反向代理实现将内网的服务暴露出去,称之为内网穿透。

具体流程是这样的。我们需要一个有公网IP的服务器C,然后从本地A向C访问,和C握手、建立稳定的信道。在外网的设备B向C发送请求,C通过刚才建立的稳定信道将请求转发给A。A收到请求后将响应发给C,C再将响应返给B。这样B就能访问到内网A的资源了。

img

比较著名的远程桌面控制软件Teamviewer其实背后的原理就是这样。
img

构建自己的内网穿透服务

我们这里使用的是ngrok。ngrok 是一个开源的反向代理工具(2.0版本后闭源),通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放。

我们会在云服务器上安装ngrok服务端,并为客户端生成证书。没有什么敲代码的工作,直接拿来用就行了。

我云服务器的环境为Ubuntu18,本地环境为macOS,不同的环境接下来的步骤可能会有区别,请大家自行解决。

安装GO

在云服务器上安装GO。

$ sudo apt upgrade
$ sudo apt install golang

装完后应该可以看到go的版本。

$ go version
go version go1.10.4 linux/amd64

配置Ngrok

从Github拉取Ngrok源码。

$ git clone https://github.com/inconshreveable/ngrok.git
$ export GOPATH=~/ngrok

接下来我们需要生成自己的证书,并编译携带该证书的客户端。

接下来的mytencent为我的hostname,请换成自己的。不能直接使用IP地址,否则会有证书错误。可以在本地的hosts里把自己的云服务器加上。

$ cd ngrok
$ NGROK_DOMAIN="mytencent.com"
$ openssl genrsa -out rootCA.key 2048
$ openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.pem 
$ openssl genrsa -out device.key 2048 
$ openssl req -new -key device.key -subj "/CN=$NGROK_DOMAIN" -out device.csr 
$ openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000

如果在第三步报错:

139632903422400:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/home/ubuntu/.rnd

删除/usr/lib/ssl/openssl.cnf开头的RANDFILE=...

执行完以上命令,在ngrok目录下会生成6个新的文件

device.crt device.csr device.key rootCA.key rootCA.pem rootCA.srl

替换证书

Ngrok通过bindata将ngrok源码目录下的assets目录打包到可执行文件(ngrokd和ngrok)中去,assets/client/tls和assets/server/tls下分别存放着用于ngrok和ngrokd的默认证书文件,我们需要将它们替换成我们自己生成的。

$ cp rootCA.pem assets/client/tls/ngrokroot.crt
$ cp device.crt assets/server/tls/snakeoil.crt
$ cp device.key assets/server/tls/snakeoil.key

编译

选择对应平台的编译方式,编译服务端

$ GOOS=linux GOARCH=amd64 make release-server

如果这步速度慢超时,手动拉一个文件

$ git clone https://gopkg.in/yaml.v1 : ~/ngrok/src/gopkg.in/yaml.v1

编译客户端

$ GOOS=darwin GOARCH=amd64 make release-client

编译完成后~/ngrok/bin/ngrokd为服务端运行文件,ngrok/bin/darwin_amd64/ngrok为客户端运行文件。将服务端文件放到/usr/bin/下就可以直接执行了。将客户端文件下载到自己的电脑上。

$ sudo cp ~/ngrok/bin/ngrokd /usr/bin/
$ scp <your user name>@<your ip>:<your generated client path> <your save path>

运行

服务端运行

$ sudo ngrokd -domain="mytencent.com" -httpAddr=":6000"

客户端目录下放一个配置文件grok.conf

server_addr: "mytencent.mt:4443"
trust_host_root_certs: false

运行

$ ./ngrok -config=ngrok.conf -subdomain=test 8080

没问题的话应该可以看到如下界面,本地和云服务器成功建立了一个img

我们在本地起个服务测试一下。用Flask快速起一个网页。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

访问localhost应该能看到如下界面

img本地访问没问题后我们访问http://example.mytencent.com:6000。如果你的云服务器只有IP地址,没有域名的话这里会有问题。因为我们在本地的hosts里把xxx.xxx.xxx.xxx和mytencent.com对应上了,但是这里又来了个subdomain,用不了。(Ngrok1的http和https协议必须带subdomain,自己服务器有域名会比较方便。Ngrok2可以去掉subdomain,但是不开源就没试了)

The reason is that subdomains are part of the DNS (Domain Name Service) system, where IP addresses are related to the underlying IP protocol. https://stackoverflow.com/questions/21499467/how-to-access-the-subdomain-of-an-ip-address-in-the-browser

所以我们使用tcp协议

$ ./ngrok -config=ngrok.conf -subdomain=test -proto=tcp 8080

可以看到img
访问mytencent.com:42557可以看到
img
这里只是个小demo,实际使用应该有其他问题,大家可以深入研究研究。

标签: 暂无
最后更新:2024年9月19日

站长

这个人很懒,什么都没留下

点赞
< 上一篇

文章评论

您需要 登录 之后才可以评论

站长

这个人很懒,什么都没留下

最新 热点 随机
最新 热点 随机
Linux systemctl 命令 linux的service IPTABLES一文通 网安路线图 DOS相关常用命令了一篇了解大全 MYSQL数据库学习记录
IPTABLES一文通linux的serviceLinux systemctl 命令搬运 linux最常用的20个命令搬运 浅谈社工搬书Linux操作系统应用与安全项目化实战教程
好用的windows目录文本搜索工具AnyTXT 密码模式和AAA模式 单臂路由与三层交换机之间通信 NTFS与DBR详解 详解FAT32文件系统 (一文双篇) centos7卸载java环境安装 OpenJDK 11 两种方式
文章目录
  • 背景
  • 反向代理-Reserve Proxy
    • 反向代理的作用有
  • 内网穿透-Intranet Penetration
    • 构建自己的内网穿透服务
  • 安装GO
  • 配置Ngrok
  • 替换证书
  • 编译
  • 运行

COPYRIGHT © 2023 茗宸bk. ALL RIGHTS RESERVED.

站长微信:printJ7

鲁ICP备2024114188号

鲁公网安备37130202372760号