1. 配置 ngrok 的编译环境
sudo apt-get install git bison build-essential mercurial bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm- installer) echo "[[ -s "$HOME/.gvm/scripts/gvm" ]] && source "$HOME/.gvm/scripts/gvm"" >> ~/.bashrc source ~/.bashrc gvm install go1.4 gvm use go1.4 export GOROOT_BOOTSTRAP=$GOROOT
参考资料:https://medium.com/@unnikked/how-to-compile-ngrok-on-a-raspberry-pi-d5a78ce4b15c#.vdw95rslb
2. 编译 ngrok
git clone https://github.com/inconshreveable/ngrok.git ngrok cd ngrok NGROK_DOMAIN="example.com" 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
编译 linux 64 bit 版本的 ngrok
GOOS=linux GOARCH=amd64 ./make.bash GOOS=linux GOARCH=amd64 make release-client
编译 linux 32 bit 版本的 ngrok
cd ~/.gwm/gos/go1.4/src GOOS=linux GOARCH=amd64 ./make.bash cd ~/ngrok GOOS=linux GOARCH=amd64 ./make.bash GOOS=linux GOARCH=arm ./make.bash GOOS=linux GOARCH=arm make release-client GOOS=windows GOARCH=amd64 ./make.bash GOOS=windows GOARCH=amd64 make release-client GOOS=windows GOARCH=386 ./make.bash GOOS=windows GOARCH=386 make release-client
参考资料:http://www.mamicode.com/info-detail-1230154.html
http://tonybai.com/2014/10/20/cross-compilation-with-golang/
3. 测试 ngrok 服务端和客户端
sudo cp ngrok /usr/local/ngrok/ sudo cp ngrokd /usr/local/ngrok/ sudo vim /usr/local/ngrok/ngrok.cfg
服务端
sudo ./ngrok -tlsKey=device.key -tlsCrt=device.crt -domain="$NGROK_DOMAIN" -httpAddr=”:8000" -httpsAddr=”:8001"
客户端
#ngrok.cfg server_addr: "zisu.org:4443" trust_host_root_certs: false inspect_addr: disabled tunnels: web: proto: http: 8081 app: proto: http: 8765 ssh: remote_port: 222 proto: tcp: 22
./ngrok -subdomain web -proto=http -config=ngrok.cfg 8081 ./ngrok -config=ngrok.cfg start web
如果服务端和客户端测试没有问题,可以设置为自启动
服务端:
sudo vim /etc/init.d/ngrokd #!/bin/sh ### BEGIN INIT INFO # Provides: ngrokd # Required-Start: $local_fs $remote_fs $network # Required-Stop: $local_fs $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: ngrokd # Description: # ### END INIT INFO NAME=ngrokd DAEMON=/usr/local/ngrok/$NAME KEY=/usr/local/ngrok/server.key CRT=/usr/local/ngrok/server.crt DOMAIN="example.com" HTTPADDR=":8080" HTTPSADDR=":8081" [ -x "$DAEMON" ] || exit 0 case "$1" in start) echo "Starting $NAME..." start-stop-daemon --start --chuid root --exec $DAEMON --quiet --oknodo --background -- -tlsKey=$KEY -tlsCrt=$CRT -domain=$DOMAIN -httpAddr=$HTTPADDR -httpsAddr=$HTTPSADDR || return 2 ;; stop) echo "Stopping $NAME..." start-stop-daemon --stop --exec $DAEMON --quiet --oknodo --retry=TERM/30/KILL/5 || return 2 ;; restart) $0 stop && sleep 2 && $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0
sudo update-rc.d ngrokd defaults
客户端:
sudo vim /etc/init.d/ngrok #!/bin/sh ### BEGIN INIT INFO # Provides: ngrok # Required-Start: $local_fs $remote_fs $network # Required-Stop: $local_fs $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: ngrok # Description: # ### END INIT INFO NAME=ngrok DAEMON=/usr/local/ngrok/$NAME CONFIG=/usr/local/ngrok/ngrok.cfg TUNNELS="web ssh" [ -x "$DAEMON" ] || exit 0 case "$1" in start) echo "Starting $NAME..." start-stop-daemon --start --chuid pi --exec $DAEMON --quiet --oknodo --background -- -config $CONFIG start $TUNNELS || return 2 ;; stop) echo "Stopping $NAME..." start-stop-daemon --stop --exec $DAEMON --quiet --oknodo --retry=TERM/30/KILL/5 || return 2 ;; restart) $0 stop && sleep 2 && $0 start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 ;; esac exit 0
sudo update-rc.d ngrok defaults
参考资料:http://www.tuicool.com/articles/MRJjmuv
4. 使用 supervisor 后台运行 ngrok
sudo apt-get install supervisor
在 supervisord.conf 添加如下配置
[include] files = supervisord.d/*.conf sudo vim ngrok.conf [program:ngrok] directory = /usr/local/ngrok command = /usr/local/ngrok/ngrok -config=ngrok.cfg -log=stdout process_name = %(program_name)s_%(process_num)s numprocs = 1 autostart = true autorestart = true stdout_logfile = /var/log/supervisor/ngrok_stdout.log stdout_logfile_maxbytes = 10MB stderr_logfile = /var/log/supervisor/ngrok_error.log stderr_logfile_maxbytes = 10MB
启动 supervisor
sudo supervisorctl reread sudo supervisorctl add ngrok sudo supervisorctl update ngrok sudo supervisorctl status
启动和停止 ngrok
sudo supervisorctl start ngrok sudo supervisorctl stop ngrok
参考资料:https://natapp.cn/article/supervisor
5. 修改 DNS 解析
同时将 example.com 和 *.example.com 解析到 VPS 上,可直接设置将其 A 记录解析到 VPS 的 IP 上,使用二级域名也是可以,但是需要选择支持泛解析的 DNS 服务商,像 DNspod。
6. 常见问题
编译成功的 ngrok 在 Linux 和 Windows 上都可以正常运行,但是 arm 版本在 Raspberry Pi 上会出现内存泄漏的问题,一般运行一段时间后内存耗尽后就会自动退出。
https://github.com/inconshreveable/ngrok/issues/109
解决方法就是在配置文件 ngrok.cfg 下添加 inspect_addr: disabled,关闭管理界面。
#sudo vim ngrok.cfg server_addr: "domain.com:4443" trust_host_root_certs: false inspect_addr: disabled
同时将记录以正常文本的形式输出,即在启动命令后面加入 -log=stdout 选项。
./ngrok -config=ngrok.cfg -log=stdout start web
在程序能正确运行无错误时,甚至可以将记录输出到 /dev/null 文件,ngrok 正常输出的 log 实在太多了。
./ngrok -config=ngrok.cfg -log=stdout start web >/dev/null
7. ngrok 与 nginx 配合使用
上面的配置是针对单独的 VPS 用来搭建 ngrok 的情况,但是,如果 VPS 上的 80 端口还要用于其它服务的话,就需要修改 nginx 的配置。
server { listen 80; server_name *.domain.com; root html; index index.html index.htm index.php; location / { proxy_pass http://127.0.0.1:8000; #Proxy Settings proxy_redirect off; #proxy_set_header Host downloads.openwrt.org; proxy_set_header Host $host:8000; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } } server { listen 443; server_name *.*.domain.com; ssl on; ssl_certificate /etc/fullchain.pem; ssl_certificate_key /etc/privkey.pem; root html; index index.html index.htm index.php; location / { proxy_pass https://127.0.0.1:8001; #Proxy Settings proxy_redirect off; #proxy_set_header Host downloads.openwrt.org; proxy_set_header Host $host:8001; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } }
上述配置中需要修改的是 server_name 处的域名,proxy_pass 和 proxy_set_header 处的端口号,共计6处。然后测试 nginx 能否通过。
sudo nginx -t sudo nginx -s reload
Recent Comments