标签(空格分隔): 开发工具 前端
[toc]
前言
前端开发,有时候需要给外网的测试人员浏览,此时若没有专门的测试服务器,那么使用内网穿透就是最简便通用的方式了。一个常见的选择就是 ngrok
。 也有 frp
内网穿透原理
本地客户端跑起,搭建内网端口隧道给外网服务器,用户访问外网服务器对应地址,自动映射到本地对应地址。
使用 ngrok 的免费服务器
- 官方注册获得自己的 auth token,下载客户端 ngrok 文件;
- 命令行执行
./ngrok authtoken <token>
绑定客户端; - 命令行执行
./ngrok http <port>
搭建端口 port 的隧道。 - 使用生成的 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
选项就不会有子域名