天天看點

linux下ngrok配置和使用

什麼是Ngrok

Ngrok是一款用go語言開發的開源軟體,它是一個反向代理。通過在公共的端點和本地運作的Web伺服器之間建立一個安全的通道。Ngrok可捕獲和分析所有通道上的流量,便于後期分析和重放。

應用場景

用于對處在内網環境中,無外網IP的計算機的遠端連接配接。

Ngrok可以做TCP端口轉發,對于Linux可以将其映射到22端口進行SSH連接配接。Windows的遠端桌面可以将其映射到3389端口來實作。同理,如果要做MySQL的遠端連接配接,隻需映射3306端口即可。

用作臨時搭建網站并配置設定二級域名,可用作微信二次開發的本地調試。

微信公衆平台二次開發時,伺服器必須要能通過外網通路,而且必須是80接口。我們一般會在自己的電腦上寫代碼,但是由于電信營運商将80端口屏蔽了,甚至很多人通過無線路由器上網,根本就沒有公網ip。在這種情況下,我們每次都要上傳代碼到伺服器對微信公衆平台進行接口調試,十分的不友善。而Ngrok可以将内網映射到一個公網位址,這樣就完美的解決了我們的問題。

Ngrok官方為我們免費提供了一個伺服器,我們隻需要下載下傳Ngrok用戶端即可正常使用,但是後來官方的服務越來越慢,直到Ngrok官網被完全屏蔽。現在我們已經無法使用ngrok官方的伺服器了。是以,接下來我們自行搭建屬于自己的ngrok伺服器,為自己提供友善快捷又穩定的服務,一勞永逸。

注意:ngrok.com 提供的服務是基于 ngrok 2.0,github 上目前隻有 1.0 的源碼,二者功能和指令有一些差別,用的時候别搞混了

編譯ngrok

安裝go get工具

#ubuntu
apt-get install build-essential golang mercurial git

#centos
yum install mercurial git bzr subversion  golang

#git版本需要在1.7.9.5以上,如果不符合條件需要将git版本更新。
yum --disablerepo=base,updates --enablerepo=rpmforge-extras update git
           

擷取ngrok源碼

GOPATH=~/goproj
mkdir ~/goproj/src/github.com/inconshreveable
cd ~/goproj/src/github.com/inconshreveable
#官方位址編譯時要報錯
git clone https://github.com/inconshreveable/ngrok.git
#請使用下面的位址,修複了無法通路的包位址
git clone https://github.com/tutumcloud/ngrok.git ngrok
export GOPATH=~/goproj/src/github.com/inconshreveable/ngrok

修改源代碼中庫引用的錯誤
由于google code的關閉,是以我們要把作者代碼中的庫引用位址修改一下
修改src/ngrok/log/logger.go檔案
log "code.google.com/p/log4go" 改為log "github.com/alecthomas/log4go"
注:最新github.com上的代碼這個問題已修複
           

生成自簽名證書

使用ngrok.com官方服務時,我們使用的是官方的SSL證書。自建ngrokd服務,我們需要生成自己的證書,并提供攜帶該證書的ngrok用戶端。生成并替換源碼裡預設的證書,注意域名修改為你自己的。(之後編譯出來的服務端用戶端會基于這個證書來加密通訊,保證了安全性)

證書生成過程需要一個NGROK_DOMAIN。以ngrok官方随機生成的位址693c358d.ngrok.com為例,其NGROK_DOMAIN就是”ngrok.com”,如果你要提供服務的位址為”example.tunnel.imike.me”,那NGROK_BASE_DOMAIN就應該是”tunnel.imike.me”。

cd ngrok
NGROK_DOMAIN="tunnel.imike.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
           

執行完以上指令,在ngrok目錄下就會新生成6個檔案

ls -lt                           
總用量 56
-rw-r--r-- 1 root root  973 3月  23 11:23 server.crt
-rw-r--r-- 1 root root   17 3月  23 11:23 base.srl
-rw-r--r-- 1 root root  891 3月  23 11:23 server.csr
-rw-r--r-- 1 root root 1675 3月  23 11:23 server.key
-rw-r--r-- 1 root root 1115 3月  23 11:23 base.pem
-rw-r--r-- 1 root root 1679 3月  23 11:23 base.key
           

