一分鐘實現內網穿透(ngrok伺服器搭建)

簡單來說內網穿透的目的是:讓外網能訪問你本地的應用,例如在外網開啟你本地http://127.0.0.1指向的Web站點。

最近公司的花生殼到期了,要續費,發現價格一直在漲,都是5年以上的老使用者,旗艦版都沒有實現內網完全穿透,打算自己動手替換這個服務,中間走了不少的彎路,這裡記錄一些文字為大家提供參考。

隨著開發與執行移動網際網路的應用越來越多對打通內外網的需要也更加迫切,如微信開發、IOS與Android開發等。

雖然租用VPS、ECS等伺服器可以解決很多問題但高效能的外網伺服器價格非常貴還有資料安全問題,我選擇的是公網伺服器僅做代理與輕量應用,複雜的應用部署到內網伺服器再穿透訪問。

一、內網穿透概要

為了理解內網穿透我們先來了解幾個概念:

1.1、IP地址

網路中唯一定位一臺裝置的邏輯地址,類似我們的電話號碼

在網際網路中我們訪問一個網站或使用一個網路服務最終都需要通過IP定位到每一臺主機,如訪問baidu網站:

其中119.75.213.61就是一個公網的IP地址,他最終指向了一臺伺服器。

IP地址是IP協議提供的一種統一的地址格式,它為網際網路上的每一個網路和每一臺主機分配一個邏輯地址,以此來遮蔽實體地址的差異。

內網IP可以同時出現在多個不同的區域網絡中,如A公司的U1使用者獲得了192.168.0.5,B公司的U3使用者也可以獲得192.168.0.5;但公網IP是唯一的,因為我們只有一個Internet。

//區域網可使用的網段(私網地址段)有三大段:
10.0.0.0~10.255.255.255(A類)
172.16.0.0~172.31.255.255(B類)
192.168.0.0~192.168.255.255(C類)

1.2、域名

域名是IP的別名,便於記憶,域名最終通過DNS解析成IP地址。

IP V4是一個32位的數字,IP V6有128位,要記住一串毫無意義的數字非常困難,域名解決了這個問題。

如www.zhangguo.com.cn就是一個域名,cn表示地區,com表示商業機構,zhangguo是公司名稱,www是主機名

DNS查詢過程如下,最終將域名變成IP地址

 

 

1.3、NAT

NAT(Network Address Translation)即網路地址轉換,NAT能將其本地地址轉換成全球IP地址。

內網的一些主機本來已經分配到了本地IP地址(如區域網DHCP分配的IP),但現在又想和因特網上的主機通訊(並不需要加密)時,可使用NAT方法。

通過使用少量的公有IP 地址代表較多的私有IP 地址的方式,將有助於減緩可用的IP地址空間的枯竭。

NAT不僅能解決了lP地址不足與共享上網的問題,而且還能夠有效地避免來自網路外部的攻擊,隱藏並保護網路內部的計算機。

多路由器可完成NAT功能。

NAT的實現方式:

靜態轉換是指將內部網路的私有IP地址轉換為公有IP地址,IP地址對是一對一。

動態轉換是指將內部網路的私有IP地址轉換為公用IP地址時,IP地址是不確定的,是隨機的。

埠多路複用(Port address Translation,PAT),內部網路的所有主機均可共享一個合法外部IP地址實現對Internet的訪問,從而可以最大限度地節約IP地址資源。同時又可隱藏網路內部的所有主機,有效避免來自internet的攻擊。因此,目前網路中應用最多的就是埠多路複用方式。

應用程式級閘道器技術(Application Level Gateway)ALG:傳統的NAT技術只對IP層和傳輸層頭部進行轉換處理,ALG它能對這些應用程式在通訊時所包含的地址資訊也進行相應的NAT轉換。

1.4、Proxy

Proxy即代理,被廣泛應用於計算機領域,主要分為正向代理與反向代理:

1.4.1、正向代理

比如X花店代A,B,C,D,E五位男生向Candy女生送匿名的生日鮮花,這裡的X花店就是5位顧客的代理,花店代理的是客戶,隱藏的是客戶。這就是我們常說的代理。

正向代理隱藏了真實的請求客戶端。服務端不知道真實的客戶端是誰,客戶端請求的服務都被代理伺服器代替來請求,某些科學上網工具扮演的就是典型的正向代理角色。用瀏覽器訪問http://www.google.com時被牆了,於是你可以在國外搭建一臺代理伺服器,讓代理幫我去請求google.com,代理把請求返回的相應結構再返回給我。

