# 使用Ngrok實現內網穿透服務
tags: 網絡 Linux ngrok
ngrok是什么?
ngrok是一個能夠實現不能直接與外網溝通的設備,通過外網服務器的轉發實現自我服務器化的軟件,也就是不需要通過路由器的端口映射,就能實現內網設備向外網暴露端口的軟件。
實現ngrok服務需要什么?
需要一個能夠提供服務的外網服務器,并運行ngrok服務端,它將默認監聽4443端口,當內網的機器運行ngrok客戶端并連接上服務器時,將通過4443端口進行轉發設置,并按設定將指定的端口的數據動作與服務器進行轉發。協議上它支持http,https,tcp協議
如何搭建自己的ngrok服務器
最新版ngrok目前僅由官方提供技術支持和服務器,開源的ngrok代碼只支持到1.7版本,只有自己編譯的ngrok才能在自己的服務器上提供內網穿透服務。ngrok使用GO語言編寫,可以自己配置實現交叉編譯,全平臺通用
一. 軟件的編譯
以下動作發生在debian 8.2 x86平臺
1. 編譯安裝GO
建議安裝1.4版本平臺,由于軟件開發時間問題,新版本的GO可能會出現編譯問題
下載GO1.4
# pwd
# ~/Software
# apt-get install gcc cmake
# wget http://www.golangtc.com/static/go/1.4/go1.4.linux-386.tar.gz
# tar xvf http://www.golangtc.com/static/go/1.4/go1.4.linux-386.tar.gz
配置編譯環境
# export GOROOT=$HOME/software/go
# export PATH=$PATH:$GOROOT/bin
編譯&檢查
# cd go/src/
# ./all.bash
編譯完成后~/go/bin中的go就是我們的二進制go程序
2. 編譯安裝ngrok
下載ngrok
# cd ~/software
# git clone https://github.com/inconshreveable/ngrok.git ngrok
# cd ngrok
配置ssl證書信息
# NGROK_DOMAIN="moonwalker.me"
注意域名換成你自己的
# 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
將生成的證書文件拷貝到指定位置,替代默認證書
# cp base.pem assets/client/tls/ngrokroot.crt
# cp server.crt assets/server/tls/snakeoil.crt
# cp server.key assets/server/tls/snakeoil.key
編譯生成服務端和客戶端
# make release-server release-client
編譯出的程序會放在ngrok/bin/下,ngrok為客戶端程序,ngrokd為服務器程序。注意這個服務端和客戶端只適合你用于編譯的機器的所屬平臺上運行,例如使用x86構架的主機編譯無法在arm構架上運行,需要后面的交叉編譯
3. 啟動Ngrok服務
# ./ngrokd -domain="ngrok.moonwaker.me" -httpAddr=":8080" -httpsAddr=":8081" -tunnelAddr=":4443"
使用netstat -tunlp
可以看到服務器已經做好端口監聽,并且已經將兩個協議的轉發端口做了監聽,當然三個參數的端口都是默認好的,這里寫出來是為了方便修改。
4. 運行客戶端
如果是同樣平臺的機器可以直接將ngrok復制走運行,如果是想在樹莓派等arm平臺上要配置交叉編譯再編譯一次
配置編譯平臺
# cd ~/software/go/src
# GOOS=linux
# GOARCH=arm
# ./make.bash
通過上面的命令配置好go編譯器的交叉編譯選項,然后重新編譯
# cd ~/software/ngrok/src
# make release-server release-client
寫一個配置文件ngrok.cfg,基礎的配置如下
server_addr: ngrok.moonwalker.me:4443
trust_host_root_certs: false
這里已經可以通過命令
# ./ngrok -subdomain ngrok -proto=http -config=ngrok.cfg 80
直接將80端口轉發到服務器端的8081端口,并且協議走的是http
當然也可以對其它端口進行tcp轉發,比如轉發22端口
# ./ngrok -proto=tcp -config ngrok.cfg 22
ngrok會隨意選擇一個端口對本機的22端口進行轉發
如果想一次性轉發多個端口或者想指定遠程的對應端口,需要完善ngrok.cfg
server_addr: ngrok.moonwalker.me:4443
trust_host_root_certs: false
tunnels:
ssh:
remote_port: 1122
proto:
tcp: 22
ss:
emote_port: 8388
proto:
tcp: 8388
ftp:
remote_port: 20
proto:
tcp: 20
ftp2:
remote_port: 21
proto:
tcp: 21
http:
subdomain: www
proto:
http: 80
https: 192.168.1.4:443
特別需要注意的是配置文件為YAML語法,所有縮進都要使用空格,不能夠使用tab
而且可以看出不但可以轉發本機的端口,亦可以轉發其它內網設備
啟動特定的轉發tunnel
# ./ngrok -config ngrok.cfg start ssh ss
當然也可以將所有配置全部轉發
# ./ngrok -config ngrok.cfg start-all