赞
踩
1、一个可用的域名(不是必须,但是最好有)
2、一台有公网IP的服务器
本文的操作过程主要参考了《教你自己服务器搭建Ngrok》,但是随着时间的推移,很多软件因版本升级而产生了一些变化,因此有必要重新梳理一遍部署过程。同时,本文也是操作笔记,方便日后查阅。
在服务商处购得一台云服务器,使用MobaXterm以SSH远程登录,首先是更新一下软件
yum update
然后安装golang
yum install go
提示找不到包
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirror.xtom.com.hk
* extras: mirror.xtom.com.hk
* updates: mirror.xtom.com.hk
No package go available.
Error: Nothing to do
需要添加源
- rpm --import https://mirror.go-repo.io/centos/RPM-GPG-KEY-GO-REPO
- curl -s https://mirror.go-repo.io/centos/go-repo.repo | tee /etc/yum.repos.d/go-repo.repo
这时再安装golang便会提示安装成功。查看一下go的版本
go version
go version go1.21.5 linux/amd64
golang的当前最新版。下面,拉取Ngrok的源码。也可以使用国内源ngrok: ngrok 国内加速版本
git clone https://github.com/inconshreveable/ngrok
然后,进入ngrok目录,并创建ssl目录
- cd ngrok/
- mkdir ssl
- cd ssl
生成自签名证书
- export NGROK_DOMAIN="xx.xx.xxx"
- openssl genrsa -out base.key 2048
- openssl req -new -x509 -nodes -key base.key -days 5000 -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 -days 5000 -out server.crt
NGROK_DOMAIN那里设置成你的域名,此时会生成6个文件
base.key base.pem base.srl server.crt server.csr server.key
然后执行下面的命令替换源码包自带的证书
- cp base.pem ../assets/client/tls/ngrokroot.crt
- cp server.crt ../assets/server/tls/snakeoil.crt
- cp server.key ../assets/server/tls/snakeoil.key
回到上级目录,然后生成服务端
- cd ../
- GOOS=linux GOARCH=amd64 make release-server
结果提示错误
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
-debug=false \
-o=src/ngrok/client/assets/assets_release.go \
assets/client/...
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
-debug=false \
-o=src/ngrok/server/assets/assets_release.go \
assets/server/...
go get -tags 'release' -d -v ngrok/...
go: go.mod file not found in current directory or any parent directory.
'go get' is no longer supported outside a module.
To build and install a command, use 'go install' with a version,
like 'go install example.com/cmd@latest'
For more information, see https://golang.org/doc/go-get-install-deprecation
or run 'go help get' or 'go help install'.
make: *** [deps] Error 1
修改一下go的环境变量
go env -w GO111MODULE=auto
再次编译就会通过。接着生成Windows版的客户端
GOOS=windows GOARCH=amd64 make release-client
注: 如果是32位系统,GOARCH=386;如果是64为系统,GOARCH=amd64
如果要编译linux,GOOS=linux; 如果要编译window,GOOS=windows
在./bin/windows_amd64/目录下,会生成 ngrok.exe,将其下载到本地电脑上。在本地电脑ngrok.exe的同目录下,新建一个配置文件ngrok.cfg,保存以下内容
server_addr: "xx.xx.xxx:4443"
trust_host_root_certs: false
这里的域名要和上文证书签名那里的保持一致。
接下来,先启动服务端。在服务器输入
./bin/ngrokd -domain="xx.xx.xxx"
[06:51:54 UTC 2024/03/01] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[06:51:54 UTC 2024/03/01] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[06:51:54 UTC 2024/03/01] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:80
[06:51:54 UTC 2024/03/01] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443
[06:51:54 UTC 2024/03/01] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
[06:52:24 UTC 2024/03/01] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting: {"bytesIn.count":0,"bytesOut.count":0,"connMeter.count":0,"connMeter.m1":0,"httpTunnelMeter.count":0,"linux":0,"osx":0,"other":0,"tcpTunnelMeter.count":0,"tunnelMeter.count":0,"tunnelMeter.m1":0,"windows":0}
然后启动客户端,在本地电脑的CMD中输入
ngrok.exe -log=stdout -config=ngrok.cfg 8080
再然后,不出意外地出意外了。本地电脑提示
[15:02:25 CST 2024/03/01] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [ctl:7cd75b8e] Closing
[15:02:25 CST 2024/03/01] [EROR] (ngrok/log.Error:120) control recovering from failure tls: failed to verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead
服务器提示
[07:02:28 UTC 2024/03/01] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:134e61f5] Waiting to read message
[07:02:28 UTC 2024/03/01] [WARN] (ngrok/log.(*PrefixLogger).Warn:87) [tun:134e61f5] Failed to read message: remote error: tls: bad certificate
[07:02:28 UTC 2024/03/01] [DEBG] (ngrok/log.(*PrefixLogger).Debug:79) [tun:134e61f5] Closing
这个报错原因是生成证书没有开启SAN扩展,go 1.15 版本开始废弃 CommonName,因此推荐使用 SAN 证书。
那么可否使用低版本的go来编译ngrok呢?答案是不行,ngrok的一些依赖组件在低版本的go下无法编译通过。
下面,在服务器上重新制作证书,并启用SAN。
- cd ssl/
- echo subjectAltName = DNS:xx.xx.xxx>extfile.cnf
然后,重新签名,在上述签名命令的最后一句加上 -extfile extfile.cnf
- openssl genrsa -out base.key 2048
- openssl req -new -x509 -nodes -key base.key -days 5000 -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 -days 5000 -out server.crt -extfile extfile.cnf
完成之后,还是先替换证书,make clean 之后再重新编译服务端和客户端。
重新运行服务端和客户端,可以看到,ngrok会随机分配域名前缀。这就需要我们配置 *.xx.xx.xxx的泛解析为服务器IP。
Tunnel Status online
Version 1.7/1.7
Forwarding http://4ec9da1.xx.xx.xxx -> 127.0.0.1:8080
Forwarding https://4ec9da1.xx.xx.xxx -> 127.0.0.1:8080
Web Interface 127.0.0.1:4040
# Conn 0
Avg Conn Time 0.00ms
但是,我申请到的域名是一个二级域名,无法配置泛解析,必须修改源码,让ngrok不分配前缀。
在ngrok/src/ngrok/server/tunnel.go的89行,删掉 %x.
rand.Int31()
,以及该文件第一行引入的 math/rand
,重新编译出服务端与客户端即可。
- // Register for random URL
- t.url, err = tunnelRegistry.RegisterRepeat(func() string {
- return fmt.Sprintf("%s://%x.%s", protocol, rand.Int31(), vhost)
- }, t)
如果你没有域名,可以直接使用IP地址,那么前文把DNS字段改成IP即可。
verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。