https://aotu.io/notes/2016/02/19/ngrok/index.html
ngrok
是啥,這里就不贅述了,本文主要講如何搭建的自己的 ngrok
服務,包含 ngrok
服務端、ngrok
客戶端。
前置條件
- 一臺外網可訪問的主機
- 一個可用域名并解析至主機上
搭建服務端
安裝golang
ngrok是利用go語言開發的,所以先要在服務器上安裝go語言開發環境。
以CentOS的服務器示例,安裝Go語言很簡單,可參考:安裝 golang,有一點需要注意的是,最好安裝 1.15
以下的版本,然后配置環境變量的時候,使用 export GO111MODULE=off
,而不是文章中的 export GO111MODULE=on
# 查看是否安裝成功
$ go version
go version go1.13.5 linux/amd64
安裝Git
$ sudo yum install git
# 查看是否安裝成功
$ git --version
git version 1.8.3.1
拉取ngrok源碼
$ mkdir /opt/local && cd /opt/local
# 拉取ngrok源碼
$ git clone https://github.com/inconshreveable/ngrok.git
生成自簽名證書
$ cd ngrok
# 生成證書
mkdir cert && cd cert
NGROK_DOMAIN="ngrok.sprainkle.com"
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out ca.pem
openssl genrsa -out ngrok.key 2048
openssl req -new -key ngrok.key -subj "/CN=$NGROK_DOMAIN" -out ngrok.csr
openssl x509 -req -in ngrok.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out ngrok.crt -days 5000
# 目錄下就新生成6個文件
$ ll
-rw-r--r-- 1 root root 1675 Jul 2 18:24 ca.key
-rw-r--r-- 1 root root 1123 Jul 2 18:24 ca.pem
-rw-r--r-- 1 root root 17 Jul 2 18:24 ca.srl
-rw-r--r-- 1 root root 1005 Jul 2 18:24 ngrok.crt
-rw-r--r-- 1 root root 903 Jul 2 18:24 ngrok.csr
-rw-r--r-- 1 root root 1679 Jul 2 18:24 ngrok.key
# 復制證書ngrok目錄
cp ca.pem ../assets/client/tls/ngrokroot.crt
cp ngrok.crt ../assets/server/tls/snakeoil.crt
cp ngrok.key ../assets/server/tls/snakeoil.key
cd ../
服務端程序ngrokd和客戶端程序ngrok
$ pwd
/opt/local/ngrok/cert
# 當前目錄在cert,需要先回到上一層,即ngrok
$ cd ../
# 編譯
export GOPATH=`pwd`
## centos 64
GOOS=linux GOARCH=amd64
# 編譯客戶端及服務器端
make release-server release-client
注:若生成簽名或編譯過程中出現錯誤,比如未安裝
gcc
、gcc-c++
、openssl
等,用yum install -y <softwares>
安裝即可。
編譯成功后,會在 bin
目錄下看到 ngrok
的兩個程序:
$ cd bin && ll
-rwxr-xr-x 1 root root 2772750 Jul 2 18:27 go-bindata
-rwxr-xr-x 1 root root 11833510 Jul 2 21:13 ngrok
-rwxr-xr-x 1 root root 9308170 Jul 2 18:41 ngrokd
ngrokd
就是我們的服務端程序了,ngrok
是客戶端程序,這個不一定用的到,因為這是在linux
上編譯的,所以只能在linux
系統上使用。
啟動服務器端
# 運行并打印日志
$ ./ngrokd -domain="ngrok.sprainkle.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000"
# 在后臺運行
$ nohup ./ngrokd -domain="ngrok.sprainkle.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000" > /dev/null 2>&1 &
- 8002:為HTTP端口,一般代理訪問的地址
- 8003: 為HTTPS端口
- 4000: 為Ngrok服務器端口,配置時使用此地址
為ngrok.sprankle.com添加dns解析
ps: 因為域名和主機都是在阿里云購買的,所以這里以阿里云做例子。
先進入域名控制臺,然后找到對應域名,點擊解析:
域名控制臺
然后添加兩條解析記錄:
注意:一般情況下,服務器的防火墻是開啟的,所以還需要配置防火墻開放某些端口,一般需要開放
4000
,8002
和8003
為可選(因為域名后面接上端口比較丑,所以一般使用Nginx
做代理),具體可以參考 centos7 開放端口并對外開放。
設置開機啟動
$ vim /etc/init.d/ngrok_start
cd /opt/local/ngrok/bin
nohup ./ngrokd -domain="ngrok.sprainkle.com" -httpAddr=":8002" -httpsAddr=":8003" -tunnelAddr=":4000" > /dev/null 2>&1 &
$ chmod 755 /etc/init.d/ngrok_start
小結
至此為止,我們的 ngrokd
服務端搭建配置完成,同時我們在 CentOS
系統的服務器上編譯了一份客戶端的執行程序——ngrok
文件。
如果你的開發機器系統也是 Linux
,是可以直接將 ngrok
這個客戶端執行文件拷貝到本地開發機器中來使用的。
但如果你的機器是 Mac
或者 Windows
,我們還需要在自己的電腦中編譯一份相同簽名文件的客戶端程序!
在MAC中編譯ngrok客戶端
服務器是 CentOS
,自己的電腦是 macOS
,所以這里以 macOS
為例子,在自己的電腦中編譯一份 相同簽名文件 的客戶端程序!
安裝Go
略。
拉取ngrok源碼到本地
略。
拷貝云主機上的簽名到本地
scp root@your_public_ip:/opt/local/ngrok/cert/ca.pem ~/Desktop/ngrok/assets/client/tls/ngrokroot.crt
scp root@your_public_ip:/opt/local/ngrok/cert/ngrok.crt ~/Desktop/ngrok/assets/server/tls/snakeoil.crt
scp root@your_public_ip:/opt/local/ngrok/cert/ngrok.key ~/Desktop/ngrok/assets/server/tls/snakeoil.key
ps: 演示的時候,我是把
ngrok
源碼clone
到桌面,所以需要把上面的~/Desktop
以及下文的都替換成自己的目錄。
編譯客戶端
$ pwd
~/Desktop/ngrok
$ export GOPATH=`pwd`
# mac 64位
$ GOOS=darwin GOARCH=amd64
# mac 32位
$ GOOS=darwin GOARCH=386
# 編譯客戶端及服務器端
$ make release-server release-client
編譯完成后,同樣在 bin
目錄下有 ngrokd
、ngrok
兩個程序,我們只需要客戶端程序 ngrok
即可。
使用客戶端
- 拷貝
ngrok
客戶端程序到其他目錄,這里為了簡單直接拷貝到桌面:
$ pwd
~/Desktop/ngrok/bin
$ cp ngrok ~/Desktop/ngrok
- 在桌面創建一個ngrok配置文件:ngrok.cfg,內容如下:
server_addr: ngrok.sprainkle.com:4000
trust_host_root_certs: false
注:請把 ngrok.sprainkle.com
換成自己的 ngrok
二級域名。
- 運行客戶端,代理的是本地的80端口
# demo 這個參數可以隨便填,這最后會變成第三級域名
$ ./ngrok -subdomain demo -config=~/Desktop/ngrok.cfg 80
啟動結果如下:
- 驗證
前提是,80
端口有程序綁定了,此時訪問:http://demo.ngrok.sprainkle.com:8002/,即可訪問本地的80
端口了。
訪問本地80端口
ps: 本地的80端由nginx代理了,所以看到了上面的頁面。
小結
上面的演示是為了簡單,才把客戶端程序和配置文件都放桌面了,其實可以把這2個文件拷貝到單獨目錄,下次需要代理本地服務時,直接使用下面的命令即可:
# 假設當前目錄包含客戶端程序和配置文件
$ ./ngrok -subdomain demo -config=ngrok.cfg 80
另外,除了代理本地服務,已可以代理其他機器的服務,比如,開發環境為 192.168.0.100:5000
,那么可以使用如下命令代理:
$ ./ngrok -subdomain demo -config=ngrok.cfg 192.168.0.100:5000
云主機使用nginx代理8002端口
安裝nginx
略。可參考:Centos 7下編譯安裝Nginx。
新建ngrok_nginx.conf文件
upstream ngrok {
server 127.0.0.1:8002;
keepalive 64;
}
server {
listen 80;
server_name *.ngrok.sprainkle.com;
access_log /var/log/nginx/ngrok_access.log;
proxy_set_header "Host" $host:8002;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host:8002;
proxy_pass_header Server;
proxy_redirect off;
proxy_pass http://ngrok;
}
access_log off;
log_not_found off;
}
然后include
到 nginx.conf
中:
然后,reload
一下 nginx
配置:
# 重新加載
./nginx -s reload
最后可以使用 http://demo.ngrok.sprainkle.com/
即可正常訪問了,再也不用在后面接一個端口 8002
。
參考
https://aotu.io/notes/2016/02/19/ngrok/index.html
https://yangbingdong.com/2017/self-hosted-build-ngrok-server/
ngrok 1.x 內存泄露 bug 的解決方案
Ngrok 客戶端連接配置
Ngrok 配置文檔
http://www.lxweimin.com/p/fc74f99ba9e2
https://blog.csdn.net/cuichenghd/article/details/109230584