網穿透利器NGROK學習筆記
2019.10.31 SofM
1. 介紹
10月28號,某客戶內網虛擬機服務出現故障,云計算中心工程師是在得到用戶的報障后進行的處理。雖然,云計算中心工程師具有高度的責任心以及快速的問題處理能力,但是監控體系的部署使我們進一步提升服務質量的目標。
因此,為了更及時的發現客戶系統中的異常,避免因系統服務對用戶造成使用上的影響,于是安裝部署了Nagios監控。但是,由于該機器深入內網,并與我們的辦公網進行了網絡隔離,雖然能夠發出報警郵件,但是及時查看Nagios的管理頁面有一定困難。
經過大家討論,可以借助ngrok這一軟件的功能,提供靈活地服務轉發或者內網穿透服務。
2. 原理介紹
ngrok整個系統由如下四部分組成:
ngrokd服務:服務端,開放4443端口作為管理端口,用于ngrok之間的管理通信,并且開放http以及https服務端口。
ngrok程序:客戶端,該客戶端可以使用ngrok程序向ngrokd服務端發起驗證,并將其代理的http或者其他服務進行ngrokd代理。
業務服務端:和ngrok程序部署在同一臺機器,或者和ngrok運行程序的主機在同一網絡中,或者網絡可達。
業務訪問端:訪問業務服務的客戶。
組成
Client與Server建立一個scoket連接,然后發送一個Auth請求,Server驗證后,返回AuthResp。
接著Client發送ReqTunnel像服務器注冊通道,比如,HTTP,HTTPS,TCP,其中包含想要申請的二級域名,服務器返回NewTunnel,如果Client的二級域名請求為空,服務器會隨機分配。
Ngrokd Server等待瀏覽器,APP等客戶端的訪問,當有APP訪問,Server會檢查二級域名是否是已經注冊了的。如果是,則發送ReqProxy給Client;Client收到請求后會創建一個新的Socket連接到Server,并發送RegProxy請求;服務器收到后,返回StartProxy,并開始使用新的Socket連接做中繼。
原理
3. 實驗步驟
3.1. 準備實驗環境
1、ngrokd服務
一臺阿里云服務器
2、ngrok程序
自己的PC上,運行Win10系統
3、業務服務端
自己的PC上,通過Everything建立一個HTTP服務
4、業務訪問端
手機網頁瀏覽器
5、域名
sofm.xyz
3.2. Ngrok服務端部署編譯環境
1、安裝git
yum install git
2、安裝go
wget https://studygolang.com/dl/golang/go1.8.linux-amd64.tar.gz tar -zxvf go1.8.linux-amd64.tar.gz
3、配置go
export GOROOT=你的go語言解壓地址 export PATH=$PATH:$GOROOT/bin source /etc/profile go version
3.3. Ngrok服務端部署ngrokd服務
1、創建一個ngrok目錄
mkdir /usr/local/ngrok cd /usr/local/ngrok
2、下載源碼
git clone https://github.com/inconshreveable/ngrok.git
3、配置證書
NGROK_DOMAIN=“自己的域名” openssl genrsa -out base.key 2048 openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem openssl genrsa -out server.key 2048 openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr openssl x509 -req -in server.csr -CA base.pem -CAkey base.key -CAcreateserial -days 10000 -out server.crt
4、拷貝證書到目的地
cp base.pem assets/client/tls/ngrokroot.crt
5、編譯程序
# 編譯會持續5分鐘,編譯完成后,會在ngrok目錄的bin目錄生成ngrok和ngrokd兩個文件
make release-all
6、運行命令
./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain=”sofm.xyz” -httpAddr=“:18080”-httpsAddr=“:18090”
7、防火墻端口放行
需要在阿里云虛擬機的安全組里,開放4443、18080、18090三個TCP端口。
ngrokd運行示意圖
3.4. 域名解析配置
我們需要配置兩個域名解析。
A記錄名稱
A記錄解析
1、A記錄名稱@A記錄解析47.104.144.68
A記錄名稱*A記錄解析47.104.144.68
3.5. Ngrok Client端程序生成
1、進入目錄
cd /usr/local/ngrok
2、生成windows客戶端
GOOS=windows GOARCH=amd64 make release-client # 生成的程序在/usr/local/ngrok/bin/windows_amd64/ngrok.exe
3、生成linux客戶端
GOOS=linux GOARCH=amd64 make release-client
3.6. Ngrok Client程序配置與運行
1、拷貝
將/usr/local/ngrok/bin/windows_amd64/ngrok.exe程序拷貝到PC上。
2、在ngrok.exe目錄里配置ngrok.cfg文件
server_addr: "sofm.xyz:4443" trust_host_root_certs: false
3、在ngrok.exe目錄里建立start.bat腳本
@echo on cd %cd% ngrok -config=ngrok.cfg -log=ngrok.log -subdomain=www 80
4、運行
直接雙機start.bat文件
ngrok運行情況示意圖
3.7. 業務服務端配置Everything HTTP服務
打開Everything軟件,在工具-選項中,配置HTTP服務,并配置用戶名和密碼。
everything HTTP
3.8. 業務訪問端測試業務訪問
正常訪問
4. 總結
安全組一定要打開。遇到了好幾次,配置沒有啥問題,但是ngrok程序始終無法連接ngrokd成功。
域名解析一定要解析對。除了新增*的A記錄外,也要新增@的A記錄。@的意思是sofm.xyz的解析。
# 安裝 gcc
yum -y install gcc
yum -y install gcc-c++
安裝 golang , 下載地址在https://studygolang.com/dl中找的,想換版本可以在這里找
wget https://studygolang.com/dl/golang/go1.8.linux-amd64.tar.gz
tar -zxvf go1.8.linux-amd64.tar.gz
vi /etc/profile #文件中加上環境變量
export GOROOT=你的go解壓地址(如:/root/go)
export PATH=$PATH:$GOROOT/bin
source /etc/profile #使環境生效(或者重啟:reboot)
go version #查看go是否安裝成功
#安裝git 用于下載ngrok代碼
yum -y install git
#克隆代碼,文件夾命名為 ngrok-server,也可以填寫,默認就是ngrok
git clone https://github.com/inconshreveable/ngrok.git ngrok-server
執行一下命令。使用ngrok.com官方服務時,我們使用的是官方的SSL證書。自建ngrokd服務,如果不想買SSL證書,我們需要生成自己的自簽名證書,并編譯一個攜帶該證書的ngrok客戶端。
證書生成過程需要一個NGROK_BASE_DOMAIN。 填寫我們的域名地址
cd ngrok-server #進入安裝根目錄
NGROK_DOMAIN="ngrok.你的域名.com"
openssl genrsa -out rootCA.key 2048
openssl req -new -x509 -nodes -key rootCA.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out rootCA.pem
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=$NGROK_DOMAIN" -out server.csr
openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -days 10000 -out server.crt
經過以上步驟,證書已經生成,下面復制證書到默認讀取目錄下
#復制rootCA.pem到assets/client/tls/并更名為ngrokroot.crt
cp rootCA.pem assets/client/tls/ngrokroot.crt
#復制server.crt到assets/server/tls/并更名為snakeoil.crt
cp server.crt assets/server/tls/snakeoil.crt
#復制server.key到assets/server/tls/并更名為snakeoil.key
cp server.key assets/server/tls/snakeoil.key
上面會讓你提示是否覆蓋,輸入y即可。如果不想每次都提示,可以使用如下命令,這是一個騷操作。
cp前面加上一個\,然后加上-rf即可沒有提示,直接覆蓋。
\cp -rf rootCA.pem assets/client/tls/ngrokroot.crt
\cp -rf server.crt assets/server/tls/snakeoil.crt
\cp -rf server.key assets/server/tls/snakeoil.key
網站配置SSL證書(https),使網站可以通過https訪問
我們申請的是Let's Encrypt通配符SSL證書,因為他是免費的
1.獲取 Certbot 客戶端
下載 Certbot 客戶端 ,并且添加可執行權限
cd /usr/local/
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto certonly -d "*.ngrok.你的域名.com" -d "ngrok.你的域名.com" --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
執行到最后一步時,先暫時不要回車。申請通配符證書是要經過DNS認證的,接下來需要按照提示在域名后臺添加對應的DNS TXT記錄。等個10分鐘左右
確認生效后,回車繼續執行
更換證書
cd /root/ngrok-server
cp /etc/letsencrypt/live/ngrok.你的域名.com/privkey.pem /root/ngrok-server/assets/server/tls/snakeoil.key
cp /etc/letsencrypt/live/ngrok.你的域名.com/fullchain.pem /root/ngrok-server/assets/server/tls/snakeoil.crt
cp /etc/letsencrypt/live/ngrok.你的域名.com/fullchain.pem /root/ngrok-server/assets/client/tls/ngrokroot.crt
生成客戶端和服務器端
#win服務端
GOOS=windows GOARCH=386 make release-server
#win客戶端
GOOS=windows GOARCH=386 make release-client
#linux服務端
GOOS=linux GOARCH=386 make release-server
#linux客戶端
GOOS=linux GOARCH=386 make release-client
我只用到linux服務器端和win客戶端,我只需要執行如下即可。
根據自己需要生成
#linux服務端
GOOS=linux GOARCH=386 make release-server
#win客戶端
GOOS=windows GOARCH=386 make release-client
第一次生成需要點時間,因為golang編譯需要下載一些插件。
編譯后的軟件在bin目錄下
httpAddr,httpsAddr為訪問服務端端口,可以設置為80和443,訪問的時候不用加端口號.
tunnelAddr為給客戶端提供的連接端口默認4443可自行修改,這里改為8092
### 后臺運行
使用服務模式
將以下代碼保存為ngrokd.service文件,放在/etc/systemd/system/目錄
注意替換路徑 root/ngrok-server/bin/linux_386/ 為ngrok服務端目錄
#/etc/systemd/system/ngrokd.service
[Unit]
Description=ngrok
After=network.target
[Service]
ExecStart=/root/ngrok-server/bin/linux_386/ngrokd -tlsKey="/root/ngrok-server/assets/server/tls/snakeoil.key" -tlsCrt="/root/ngrok-server/assets/server/tls/snakeoil.crt" -domain="ngrok.你的域名.com" -httpAddr=":8090" -httpsAddr=":8091" -tunnelAddr=":8092"
LimitNOFILE=1048576
LimitNPROC=1048576
Restart=always
RestartSec=10
StartLimitInterval=0
[Install]
WantedBy=multi-user.target
systemctl enable ngrokd.service#開機啟動ngrokd服務
systemctl start ngrokd.service#啟動ngrokd服務
注意:阿里云需要配置安全組規則
下載bin/windows_386目錄下的ngrok.exe文件
http/https
ngrok.cfg
server_addr: ngrok.你的域名.com:8092
trust_host_root_certs: false
start.bat
@echo OFF
set /p clientid=請輸入域名前綴:
echo.
set /p port=請輸入內網端口:
echo.
ngrok -config=ngrok.cfg -proto=http -subdomain=%clientid% %port%
# https使用
# ngrok -config=ngrok.cfg -proto=https -subdomain=%clientid% %port%
運行start.bat
tcp
start.bat
start ngrok.exe -proto=tcp -config=tcp.cfg start vnc ssh
ngrok.cfg
server_addr: ngrok.你的域名.com:8092
trust_host_root_certs: false
tunnels:
ssh:# 名稱
remote_port: 33333 #服務器分配tcp轉發端口,不填寫由服務器隨機分配
proto:
tcp: 33333 #映射本地的端口
vnc:# 名稱
remote_port: 33339
proto:
tcp: 33339
注意:tcp需要開放對應的端口
8.注意事項