Ngrok通過bindata将ngrok源碼目錄下的assets目錄(資源檔案)打包到可執行檔案(ngrokd和ngrok)中去,assets/client/tls和assets/server/tls下分别存放着用于ngrok和ngrokd的預設證書檔案,我們需要将它們替換成我們自己生成的(是以這一步務必放在編譯可執行檔案之前)

cp base.pem assets/client/tls/ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt
cp server.key assets/server/tls/snakeoil.key
           

編譯Linux服務端和用戶端

make release-server release-client
           

編譯之後,就會在ngrok源碼的bin目錄下生成兩個可執行檔案:ngrokd、ngrok。其中ngrokd就是ngrok的服務端程式,ngrok就是ngrok的用戶端程式。

編譯Linux用戶端

make release-client
           

編譯window版本用戶端

上述編譯過程生成的服務端和用戶端都是linux下的,不能在windows下用。如果想編譯生成windows用戶端,需要重新配置環境并編譯。交叉編譯過程如下:

進入go目錄,進行環境配置
cd  /usr/local/go/src/
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 ./make.bash  
進入ngrok目錄重新編譯
GOOS=windows GOARCH=amd64 make release-client
編譯後,就會在bin目錄下生成windows_amd64目錄,其中就包含着windows下運作的伺服器和用戶端程式。
#以上GOARCH=amd64指的是編譯為64位版本,如需32位改成GOARCH=386即可
           

編譯arm用戶端

cd /usr/lib/golang/src/
sudo GOOS=linux GOARCH=arm CGO_ENABLED=0 ./make.bash
sudo GOOS=linux GOARCH=arm make release-client
           

編譯mac版本用戶端

GOOS=darwin GOARCH=amd64 make  release-client
           

設定域名解析

添加兩條A記錄:tunnel.imike.me和*.tunnel.imike.me,指向所在的Ngrok伺服器ip。

運作Ngrok

服務端啟動

nohup ngrokd -domain="onlineweifu.cn" -httpAddr=":8888" &   #背景運作

指定證書、域名和端口啟動它(證書就是前面生成的,注意修改域名)

./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="tunnel.imike.me" -httpAddr=":8081" -httpsAddr=":8082"
[14:54:30 CST 2016/03/23] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [registry] [tun] No affinity cache specified
[14:54:30 CST 2016/03/23] [INFO] (ngrok/log.(*PrefixLogger).Info:83) [metrics] Reporting every 30 seconds
[14:54:30 CST 2016/03/23] [INFO] (ngrok/log.Info:112) Listening for public http connections on [::]:8081
[14:54:30 CST 2016/03/23] [INFO] (ngrok/log.Info:112) Listening for public https connections on [::]:8082
[14:54:30 CST 2016/03/23] [INFO] (ngrok/log.Info:112) Listening for control and proxy connections on [::]:4443
           

到這一步,ngrok 服務已經跑起來了,可以通過螢幕上顯示的日志檢視更多資訊。httpAddr、httpsAddr 分别是ngrok用來轉發http、https服務的端口,可以随意指定。ngrokd還會開一個4443端口用來跟用戶端通訊(可通過-tunnelAddr=”:xxx” 指定),如果你配置了iptables 規則,需要放行這三個端口上的TCP協定。

現在通過

http://tunnel.imike.me:8081

https://tunnel.imike.me:8082

就可以通路到ngrok提供的轉發服務。

設定開機自動啟動ngrok服務

vim /etc/init.d/ngrok_start:
cd /root/goproj/src/github.com/inconshreveable
./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="tunnel.imike.me" -httpAddr=":8081" -httpsAddr=":8082"
chmod 755 /etc/init.d/ngrok_start
           

用戶端啟動

使用預設配置檔案啟動

對預設設定檔案 ~/.ngrok 進行編輯:

server_addr: tunnel.imike.me:4443
trust_host_root_certs: false
tunnels:
    #http:subdomain: "test"
    web:
        #auth: "AuthUser:AuthPassWord"
        proto:
            http: 80
    ssh:
        remote_port: 12222
        proto:
            tcp: 22
           

