1. 程式人生 > >搭建並配置優雅的 ngrok 服務實現內網穿透

搭建並配置優雅的 ngrok 服務實現內網穿透

問題

隨著網際網路生態圈的發展,現今的 Web 專案中開始越來越多的使用第三方服務,通常這些第三方服務都是由 Client 通過 Server 的 API 主動發起請求,但是 Server 回撥 Client 這種方式也是很多服務中不可避免的一種方式。這樣的場景下,對於開發者就有個比較麻煩的問題:

如何在開發的過程中讓處於內網的開發機收到回撥?

古老的解決方案

方案一

傳統解決方案中,如果沒有固定 ip 首先需要動態域名,然後需要維護一份外網到內網的埠對映表,最後如果 Client 中有取 Host 資訊的操作還需要響應的 Hack(這點後面會提到)。當然,如果你連公網 ip 都沒有,那麼就可以直接放棄這個方案了。

方案二

一種更為有效的解決方案是:使用一臺擁有公網 IP 的主機,通過隧道來實現轉發。其實在很早之前,為了讓處於校園網內網的伺服器在外網可以訪問,我經常通過 SSH Tunnel 來解決這個問題。

# 將遠端主機的 10086 轉發到本地的 3000
ssh -C -f -N -g -R 10086:127.0.0.1:3000 [email protected]_Server

這種方式雖然使用簡單,但是穩定性並不理想,一段時間內沒有請求 Tunnel 就會自動斷開。而且使用者必須有 Tunnel_Server 的 ssh 登入許可權,每開一個服務就需要佔用 Tunnel_Server 一個埠。

Ngrok

正當我苦於寫 SSH Tunnel 的各種連線指令碼和守護指令碼的時候,第一次接觸到了 Ngrok。(2013年)那個時候 ngrok 還是一個很冷門的小工具,它所依賴的 Go 也一樣,加上文件有限,各種嘗試之後並沒有把這套服務搭起來。

再後來,國內出現了金資料團隊維護的 tunnel.mobi,默默的為國內的開發者提供了很長一段時間的便利。國內 ngrok 的快速普及,個人覺得很大程度上都得益與 tunnel.mobi 的影響。然而這樣一個優秀的服務,在維持一年之後(2014.10-2015.10),選擇了關閉。

此後,國內各種 ngrok 服務提供者如雨後春筍般出現,我司對於 ngrok 的依賴也比較大,於是我也在我們自己的伺服器上搭了一套 ngrok,不覺然都快過去一年了。在這段時間的使用裡,也發現了一些不方便或不夠友好的地方,加上之前的搭建的那臺伺服器如今已不堪重負,於是趁週末的時候重新搭建了一份,並做了一點點配置上的優化。

服務端

我使用的環境是 Aliyun ECS + Ubuntu 14.04,雙網絡卡(內網網絡卡+外網網絡卡)

原始碼安裝

首先裝必要的工具:

sudo apt-get install build-essential golang mercurial git

獲取 ngrok 原始碼:

git clone https://github.com/inconshreveable/ngrok.git ngrok
cd ngrok

編譯&安裝:

sudo make release-server
sudo cp bin/ngrokd /usr/local/bin/ngrokd

Apt-get 安裝(二選一)

如果你並不需要最新版本的 ngrokd, 同時對原始碼安裝也沒什麼興趣,那麼其實可以偷懶

sudo apt-get install ngrok-server

域名

選定你要使用的域名,比如:yii.im,新增兩條解析到你的伺服器

  • yii.im
  • *.yii.im

證書

ngrok 通訊依賴 TLS 證書來加密,所以啟動的時候需要指定你的域名和對應的證書

既然依賴證書的話,那你應該先有一份證書。在搭建 ngrok 服務的時候,對於證書的處理有多種方式可選:

  • 使用 CA 頒發的證書,也就是正式的 TLS 證書
  • 使用自簽名證書,並自行編譯分發帶自簽名證書的客戶端
  • 使用自簽名證書,使用通用的客戶端,但需要使用者把自簽名證書新增到自己根證書

