最近和微信公众号杠上了。和微信打过交道的叉子们肯定都见过微信这个配置。微信开发需要有一个公网IP,而我们绝大部分都用的公司的内网,所以每次都得自己在本地模拟微信请求(可以用[postman]),然后提交代码至服务器验证。一旦遇到错误需要重新发布,给调试代码带来极大不便,效率甚低。。。所以很多时候我的心情是这样的:
带着些许期待,遨游了一下google,于是就认识了它—[ngrok]。百度百科解释如下:
1 | ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。 |
顾名思义,「ngrok」这个东东就是一个反向代理,让本地运行的服务可以被外网访问。
一个令人悲伤的消息是 ngrok v2.x 官方已经闭源,那就意味着要收费了。不过,还好ngrok v1.x 是开源的,代码托管在github上。虽然「ngrok v1.x」已经不再开发和维护了,但是不影响其发挥作用。值得我们可以在自己服务器上折腾一番。
如果嫌自己搭建麻烦,可以使用国内的免费服务,如 http://ngrok.2bdata.com/, 感谢哪些无私贡献服务器的人~
但是~ 但是~ 作为一个爱折腾,爱捣鼓的码农,自给自足才是最大的乐趣。所以,在疯狂的折腾一天后,终于搞定了。。。不禁流下了幸福的汗水。。。
本次测试的「linux」版本是 Centos6
1 | Linux 2.6.32-042stab113.21 #1 SMP Wed Mar 23 11:05:25 MSK 2016 x86_64 x86_64 x86_64 GNU/Linux |
域名解析
我的域名DNS是在阿里云解析的,增加两条A记录只想服务器IP地址如下。DNS解析速度很快,一般修改后立马生效。
GO环境搭建
首页,我们要知道「ngrok」是用「go」语言写的,所以需要先安装「go」环境,安装「go」最新版本,采用源码安装,最新版本是「1.7.1」,注意:「1.4」以下版本会有编译问题,没有亲测,不敢尝试。
1 | mkdir /usr/go # 创建go目录 |
设置环境变量
1 | #根据自己不同目录自行调整 |
注意,「GOPATH」如果设置不正确会出现找不到「package」错误。如果出现错误,可以将「GOPATH」值设置成「ngrok」根目录(具体原因没有仔究),更改后记得输入 source /etc/profile
命令更新环境变量。
检测是否安装成功
1 | go version #go version go1.7.1 linux/amd64 |
git环境搭建
在编译「ngrok」的时候,出现了卡在下载某个东西的时候,找了好多资料才发现原来是「git」版本过低,版本必须 >=1.7.9.5方能正常编译。这个坑我踩了。唉~
1 | gopkg.in/inconshreveable/go-update.v0 (download) |
「git」安装及升级具体可参照官方文档:git 升级
以上依赖环境顺利安装好以后,就可以开始今天的主菜了。
下载「ngrok」源码
1 | mkdir /usr/ |
生成证书
以ngrok.twindy.org
为列子
1 | mkdir /usr/ngrok/cert #创建保存证书目录 |
执行完以上命令,就会在/usr/ngrok/cert
目录下新生成6个文件
1 | ls /usr/ngrok/cert # 文件列表 |
「ngrok」通过「bindata」将「ngrok」源码目录下的「assets」目录(资源文件)打包到可执行文件(「ngrokd」和「ngrok」)中去,assets/client/tls 和 assets/server/tls 下分别存放着用于「ngrok」和「ngrokd」的默认证书文件,我们需要将它们替换成我们自己生成的:(因此这一步务必放在编译可执行文件之前)
1 | cp cert/rootCA.pem assets/client/tls/ngrokroot.crt |
编译「ngrokd」和「ngrok」
注意,参数里可以设置操作系统位数、类型。傻傻的我,居然为了编译「window」版本,在「window」下又搭了一套环境重新编译。 无限笨~
1 | make clean #clean |
顺利的话,可以正常编译,在bin下面可以看到「ngrokd」和「ngrok」,其中「ngrokd」是服务端执行程序,「ngrok」是客户端执行程序。
查看 「ngrokd」参数
1 | ngrokd -h #查看参数说明 |
启动「ngrokd」服务端
注意: http和https端口可以自己指定,这里不采用80端口,是因为其他程序已经占用了,端口转发在上面nginx已经配置完成
1 | # domain填写刚才生成证书时填写的域名 |
####「ngrok」客户端连接
已下在「window」上测试「ngrok」客户端连接。
将生成的「ngrok.exe」下载至本地d:/ngrok/ngrok.exe
,新建配置文件d:/ngrok/ngrok.cfg
:
1 | server_addr: "ngrok.twindy.org:4443" |
启动「ngrok」客户端
1 | cd d:\ngrok |
如果没有错误,则会出现以下结果:
1 | Tunnel Status reconnecting |
到这里,内网已经成功穿透。但是,事情还还有结束!!!!
微信开发中的api地址,是不认80以外的端口的,也就是说虽然
1 | http://example.ngrok.twindy.org:8002 |
外网已经可以访问本地服务,但是微信不认识。而我们又不能在「ngrokd」用80
端口启动。因为80
端口已经被「nginx」占用
1 | bin/ngrokd -domain="ngrok.twindy.org" -httpAddr=":80" |
怎么办?怎么办??
既然「nginx」占用了80
端口,那么就在「nginx」上做文章。只要绑定example.ngrok.twindy.org
并将所有请求转发到8002
端口即可。在服务器中新建/etc/nginx/conf.d/ngrock.twindy.org.conf
文件,添加以下内容:
1 | upstream ngrok { |
重新加载「nginx」
1 | nginx -s reload |
此外,「ngrok」+ 「nginx」+「Docker」也可以完美实现,由于对Docker」不了解没有去折腾
参考地址:搭建自己的 Ngrok 服务器, 并与 Nginx 并存
至此,「ngrok」内网穿透成功实现。幸福的汗水。。。
总结:
- 今天遇到坑太多,还好之前自学过「nginx」,虽然折腾了一天最终还是成功了,满满的成就感。
- coding无止境。