從指令行運作:

./bin/ngrok start web ssh
           

當用戶端使用http/https協定連接配接,可指定一個二級域名,服務端會配置設定該二級域名給用戶端作為入口,比如web.tunnel.imike.me;

當用戶端使用tcp 協定連接配接,則服務端不會配置設定二級域名,改為監控一個随機端口,比如 tunnel.imike.me:12345,remote_port可由用戶端對該端口進行指定,比如tunnel.imike.me:12222。

使用自定義配置檔案

建立一個配置檔案ngrok.cfg,内容如下:

vim ngrok.cfg:
server_addr: tunnel.imike.me:4443
trust_host_root_certs: false
           

映射HTTP

#啟動ngrok用戶端
#指定子域、要轉發的協定和端口,以及配置檔案,運作用戶端:
#注意:如果不加參數-subdomain=test,将會随機自動配置設定子域名。
./bin/ngrok -subdomain web -proto=http -config=ngrok.cfg 80

#用戶端ngrok正常執行顯示的内容
ngrok                                                  (Ctrl+C to quit)

Tunnel Status     online
Version           1.7/1.7
Forwarding        http://web.tunnel.imike.me:8081 -> 127.0.0.1:80
Web Interface     127.0.0.1:4040
# Conn            0
Avg Conn Time     0.00ms
           

打開浏覽器,分别在位址欄中輸入

http://localhost

http://web.tunnel.imike.me:8081

,如果後者正常顯示并且和

http://localhost

顯示的内容相同,則證明我們已經成功了。

映射TCP

有時候,我們使用遠端桌面功能,或者在linux中進行SSH連接配接,對于處在内網環境中的計算機,我們可以對該端口進行TCP映射。

#這裡以SSH連接配接Linux時的22端口為例
./bin/ngrok -config=ngrok.cfg -proto=tcp 22
映射成功的話,會顯示如下内容:
#用戶端ngrok正常執行顯示的内容

ngrok                                                  (Ctrl+C to quit)

Tunnel Status     online
Version           1.7/1.7
Forwarding        tcp://imike.me:12222 -> 127.0.0.1:22
Web Interface     127.0.0.1:4040
# Conn            0
Avg Conn Time     0.00ms
           

現在,在putty等ssh工具中即可連接配接imike.me。切記端口是号12222,是随機配置設定的一個端口号,而不是預設的22端口了。Windows的遠端桌面可以将其映射到3389端口來實作。同理,如果要做MySQL的遠端連接配接,隻需映射3306端口即可。FTP可映射21端口。

注意:用戶端必須使用自己編譯的ngrok檔案

管理界面

Ngrok用戶端運作後,有一個Web Interface位址,這是ngrok 提供的監控界面。通過這個界面可以看到遠端轉發過來的http 詳情,包括完整的request/response 資訊,可以不重新整理頁面通過replay按鈕重新送出請求,非常友善。

通路管理界面:

http://127.0.0.1:4040

後續定制及優化

通過以上操作,我們的ngrok伺服器就已經成功搭建了,用戶端也成功的跑了起來。但是,如果我們想要對ngrok進行一些定制和優化,可以參考這些後續定制及優化的方法。

為什麼在啟動服務端的時候,端口不指定為80

很遺憾,因為這台vps不是隻用來做ngrok服務的,我部落格還在上面呢,80端口已經被nginx占用了。

那怎麼辦?不得不提nginx是個牛逼的軟體,我們可以在nginx中配置一個server,就綁定web.tunnel.imike.me域名,然後将所有請求轉發到後端:8081端口上,這就是反向代理。我發一下自己的nginx配置:

#ngrok.imike.me.conf
upstream ngrok {
    server 127.0.0.1:8888;
    keepalive 64;
}

server {
    listen 80;
    server_name *.onlineweifu.cn;
    access_log /var/log/nginx/ngrok_access.log;
    location / {
        proxy_set_essay-header X-Real-IP $remote_addr;
        proxy_set_essay-header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_essay-header Host  $http_host:8081;
        proxy_set_essay-header X-Nginx-Proxy true;
        proxy_set_essay-header Connection "";
        proxy_pass      http://ngrok;

    }

}
           

