標簽(空格分隔): 開發工具 前端
[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/
已經寫好的搭建腳本,參看 http://www.lxweimin.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
選項就不會有子域名