本文中使用第一種方式,域名證書通過 沃通CA免費SSL證書 取得。

第三種方式,除了需要使用者新增根證書以外,其他配置與本文一樣。

關於 https 的支援

由於 ngrok 工作是通過分配 subdomain 的方式,所以我們實際使用到的域名都是 yii.im 的子域名,如 pub.yii.im 如果要對這個子域名啟用 https 服務,那麼至少需要三點支援:

  1. ngrok 支援 https, 這個預設就是開啟的
  2. pub.yii.im 也需要有證書或包含在一個泛域名證書中
  3. 瀏覽器(或其他終端)信任 pub.yii.im 的根證書

根據這三點要求,我們重新解讀上面三種證書的處理方式:

第一種:由於免費證書是單域名證書,所以你需要給可能會用到二級域名也簽上證書才行,當然,如果夠錢,買個包含所有二級域名的證書也是可以的

第二種:自簽名證書很容易做到第二點,然而並無卵用,除了自編譯的 ngrok-client外誰也不認這個證書

第三種:可以支援 https,但是要所有使用者(包括訪問使用者)都新增根證書這種要求,略微有點…

綜上所述,我們選擇放棄了 https ,因為日常使用並沒有強制要求 https 的情況,能跑就夠了,要什麼自行車。

ㄟ( ▔, ▔ )ㄏ手動滑稽

啟動設定

前面生成了 ngrokd 就是 ngrok server ,指定證書、域名和埠就可以啟動它了:

# 獲取幫助資訊
ngrokd -h

# Usage of ngrokd:
#   -domain="ngrok.com": Domain where the tunnels are hosted
#   -httpAddr=":80": Public address for HTTP connections, empty string to disable
#   -httpsAddr=":443": Public address listening for HTTPS connections, emptry string to disable
#   -log="stdout": Write log messages to this file. 'stdout' and 'none' have special meanings
#   -tlsCrt="": Path to a TLS certificate file
#   -tlsKey="": Path to a TLS key file
#   -tunnelAddr=":4443": Public address listening for ngrok client

# 試著啟動
ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain=yii.im -httpAddr=:8081 -httpsAddr=

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

現在,通過 http://sub.yii.im:8081 就可以訪問到 ngrok 提供的轉發服務。在客戶端連進來之前,你應該會看到:

Tunnel sub.yii.im:8081 not found

這說明萬事俱備,只差客戶端來連了。

埠問題(可選)

url 上帶上埠通常來說並不會有什麼影響,而且通過 nginx 隱藏起來也很簡單:

# ngrokd.conf
server {
    server_name *.yii.im;
    listen 80;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:8081;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8081;
    }

}

但是!這裡就有一個很煩躁的地方了,ngrokd 裡面有一層自己的 Host 處理,於是 proxy_set_header Host 必須帶上 ngrokd 所監聽的埠,否則就算請求被轉發到對應埠上, ngrokd 也不會正確的處理。

帶上埠號又會導致了另一個操蛋的問題:你請求的時候是 sub.yii.im,你在 web 應用中獲取到的 Host 是 sub.yii.im:8081,如果你的程式裡面有基於 Request Host 的重定向,就會被重定向到 sub.yii.im:8081 下面去。

要完美的解決這個埠的問題,就需要讓 ngrokd 直接監聽 80 埠。

通常來說 VPS 都是雙網絡卡的(一內一外),讓 ngrokd 監聽外網的 80 實在有些浪費,這個埠還是留給 nginx 比較合理。所以比較理想的方式是:nginx 監聽外網 80,ngrokd 監聽內網 80,讓 nginx 將對應的請求轉發到內網 80 上來。

如:

  • 內網 ip: 10.160.xx.xx
  • 外網 ip: 112.124.xx.xx

