前言
进行微信公众号的开发时,需要有公网IP的服务器才行,这样每次都得在本地开发再把代码提交到服务器,或直接在服务器上开发,不是很方便。
并且有时可能需要把本机开发的网站等web项目给其他人演示
,以前都是上传到VPS上,也不是很方便。
通过google查找到ngrok
这个东西,可以实现在本地开发即时调试,可以非常方便地实现内网穿透。
ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放。
详细介绍可以看百度百科的介绍:ngrok介绍。
国内有些人也贡献了自己的服务器,如http://ngrok.cc/,如果不想自己搭建ngrok
环境,可以直接去使用。
ngrok
的v1.x版本是开源的,2.0就不是开源,而且两者的命令有些不同。
这里使用其1.x的开源代码进行布署。经过几个小时的奋斗,中间遇到一些坑,终于在VPS上弄好,现记录如下。
拿了两台服务器进行了安装和测试,系统分别为
CentOS 7 64bit
,CentOS 6.5 64bit
GO安装
需要先安装go环境
设置环境变量
1 2 3 4 5 |
# 可以根据自己需要调整路径 echo 'export GOROOT=/usr/local/go' /etc/profile echo 'export PATH=$PATH:$GOROOT/bin' /etc/profile echo 'export GOPATH=$HOME/go' /etc/profile echo 'export GOROOT_BOOTSTRAP=/usr/local/go' /etc/profile |
下载源码安装
由于
yum
安装的go
版本是1.4
的,后面可能会有点问题,所以这里采用源码安装(2016.03.31最新版本为1.6)的方式
1 2 3 |
cd ~/your_download_dir wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz |
查看是否安装成功
1 2 |
go version # 正常的话会返回类似这样的信息: go version go1.6 linux/amd64 |
ngrok安装
git版本
如果你的git版本>=1.7.9.5
,可以直接跳过git版本这一步;如果不是,需要先进行升级。
我在一台服务器上的版本是1.7.1
,在ngrok安装过程中,会一直卡在某个东西的下载,我是卡在这里
1
|
gopkg.in/inconshreveable/go-update.v0 (download)
|
最好先进行一些git依赖的安装
1
|
yum -y install zlib-devel openssl-devel perl hg cpio expat-devel gettext-devel curl curl-devel perl-ExtUtils-MakeMaker hg wget gcc gcc-c++
|
然后再升级git
版本,升级方法是先安装第三方源(rpmfore),再使用该源进行git的更新。
这里不再详细说明git
的升级,大体可以照这篇教程弄;
唯一不同的是,因为启用了priorities
,所以在最后更新git时一直查找的是base
的repo
,而不是rpmforge
的repo
,所以需要在更新时将base,updates
等repo
禁用(参考这篇文章),如下:
1
|
yum --disablerepo=base,updates --enablerepo=rpmforge-extras update git
|
下载ngrok源码
1 2 3 |
cd ~/your_download_dir git clone https://github.com/inconshreveable/ngrok.git ngrok cd ngrok |
生成证书
注意这里有个NGROK_BASE_DOMAIN
;
假设最终需要提供的地址为aevit.your-domain.com
,则NGROK_BASE_DOMAIN
设置为your-domain.com
;
假设最终需要提供的地址为aevit.ngrok.your-domain.com
,则NGROK_BASE_DOMAIN
设置为ngrok.your-domain.com
;
下面以ngrok.your-domain.com
为例:
1 2 3 4 5 |
openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=ngrok.your-domain.com" -days 5000 -out rootCA.pem openssl genrsa -out device.key 2048 openssl req -new -key device.key -subj "/CN=ngrok.your-domain.com" -out device.csr openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000 |
执行完以上命令,就会在ngrok
目录下新生成6个文件
1 2 3 4 5 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
的默认证书文件,我们需要将它们替换成我们自己生成的:(因此这一步务必放在编译可执行文件之前)
1 2 3 |
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和ngrok
编译linux端版本
1 2 3 4 |
make clean # 如果是32位系统,这里 GOARCH=386 GOOS=linux GOARCH=amd64 make release-server release-client |
最后成功的话,会在当前目录生成一个bin
文件夹,里面包含了ngrokd
和ngrok
文件;
其中,bin/ngrokd
文件是服务端程序;
bin/ngrok
文件是客户端程序(注意上面指定了GOOS
为64位linux的,所以这个文件是不能在mac
或win
等其他平台跑的,下面将进行说明如何交叉编译)
编译mac端版本
1 2 3 4 |
cd ~/your_download_dir/ngrok # 如果是win端版本,GOOS=windows;如果是32位系统,GOARCH=386 GOOS=darwin GOARCH=amd64 make release-client |
成功的话,会在./bin/darwin_amd64/
下有个文件,将这个文件下载到mac上
1 2 |
sz . darwin_amd64/ngrok |
设置域名解析
1 2 3 4 5 6 7 |
# 如果最终需要的ngrok地址为: example.your-domain.com,则 设置 * 记录指向服务器IP # 如果最终需要的ngrok地址为: example.ngrok.your-domain.com,则 设置 *.ngrok 记录指向服务器IP # 或者不想进行泛解析,则手动添加即可,如设置example记录指向服务器IP,example.ngrok记录指向服务器IP |
使用方法
服务端
nginx端口转发
由于本机的80
端口已经被占用了,所以需要利用nginx
进行端口的转发,加上如下配置即可:
1 2 |
vim local conf nginx.your-domain.com.conf |
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
upstream ngrok { server 127.0.0.1:8777; # 此处端口要跟 启动服务端ngrok 时指定的端口一致 keepalive 64; } server { listen 80; server_name *.ngrok.your-domain.com; access_log /data/wwwlogs/ngrok.your-domain.com_access.log; error_log /data/wwwlogs/ngrok.your-domain.com_error.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host:8777; # 此处端口要跟 启动服务端ngrok 时指定的端口一致 proxy_set_header X-Nginx-Proxy true; proxy_set_header Connection ""; proxy_pass http://ngrok; } } |
重启nginx
1 2 |
nginx -t nginx -s reload |
启动服务端ngrok
1 2 3 4 5 6 7 8 9 10 11 |
bin/ngrokd -domain="ngrok.your-domain.com" -httpAddr=":8777" -httpsAddr=":8778" nohup bin/ngrokd -domain="ngrok.your-domain.com" -httpAddr=":8777" -httpsAddr=":8778" > /dev/null 2>&1 & vim /etc/rc.d/rc.local {your-ngrok-dir}/bin/ngrokd -domain="ngrok.your-domain.com" -httpAddr=":8777" -httpsAddr=":8778" > /var/log/ngrok.log & |
客户端
确保刚才下载的mac版ngrok
有执行权限
1
|
chmod +x ngrok
|
在ngrok
程序的同级目录下,编写配置文件
1
|
vim ngrok.cfg
|
内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
server_addr: "ngrok.your-domain.com:4443" trust_host_root_certs: false tunnels: example: subdomain: "example" proto: http: 80 https: 80 web: subdomain: "web" proto: http: 192.168.1.100:80 https: 192.168.1.100:80 web1: hostname: "ngrok.your-domain.com" proto: http: 80 web2: hostname: "your-domain.com" proto: http: 80 ssh: remote_port: 50001 proto: tcp: 22 ssh1: proto: tcp: 21 |
启动ngrok
1 2 3 4 5 6 7 8 9 |
./ngrok -subdomain example -config=ngrok.cfg 80 ./ngrok -config ngrok.cfg start example |
在本地进行微信公众号的调试
接下来就可以进行微信公众号在本地的开发了,只要在本地设置好nginx
(server_name
要跟上文对应,如上面的example.ngrok.your-domain.com
)
由于微信只允许使用80端口,所以一定要进行上面的nginx的端口转发设置才行
另外,ngrok
本身提供了127.0.0.1:4040
这个地址,可以查看到所有的http数据包内容(在php文件里var_dump
的东西也可以看到)
遇到的问题
ngrok端口的防火墙问题
由于服务器上开启了防火墙,使用的是iptables
,所以需要将上面的端口添加到白名单
(一共3个,一个是ngrok
自身的4443
端口,还有自定义的8777
http端口,8778
https端口)
1
|
vim sysconfig/iptables
|
添加以下内容
1 2 3 |
-A RH-Firewall-1-INPUT -m state -state NEW -m tcp -p tcp -dport 4443 -j ACCEPT -A RH-Firewall-1-INPUT -m state -state NEW -m tcp -p tcp -dport 8777 -j ACCEPT -A RH-Firewall-1-INPUT -m state -state NEW -m tcp -p tcp -dport 8778 -j ACCEPT |
重启iptables
1
|
service iptables restart
|
ngrok的交叉编译
在服务器上要编译个mac
端的版本时,网上说需要进行go的源码,去进行GOOS的设置:
1 2 |
cd /usr/local/go/src GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 ./make.bash |
但是我拿另一台服务器测试过后,不用这样也行,直接按刚才上面说的,在ngrok
目录去进行mac端版本
的编译即可。
PS: 以下内容不能看也行,只是中间遇到的问题的一些记录而已
我第一次照着网上说的去go源码设置GOOS,反而会报这样的错:
1 2 3 |
go ./make.bash: eval: line 135: syntax error near unexpected token `( ERROR: Cannot find /root/go1.4/bin/go. Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4. |
google了下,说现在新的go都不用C编写了,而1.4之前的是C编写的,所以需要先安装1.4的,才能编译1.6的,于是便先安装了1.4,再安装1.6,步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
echo 'export GOROOT=/usr/local/go' >> /etc/profile echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/profile echo 'export GOPATH=$HOME/go' >> /etc/profile echo 'export GOROOT_BOOTSTRAP=/usr/local/go' >> /etc/profile source /etc/profile cd ~/your_download_dir # 先下载1.4的源码 wget https://storage.googleapis.com/golang/go1.4.3.linux-amd64.tar.gz tar -C /usr/local -xzf go1.4.3.linux-amd64.tar.gz #tar -xzf go1.4.3.linux-amd64.tar.gz #mv ./go /usr/local/go cd /usr/local/go/src ./all.bash # 查看版本,现在是1.4.3的 go version # 将1.4的源码目录名更改为go1.4,go这个目录名等下给1.6用 mv /usr/local/go/ /usr/local/go1.4/ vim /etc/profile # 默认的 GOROOT_BOOTSTRAP 是: $HOME/go1.4,因为我放在了`/usr/local/go1.4`,所以这里要指定该值 export GOROOT_BOOTSTRAP=/usr/local/go1.4 cd ~/your_download_dir wget https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz cd /usr/local/go/src ./all.bash # 查看版本,现在是1.6的 go version |
最后再次进行测试验证了不用先安装1.4再安装1.6这么麻烦。。
总结
中间虽然遇到了一些坑,google查了好几个钟的资料,昨晚弄到凌晨2点多,不过最终弄成功,并且验证了一些安装过程的想法,还是挺有成就感的。
还好大学时就有稍微折腾过linux,去年转后台开发时就用上了一些知识,现在服务器遇到一些基本问题最终也能解决了。
所以还是不能停止学习的脚步啊。
趁现在还年轻,多折腾。。