1. 安装

  • 手动搭建ngrok服务器(生成ngrok服务端和客户端文件)、启动ngrok服务器
  • 安装杂项
[root@host ~]# 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++ build-essential  mercurial
  • 安装golang
## 境外
    [root@host ~]# wget https://storage.googleapis.com/golang/go1.7.6.linux-amd64.tar.gz
## 境内
    [root@host ~]# wget https://www.golangtc.com/static/go/1.7.6/go1.7.6.linux-amd64.tar.gz
[root@host ~]# tar zxvf go1.7.6.linux-amd64.tar.gz
[root@host ~]# mv go /usr/local/
[root@host ~]# ln -s /usr/local/go/bin/* /usr/bin/
[root@host ~]# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build554985173=/tmp/go-build"
CXX="g++"
CGO_ENABLED="1"
  • Go编译过程中要求高版本的git
[root@host ~]# wget https://www.kernel.org/pub/software/scm/git/git-2.9.3.tar.gz
[root@host ~]# tar zxvf git-2.9.3.tar.gz
[root@host ~]# cd git-2.9.3
[root@host git-2.9.3]# ./configure --prefix=/usr/local/git-2.9.3
[root@host git-2.9.3]# make && make install
[root@host git-2.9.3]# yum remove git*
[root@host git-2.9.3]# ln -s /usr/local/git-2.9.3/bin/* /usr/bin/
[root@host git-2.9.3]# git --version
git version 2.9.3
  • ngrok源码配置
## 声明编译的路径和必要的域名(域名改成你自己的)
[root@host ~]# git clone https://github.com/inconshreveable/ngrok.git ~/ngrok
[root@host ~]# export GOPATH=~/ngrok/
[root@host ~]# export NGROK_DOMAIN="ngrok.test.com"
[root@host ~]# cd ~/ngrok
  • 生成证书,Ngrok会使用此证书加密通讯
[root@host ngrok]# openssl genrsa -out base.key 2048
[root@host ngrok]# openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
[root@host ngrok]# openssl genrsa -out server.key 2048
[root@host ngrok]# openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
[root@host ngrok]# openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt
  • 复制证书到指定位置
[root@host ngrok]# cp base.pem assets/client/tls/ngrokroot.crt -i
[root@host ngrok]# cp server.crt assets/server/tls/snakeoil.crt -i
[root@host ngrok]# cp server.key assets/server/tls/snakeoil.key -i
  • 编译服务器端与客户端
# 服务器端为linux-x86-64
[root@host ngrok]# export GOOS=linux
[root@host ngrok]# export GOARCH=386
[root@host ngrok]# make release-server

# 如果客户端也是x86架构,则直接生成客户端
[root@host ngrok]# make release-client

# 如果客户端为arm架构(比如树莓派)
[root@host ngrok]# export GOARCH=arm
[root@host ngrok]# make release-client

# 编译完客户端位于:/root/ngrok/bin/linux_386
  • 添加域名解析
  • 到你的域名托管后台添加相应的域名解析到服务器ip(如:ngrok.test.com 和 *.ngrok.test.com)
  • 服务器端部署
# 将编译好的可执行文件移至/usr/bin/下
[root@host linux_386]# ln -s /root/ngrok/bin/linux_386/ngrokd /usr/bin/

# 运行ngrokd
[root@host linux_386]# ngrokd -domain="ngrok.test.com" -httpAddr=":10000" -httpsAddr=":443"

屏幕会输出一连串日志信息,httpAddr、httpsAddr 分别是 ngrok 用来转发 http、https 服务的端口,ngrokd 还会开一个 4443 端口用来跟客户端通讯,注意设置防火墙使端口开放。

  • 客户端部署
# 将/root/ngrok/bin/linux_386/ngrok 移至本地服务器,并在同目录下新建配置文件:ngrok.cfg
[xxx@host ~]# sudo mkdir /home/xxx/ngrok_client && cd /home/xxx/ngrok_client
[xxx@host ngrok_client]# sudo vi ngrok.cfg
server_addr: test.com:4443
trust_host_root_certs: false
inspect_addr: disabled
tunnels:
    ssh:
        remote_port: 2200
        proto:
            tcp: 22
    ftp:
        remote_port: 2000
        proto:
            tcp: 20
    mysql:
        remote_port: 33060
        proto:
            tcp: 3306
    test:
        subdomain: test
        proto:
            http: 80
    ip:
        hostname: 12.34.56.78
        proto:
            http: 80
    www:
        hostname: www.test.com
        proto:
            http: 80
            https: 192.168.1.4:443
  • 部分参数说明