啟動 ngrokd:

sudo ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain=yii.im -httpAddr=10.160.xx.xx:80 -httpsAddr=

配置 nginx:

# ngrokd.conf
server {
    listen      112.124.xx.xx:80;
    server_name *.yii.im;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect  off;
        proxy_pass      http://10.160.xx.xx:80;
    }
}

# the_others_need_80.conf
server {
    listen      112.124.xx.xx:80;
    #...
}

也可以手動新增ip
[[email protected] conf]# ifconfig eth0:0 192.168.3.60/24 up  
[[email protected] conf]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:0C:29:12:99:D4  
          inet addr:192.168.3.49  Bcast:192.168.3.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe12:99d4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:792652 errors:0 dropped:0 overruns:0 frame:0
          TX packets:460481 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:972250327 (927.2 MiB)  TX bytes:92493014 (88.2 MiB)


eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:12:99:D4  
          inet addr:192.168.3.60  Bcast:192.168.3.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

維護指令碼(可選)

由於 ngrokd 的啟動命令老長老長,偶爾發現它死了需要重啟,拼(找)命令都拼半天,於是我順手寫了一個維護指令碼

注意: Ubuntu 適用,Centos 需要一點修改

wget https://gist.githubusercontent.com/IvanChou/1be8b15b1b41bf0ce2e9d939866bbfec/raw/1a2445599fe7fd706505a6e103a9dc60b4d3a0ed/ngrokd -O ngrokd

# 修改 指令碼中的配置
vi ngrokd

chomd +x ngrokd
sudo mv ngrokd /etc/init.d/ngrokd

TCP支援 - SSH etc.(可選)

ngrok 是 TCP 穿透,也就是說只要是基於 TCP 協議的通訊,它都能協助我們進行穿透,當然也包括 SSH 和 mstsc。

ngrok 在進行 TCP 連線的時候,是通過額外開啟一個埠的方式,如果 Client 沒有指定埠,ngrokd 將會隨機開啟一個大號埠。如指定 ngrokd 使用 10086 埠,連線建立後可通過 yii.im:10086 訪問到 Client 的指定埠。

建議可以在 iptables 中放行少量 大口徑埠 備用。

客戶端

下載

由於使用的是 CA 證書,所以不需要自行編譯客戶端,可以網上自行下載各種 ngrok v1.7 的客戶端,理論上都是可用的(有的似乎對客戶端做了修改,或許有其它未知原因而無法使用,請自行略過)

2016年10月: Mac 升級到 10.12 後,稍微舊一點的 ngrok-client 都有心跳 bug,導致經常斷開且介面狀態無變化,需要重新下載或編譯一下最新的客戶端。

MAC & Linux 下,可以將 ngrok 放到 /usr/local/bin/ 下備用

ngrok.yml

server_addr: "yii.im:4443"
trust_host_root_certs: true

這段配置是用來指定 Server 和 認證方式 的:

  • server_addr 中的 host 需要與 ngrokd 所使用的證書嚴格對應
  • trust_host_root_certs 是否信任系統根證書,如果是帶自簽名證書編譯的 ngrok 客戶端,這個值應該設定為 false;如果使用 CA 證書,或者使用者添加了根證書,這個值應該設定為 true。

由於官網現在只有 2.0 以上版本的支援,這裡只能參照配置的寫法,啟動方式請勿參考。

Http 連線

ngrok -config=path/to/ngrok.yml -proto=http -subdomain pub 3000

可以看到

ngrok                                               (Ctrl+C to quit)

Tunnel Status                 online
Version                       1.7/1.7
Forwarding                    http://pub.yii.im -> 127.0.0.1:3000
Web Interface                 127.0.0.1:4040
# Conn                        0
Avg Conn Time                 0.00ms

說明連線成功,現在訪問 http://pub.yii.im 就可以訪問到本機 3000 埠上的服務了

介面管理(推薦)

