当前位置:   article > 正文

手把手教你在 CentOS7 上部署Ngrok (踩坑&填坑)

ngrok

一、项目准备

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

需要添加源

  1. rpm --import https://mirror.go-repo.io/centos/RPM-GPG-KEY-GO-REPO
  2. 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目录

  1. cd ngrok/
  2. mkdir ssl
  3. cd ssl

生成自签名证书

  1. export NGROK_DOMAIN="xx.xx.xxx"
  2. openssl genrsa -out base.key 2048
  3. openssl req -new -x509 -nodes -key base.key -days 5000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
  4. openssl genrsa -out server.key 2048
  5. openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
  6. 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

然后执行下面的命令替换源码包自带的证书

  1. cp base.pem ../assets/client/tls/ngrokroot.crt
  2. cp server.crt ../assets/server/tls/snakeoil.crt
  3. cp server.key ../assets/server/tls/snakeoil.key

回到上级目录,然后生成服务端

  1. cd ../
  2. 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。

  1. cd ssl/
  2. echo subjectAltName = DNS:xx.xx.xxx>extfile.cnf

然后,重新签名,在上述签名命令的最后一句加上 -extfile extfile.cnf

  1. openssl genrsa -out base.key 2048
  2. openssl req -new -x509 -nodes -key base.key -days 5000 -subj "/CN=$NGROK_DOMAIN" -out base.pem
  3. openssl genrsa -out server.key 2048
  4. openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
  5. 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,重新编译出服务端与客户端即可。

  1. // Register for random URL
  2. t.url, err = tunnelRegistry.RegisterRepeat(func() string {
  3. return fmt.Sprintf("%s://%x.%s", protocol, rand.Int31(), vhost)
  4. }, t)

如果你没有域名,可以直接使用IP地址,那么前文把DNS字段改成IP即可。

三、参考文献

内网穿透 ngrok 服务器搭建与坑点

教你自己服务器搭建Ngrok 

ngrok的https等多隧道搭建及使用(菜鸟篇) 

verify certificate: x509: certificate relies on legacy Common Name field, use SANs instead 

我们来亲手搭建一个Ngrok内网穿透服务器 

Ngrok内网穿透 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/516467
推荐阅读
相关标签
  

闽ICP备14008679号