當多個客戶端訪問伺服器時伺服器不知道真正訪問自己的客戶端是那一臺。正向代理中,proxy和client同屬一個LAN,對server透明;

1.4.2、反向代理

撥打10086客服電話,接線員可能有很多個,排程器會智慧的分配一個接線員與你通話。這裡的排程器就是一個代理,只不過他代理的是接線員,客戶端不能確定真正與自己通話的人,隱藏與保護的是目標物件。

反向代理隱藏了真實的服務端,當我們請求 ww.baidu.com 的時候,就像撥打10086一樣,背後可能有成千上萬臺伺服器為我們服務,但具體是哪一臺,你不知道,也不需要知道,你只需要知道反向代理伺服器是誰就好了,ww.baidu.com 就是我們的反向代理伺服器,反向代理伺服器會幫我們把請求轉發到真實的伺服器那裡去。Nginx就是效能非常好的反向代理伺服器,用來做負載均衡。

反向代理中,proxy和server同屬一個LAN,對client透明。

瞭解更多關於代理內容請點選這裡

1.5、DDNS

DDNS即動態域名解析,是將使用者的動態IP地址對映到一個固定的域名解析服務上,使用者每次連線網路的時候,客戶端程式就會通過資訊傳遞把該主機的動態IP地址傳送給位於服務商主機上的伺服器程式,服務程式負責提供DNS服務並實現動態域名解析。就是說DDNS捕獲使用者每次變化的IP地址,然後將其與域名相對應,這樣域名就可以始終解析到非固定IP的伺服器上,網際網路使用者通過本地的域名伺服器獲得網站域名的IP地址,從而可以訪問網站的服務。

1.6、為什麼需要內網穿透

當內網中的主機沒有靜態IP地址要被外網穩定訪問時可以使用內網穿透

在網際網路中唯一定位一臺主機的方法是通過公網的IP地址,但固定IP是一種非常稀缺的資源,不可能給每個公司都分配一個,且許多中小公司不願意為高昂的費用買單,多數公司直接或間接的撥號上網,電信部門會給接入網路的使用者分配IP地址,以前上網使用者少的時候基本分配的都是臨時的靜態IP地址,租約過了之後可能會更換成另一個IP地址,這樣外網訪問就不穩定,因為內網的靜態IP地址一直變化,為了解決這個問題可以使用動態域名解析的辦法變換域名指向的靜態IP地址。但是現在越來越多的上網使用者使得臨時分配的靜態IP地址也不夠用了,電信部門開始分配一些虛擬的靜態IP地址,這些IP是公網不能直接訪問的,如以125開頭的一些IP地址,以前單純的動態域名解析就不好用了。

1.7、內網穿透的定義與障礙

簡單來說實現不同區域網內的主機之間通過網際網路進行通訊的技術叫內網穿透。

障礙一:位於區域網內的主機有兩套 IP 地址,一套是區域網內的 IP 地址,通常是動態分配的,僅供區域網內的主機間通訊使用;一套是經過閘道器轉換後的外網 IP 地址,用於與外網程式進行通訊。

障礙二:位於不同區域網內的兩臺主機,即使是知道了對方的 IP 地址和埠號,“一廂情願”地將資料包傳送過去,對方也是接收不到的。

因為出於安全起見,除非是主機主動向對方發出了連線請求(這時會在該主機的資料結構中留下一條記錄),否則,當主機接收到資料包時,如果在其資料結構中查詢不到對應的記錄,那些不請自來的資料包將會被丟棄。

解決辦法:要想解決以上兩大障礙,我們需要藉助一臺具有公網 IP 的伺服器進行橋接。

二、常見的內網穿透產品

2.1、花生殼

花生殼既是內網穿透軟體、內網對映軟體,也是埠對映軟體。規模最大,較正規,完善。

收費高,使用簡單

官網:http://www.oray.com/

2.2、Nat123

nat123是內網埠對映與動態域名解析軟體,在內網啟動對映後,可在外網訪問連線內網網站等應用。整個網站我都沒有找到客服電話,網友發了一些反面的評價

收費,使用簡單

官網:http://www.nat123.com

2.3、NATAPP

NATAPP基於ngrok的國內內網穿透服務,免費版會強制更換域名,臨時用一下可以

收費,使用簡單

官網:https://natapp.cn/

2.4、frp與其它

frp 是一個高效能的反向代理應用,可以幫助您輕鬆地進行內網穿透,對外網提供服務,支援 tcp, http, https 等協議型別,並且 web 服務支援根據域名進行路由轉發。

開源免費

使用相對複雜,需要代理伺服器支援