在上面的執行時介面中,有一個 Web Interface 地址,這是 ngrok 提供的監控介面。通過這個介面可以看到遠端轉發過來的 http 詳情,包括完整的 request/response 資訊,相當於附帶了一個抓包工具。

TCP 連線

指定 server 埠需要在 ngrok.yml 中配置才能實現

不指定埠

ngrok -config=path/to/ngrok.yml -proto=tcp 22

連線狀態:

ngrok                                               (Ctrl+C to quit)

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

– EOF –

實際上,由於 ngrok 可以轉發 TCP,所以還有很多玩法,原理都一樣,這裡就不多寫了。

– PS –

文中使用的 yii.im 只是為了說明使用的域名,這個域名下並沒有搭 ngork 服務

(/= _ =)/~┴┴ ╮(╯▽╰)╭

相關推薦

搭建配置優雅ngrok 服務實現穿透

問題 隨著網際網路生態圈的發展,現今的 Web 專案中開始越來越多的使用第三方服務,通常這些第三方服務都是由 Client 通過 Server 的 API 主動發起請求,但是 Server 回撥 Client 這種方式也是很多服務中不可避免的一種方式。這樣的場景下,對於

阿里雲搭建自己的ngrok服務-實現穿透

參考博文:https://blog.csdn.net/qq_34292044/article/details/78559128https://blog.csdn.net/huanxiang201311/article/details/72725891一.環境準備       

搭建 ngrok 服務實現穿透

文章目錄 提醒:本文最後更新於 1362 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 我們經常會有「把本機開發中的 web 專案給朋友看一下」這種臨時需求,為此專門在 VPS 上部署一遍就有點太浪費了。之前我通常是在 ADSL 路由器上配個埠對映讓本機服務在外網可以訪問,但現在大部

