利用ngrok實現內網穿透
阿新 • • 發佈:2019-02-20
實現內網穿透紫ngrok無法通過天牆之後,國內也出現了一批成熟的商業化實現方案,諸如花生殼、net123、Sunny-ngrok等。不過免費的極不穩定還有流量頻寬限制,最後還是決定自己搭一個。本文利用ngrok搭建一個用於內網穿透的環境。需求是通過一層反向代理,實現通過一個外網域名訪問一個部署在區域網上的服務。
準備
- 一個公網伺服器(Linux系統) ==> 阿里雲,騰訊雲之類的都行
- 這個公網伺服器主要用作反向代理,我們在本文中稱之為VPS伺服器
- 一個獨立的域名
- 一個用於提供服務的本地PC
步驟
GO語言環境搭建
ngrok專案是用GO語言實現的,需要先安裝GOLANG開發環境,系統不限,因為GO語言是跨平臺的!安裝過程很簡單,參考
獲取ngrok原始碼
# 下面是直接去ngrok的github地址下載(待會兒make的時候還會需要裝幾個其它的依賴,可能會出現很多問題) git clone https://github.com/inconshreveable/ngrok.git # 下面是筆者將程式碼clone下來,並添加了相應依賴之後的地址,如果用上面的方式出現錯誤,可以clone下面的地址 git clone https://github.com/SunnyQjm/ngrok.git
解析域名
因為我們自己搭建,需要使用自己的域名(以 test.j.cn )為例,我們需要做以下解析:
test.j.cn ------------> A記錄到你的VPS伺服器的IP # ngrok可以指定子域名,下面的解析方式可以讓任意子域名都能得到正確的解析
生成簽名證書
- 因為我們是自己搭建,就不能用ngrok官方的SSL證書,需要自己生成
- 下面生成的證書在編譯專案的時候要用到,所以務必要在編譯之前生成
- 需要注意的是,客戶端和伺服器的證書必須是同一份,這樣在程式在認證的時候才能正確解析
# 首先匯出環境變數,將下面的值替換成你的域名 export NGROK_DOMAIN="test.j.cn" #先進入到ngrok的根目錄,生成證書的操作需要在根目錄下進行 cd ngrok # 下面的命令用於生成證書 openssl genrsa -out rootCA.key 2048
編譯執行
服務端(VPS伺服器一端)
首先指定一下環境變數,在不同的作業系統下需要指定不同的環境變數,才能正確編譯(預設是Linux 64位的配置,如果你的伺服器是64位的Linux系統,也可以不指定,直接用預設的就行)
GOOS=linux GOARCH=amd64 #如果是32位系統,這裡 GOARCH=386 #如果是windows系統,GOOS=windows
然後make出服務端程式
make release-server
如果編譯成功,你會在bin目錄下看到ngrokd程式
cd bin # 檢視使用幫助 ./ngrokd -h
檢視使用幫助
# 檢視使用幫助 ./ngrokd -h -domain string Domain where the tunnels are hosted (default "ngrok.com") -httpAddr string Public address for HTTP connections, empty string to disable (default ":80") -httpsAddr string Public address listening for HTTPS connections, emptry string to disable (default ":443") -log string Write log messages to this file. 'stdout' and 'none' have special meanings (default "stdout") -log-level string The level of messages to log. One of: DEBUG, INFO, WARNING, ERROR (default "DEBUG") -tlsCrt string Path to a TLS certificate file -tlsKey string Path to a TLS key file -tunnelAddr string Public address listening for ngrok client (default ":4443")
啟動服務端
# 如果不能執行,你可能需要用 sudo chmod +x ngrokd 給它執行許可權 # domain域輸入之前生成證書時指定的域名 # httpAddr 指定轉發http協議的哪個埠 # httpAddrs 指定轉發https協議的哪個埠(如果不需要可以省略) ./ngrokd -domain="$NGROK_DOMAIN" -httpAddr=":8000" -httpsAddr=":4433"
如果執行成功,你會看到類似以下介面:
[16:23:40 CST 2018/03/19] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified [16:23:40 CST 2018/03/19] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:9748 [16:23:40 CST 2018/03/19] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:443 [16:23:40 CST 2018/03/19] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443 [16:23:40 CST 2018/03/19] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
自此,服務端算是配置好了
客戶端(部署了服務,需要內網穿透訪問的主機)
客戶端要做的事情就是指定把本機的那個埠暴露給VPS伺服器,客戶端要在該埠上部署了服務(web服務或者tomcat服務等),這樣VPS就能夠將請求轉發到該埠對應的服務上了
# 因為前面說過,服務端和客戶端的證書要是同一份,這樣認證才能通過,所以好的解決方案是在服務端上把客戶端程式也編譯出來,然後通過scp命令拷貝到客戶端 # 假設我要在mac上執行客戶端,需要在編譯命令前加上一些引數(如果客戶端伺服器也是Linux 64位,則不用指定環境變數) GOOS=darwin GOARCH=amd64 make release-client make release-client # 編譯好後scp到本地 scp xxx xxx # 下面開始本地配置(下面的配置在客戶端進行) # 新建一個配置檔案(在ngrok/bin目錄下) vim ngrok.cfg # 新增一下兩行 # 第一行是將要繫結的域名+4443埠(因為ngrok服務端預設有一個服務是堅挺在4443埠的,客戶端會通過這個埠與之相連)==> 記得將域名換成自己在生成證書時指定的 server_addr: "test.j.cn:4443" trust_host_root_certs: true # 幫助資訊 ./ngrok -h Examples: ngrok 80 ngrok -subdomain=example 8080 ngrok -proto=tcp 22 ngrok -hostname="example.com" -httpauth="user:password" 10.0.0.1 # 80就是我們要轉發的埠了 ./ngrok -config=./ngrok.cfg 80 # 指定協議和埠,不指定預設是 http+https ./ngrok -config=./ngrok.cfg -proto=tcp 22 # 指定子域名,不指定就會隨機生成 ./ngrok -config=./ngrok.cfg -subdomain=test 80
注意
上文中所有出現域名的地方都要統一,客戶端和服務端的證書要是同一份,否則在連線的時候會出現bad certification
參考