官網:https://github.com/fatedier/frp

文件:檢視幫助文件簡書示例

利用處於內網或防火牆後的機器,對外網環境提供 http 或 https 服務。

對於 http, https 服務支援基於域名的虛擬主機,支援自定義域名繫結,使多個域名可以共用一個80埠。

利用處於內網或防火牆後的機器,對外網環境提供 tcp 和 udp 服務,例如在家裡通過 ssh 訪問處於公司內網環境內的主機。

因為frp 仍然處於前期開發階段,未經充分測試與驗證,不推薦用於生產環境,所有我選擇了ngrok,資料比較多。

還有如聖劍內網通、ngrok(開源免費)、更多辦法

三、ngrok

ngrok是一個反向代理,通過在公共的端點和本地執行的Web伺服器之間建立一個安全的通道。ngrok可捕獲和分析所有通道上的流量,便於後期分析與響應。

開源免費

官網:https://ngrok.com/

原始碼:https://github.com/inconshreveable/ngrok

ngrok1.x開源,ngrok2.x不開源

ngrok使用go語言開發,原始碼分為客戶端與伺服器端。

國內免費伺服器:http://ngrok.ciqiuwl.cn/,更多免費伺服器請大家挖掘,資源共享,我隨時更新:)

如果有伺服器,僅客戶端的使用是不復雜的,以上面的免費伺服器為示例完成內網穿透

現在假定我的本地已成功部署了一個網站,訪問地址為127.0.0.1,想內網穿透後被公網上的使用者訪問,一般步驟如下:

步驟1、下載windows版本的客戶端,解壓。一般在為你提供代理伺服器的網站上找你要下載的客戶端:

步驟2、在命令(cmd)行下進入到ngrok客戶端目錄下

步驟3、執行 ngrok -config=ngrok.cfg -subdomain xxx 80 //(xxx 是你自定義的域名字首),建議批處理

如果連線成功,會提示如下資訊:

這一步如果你認為太麻煩,可以直接執行目錄下的start.bat批處理檔案就不用進DOS環境了。執行start.bat直接跳過2,3步

步驟4、如果開啟成功 你就可以使用 xxx.ngrok.xiaomiqiu.cn 來訪問你本機的 127.0.0.1:80 的服務了,當然你必須確定的是你本機的Web是可以正常訪問的。

注意:

如果你自己有頂級域名,想通過自己的域名來訪問本機的專案,那麼先將自己的頂級域名解析到120.25.161.137(域名需要已備案哦,80埠必須備案),然後執行 ngrok -config=ngrok.cfg -hostname xxx.xxx.xxx 80 //(xxx.xxx.xxx是你自定義的頂級域名)

四、ubuntu下生成ngrok伺服器主程式

4.1、步驟與先決條件

如果你只是臨時穿透或除錯用,到第三步基本就可以了,但如果想作為穩定的商業服務,用別人的伺服器還是受制於人,這裡我們準備搭建自己的ngrok伺服器。大致的步驟如下:

ngrok伺服器可以是多種平臺,如windows、Linux(CentOS、Debian、Ubuntu等)、Mac OS等。

編譯原始碼生成應用強烈建議大家使用linux環境,windows肯定可以成功,但非常麻煩,我在windows作業系統上兜了一個大圈圈。

先決條件:

a)、您有一臺公網上的伺服器,如阿里雲的ECS

b)、您有一個域名,最好ICP備案成功,不然80埠沒有辦法使用,不過像微信開發是不使用80埠的,可以用nginx代理轉換。

4.2、安裝ubuntu作業系統

在linux環境下編譯ngrok的原始碼比windows下 方便很多,這裡我們選擇使用ubuntu,獲得ubuntu的方法有如下幾種:

1)、全新安裝ubuntu系統

2)、申請VPS伺服器, 阿里雲、騰訊雲、華為雲、百度雲、新浪雲等,僅編譯一下這種方法不錯

3)、在虛擬機器中安裝ubuntu系統

綜合考慮我選擇了在虛擬機器中安裝ubuntu作業系統

4.2.1、安裝VMware虛擬機器

VMware Workstation是一款功能強大的虛擬機器軟體,在不影響本機作業系統的情況下,使用者可以在虛擬機器中同時執行不同版本的作業系統,用於開發、測試以及部署工作。

VMware Workstation 12 pro下載:VMware-workstation-full-12.1.0-3272444.exe

序列號:5A02H-AU243-TZJ49-GTC7K-3C61N(商業應用請購買正式版權,這裡僅為學習使用)

