内网穿透 ngrok 服务器和客户端配置

2019-03-15 15:31:21

内网穿透 ngrok 服务器和客户端配置


ngrok 简介及作用

ngrok 是一款用 go 语言开发的开源软件,它是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。下图简述了 ngrok 的原理。


完美代替“花生壳”软件。

“花生壳”是一款老牌的内网穿透软件,一年的内网版服务要两百多块钱,都快可以买一年垃圾点的 VPS 服务器了。而免费版的“花生壳”稳定性较差,隔三差五的不能访问,每个月只有 1G 流量,以前做项目没少被坑。ngrok 是一款免费开源的软件,稳定性极强,我曾做过测试,将 ngrok 客户端所在计算机的网络断开一阵子,再连接另一个网络,ngrok 很快会自动重连,几乎不受影响。


用于对处在内网环境中,无外网 IP 的计算机的远程连接。

ngrok 可以做 TCP 端口转发,对于 Linux 可以将其映射到 22 端口进行 SSH 连接。Windows 的远程桌面可以将其映射到 3389 端口来实现。同理,如果要做 MySQL 的远程连接,只需映射 3306 端口即可。


过程梗概

这个配置的过程比较复杂,我的配置环境是:


server 端是debian8

client 端是对多的,有 mac、windows、基本上要覆盖到所有的平台 linux 、 windows 和 arm 。

所以配置的过程分为了以下步骤


server 环境配置

git 上下载

生成证书

生成服务器版本 server 上安装的 ngrokd

生成各个平台上的 client 上安装的 ngrok

调试

有一些要点要特别注意,我就是在这些东西上面绕了很久,配置的时候需要特别注意的地方:


防火墙设置:服务器和客户端都要关闭对应端口的防火墙,否则不能链接会一直显示 connecting 。

证书一定要设置正确: 证书会被编译到可执行文件中去,所以设置的时候需要正确设置地址,如果设置错误,最好是重新 git clone 一份代码来配置,make clean 在这里面似乎不能清除原有的配置。

交叉编译的时候要注意平台是 32 位系统(386)、64 位系统(amd64)或者 arm ,设置错了不能运行

server 配置

首先要安装 server 必须要的软件, 因为现在的阿里云自己的镜像带了 rhel 的源,所以可以直接偷懒用 yum 安装所有的东西。


yum install mercurial git gcc golang

这里要注意,golang的版本要1.8的测试可以正常编译,1.3.3的编译通不过,可以直接参考:https://tecadmin.net/install-go-on-debian/#


因为以后还要保持运行,所以我加上了 supervisor 的设置。这样可以保持服务运行,重启电脑之后之类的都可以保持正常运行。supervisor 需要依赖 python,所以在安装的时候会要求安装 python 等相关的依赖。


yum install supervisor

git 下载

我安装的时候用的 root, 所以比较偷懒的在目录 /root/ 下配置


cd /root

 

#官方地址,可能会报错,最近应该已经修复

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

 

#修复地址,不会报错,感谢 tutumcloud

#git clone https://github.com/tutumcloud/ngrok.git

证书生成

在使用官方服务的时候,我们使用的是官方的 SSL 证书,所以如果直接编译的话,默认的链接地址会到官方的 ngrok.com 去,所以我们需要自己生成证书。 ** 证书非常关键,所有编译的文件都会携带证书文件在程序内部 ** 所以证书生成的时候要保证所有的地方都是对应的。


首先我们要确定我们要使用的地址,这是受到域名解析服务的影响的。最简单的办法就是 ping 一下这个地址看是不是能够获得自己的服务器 ip 。这个服务一定是架设在当前的服务器上的,所以 dns 一定是 ping 了之后指向当前的服务器。


我使用的域名是 www.example.com , ip 地址就是我自己的服务器。最好先 ping 一下确定一下,有一些 dns 没有绑定,会导致不能访问;如果更换域名,又需要重新来一遍全过程,非常繁琐。所以一定要先确定好。


当域名为 www.example.com 的时候,最终效果是远程机器的设置子域名为 abc 时,访问 abc.www.example.com: 端口 就可以。端口是由运行的时候配置的,并不需要确定某一个端口,都是可以设置的。


大概的原理和效果讲清楚之后就开始写怎么做了:


cd /root/ngrok

 

#这里修改为自己的域名

NGROK_DOMAIN="www.example.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

首先进入到 ngrok 的目录,然后设定域名地址,这里需要修改为自己的。openssl 就是生成 SSL 证书文件的过程,之后会在 ngrok 目录下生成 root,device 等六个文件。 然后需要拷贝到配置的目录中,在编译的时候会使用这些文件。


cp -r rootCA.pem assets/client/tls/ngrokroot.crt 