修改用戶端ngrok預設服務位址

用戶端每次還需要加載配置檔案,這樣顯得有些麻煩。能不能像官方服務那樣直接執行指令 ngrok 80就能使用呢?我們隻需要在編譯用戶端之前,稍作修改即可。同樣,如果需要指定域名可以執行指令 ngrok -subdomain=test 80來運作用戶端。

修改預設服務位址

vim ./src/ngrok/client/model.go
找到第23行,将 defaultServerAddr = "ngrokd.ngrok.com:443"
修改為defaultServerAddr = "tunnel.mydomain:4443" 即可。
           

修改用戶端ngrok左上角藍色文字logo

運作用戶端後,我們會發現在用戶端左上角會有一個藍色字型的”ngrok”字樣的文字logo,如果覺得不太喜歡,或者想修改一下的話,可以在編譯用戶端之前,作如下修改。

修改用戶端藍色文字logo

Vim ./src/ngrok/client/views/term/view.go
找到第100行,将
v.APrintf(termbox.ColorBlue|termbox.AttrBold, 0, 0, "ngrok")
修改為
v.APrintf(termbox.ColorBlue|termbox.AttrBold, 0, 0, "your logo")
即可。
           

修改用戶端幫助資訊

Ngrok用戶端預設的幫助資訊很少,我們可以在編譯用戶端之前,自己定制幫助内容。

修改用戶端預設幫助資訊

vim ./src/ngrok/client/client/cli.go
找到第14行,修改 const usage2 string的值即可。
           

用戶端程式加殼優化

編譯好的Windows用戶端ngrok.exe大小為10MB,感覺有點大,這樣加載到記憶體中,需要讀取硬碟的内容也相對較多,影響速度。是以,我們來給用戶端程式加個壓縮殼,對程式進行壓縮。

這裡采用mpress進行加殼,先從網上下載下傳mpress.exe,之後将ngrok.exe拖放到mpress.exe的圖示上,就能完成加殼操作。我們可以看到,加殼後的程式隻有1.94MB,壓縮率不到20%,大大節省了磁盤空間。同時小檔案加載起來,速度會更快。

常見錯誤

在編譯ngrok的時候,安裝yaml的時候不能下載下傳,無反應

gopkg.in/inconshreveable/go-update.v0  (download)
或者
gopkg.in/yaml.v1 (download)
原因git版本太低,需>= 1.7.9.5,通過RPMForge源安裝最新版本git解決:
yum --enablerepo=rpmforge-extras install git
           

把編譯出來的32位用戶端放在64位上運作時會報錯

/lib/ld-linux.so.2: bad ELF interpreter

#解決方法
yum install -y glibc.i686
           

在ngrok目錄下執行如下指令,編譯ngrokd

$ make release-server

出現如下錯誤:
GOOS="" GOARCH="" go get github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=release \
        -debug=false \
        -o=src/ngrok/client/assets/assets_release.go \
        assets/client/…
make: bin/go-bindata: Command not found
make: *** [client-assets] Error 127
go-bindata被安裝到了$GOBIN下了,go編譯器找不到了。修正方法是将$GOBIN/go-bindata拷貝到目前ngrok/bin下。

$cp /home/ubuntu/.bin/go14/bin/go-bindata ./bin
           

用戶端ngrok.cfg中server_addr後的值必須嚴格與-domain以及證書中的NGROK_BASE_DOMAIN相同,否則Server端就會出現如下錯誤日志

[03/13/15 09:55:46] [INFO] [tun:15dd7522] New connection from 54.149.100.42:38252
[03/13/15 09:55:46] [DEBG] [tun:15dd7522] Waiting to read message
[03/13/15 09:55:46] [WARN] [tun:15dd7522] Failed to read message: remote error: bad certificate
[03/13/15 09:55:46] [DEBG] [tun:15dd7522] Closing
           

伺服器啟動ngrok:nohup ngrokd -domain="onlineweifu.cn" -httpAddr=":8888" -httpsAddr=":8889" &

繼續閱讀