文章摘要:
ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放。

反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

通俗的来说,在一个局域网里,所有主机对外共用一个公网IP,外网是不能直接访问局域网内的主机的,如果某台主机需要映射至外部的话,需要在路由器端进行端口映射,或指明一台DMZ主机,但很多情况下,路由器并不是你家的,不是你想改就能改的,比如在公司,就里就需要网络管理员来操作,而且某些ISP并不提供公网IP,这时就需要用到反向代理了。

请输入图片描述


测试平台:

服务器:Centos7(具有公网IP的服务器)
客户端:Windows7/Debian8


1.安装工具
由于ngrok采用GO语言编写,所以需要先搭建GO语言环境:
下载编译好的文件:

# wget https://golang.google.cn/dl/go1.4.linux-386.tar.gz
# tar -xvf go1.4.linux-386.tar.gz -C/usr/local

添加环境变量:

export PATH=$PATH:/usr/loca/go/bin

注意事项: GO语言版本不要太高,编译GO1.6版本以上的需要依赖GO1.4版本的二进制,所以不如直接用V1.4就好。

安装openssl用于生成证书

# yum install openssl

安装其他工具

# yum install mercurial git bzr subversion

如果服务器上已经有相关软件,可以略过此步骤;


2.下载源码

# cd /usr/src/
# git clone https://github.com/inconshreveable/ngrok.git
# cd ngrok

3.设置参数(脚本)

#!/bin/sh

# 指定绑定的域名(重要),用于在下一步中生成证书;
export NGROK_DOMAIN="5201.pub" 
# 指定GO语言工作目录(源码目录)
export GOPATH=/usr/src/ngrok/       

# 生成SSH证书
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
# 复制证书到对应目录
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt 
cp device.key assets/server/tls/snakeoil.key

4.编译

编译服务器上运行的服务端

#GOOS=linux GOARCH=386 make release-server 

此操作将在bin/linux_386目录下生成ngrokd文件;

编译Linux上运行的客户端

#GOOS=linux GOARCH=386 make release-client

此操作将在bin/linux_386目录下生成ngrok文件,适用于Linux系统;


编译Windows上运行的客户端

设置交叉编译环境:

# cd /usr/local/go/src
# GOOS=windows GOARCH=386 ./make.bash

交叉编译:

# cd /usr/local/src/ngrok
# GOOS=windows GOARCH=386 make release-client

此操作将在bin/windows_386目录下生成ngrok文件,适用于Windows系统;


生成ARM开发板上运行的客户端

设置交叉编译环境:

# cd /usr/local/go/src
# GOOS=linux GOARCH=arm ./make.bash

交叉编译:

# cd /usr/local/src/ngrok
# GOOS=linux GOARCH=arm make release-client

此操作将在bin/linux_arm目录下生成ngrok文件,适用于ARM架构的Linux系统;
不适用用于没有硬件浮点运算单元的处理器(如S3C2410等)。


测试

服务器端

#./ngrokd -domain=5201.pub -httpAddr=:8080

-domain: 用于指明域名(重要),缺省值为ngork.com;
-httpAddr:http服务通道,缺省值为80;
-httpAddrs:http服务通道,缺省值为443;
-log: 指明运行日志文件,缺省值为stdout;
-log-level:日志输出等级,缺省值为DEBUG;
-tunnelAddr: ngork监听端口,缺省值为4443;

-tlsCrt: TLS认证文件路径;
-tlsKey: TLS密钥文件路径。

客户端(内网Windows/Linux)

新建一个配置文件ngrok.conf内容如下:

server_addr: "5201.pub:4443"
trust_host_root_certs: false

运行命令:

# ngrok -subdomain example -config=ngrok.conf 80

显示如下:

ngrok            (Ctrl+C to quit) 

Tunnel Status    online
Version          1.7/1.7
Forwarding       http://example.5201.pub:8080 -> 127.0.0.1:80
Forwarding       https://example.5201.pub:8080 -> 127.0.0.1:80
Web Interface    127.0.0.1:4040
#Conn            0
Avg Conn Time    0.00ms

至此可以外网通过http://example.5201.pub:8080来访问本机的Web服务器;
8080端口是服务器端运行时指定的,可以在服务器端修改为其他值;


功能完善
修改服务器ngrok.conf文件,添加其他服务:

server_addr: "5201.pub:4443"
trust_host_root_certs: false

tunnels:
  http:
    subdomain: "example"
    auth: "user:12345"
    proto:
      http: "80"

  ssh:
    remote_port: 2222
    proto:
      tcp: "22"

subdomain - 指名该服务的子域名,如果省略则指向根域名;
remote_port - 服务器远程端口
proto - 协议簇及端口
auth - 身份认证,暂时不知道怎么用

注意事项: 该配置文件不支持注释;

客户端运行:

# ngrok -config ngrok.conf start http ssh

注意事项:这里的运行命令与上边的又不一样了;

显示如下:

ngrok            (Ctrl+C to quit) 

Tunnel Status    online
Version          1.7/1.7
Forwarding       http://example.5201.pub:8080 -> 127.0.0.1:80
Forwarding       tcp://5201.pub:2222 -> 127.0.0.1:22
Web Interface    127.0.0.1:4040
#Conn            0
Avg Conn Time    0.00ms

服务器添加启动进程:
新建/etc/systemd/system/ngrokd.service文件,内容如下:

[Unit]
Description=ngrok reverse proxy server
After=network.target

[Service]
Type=daemon
ExecStart=/usr/local/bin/ngrokd -domain=5201.pub -httpAddr=:8080

[Install]
WantedBy=multi-user.target

运行服务进程:

#systemctl start ngrokd.service

使能开机启动:

#systemctl enable ngrokd.service