1)、雙擊VMware Workstation 12安裝檔案,或者右鍵管理員身份開啟,提示是否允許更改,點選是;

2)、開啟VMware安裝嚮導,點選下一步;

 技術分享

3)、VMware Workstation 12啟用步驟:

  方法一、首次開啟直接輸入上文金鑰,即可啟用;
  方法二、首次開啟選擇試用,進入試用後按一下步驟啟用:

  a、開啟虛擬機器主介面,點選“幫助”—“輸入許可證金鑰”;

  技術分享

  b、在金鑰輸入框輸入永久許可證金鑰5A02H-AU243-TZJ49-GTC7K-3C61N,確定;更多

4.2.2、安裝ubuntu到虛擬機器

1)、下載ubuntu作業系統映象

下載地址:https://www.ubuntu.com/download/desktop

這裡我下載的是ubuntu-16.04.3-desktop-amd64.iso

2)、在VMware中安裝ubuntu

開啟VMware點選“建立新的虛擬機器”

嚮導選擇自定義

這裡寫圖片描述

然後下一步再下一步,直到這裡,稍後再安裝系統

這裡寫圖片描述

後面設定處理器和記憶體的,電腦配置好的可以試試,否則採用預設的,博主這裡是採用預設的,然後下一,直到這裡,選擇將虛擬機器儲存為單個磁碟:

這裡寫圖片描述

個人建議至少20G硬碟空間,記憶體建議給1.5G,當然也要看電腦本身的配置,1G的記憶體跑起來比較卡。

其它的步驟比較簡單,更多細節可以參考這裡,《VMware Ubuntu安裝詳細過程》

4.2.3、配置ubuntu系統

當ubuntu系統安裝成功後,在虛擬機器中可以啟動ubuntu系統,啟動後的系統如下:

ubuntu系統的使用還是有許多內容的,這裡需要設定的內容如下:

a)、設定上網

就是在ubuntu中可以訪問外網,可以使用多種形式

b)、設定語言

可以選擇使用中文版的ubuntu語言環境

c)、設定螢幕解析度

如果不設定預設的螢幕比較小

d)、設定以root超級管理員的身份登入

許多操作要求管理身份

e)、安裝VMware Tools工具

只有在VMware虛擬機器中安裝好了VMware Tools,才能實現主機與虛擬機器之間的檔案共享,同時可支援自由拖拽的功能,滑鼠也可在虛擬機器與主機之間自由移動(不用再按ctrl alt),且虛擬機器螢幕也可實現全屏化。
VMware Tools是VMware虛擬機器中自帶的一種增強工具,相當於VirtualBox中的增強功能(Sun VirtualBox Guest Additions),是VMware提供的增強虛擬顯示卡和硬碟效能、以及同步虛擬機器與主機時鐘的驅動程式。

 

注意如果這裡是灰色的需要您將linux.iso映象載入到虛擬光碟機中,一般在VM的安裝目錄下有,如果沒有您需要自行下載。

說明:ubuntu的使用不是本文的重點,相關操作請大家自行查詢。

4.3、生成ngrok伺服器與客戶端應用程式

4.3.1. 匯出原始碼

ngrok的原始碼託管在github上,可以先在ubuntu下安裝git再將ngrok的原始碼克隆到本地。

其實也可以直接下載到本地後解壓,這裡使用命令列完成。

啟動ubuntu,開打命令列(終端),如下所示:

以root身份執行如下命令:

mkdir ngrok #建立名稱為ngrok的目錄
apt-get update #更新包管理器
apt-get install git  #安裝git
git clone https://github.com/inconshreveable/ngrok.git ngrok2 #將ngrok原始碼克隆回本地

成功執行後如下所示:

匯出成功後的原始碼:

PS. 直接在伺服器上下載的話實在太慢,可以先在本地下載好,然後用ftp放到伺服器上去直接用,如果安裝了VMware tools直接拖進去就可以了。

4.3.2. 安裝Go語言開發環境

直接在命令模式下執行如下指令:

apt-get install golang #安裝go語言

執行結果如下:

4.3.3. 更改ngrok域名

在自己的域名管理中新增解析A記錄,如下所示:

將*.ngrok與ngrok都指向您的主機IP。

預設的域名是ngrok自己的,要替換成您自己的域名

export GOPATH=/usr/local/ngrok/  #設定環境變數,Go語言的安裝位置
export NGROK_DOMAIN="ngrok.yourdomain.com"  #設定環境變數,ngrok域名

PS. ngrok名稱可以任意,推薦名稱為ngrok或者tunnel 

