搭建Ngrok服务并实现内网穿透
内网穿透服务可以帮助我们从公网访问本地计算机上的服务与资源,对于开发人员来说是一款很实用的工具。虽然市面上有一些免费的穿透服务,但是用起来不仅慢,还有各种限制,想要更好的体验则需要使用付费服务。Ngrok(v1版本)是一个开源项目,使用Ngrok能简单、快速地实现内网穿透服务,最重要的是免费!免费!免费!(如果你有一台服务器的话)。
准备工作
Go语言
https://dl.google.com/go/go1.12.1.linux-amd64.tar.gz
注意一定要使用低版本
Ngrok源码
https://github.com/inconshreveable/ngrok/archive/refs/tags/1.7.1.zip
- 解析域名
我这里使用三级域名,因为二级域名有其他站点使用,*.rmt.yourdomain.com为三级域名,rmt.yourdomain.com为Ngrok通信使用
安装Go语言
要使用低版本,我这里使用源码安装
解压源码并移动到/usr/local/目录
tar -zxvf go1.12.1.linux-amd64.tar.gz mv go /usr/local/
添加环境变量
cd ~ vim .bashrc
向.bashrc文件中添加如下内容
export GOPROXY=https://goproxy.io,direct export GOROOT=/usr/local/go export PATH=$PATH:/usr/local/go/bin
更新环境变量
source ~/.bashrc
验证是否安装成功
go version
如果有版本信息打印出来就成功了
生成tls证书
添加NGROK_DOMAIN环境变量
vim ~/.bashrc
添加如下内容
export NGROK_DOMAIN="rmt.yourdomain.com"
更新环境变量
source ~/.bashrc
生成证书
cd /usr/local/go mkdir cert cd cert 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 server.key 2048 openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000
替换默认证书
cp rootCA.pem ../assets/client/tls/ngrokroot.crt cp server.crt ../assets/server/tls/snakeoil.crt cp server.key ../assets/server/tls/snakeoil.key
编译生成可执行文件
Linux服务端和Windows客户端
GOOS=linux GOARCH=amd64 make release-server
GOOS=windows GOARCH=amd64 make release-client
其他平台
Linux 32位:GOOS=linux GOARCH=386
Linux 64位:GOOS=linux GOARCH=amd64
Windows 32位:GOOS=windows GOARCH=386
Windows 64位:GOOS=windows GOARCH=amd64
MAC 32位:GOOS=darwin GOARCH=386
MAC 64位:GOOS=darwin GOARCH=amd64
ARM:GOOS=linux GOARCH=arm
生成的可执行文件位于bin目录下
报错解决
code.google.com/p/log4go
package code.google.com/p/log4go: unrecognized import path "code.google.com/p/log4go" (parse https://code.google.com/p/log4go?go-get=1: no go-import meta tags ()) make: *** [Makefile:8:deps] 错误 1
解决办法:将文件src/ngrok/log/logger.go中的code.google.com/p/log4go改为
github.com/alecthomas/log4go
github.com/rivo/uniseg
package github.com/rivo/uniseg: found packages uniseg (doc.go) and main (gen_breaktest.go) in /root/software/ngrok-1.7.1/src/github.com/rivo/uniseg make: *** [Makefile:8:deps] 错误 1
解决办法:使用低版本rivo/uniseg,如v0.1.0,解压替换src/github.com/rivo/uniseg中的文件
github.com/gorilla/websocket
src/github.com/gorilla/websocket/client.go:408:15: undefined: io.NopCloser src/github.com/gorilla/websocket/client.go:426:14: undefined: io.NopCloser src/github.com/gorilla/websocket/conn.go:808:25: undefined: io.Discard src/github.com/gorilla/websocket/conn.go:1113:11: undefined: io.ReadAll src/github.com/gorilla/websocket/server.go:177:23: undefined: http.NewResponseController src/github.com/gorilla/websocket/tls_handshake.go:9:19: tlsConn.HandshakeContext undefined (type *tls.Conn has no field or method HandshakeContext) make: *** [Makefile:17:client] 错误 2
解决办法:使用低版本gorilla/websocket,如v1.4.1,解压替换src/github.com/gorilla/websocket中的文件
启动服务端
Ngrok通信使用的端口只要没被占用就可以,这里以9500端口为例
./ngrokd -log=stdout -domain="rmt.yourdomain.com" -httpAddr=":1080" -httpsAddr=":10443" -tunnelAddr=":9500"
请在服务器防火墙、云服务器安全组中放行9500端口。有如下输出,没有报错就是成功了
[16:22:24 CST 2023/09/12] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[16:22:24 CST 2023/09/12] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[16:22:24 CST 2023/09/12] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:1080
[16:22:24 CST 2023/09/12] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:10443
[16:22:24 CST 2023/09/12] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:9500
启动客户端
配置文件ngrok.cfg
server_addr: "rmt.yourdomain.com:9500" trust_host_root_certs: false tunnels: site: proto: http: 80 subdomain: site win: proto: tcp: 3389 remote_port: 33890
这里配置了两个隧道,分别是80端口的http服务、3389端口的Windows远程连接。启动客户端
ngrok.exe -config=ngrok.cfg start site win
访问服务
- Windows远程
站点
由于我的服务器中安装了宝塔面板,所以我直接在宝塔中创建站点,并在站点配置中添加如下Nginx配置。其他环境大同小异,配置好代理就行。站点配置文件中添加一下代理配置并保存# 转发到1080端口 location / { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host:1080; proxy_pass_header Server; proxy_redirect off; proxy_pass http://127.0.0.1:1080; }
注意
- Ngrok v1版本不再维护,请谨慎使用
- 无法连接时请首先检查防火墙和安全组
- 请务必添加NGROK_DOMAIN环境变量
- 服务端和客户端需要一起编译生成