cp -r device.crt assets/server/tls/snakeoil.crt 

cp -r device.key assets/server/tls/snakeoil.key

到这个地方,证书生成已经复制的准备工作就已经完成了。


生成服务器的 ngrokd

前面的配置工作已经完成,后面的就比较简单轻松了。由于是 go 语言写的,所以使用 golang 的 make 选项就好。


cd /root/ngrok

make release-server

等待下载和构建,如果下载失败什么的,估计是因为链接国外的服务器会断线的问题,重新运行一遍 make release-server 就好。


构建完成以后可以在 bin 目录下看到 ngrokd 这个文件,这个就是我们后面要开启的服务器端,现在先不要运行。


编译客户端的 ngrok

这里我们需要交叉编译,使用不同的编译选项来选择编译以后生成的平台


这里我主要是生成了 windows 、 arm 和 Linux 的版本。继续在原先的目录下:


GOOS=linux GOARCH=amd64 make release-client

GOOS=windows GOARCH=amd64 make release-client

GOOS=linux GOARCH=arm make release-client

不同平台使用不同的 GOOS 和 GOARCH,前面的编译选项就是指 go os , go 编译出来的操作系统 (windows,linux,darwin) ;go arch, 对应的构架 (386,amd64,arm)


Linux 平台 32 位系统:GOOS=linux GOARCH=386

Linux 平台 64 位系统:GOOS=linux GOARCH=amd64


Windows 平台 32 位系统:GOOS=windows GOARCH=386

Windows 平台 64 位系统:GOOS=windows GOARCH=amd64


MAC 平台 32 位系统:GOOS=darwin GOARCH=386

MAC 平台 64 位系统:GOOS=darwin GOARCH=amd64


ARM 平台:GOOS=linux GOARCH=arm

通过前面的步骤,就会在bin目录里面生成所有的客户端文件,客户端平台是文件夹的名字,客户端放在对应的目录下,当前Linux平台客户端在bin目录下。然后我们就可以打个包,把所有文件下载到自己的本机了。


cd /root/ngrok

zip -r bin/

然后生成了Bin.zip的文件,通过scp之类的工具下载。


这个里面的注意


服务端叫 ngrokd

客户端叫 ngrok

所以以后要放到对应的平台,就只需要对应平台里面的ngrok文件就可以了。


配置服务器

在server端直接执行就可以了,其中NGROK_DOMAIN对应的就是一开始设置过的域名地址。


但是有一点要重点注意,就是httpAddr等端口的设置。


httpAddr 是访问普通的http使用的端口号,用后面用 子域名.www.aiesst.com:6060 来访问服务

httpsAddr 是访问的https使用的端口号,同上,只不过是需要https的服务访问才用这个端口

tunnelAddr 是通道的端口号,这个端口是Ngrok用来通信的,所以这个端口在服务器上和客户端上设置必须要对应才可以正常的链接,默认不填写好像是4433

cd /root/ngrok

NGROK_DOMAIN="www.aiesst.com"

#http,https,tcp, 注意:如果不需要http/https支持,可以直接类似-httpAddr=""来表示

bin/ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062" 

#https设置了tls

#bin/ngrokd -domain="www.aiesst.com" -httpAddr=":6060" -httpsAddr=":6061" -tunnelAddr=":6062" -tlsKey=./device.key -tlsCrt=./device.crt

验证端口是否打开的问题

当打开了服务端程序之后,如果有疑问可以测试一下,因为有时候可能会遇到这个问题。我在一开始的时候并没有注意到防火墙问题,所以一直导致不能成功。除了这个问题之外,使用阿里云还有一些问题,就是我使用的系统是CentOS,默认是没有打开对应的端口的,如果遇到这个问题需要先验证一下端口是否打开。我使用了工具nc来测试。


使用的命令是:


nc -v -w 10 -z 127.0.0.1 6060-6062

如果显示的3个端口都有响应(都显示了 succeeded 就是正常),那么就可以继续开始后面的步骤。


打开防火墙

如果是centOS的系统,防火墙应该是 firewall-cmd 来控制。对应的命令就是,其中端口号要写自己的:


firewall-cmd --permanent --zone=public --add-port=6060-6062/tcp  //永久

#firewall-cmd  --zone=public --add-port=6060-6062/tcp   //临时

如果是ubuntu之类的系统,防火墙一般是iptables来控制,对应的命令就是,也要修改自己的端口号才可以:


iptables -A INPUT -p tcp --dport 6060-6062 -j ACCEPT

iptables -A OUTPUT -p tcp --sport 6060-6062 -j ACCEPT

打开了服务器的端口,然后就可以继续配置客户端。


配置windows客户端

