记录一下自己搭建ngrok服务端及客户端时使用的教程以及遇到的坑
一、下载/编译ngrok
安装编译所需软件# 注意:git版本不能低于1.8,版本太低可能会导致编译失败
yum install -y git
yum install -y perl-ExtUtils-MakeMaker mercurial
yum install -y golang
从github下载ngrok源代码
cd /opt git clone https://github.com/inconshreveable/ngrok.git
生成二级子域名的秘钥# 修改成自己的子用户名,例如
dev.soulfree.cn
cd /opt/ngrok
NGROK_DOMAIN="dev.soulfree.cn" # 修改为自己的域名
openssl genrsa -out base.key 2048
openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.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 base.pem -CAkey base.key -CAcreateserial -out server.crt -days 5000
将生成的秘钥复制到编译目录 /assets/server/tls/ 中
cp server.crt ./assets/server/tls/snakeoil.crt
cp server.key ./assets/server/tls/snakeoil.key
cp base.pem ./assets/client/tls/ngrokroot.crt
开始编译
make release-server
可能会遇到以下报错
# 通过执行:
unset GOROOT
# 解决问题
- 第一次执行编译时候,由于编译过程中会从github中获取依赖的包(大约60多MB),所以耗时主要取决于github的访问速度。
- 如果阿里云访问github速度很慢,需要忍耐或者想办法解决。
- 如果出错,重新执行该命令,会断点续传。出错的原因一般是github被你懂的中断。
- 如果有国外的服务器,也可以在国外的服务器上进行编译。
- 第二次编译时候,由于不再需要下载一些依赖包,所以编译会瞬间完成 (我在阿里云主机上下载用了大约30多分钟,中间反复执行了该命令三次,问候了墙无数次)
编译不同平台的客户端
# 编译Linux64位版(生成:/opt/ngrok/bin/ngrok)
make release-client
# 编译Mac版 (生成:/opt/ngrok/bin/darwin_amd64/ngrok) GOOS=darwin GOARCH=amd64 make release-client
# 编译Windows64位版 (生成:/opt/ngrok/bin/windows_amd64/ngrok.exe) GOOS=windows GOARCH=amd64 make release-client
# 编译Windows32位版 (生成:/opt/ngrok/bin/windows_386/ngrok.exe) GOOS=windows GOARCH=386 make release-client
将客户端程序下载并保存起来,分发给开发组的小伙伴们。
二、服务器端设置方法
CentOS云服务器设置防火墙,然后公开需要监听的端口
# 启动防火墙
systemctl start firewalld systemctl enable firewalld
# 放行ngrok需要的4443端口
firewall-cmd --zone=public --add-port=4443/tcp --permanent
# 放行80及443端口
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=https --permanent
# 放行自定义端口,例如:TCP 7070及7071端口
firewall-cmd --zone=public --add-port=7070/tcp --permanent
firewall-cmd --zone=public --add-port=7071/tcp --permanent
firewall-cmd --zone=public --add-port=7443/tcp --permanent
# 重新加载防火墙规则
firewall-cmd --reload
服务端启动ngrok
# 样例1:监听80口及443端口 (请将dev.soulfree.cn修改成自己的域名)
/opt/ngrok/bin/ngrokd -tlsKey=/opt/ngrok/server.key -tlsCrt=/opt/ngrok/server.crt -domain=dev.soulfree.cn -httpAddr=:80 -httpsAddr=:443 -tunnelAddr=:4443 > /opt/ngrok/ngrok.log &
# 样例2:监听7070口及7071端口 (请将dev.mydomain.com修改成自己的域名)
/opt/ngrok/bin/ngrokd -tlsKey=/opt/ngrok/server.key -tlsCrt=/opt/ngrok/server.crt -domain=dev.soulfree.cn -httpAddr=:7070 -httpsAddr=:7071 -tunnelAddr=:7443 > /opt/ngrok/ngrok.log &
# 尾部添加& 为后台运行
如果需要开机自启动,可以将该命令行写入到/etc/rc.local,或者编辑一个service脚本用于自动启动。
三、客户端设置方法
Macos
在自己的用户目录下创建一个文件夹,my_ngrok
mkdir ~/my_ngrok
cd ~/my_ngrok
将编译好的ngrok客户端直接下载保存,或者用scp工具下载
scp root@服务器host:/opt/ngrok/bin/darwin_amd64/ngrok ./
在当前目录下编辑一个配置文件ngrok.cfg,内容如下:(请将dev.mydomain.com修改成自己的域名)
server_addr: dev.mydomain.com:4443
trust_host_root_certs: false
运行客户端程序
cd ~/my_ngrok
./ngrok -subdomain abc -proto=http -config=./ngrok.cfg 3000
- 请将例子中的动态子域名
abc
修改成自己想要的子域名 - 请将本地应用服务器对应的端口
3000
修改成自己实际的端口,例如tomcat的8080 - 为了便于使用,推荐创建一个Shell启动脚本
- 如果出现
Tunnel Status online
的字样,说明配置成功了。可以通过公网的地址来访问。 - 退出客户端请用Ctrl+C Tunnel Status online Version 1.7/1.7 Forwarding http://adc.dev.soulfree.cn -> 127.0.0.1:3000 Web Interface 127.0.0.1:4040 # Conn 0 Avg Conn Time 0.00ms
- 在浏览器打开
http://adc.dev.soulfree.cn
,确认能正常访问。 在微信公众等平台上填写API地址时,填写自己的http://adc.dev.soulfree.cn/访问目录
- 访问
http://127.0.0.1:4040
,就可以看到所有来自外部的请求内容。
ngrok (Ctrl+C to quit) Tunnel Status online Version 1.7/1.7
Forwarding http://adc.ngrok.soulfree.cn:7070 -> 127.0.0.1:8080 Forwarding
https://adc.ngrok.soulfree.cn:7070 -> 127.0.0.1:8080
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
Windows
# 配置ngrok.cfg
server_addr: "ngrok.xxx.cn:4443" # 4443 为服务端启动时的tunnelAddr指定
trust_host_root_certs: false
cmd
ngrok -config=ngrok.cfg -subdomain=adc 8080
# 指定adc为 3级域名 指定本地8080端口
完美!
四、与nginx共存的设置方法
如果服务器上已经启动了80端口的nginx,那么ngrok服务器端就不能在80口启动。这时候ngrok只能启动在其他端口,例如在7070端口监听http请求。
# 监听7070口及7071端口 (请将dev.mydomain.com修改成自己的域名)
/opt/ngrok/bin/ngrokd -tlsKey=/opt/ngrok/server.key -tlsCrt=/opt/ngrok/server.crt -domain=dev.mydomain.com -httpAddr=:7070 -httpsAddr=:7071 -tunnelAddr=:7443 > /opt/ngrok/ngrok.log &
这种情况下仍然希望用80端口访问ngrok的话,可以在/etc/nginx/conf.d/
目录下配置一个nginx服务器的虚拟站点,例如: ngrok.conf,使用代理转发的方式将80端口的请求转发到ngrok的实际端口上。nginx的虚拟站点的配置文件示例:
# 配置文件:/etc/nginx/conf.d/ngrok.conf
# 请根据自己的实际情况调整端口及dev.mydomain.com的二级域名。
map $scheme $proxy_port {
"http" "7070";
"https" "7071";
default "7070";
}
server {
listen 80;
listen [::]:80;
listen 443;
listen [::]:443;
server_name *.dev.mydomain.com;
location / {
resolver 114.114.114.114 valid=2s;
proxy_pass $scheme://$host:$proxy_port;
proxy_redirect off;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 6 128k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
}
ssl on;
ssl_certificate /opt/ngrok/server.crt;
ssl_certificate_key /opt/ngrok/server.key;
access_log off;
log_not_found off;
}
配置完成后,重启nginx服务器
systemctl restart nginx
用这种方式就可以与其他nginx上的站点共存在一台服务器上了。