4.3.4. 為域名生成證書

openssl genrsa -out rootCA.key 2048
openssl req -x509 -new -nodes -key rootCA.key -subj "/CN=$NGROK_DOMAIN" -days 5000 -out rootCA.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 rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 5000

生成後的結果如下:

證書如下:

4.3.5. 拷貝證書到指定位置

cp rootCA.pem assets/client/tls/ngrokroot.crt  #複製rootCA.pem到assets/client/tls/並更名為ngrokroot.crt
cp server.crt assets/server/tls/snakeoil.crt #複製server.crt到assets/server/tls/並更名為snakeoil.crt
cp server.key assets/server/tls/snakeoil.key #複製server.key到assets/server/tls/並更名為snakeoil.key

執行結果:

4.3.6. 編譯

 由於go語言的特性,在編譯時直接生成機器碼,所以在執行過程中並不需要go的環境(非託管應用)。在ngrok目錄下,執行一下命令分別生成對應的客戶端與服務端。

#win服務端
GOOS=windows GOARCH=386 make release-server 
#win客戶端
GOOS=windows GOARCH=386 make release-client
#linux服務端
GOOS=linux GOARCH=386 make release-server
#linux客戶端
GOOS=linux GOARCH=386 make release-client

生成完成後,在工作目錄的bin資料夾下,產生對應的檔案。以編譯windows平臺為例,會產生“ngrok.exe”與“ngrokd.exe”這兩個檔案,前者客戶端,後者需要執行在公網伺服器上。

因為專案中引用了一些外部資源,生成會耗費一些時間,對網路也有一定的要求,太慢會中短,命令執行下如:

生成結果:

這裡我還生成了兩個執行在windows伺服器與客戶端的應用:

ngrok.exe是客戶端,ngrokd.exe是服務端,下面是比較連續的操作結果。

 

五、部署伺服器端主程式

5.1、部署到Windows Server伺服器

 將生成的ngrokd.exe檔案複製到windows伺服器中,當然如果要部署到linux中也是沒有問題的。

這裡我將ngrokd.exe放在c:\grokeServer目錄下:

為了方便,我編寫了一個批處理檔案:ngrokserver2.bat

ngrokd.exe -tlsKey="snakeoil.key" -tlsCrt="snakeoil.crt" -domain="ngrok.你的域名.com" -httpAddr=":801" -httpsAddr=":802"

點選批處理執行結果如下:

繫結的域名換成自己的域名,http使用801埠,https使用802埠,供客戶端連線的管道埠設定為4443埠,必須前面的域名相同。

為了安全許多伺服器會將埠遮蔽,我使用的是ECS伺服器,預設801,802都是關閉的,需要手動開啟,在阿里雲的後臺新增開放的埠就可了:

5.2、一鍵部署ngrok伺服器(CentOS、Debian、Ubuntu)

如果編譯生成ngrok的原始碼生成應用太麻煩,你可以選擇網友寫的工具,支援一鍵部署到安裝平臺:CentOS、Debian、Ubuntu。

https://github.com/clangcn/ngrok-one-key-install

六、部署ngrok客戶端

這裡的客戶端就是您的web應用程式所執行的主機,將ubuntu生成的ngrok.exe客戶端應用複製到您的系統中:

新增配置檔案ngrok.cfg:

server_addr: "ngrok.你的域名.com:4443"
trust_host_root_certs: false

 新增批處理start.bat,如果只執行一次直接在命令列下輸入命令也是一樣的效果,內容如下:

ngrok.exe -subdomain kyt -config=ngrok.cfg 8987

其中8987為埠號,執行成功的結果如下所示: 

看到這個介面時說明已成功了。

七、啟動客戶端並測試

開啟瀏覽器,輸入您對映後的域名就可以穿透內網訪問您的web伺服器了。

八、總結

一開始選擇錯了平臺,在windows花了不少時間,在ubuntu下順利完成。

無論是客戶端還是伺服器端最好都做成服務,更方便與穩定。

由於伺服器上同時執行著IIS,故服務端Ngrok啟動時無法使用80埠,所以在上面,我使用了801作為Ngrok伺服器的http埠,使用IIS的代理功能可以解決這個問題,點選這裡。當然也可以使用nginx將80轉換成其它埠。

許多內容都參考了網友的文章。

如果伺服器搭建好了,只執行客戶端穿透內網一分鐘夠了:)。

歡迎您提供更加好的解決方案,歡迎您提供更多的免費代理伺服器,我隨時更新,謝謝!

作者:張果

原文:http://www.cnblogs.com/best/p/7465444.html