server_addr: test.com:4443      # 远程服务器地址
trust_host_root_certs: false    # 如使用自签名证书,则须添加此键且指定值为 `false`
remote_port: 220                # 指定远程端口, proto==tcp时必须配置,且每个tunnel对应一个不同的端口,否则冲突。
subdomain: test                 # 指定次级域名字段,通过该字段+远程服务器域名访问该tunnel
hostname: www.test.com          # 指定一个完整域名,该域名必须不与其它tunnel指定过的重复,必须唯一。指定该参数以后就可以通过该域名访问了。该参数与subdomain参数不可同时生效。
inspect_addr: disabled          # 关闭web观察器。1.7版本存在内存泄露,在使用期间会将客户端内存耗尽,关闭web观察器可使其保持稳定,具体内容参考此链接:https://github.com/inconshreveable/ngrok/issues/109
  • 开启客户端
[root@host ngrok_client]# screen -S ngrok
[root@host ngrok_client]# ./ngrok  -config=ngrok.cfg start-all
# Ctr+A+D 后台运行

2. 创建服务

  • 服务端(CentOS7)
  • 为了所有次级域名全部开启HTTPS,需要注册通配符域名(Let’s Encrypt)
  • 申请下来证书位于:"/etc/letsencrypt/",会在live目录下创建软连接,以实现自动更新。
  • 使用的时候直接引用"/etc/letsencrypt/live/xxx.com/*.pem"即可。
  • 制作脚本 /my_sh/ngrokd.sh 和 /my_sh/kill_ngrokd.sh
# vi /my_sh/ngrokd.sh
# nohup /usr/bin/ngrokd -domain="xxx.com" -httpAddr=":80" -httpsAddr=":443" -log=stdout >/dev/null &

nohup /usr/bin/ngrokd -domain="xxx.com" -httpAddr=":80" -httpsAddr=":443" -tlsKey="/etc/letsencrypt/live/xxx.com-0001/privkey.pem" -tlsCrt="/etc/letsencrypt/live/xxx.com-0001/fullchain.pem" -log=stdout >/dev/null &

# vi /my_sh/kill_ngrokd.sh
/usr/bin/killall /usr/bin/ngrokd
  • 加入服务 /etc/rc.d/init.d/ngrokd
#!/bin/sh
#chkconfig:2345 70 30
#description:ngrokd

ngrokd_path=/my_sh/ngrokd.sh
kill_ngrokd_path=/my_sh/kill_ngrokd.sh

case "$1" in
    start)
        echo "start ngrokd server..."
        sh ${ngrokd_path}
        echo "done."
        ;;
    stop)
        echo "stop ngrokd server..."
        sh ${kill_ngrokd_path}
        echo "done."
        ;;
    restart)
        echo "restart ngrokd server..."
        sh ${kill_ngrokd_path}
        sh ${ngrokd_path}
        echo "done."
        ;;
    *)
exit 1
;;
esac
  • 赋予可执行权限
[root@host ~]# chmod a+x /etc/rc.d/init.d/ngrokd
  • 安装screen
  • 启动服务并在后台运行
[root@host ~]# service ngrokd start
  • 设置开机自启动
[root@host ~]# chkconfig --add ngrokd
[root@host ~]# chkconfig ngrokd on
  • 客户端配置
  • 制作脚本 /home/xxx/my_sh/ngrok.sh 和 /home/xxx/my_sh/kill_ngrok.sh
# sudo vi /home/xxx/my_sh/ngrok.sh
nohup /home/xxx/ngrok_client/ngrok  -config=/home/xxx/ngrok_client/ngrok.cfg -log=stdout start-all >/dev/null &

# sudo vi /home/xxx/my_sh/kill_ngrok.sh
/usr/bin/killall /home/xxx/ngrok_client/ngrok
  • 加入服务 /etc/rc.d/init.d/ngrok
#!/bin/sh
#chkconfig:2345 70 30
#description:ngrok

ngrok_path=/home/xxx/my_sh/ngrok.sh
kill_ngrok_path=/home/xxx/my_sh/kill_ngrok.sh

case "$1" in
    start)
        echo "start ngrok client..."
        sh ${ngrok_path}
        echo "done."
        ;;
    stop)
        echo "stop ngrok client..."
        sh ${kill_ngrok_path}
        echo "done."
        ;;
    restart)
        echo "restart ngrok client..."
        sh ${kill_ngrok_path}
        sleep 1  
        sh ${ngrok_path}
        echo "done."
        ;;
    *)
exit 1
;;
esac
  • 赋予可执行权限
[root@host ~]# chmod a+x /etc/rc.d/init.d/ngrok
  • 安装screen
  • 启动服务并在后台运行
[root@host ~]# service ngrok start
  • 设置开机自启动
[root@host ~]# chkconfig --add ngrok
[root@host ~]# chkconfig ngrok on