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

标签(空格分隔): 开发工具 前端


[toc]

前言

前端开发,有时候需要给外网的测试人员浏览,此时若没有专门的测试服务器,那么使用内网穿透就是最简便通用的方式了。一个常见的选择就是 ngrok。 也有 frp

ngrok官网

内网穿透原理

本地客户端跑起,搭建内网端口隧道给外网服务器,用户访问外网服务器对应地址,自动映射到本地对应地址。

使用 ngrok 的免费服务器

  1. 官方注册获得自己的 auth token,下载客户端 ngrok 文件;
  2. 命令行执行 ./ngrok authtoken <token> 绑定客户端;
  3. 命令行执行 ./ngrok http <port> 搭建端口 port 的隧道。
  4. 使用生成的 url 访问即可

这个方案很简单,也很慢,超慢,无法忍受的慢。

搭建自己的服务器

官网教程参看 https://github.com/inconshreveable/ngrok/blob/master/docs/SELFHOSTING.md

从零搭建参看,https://morongs.github.io/2016/12/28/dajian-ngrok/

已经写好的搭建脚本,参看 https://www.jianshu.com/p/b81bb6a3c0b9

如果脚本安装失败,可能是有些依赖没有,例如 apt-get

搭建过程的坑点

1.依赖安装问题, go 安装

如果脚本失败,可能是依赖没装好,一般就是 go 没装,试下下面
安装 go

apt-get install golang
# 或者 yum install golang

如果没有 apt-get yum,使用下面

# 根据自己系统选择安装包 https://golang.org/dl/
wget https://dl.google.com/go/go1.13.3.linux-amd64.tar.gz
# 安装 http://docs.studygolang.com/doc/install
tar -C /usr/local -xzf go1.13.3.linux-amd64.tar.gz
# 添加环境路径
vi /etc/profile  #最后一行添加 export PATH=$PATH:/usr/local/go/bin
# 立即执行
source /etc/profile
# 检查是否安装成功
go version # >> "go version go1.13.3 linux/amd64"

2.使用 ip 来生成自签证书

按教程的做法是这样的

# 生成自签证,一年过期
export DOMAIN = xx.xx.xx.xx # 域名,这里我用了 ip

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$DOMAIN" -days 365 -out rootCA.pem
$ openssl genrsa -out device.key 2048
openssl req -new -key device.key -subj "/CN=$DOMAIN" -out device.csr
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 365

# 复制到 assets 构建的时候自动引用
cp rootCA.pem assets/client/tls/ngrokroot.crt
cp device.crt assets/server/tls/snakeoil.crt
cp device.key assets/server/tls/snakeoil.key

开启服务后,服务端报错 Failed to read message: remote error: bad certificate, 客户端端报错 x509: cannot validate certificate for xx.xx.xx.xx because it doesn't contain any IP SANs

搜索客户端报错,按此文解决,在最后一句生成证书的命令前加上以下命令,就解决了

echo subjectAltName = IP:xx.xx.xx.xx > extfile.cnf

# 最后一句加上 -extfile extfile.cnf
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 365 -extfile extfile.cnf

3.使用 ip 做域名时,随机生成的子域名导致地址错误

ngrok 客户端会自动生成一个随机子域名或者用户自定义一个,总之无论如何都会有一个域名,这就会导致 ip 域名无效, 例如http://92832de0.1.1.1.1 -> localhost:80, 解决办法就是改源码,去掉随机生成的 subdomain

// src/ngrok/server/tunel.go  #89 行
// Register for random URL
    t.url, err = tunnelRegistry.RegisterRepeat(func() string {
      return fmt.Sprintf("%s://%x.%s", protocol, rand.Int31(), vhost)
    }, t)

删掉 %x. rand.Int31(), 以及该文件第一行引入的 math/rand,重新编译出服务端与客户端即可。这样不加 -subdomain 选项就不会有子域名

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容