【内网穿透】相信很多同学没有遇到,但做微信开发时,需要接收微信服务器的消息就必须配置在线域名,最简单的办法是用ngrok工具,它可以将本地服务映射到公网,但免费版本有很多不便,自己搭建服务爽!
前提条件
一台云服务器,一个域名(二级域名也可以),并且域名正确解析到云服务器
环境配置
yum install -y gcc git
## go语言
wget https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
tar -C /usr/local/ -zxvf go1.8.linux-amd64.tar.gz
添加环境变量,编辑:vi /etc/profile,在最后添加:
#go lang
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
使环境变量生效:
source /etc/profile
检查是否安装成功:
go version
在服务器上搭建Ngrok服务
下载ngrok源码
cd /usr/local/src
git clone https://github.com/inconshreveable/ngrok.git ngrok
环境变量配置
vim /etc/profile
#这里修改为自己的域名
export NGROK_DOMAIN="uboff.com"
配置完成后,可以使用env
命令查看是否生效。
生成证书
在自生成证书时需要一个解析到服务器上的主域名(二级域名也可以,本人已经验证过),现在以”uboff.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
将新生成的证书,替换掉assets/client/tls下的证书
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key
编译生成ngrokd(服务端)
#这里是交叉编译,linux系统GOOS=linux,64位系统GOARCH=amd64,32位系统GOARCH=386
#当前系统可用go env查看
GOOS=linux GOARCH=amd64 make release-server
编译过程中可以会报依赖加载失败,这是网络原因导致,多次尝试下载直到完成编译。
启动服务端(/usr/local/src/ngrok目录下)
./bin/ngrokd -tlsKey="assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.crt" -domain="$NGROK_DOMAIN" -httpAddr=":8071" -httpsAddr=":8072" -tunnelAddr=":8073"
参数说明:
#-domain 访问ngrok是所设置的服务地址生成证书时那个
#-httpAddr http协议端口 默认为80
#-httpsAddr https协议端口 默认为8072
#-tunnelAddr 通道端口 默认8073
出现下面信息,启动成功
注意:启动服务所需要的端口一定要先开放!!!
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:8081
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:8082
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:8083
[14:52:23 CST 2017/03/18] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
编译生成ngrok(客户端)
我这里生成windows下的客户端
为go生成交叉编译环境,执行如下命令:
#这里是交叉编译,linux系统GOOS=linux,64位系统GOARCH=amd64,32位系统GOARCH=386
#当前系统可用go env查看
GOOS=windows GOARCH=amd64 make release-client
#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目录下看到windows_amd64文件夹,复制到windows电脑上即可启动
内网穿透
在windows_amd64目录下新建一个ngrok.cfg文件,内容如下:
注意:server_addr要与服务端一一对应!!!
server_addr: "xxx.com:8073"
trust_host_root_certs: false
tunnels:
http:
subdomain: "test"
proto:
http: "8090"
http2:
subdomain: "test2"
proto:
http: "8010"
https:
subdomain: "test"
proto:
https: "8091"
ssh:
remote_port: 2222
proto:
tcp: "22"
log: 'out.log'
然后就可以启动客户端,我已经把windows_amd64文件夹下载到D盘下,打开CMD输入:
多种启动方式,第一种方式可以启动多个指定隧道,第二种方式只有默认隧道(http/https)
下面的命令启动多个隧道,调试时还可以加上日志
ngrok.exe -log=out.log -config=ngrok.cfg start http https ssh
or
下面会在域名前添加子域前缀
ngrok.exe -config=ngrok.cfg -subdomain=ngrok 8090
会遇到以下错误:
control recovering from failure dial tcp: lookup xxx.com: no such host
此时需要配置本机hosts(c:\windows\system32\drivers\etc),如下:
如果不配置hosts,本地的ngrok就无法识别。
42.192.22.11 xxx.com
再次执行,看到下面信息则启动成功:
打开http://www.xxx.com:8081即可看到成功打开,到此Ngrok服务搭建完成。
后台运行
使用上面的命令可以运行服务,但不能后台运行,这样关闭命令窗口就会终止程序。
nohup ./bin/ngrokd -tlsKey="assets/server/tls/snakeoil.key" -tlsCrt="assets/server/tls/snakeoil.crt" -domain="$NGROK_DOMAIN" -httpAddr=":8071" -httpsAddr=":8072" -tunnelAddr=":8073" &
公众号坑
当在公众号中启用【服务端URL】时,域名后面不能使用端口,如下:
此时就需要把上面启动服务的端口8081-->改为80,但是发现80端口已经被占用了,怎么解决?
二级域名
解决方案是使用二级域名,正常注册的域名是“xxx.com”,那么二级域名就是加一个前缀,如“ngrok.xxx.com”
理论上一个域名可以配置无数个二级域名。
配置二级域名
首先登录到你注册的域名服务器,按如下步骤操作
-
登录管理控制台,找到“域名”并点击进入域名中
-
找到“域名解析”
-
添加二级域名
添加完成后,就可以测试二级域名了,ping ngrok.xxx.com
,正常情况是可以ping通的。
注意:二级域名的解析IP要改为另一台公网服务器,因为要用80端口!!!
记得把本地hosts也加上二级域名哦
重新配置ngrok服务,测试结果如下:
终于把端口去掉了。
问题又来了,看ngrok生成的域名前面加了www,这样的域名是无法访问的?
配置三级域名
ngrok默认会加个www,所以咱们要手动指定三级域名,如
ngrok.exe -log=out.log -config=ngrok.cfg -subdomain=test 8090
内网穿透的结果如下:
现在把前面的www换成了test,这是一个三级域名,如何让这个三级域名能够正常访问呢?方法与添加二级域名一样,只是此时的名字是“test.ngrok”
配置三级域名完成后,就可以正常访问了,就可以配置到公众号的服务端URL了。
内网穿透调用流程
- 公众号---->微信服务器---->服务端URL---->解析三级域名---->ngrok服务器--->跳转到本地ngrok服务8090---->8090是一个ng服务
- ng服务----->以/wx/开头则跳转到wxjava服务器处理来自微信服务器的消息。
- ng服务----->非/wx/开头则跳转到web应用服务
小结
有了这样的内网穿透服务,在开发调试公众号就方便多了。
参考:
https://blog.csdn.net/weixin_39496190/article/details/80385263