Leo Code

主页 > 服务器 > 搭建ngrok服务器及跨平台客户端内网穿透的使用

搭建ngrok服务器及跨平台客户端内网穿透的使用

有些时候需要开发微信或者支付等接口时需要一个公网地址,调试的时候只能上传到服务器检查错误,这样不断的在服务器上调试,效率是非常低的。当然,我们可以使用花生壳一类的内网穿透软件,但是免费版限制重重,不如自己搭建一个内网穿透的服务器,用起来的心应手,也不用担心隐私泄露等问题。

目前比较流行的就是ngrok,这个软件有官方的服务器,国内是无法直接使用的(需要翻出去),但是这个软件是开源的,那么自己搭建一个是再好不过的选择了。下面开始搭建步骤:

一、准备工作

1.准备一个有公网IP的VPS。
2.需要一个能够自由解析的域名。

二、解析域名

使用自己的域名,把域名解析到VPS的地址,解析方式如下:

ngrok.leocode.net     ------->  A记录到你的VPS IP
*.ngrok.leocode.net   ------->  CNAME到ngrok.leocode.net

三、VPS服务端安转go环境

因为ngrok是由go语言开发的,所以,要先安装go环境(不要使用yum安装,因为yum安装的go版本过低会导致ngrok编译失败),步骤如下:

官方网址:https://golang.org/dl/

目前最新的版本是1.6.2,对应系统,64位系统选择 go1.6.2.linux-amd64.tar.gz,32位请选择 go1.6.2.linux-386.tar.gz。

1.依次执行以下命令

cd ~
wget https://go.googlecode.com/files/go1.6.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz

2.设置环境变量

# 可以根据自己需要调整路径  
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

3.检查是否安装成功

go version
# 正常的话会返回类似这样的信息: go version go1.6.2 linux/amd64

4.这里有个坑,现在还没有遇到,等一会安装编译ngrok时如果出现问题,请查看文章的失败处理部分。

四、VPS安装git

ngrok的源文件在Github上维护,所以,安装最新版的git,请不要使用yum安装或自带的git,因为yum安装的git版本过低,导致无法同步ngrok的最新版本。执行下面步骤前一定要确保自己的git版本大于1.7.9.5,git版本过低的话,我曾经试过,下载ngrok时会莫名奇妙的卡住不动,也不报错。这一步当时的莫名其妙的错误让我费了不少周折,也查阅了不少资料。安装步骤如下:

1. 卸载自带的1.7.1版本git

yum remove git

2.安装一些 git 构建或执行时需要的其他依赖。

yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
yum install  gcc perl-ExtUtils-MakeMaker

3.下载 git 最新版本的源代码

cd ~
wget https://www.kernel.org/pub/software/scm/git/git-2.9.1.tar.gz
tar xzf git-2.9.1.tar.gz

4.安装并修改环境变量

cd git-2.9.1
make prefix=/usr/local/git all
make prefix=/usr/local/git install
echo "export PATH=$PATH:/usr/local/git/bin" >> /etc/bashrc
source /etc/bashrc

5.查看版本

# git --version
正常返回git version 2.9.1

五、VPS安装ngrok

1.下载ngrok,并修改参数

cd /usr/local/
git clone https://github.com/inconshreveable/ngrok.git
export GOPATH=/usr/local/ngrok/
export NGROK_DOMAIN="ngrok.leocode.net"
cd ngrok

2.生成证书(重要)

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 server.key 2048
openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000

3.在软件源代码目录下面会生成一些证书文件,我们需要把这些文件拷贝到指定位置

cp rootCA.pem assets/client/tls/ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt
cp server.key assets/server/tls/snakeoil.key

4.如果是在国内的服务器需要执行此步,香港或者国外的服务器不需要

vim /usr/local/ngrok/src/ngrok/log/logger.go
log "github.com/keepeye/log4go"

5.编译服务端(同时也编译了一个linux下的客户端),注意这里的amd64,如果是32位的话,请修改成386

cd /usr/local/go/src
GOOS=linux GOARCH=amd64 ./make.bash
cd /usr/local/ngrok/
GOOS=linux GOARCH=amd64 make release-server release-client

6.编译MAC 64位客户端

cd /usr/local/go/src
GOOS=darwin GOARCH=amd64 ./make.bash
cd /usr/local/ngrok/
GOOS=darwin GOARCH=amd64 make release-client

7.编译windows 64位客户端

cd /usr/local/go/src
GOOS=windows GOARCH=amd64 ./make.bash
cd /usr/local/ngrok/
GOOS=windows GOARCH=amd64 make release-client

六、服务端的运行及使用

1.进入服务端目录,服务端程序文件名是ngrokd

cd /usr/local/ngrok/bin

2.运行服务端程序,注意这里有个坑的可能,我是遇到了,如果待会客户端运行时连上服务端了但是域名不完整,请看文章的失败处理部分。

./ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":80"

3.运行成功后会返回类似如下的结果

[22:19:07 EDT 2016/07/13] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[22:19:07 EDT 2016/07/13] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[22:19:07 EDT 2016/07/13] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[22:19:07 EDT 2016/07/13] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[22:19:07 EDT 2016/07/13] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds

七、客户端的运行及使用

1.把刚刚从VPS服务器上生成的客户端文件下载到本机

mac的客户端位置:

/usr/local/ngrok/bin/darwin_amd64/ngrok

windows客户端位置:

/usr/local/ngrok/bin/windows_amd64/ngrok.exe

2.把里面的客户端文件下载到本地,并在同目录下新建一个配置文件,文件名ngrok.cfg,文件内容如下

server_addr: "ngrok.leocode.net:4443"
trust_host_root_certs: false

3.客户端的运行

./ngrok -config=./ngrok.cfg -subdomain=test 8011
# -subdomain参数指的是域名,例如这里是test.ngrok.leocode.net
# 后面的80是指本机端口,这里是指把本机的8011端口开放穿透
# windows运行客户端,请把./改成win风格的目录方式

4.成功运行后返回类似如下

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://test.ngrok.leocode.net -> 127.0.0.1:8011
Forwarding                    https://test.ngrok.leocode.net -> 127.0.0.1:8011
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

5.打开http://test.ngrok.leocode.net即可访问到本机8011端口的网站

八、失败处理

我在编译和使用的过程中出现过很多失败和错误,在这里简单说一说,免得走弯路。

1.下载编译和安装ngrok的时候一直卡在一个地方不动,这是git版本过低表现。

2.编译ngrok服务端和客户端时提示错误

ERROR: Cannot find /root/go1.4/bin/go.
Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.

3.遇到上面的错误,说明便宜的时候,说明还要使用1.4版本的内容,请执行下面的步骤

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
source /etc/profile

cd ~/your_download_dir
wget https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.6.2.linux-amd64.tar.gz
cd /usr/local/go/src
./all.bash

# 查看版本,现在是1.6.2的
go version

4.客户端可以连上,但是域名不完全,显示方式如下:

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://test. -> 127.0.0.1:8011
Forwarding                    https://test. -> 127.0.0.1:8011
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

这种错误出现,请在服务端运行时的命令改一下,使用以下命令强制规定域名

./ngrokd -domain="ngrok.leocode.net" -httpAddr=":80"

九、如果VPS服务器已有80端口的网站在线上,那么服务端运行的时候,似乎就不能使用80端口了,至于还想使用80端口穿透到内网的地址的话,需要nginx做反向代理,这个我没有做测试,因为我的服务器没有网站在上面。可查阅其他资料。