这里的客户端就是指另外一台电脑,这一台电脑可以链接到服务器的电脑上,客户端常常是我们内网的电脑,这个就是ngrok实现的最大意义,可以和在公网的服务器通信之后,再直接访问内网电脑提供的服务,实现内网穿透。


这里我先使用了windows来测试,因为平时用的系统,有各种工具,相对会比较方便。


先找到一开始通过 scp 下载的 Bin.zip 文件,解压到任意目录。然后找到window版本的客户端 ngrok.exe。复制到任意目录,自己方便操作就好。我使用了 D:\tmp\ 文件夹


先在这个目录下建立一个文件 ngrok.cfg ,然后写入内容:


地址和服务器设置的 NGROK_DOMAIN=”www.aiesst.com” 中的地址保持一致

端口和服务器设置的通道端口 tunnelAddr=”:6062” 保持一致

server_addr: "www.aiesst.com:6062"

trust_host_root_certs: false

然后 ctrl-r 打开运行,运行 cmd,输入:


日志: -log=ngrok_log.txt 是记录ngrok的日志,如果前期调试的时候加上这个参数,如果不能访问就可以查看到底是什么问题

子域名: -subdomain=abc 是定义访问的时候的子域名,现在访问 abc.www.aiesst.com:6060 就可以访问到这一台机器上80端口的服务

D:

cd tmp

ngrok.exe -log=ngrok_log.txt -subdomain=abc -config="ngrok.cfg" 80

稍微等待5秒钟,如果看到显示有 tunnel status: online ,那么后面的 forwarding 对应的内容就是访问本机的地址。


当然在windows上面,你需要再跑一个其他的服务在80端口可以看到访问的效果。


总之就是如果显示了 tunnel status: online 就是服务器和客户端是正常链接的,通过浏览器访问 abc.www.aiesst.com:6060 就可以链接到现在的内网主机上的服务。


TCP转发(11月5日更新)

这里以转发ssh为例,重新改写客户端配置文件ngrok.cfg


server_addr: ngrok.sfantree.com:4443

trust_host_root_certs: false

tunnels:

    http:

        proto:

            http: 80

        subdomain: pi

    ssh:

        remote_port: 10086

        proto:

            tcp: 22

这里我把需要转发的http和ssh都写入配置文件,其他tcp服务语法格式和ssh相似,remote_port为远程端口,等下外网连接的时候用的就是这个remote_port,tcp:22为需要转发的本地端口。


./ngrok-for-arm -config=ngrok.cfg start http ssh

重新运行客户端,start指明需要的服务类型,建议开一个screen。


ssh popy32@ngrok.sfantree.com -p 10086

连接时指明远程端口


总结

从Ngrok强大的反向代理功能可以看出Go语言独特魅力,除了glibc的版本有一定要求,其跨平台编译为部署省去了不少时间,当然Go还有更多的优点,本文提到的也只是Ngrok的冰山一角,利用其TCP转发也可以远程SSH树莓派,更多玩法就自行百谷了。

--------------------- 

作者:yine 

来源:CSDN 

原文:https://blog.csdn.net/y_xianjun/article/details/73194622 

版权声明:本文为博主原创文章,转载请附上博文链接!


  • 2020-05-24 08:10:18

    echarts标题(title)配置

    show:true,//显示策略,默认值true,可选为:true(显示) | false(隐藏) text: '主标题',//主标题文本,'\n'指定换行 link:'',//主标题文本超链接,默认值true target: null,//指定窗口打开主标题超链接,支持'self' | 'blank',不指定等同为'blank'(新窗口) subtext: '副标题',//副标题文本,'\n'指定换行 sublink: '',//副标题文本超链接

  • 2020-06-02 08:57:12

    clipboard复制成功但是粘贴板是空的

    将文本复制到剪贴板应该不难。配置它不需要几十个步骤,也不需要加载数百KB的js文件 。但最重要的是,它不应该依赖Flash或任何臃肿的框架。这就是clipboard.js存在的原因。

  • 2020-06-04 13:54:21

    vue生成的__ob__: Observer无法解析jsonp

    computed 从vuex获得数据,watch监听数据 然而问题就出现在了监听上,监听不到,给个setTimeOut 1000 就能检测到数据了,不然打印时又数据,用的时候时空的,不知道时什么原因。

  • 2020-06-06 20:22:56

    laravel 接收json串

    在做项目的时候发现 用平时的$request->all() 无法获取到请求值

  • 2020-06-09 08:50:28

    LRU原理以及js实现

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

  • 2020-06-20 06:31:16

    mac下全局配置adb环境

    不提示“command not found”,而是出现一长串帮助说明,那就证明adb已经配置好了。