利用ngrok做内网穿透

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013705066/article/details/82382614

内网穿透

内网穿透,即NAT穿透,让外网与内网的计算机节点进行连接通信。
有时候我们需要在外网访问我们局域网里的应用,这时候就需要使用内网穿透技术。

NAT

NAT英文全称是“Network Address Translation”,中文意思是“网络地址转换”,它是一个IETF(Internet Engineering Task Force, Internet工程任务组)标准,允许一个整体机构以一个公用IP(Internet Protocol)地址出现在Internet上。顾名思义,它是一种把内部私有网络地址(IP地址)翻译成合法网络IP地址的技术。
NAT 可以让那些使用私有地址的内部网络连接到Internet或其它IP网络上。NAT路由器在将内部网络的数据包发送到公用网络时,在IP包的报头把私有地址转换成合法的IP地址。

Ngrok

ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放。
说白了就是一个实现内网穿透的工具。

Ngrok工作原理

ngrok分为服务端和客户端。
ngrok会根据配置的域名生成具有证书加密的服务端程序和客户端程序。
ngrok服务端程序启动以后,会监听来自客户端的链接。
当客户端启动的时候,通过验证后服务器端和客户端会建立一条TCP连接通道。由客户端维持心跳。毕竟服务器无法主动联系客户端。当连接建立时,服务器会记录客户端启动时配置的url与通道信息。做一个映射。可以理解该连接为一个master进程。
当用户有数据需要请求客户端里的服务时,服务端会根据请求的域名找到已经建立的通道,传输一些控制信息给客户端。大意是让客户端发起一个传输数据的通道过来。然后后续的传输数据走新建立的数据通道。可以理解为worker进程。
说白了ngrok就是一个流量中转站。通过一定的协议,负责公网和内网建立传输通道的工具。
因此ngrok必须需要一个公网的服务器来做中转。

Ngrok使用

安装

本文介绍使用docker安装方式。
ngrok没有官方的docker镜像。因此从github上找到了一个用于构建ngrok镜像的项目。
感谢 https://github.com/hteen/docker-ngrok
我修改了一些东西。一个是换了go的版本为最新版。换了ngrok为github上星星最多的版本库。换了n个端口。
修改以后的Dockerfile文件如下:

FROM golang:1.11-alpine3.8

RUN apk add --no-cache git make openssl

RUN git clone https://github.com/inconshreveable/ngrok.git /ngrok

ADD *.sh /

ENV DOMAIN **None**
ENV MY_FILES /myfiles
ENV TUNNEL_ADDR :8880
ENV HTTP_ADDR :80
ENV HTTPS_ADDR :443

EXPOSE 8880
EXPOSE 80
EXPOSE 443

CMD /bin/sh

你们可以使用上面的Dockerfile文件。也可以使用原作者默认的。
下面开始介绍使用过程。
1.生成docker镜像,进入到docker-ngrok根目录

docker build -t ngrok .

2.生成ngrok服务器和客户端程序

docker run --rm -it -e DOMAIN="ngrok.域名.com" -v /usr/local/ngrok/data/:/myfiles ngrok /bin/sh /build.sh

3.运行服务器端程序

docker run -idt --name ngrok-server\
-e DOMAIN="ngrok.域名.com" \
-p 8880:80 \
-p 8883:443 \
-p 8885:8880 \
-v /usr/local/ngrok/data/:/myfiles ngrok:v1 /bin/sh /server.sh

4.配置nginx反向代理,参考注意事项2

域名解析

添加两条域名解析,也就是上面配置的域名:
ngrok.域名
*.ngrok.域名

客户端使用

将上面步骤2生成的客户端程序下载下来。目录就是你挂载的目录。
例如linux下,下载linux版本的客户端:
1.新建一个ngrok.cfg的配置文件

server_addr: "ngrok.域名.com:8885"
trust_host_root_certs: false

2.执行以下命令

./ngrok -subdomain sonar -config=ngrok.cfg 192.168.0.111:9000

3.看到以下内容,说明内网穿透成功

Tunnel Status                 online                                            
Version                       1.7/1.7                                           
Forwarding                    http://sonar.ngrok.域名.com -> 192.168.0.111:90000
Forwarding                    https://sonar.ngrok.域名.com -> 192.168.0.111:9000
Web Interface                 127.0.0.1:4040                                    
# Conn                        9                                                 
Avg Conn Time                 96.07ms   

浏览器

访问http://sonar.ngrok.域名.com 即可外网访问我部署在内网的服务。

注意事项

1.ngrok默认会使用80和443端口,我的机子上已经安装了nginx,为了避免端口冲突,我在启动容器时将机子的8880映射容器内部80端口,8883映射443端口。
2.如果采用了1的做法,需要配置nginx反向代理,监听域名的80端口,指向本机的8880端口。同样为了避免每次都输入端口号,也可以配置nginx的反向代理来解决。以下是配置nginx反向代理的例子:

server {
     listen       80;
     server_name  ngrok.域名 *.ngrok.域名;
     location / {
             proxy_redirect off;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_pass http://127.0.0.1:8880;
     }
 }
 server {
     listen       443;
     server_name  ngrok.域名 *.ngrok.域名;
     location / {
             proxy_redirect off;
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_pass http://127.0.0.1:8883;
     }
 }

3.如果你是使用的阿里云ECS做ngrok的服务,记得配置通道端口的入网端口规则。例如我配置的通道端口是8885,需要在阿里云的控制台打开TCP8885的入网端口。

猜你喜欢

转载自blog.csdn.net/u013705066/article/details/82382614