文章目錄html
咱們常常會有「把本機開發中的 web 項目給朋友看一下」這種臨時需求,爲此專門在 VPS 上部署一遍就有點太浪費了。以前我一般是在 ADSL 路由器上配個端口映射讓本機服務在外網能夠訪問,但如今大部分運營商不會輕易讓你這麼幹了。通常小運營商也沒有公網 IP,本身的路由器出口仍是在局域網內,端口映射這種作法就無論用了。golang
以前我就想過可否藉助擁有公網 IP 的主機中轉來實現這種需求,後來發現已經有這樣的軟件了:ngrok。並且 ngrok 官網自己還提供了公共服務,只須要註冊一個賬號,運行它的客戶端,就能夠快速把內網映射出去。不過這麼好的服務,沒多久就被牆了~web
好在 ngrok 是開源的,我在 VPS 上搭了一套服務本身用,一勞永逸地解決了內網穿透這個難題,這裏記錄一下過程。(注意:ngrok.com 提供的服務是基於 ngrok 2.0,github 上目前只有 1.0 的源碼,兩者功能和命令有一些區別,用的時候別搞混了)安全
個人 VPS 系統是 Ubuntu 14.04.2 LTS,首先裝必要的工具:app
sudo apt-get install build-essential golang mercurial git
獲取 ngrok 源碼:dom
BASHgit clone https://github.com/inconshreveable/ngrok.git ngrok### 請使用下面的地址,修復了沒法訪問的包地址git clone https://github.com/tutumcloud/ngrok.git ngrokcd ngrok
生成並替換源碼裏默認的證書,注意域名修改成你本身的。(以後編譯出來的服務端客戶端會基於這個證書來加密通信,保證了安全性)
BASHNGROK_DOMAIN="imququ.com"openssl genrsa -out base.key 2048openssl req -new -x509 -nodes -key base.key -days 10000 -subj "/CN=$NGROK_DOMAIN" -out base.pem openssl genrsa -out server.key 2048openssl 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
開始編譯:
sudo make release-server release-client
若是一切正常,ngrok/bin 目錄下應該有 ngrok、ngrokd 兩個可執行文件。
前面生成的 ngrokd 就是服務端程序了,指定證書、域名和端口啓動它(證書就是前面生成的,注意修改域名):
sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="imququ.com" -httpAddr=":8081" -httpsAddr=":8082"
到這一步,ngrok 服務已經跑起來了,能夠經過屏幕上顯示的日誌查看更多信息。httpAddr、httpsAddr 分別是 ngrok 用來轉發 http、https 服務的端口,能夠隨意指定。ngrokd 還會開一個 4443 端口用來跟客戶端通信(可經過 -tunnelAddr=":xxx" 指定),若是你配置了 iptables 規則,須要放行這三個端口上的 TCP 協議。
如今,經過 https://imququ.com:8081 和 https://imququ.com:8082 就能夠訪問到 ngrok 提供的轉發服務。爲了使用方便,建議把域名泛解析到 VPS 上,這樣能方便地使用不一樣子域轉發不一樣的本地服務。我給 imququ.com 作了泛解析,隨便訪問一個子域,如:http://pub.imququ.com:8081,能夠看到這樣一行提示:
Tunnel pub.imququ.com:8081 not found
這說明萬事俱備,只差客戶端來連了。
若是要把 linux 上的服務映射出去,客戶端就是前面生成的 ngrok 文件。但我用的是 Mac,須要指定環境變量再編一次:
sudo GOOS=darwin GOARCH=amd64 make release-server release-client
這樣在 ngrok/bin 目錄下會多出來一個 darwin_amd64 目錄,這裏的 ngrok 文件就能夠拷到 Mac 系統用了。
寫一個簡單的配置文件,隨意命名如 ngrok.cfg:
server_addr: imququ.com:4443trust_host_root_certs: false
指定子域、要轉發的協議和端口,以及配置文件,運行客戶端:
./ngrok -subdomain pub -proto=http -config=ngrok.cfg 80
不出意外能夠看到這樣的界面,這說明已經成功連上遠端服務了:
如今再訪問 http://pub.imququ.com:8081,訪問到的已是我本機 80 端口上的服務了。
上面那張 ngrok 客戶端運行界面截圖中,有一個 Web Interface 地址,這是 ngrok 提供的監控界面。經過這個界面能夠看到遠端轉發過來的 http 詳情,包括完整的 request/response 信息,很是方便。
實際上,因爲 ngrok 能夠轉發 TCP,因此還有不少玩法,原理都同樣,這裏就很少寫了。
本文連接:https://imququ.com/post/self-hosted-ngrokd.html,參與評論。
--EOF--