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
参考资料:https://segmentfault.com/q/1010000004277269
Recent Comments