基於小米球(Ngrok實現穿透

一、前言 在公司部署了一套大資料叢集。為了方便測試。所以需要弄個內網穿透實現在家裡訪問公司內部網路,但是不想付費。所以整了個免費

一分鐘實現穿透ngrok伺服器搭建

簡單來說內網穿透的目的是:讓外網能訪問你本地的應用,例如在外網開啟你本地http://127.0.0.1指向的Web站點。 最近公司的花生殼到期了,要續費,發現價格一直在漲,都是5年以上的老使用者,旗艦版都沒有實現內網完全穿透,打算自己動手替換這個服務,中間走

阿里雲搭建ngrok實現穿透

內網穿透想必是開發微信的同志所必須的,大部分人首先想到的是去網上找各種現成的吧,比如sunny-ngrok或者向日葵之類的,但是世界上沒有免費的午餐,免費的都是會崩的!!!下面我就來教大家怎麼用阿里雲和ngrok搭建一個內網穿透!!!! 1.準備工作: 要能實現內網穿透,

配置frp實現穿透

一、frp的作用 利用處於內網或防火牆後的機器,對外網環境提供 http 或 https 服務。 對於 http, https 服務支援基於域名的虛擬主機,支援自定義域名繫結,使多個域名可以共用一個80埠。 利用處於內網或防火牆後的機器,對外網環境提供 tcp 和 udp

MAC 下使用 ngrok 實現穿透

2. 解壓到指定目錄:$ unzip -n ngrok-stable-darwin-amd64.zip -d /tmp3. 進入到解壓後的 ngrok 所在路徑:  $ cd /tmp4. 開啟服務: 

樹莓派通過ngrok實現穿透

最近在折騰樹莓派,想要實現遠端對寢室內的監控和對部件的控制,即通過外網訪問本地樹莓派。自然而然想到使用內網穿透,百度了一下有花生殼和NATAPP之類的服務提供商。不過這種事情還是自己折騰有意思,而且手頭也有一個沒用的域名和兩臺VPS,就決定自己來做了。

利用ngrok實現穿透

實現內網穿透紫ngrok無法通過天牆之後,國內也出現了一批成熟的商業化實現方案,諸如花生殼、net123、Sunny-ngrok等。不過免費的極不穩定還有流量頻寬限制,最後還是決定自己搭一個。本文利用ngrok搭建一個用於內網穿透的環境。需求是通過一

【免費穿透】利用NatApp實現穿透

一,註冊賬號 在NatApp上註冊賬號:https://natapp.cn/register 二,實名認證 三,購買隧道 1,購買免費隧道 2,選擇8080埠進行內網穿透,併購買 四,下載客戶端

關於 frp+nginx實現穿透+共用埠

首先  frps  和 frpc  對比 [common] bind_addr = 0.0.0.0 bind_port = 7000 vhost_http_port = 80 vhost_https_port = 8443 dashboard_port = 7500

可以實現穿透的幾款工具

首先說下內網穿透的原理。   NAPT原理   在NAT閘道器上會有一張對映表,表上記錄了內網向公網哪個IP和埠發起了請求,然後如果內網有主機向公網裝置發起了請求,內網主機的請求資料包傳輸到了NAT閘道器上,那麼NAT閘道器會修改該資料包的源IP地址和源埠為NAT

簡簡單單教你實現穿透

                sudo ./bin/ngrokd -tlsKey=server.key -tlsCrt=server.crt -domain="zzmd.superboycxx.top" -httpAddr=":8081" -httpsAddr=":8082"屁話不講,先來看下效果:1.搭

frp實現穿透

一、frp的作用 利用處於內網或防火牆後的機器,對外網環境提供 http 或 https 服務。 對於 http, https 服務支援基於域名的虛擬主機,支援自定義域名繫結,使多個域名可以共用一個80埠。 利用處於內網或防火牆後的機器,對外網環境提供 tcp 和 udp 服務,例如在家裡通

【原創】配置微信伺服器與穿透--轉載請註明出處

微信公眾號開發 在進行學習微信公眾號開發時,首先我們需要做好一些必須的準備。 1.具有一個自己的公眾號平臺,方便進行學習。 2.在網上找一款內網穿透器,進行內網穿透,接入微信開發。 3.有一個已經搭建好的Web專案。 1.申請微信公眾號 進行微信公眾號申請時,在下方地址進

【智慧路由器】openwrt實現穿透(p2p、n2n)

背景 有時候在對線上裝置進行維護,由其是除錯的時候希望技術人員遠端進入路由後臺除錯路由資訊的時候,如果沒有內網穿透就會比較麻煩。 本篇部落格是在路由上實現內網穿透,以實現資料、檔案的點對點傳輸或訪問 閱讀時需要額外瞭解下p2p協議原理,以及n2n工

使用電信光貓加路由器實現穿透,外訪問

準備工作:1. 需註冊一個花生殼賬號和購買一個殼域名(可以免費獲取殼域名)2. 電腦下載安裝花生殼客戶端3. 使用電信光貓超級管理員密碼獲取器獲取光貓超級密碼4. 寬頻賬號與寬頻密碼(光貓配置後,需登入路由器上網,路由器需使用寬頻賬號與密碼登入上網)一.電信光貓配置1.1 在

可以實現穿透的幾款工具 侵立刪

轉自:https://mp.weixin.qq.com/s/TZmEbJ63f-N1RU1850VMaA   最近沒什麼事情,看了一些關於內網穿透的文章,因我本身已是做微信開發相關的工作,對這部分關注的比較多,現分享給大家。   首先說下內網穿透的原理。 &n

如何實現穿透

        區域網是指在某一區域內由多臺計算機互聯成的計算機組。一般是方圓幾千米以內。區域網可以實現檔案管理、應用軟體共享、印表機共享、工作組內的日程安排、電子郵件和傳真通訊服務等功能。區域網是封閉型的,可以由辦公室內的兩臺計算機組成,也可以由一個公司內的上千臺計算機組