常用集中內網穿透&埠對映軟體工具

天府雲創發表於2018-12-14

大家都用什麼內網穿透?ngrok還是frp?自己搭建的還是國內免費的。

對於沒有公網 IP 的內網使用者來說,遠端管理或在外網訪問內網機器上的服務是一個問題。通常解決方案就是用內網穿透工具將內網的服務穿透到公網中,便於遠端管理和在外部訪問。內網穿透的工具很多,之前也介紹過 Ngrok、Localtunnel、N2N內網穿透(http://www.lu8.win/)。免費內網穿透有:ngrok、frp、n2n等

——直接向網路運營商索取公網固定ip

1、https://www.ngrok.cc/

  • 提供免費內網穿透服務,免費伺服器支援繫結自定義域名
  • 管理內網伺服器,內網web進行演示
  • 快速開發微信程式和第三方支付平臺除錯
  • 本地WEB外網訪問、本地開發微信、TCP埠轉發

2、https://natapp.cn/

全面支援HTTPS協議以及本地SSL證書,支援WSS協議.同時支援HTTP/2 WEB協議,支援微信小程式本地開發.

跨平臺,支援windows、linux和蘋果系統,更重要的是支援主流路由器系統和樹莓派。

3、http://www.senra.me/tag/%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F/

WireGuard是個新出的隧道程式,核心級的,所以資料處理能力以及資源消耗就會很理想,而且它可以工作於一方動態IP一方靜態IP的環境下,這就能夠很好的利用於內網穿透的環境下。當然,有幾個大佬拿它做搭隧道來實現自己的全球大內網(x, 看得我也很是羨慕。

具體的介紹我不提了,感興趣的去它的官網看看就知道了,針對以往的隧道程式做了不少方面的對比,可以看出來優勢還是挺大的。 ——> 傳送門

4、https://diannaobos.com/frp/

FRP 服務可以分配給你一個域名讓你本地的web專案提供給外網訪問, 特別適合向別人展示你本機的web demo 以及除錯一些遠端的API (比如微信公眾號,企業號的開發)

下載地址 https://github.com/fatedier/frp/releases

FRP內網穿透工具-免費Frp內網穿透伺服器,支援繫結頂級域名,開放80埠。 http://www.chuantou.org/

5、http://www.peergine.com/cn/product-connect.html

ZeroTier方案內網穿透原理

http://www.zerotier.com/

6、魔法隧道 | 內網穿透 | 花生殼 | nat123 | ngrok | frp | 網路穿透 | 穿透技術 | 穿透內網 http://mofasuidao.cn/

【論壇討論】

建議使用 frp 代替 ngrok - V2EX https://www.v2ex.com/t/334792  https://www.hi-linux.com/posts/25686.html

最近因為專案開發需要,在本地測試時需要將本地的應用對映到網際網路,完成一系列後續相關業務的開發。其實說白了就是小程式的開發,小程式開發其實是比較簡單的,但是對於新手入門卻是有一定的難度,首先你需要解決一系列的網路配置與網路對映的問題,如果這些問題解決不了的話,那麼你開發的軟體就很難與後端互動,也就沒有什麼商業價值了。這兩天空閒之餘順便整理了下近幾年來用的一下內網穿透工具,給新手一些幫助。

小程式開發與公眾號開發其實在本質上沒有多大的區別,但是有一個很重要的區別就是小程式資料傳輸有的是https協議,相比http協議有了更多的安全保障。但是在配置伺服器資訊時,域名是需要有嚴格的要求的,必須在工信部備案過的域名,否則無法使用。所以你有域名僅僅是不夠的,期間我也試了很多方法,比如tomcat在本地走https,然後通過其他域名對映轉發,結果都還是不行,所以還是乖乖地備案吧。如果想要在本地開發除錯的話,當然還需要進行內網的對映。對於內網穿透工具最常用的無非就是一下集中,如果有更好使用的歡迎告訴我。

ngrok穿透

這是一款非常優秀的免費軟體,雖然小巧但是功能很多,基本上能夠滿足日常的開發,使用起來也是非常的簡單,只需要一個簡簡單單的命令就可以了。能夠實時檢測到外網請求到的一些資料。同時還能夠提供一些簡單的域名免費讓開發者使用,所以這款軟體是我比較推薦的。

花生殼穿透

這款軟體我就不做過多的評價了,客戶端時常會斷線,很是讓人無語。但是他的流量通道還是比較不錯的,對映出去的內網響應與請求都是比較快的,限速的不是很厲害。對於沒有備案域名可以使用一個殼域名,這個殼域名是經過備案了的。但是通過花生殼進行相關的內網對映,但是不能走https協議。測試了本地tomcat配置了https通道,通過本地走https正常,把埠對映出去發現無法訪問,也就是說通過花生殼無法走https協議。這一點開發人員一定要注意!

nat123穿透

這一款工具的優勢是它能夠走https通道,其他的確定真的是呵呵了,網路訪問速度超級慢,不是vip使用者明顯的被限速了。個人還是比較不喜歡的,但是目前為了走https通道,也似乎只能用它了。但是需要記住,它提供的一些臨時域名都是未備案的。

當然,還有其他的一些方式可以免費的只用已經備案的域名,並且走https協議,在這裡就不一一舉例了,感興趣的小夥伴們還在等什麼,趕緊去嘗試這幾款工具吧。網路幽靈之內網穿透。網路通。

今天給大家介紹另一款好用內網穿透工具 FRPFRP 全名:Fast Reverse Proxy。FRP 是一個使用 Go 語言開發的高效能的反向代理應用,可以幫助您輕鬆地進行內網穿透,對外網提供服務。FRP 支援 TCPUDPHTTPHTTPS等協議型別,並且支援 Web 服務根據域名進行路由轉發。

FRP 專案地址:https://github.com/fatedier/frp

FRP 的作用

  • 利用處於內網或防火牆後的機器,對外網環境提供 HTTP 或 HTTPS 服務。
  • 對於 HTTPHTTPS 服務支援基於域名的虛擬主機,支援自定義域名繫結,使多個域名可以共用一個 80 埠。
  • 利用處於內網或防火牆後的機器,對外網環境提供 TCP 和 UDP 服務,例如在家裡通過 SSH訪問處於公司內網環境內的主機。

FRP 架構

FRP 安裝

FRP 採用 Go 語言開發,支援 WindowsLinuxMacOSARM等多平臺部署。FRP 安裝非常容易,只需下載對應系統平臺的軟體包,並解壓就可用了。

這裡以 Linux 為例,為了方便管理我們把解壓後的目錄重新命名為 frp :

1
2
3
$ wget https://github.com/fatedier/frp/releases/download/v0.15.1/frp_0.15.1_linux_amd64.tar.gz
$ tar xzvf frp_0.15.1_linux_amd64.tar.gz
$ mv frp_0.15.1_linux_amd64 frp

更多平臺的軟體包下載地址:https://github.com/fatedier/frp/releases

FRP 配置

FRP 服務端配置

配置 FRP 服務端的前提條件是需要一臺具有公網 IP 的裝置,得益於 FRP 是 Go 語言開發的,具有良好的跨平臺特性。你可以在 WindowsLinuxMacOSARM等幾乎任何可聯網裝置上部署。

這裡以 Linux 為例,FRP 預設給出兩個服務端配置檔案,一個是簡版的 frps.ini,另一個是完整版本 frps_full.ini。

我們先來看看簡版的 frps.ini,通過這個配置可以快速的搭建起一個 FRP 服務端。

1
2
3
4
$ cat frps.ini

[common]
bind_port = 7000
  • 預設配置中監聽的是 7000 埠,可根據自己實際情況修改。

啟動 FRP 服務端

1
2
3
4
$ ./frps -c ./frps.ini
2018/01/25 10:52:45 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
2018/01/25 10:52:45 [I] [main.go:112] Start frps success
2018/01/25 10:52:45 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

通過上面簡單的兩步就可以成功啟動一個監聽在 7000 埠的 FRP 服務端。

FRP 客戶端配置

和 FRP 服務端類似,FRP 預設也給出兩個客戶端配置檔案,一個是簡版的 frpc.ini,另一個是完整版本 frpc_full.ini。

這裡同樣以簡版的 frpc.ini 檔案為例,假設 FRP 服務端所在伺服器的公網 IP 為 4.3.2.1。

1
2
3
4
5
6
7
$ vim frpc.ini

[common]
# server_addr 為 FRP 服務端的公網 IP 
server_addr = 4.3.2.1
# server_port 為 FRP 服務端監聽的埠 
server_port = 7000

啟動 FRP 客戶端

1
2
3
4
5
6
$ ./frpc -c ./frpc.ini
2018/01/25 11:15:49 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 11:15:49 [I] [proxy_manager.go:294] proxy added: []
2018/01/25 11:15:49 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 11:15:49 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 11:15:49 [I] [control.go:240] [83775d7388b8e7d9] login to server success, get run id [83775d7388b8e7d9], server udp port [0]

這樣就可以成功在 FRP 服務端上成功建立一個客戶端連線,當然現在還並不能對外提供任何內網機器上的服務,因為我們並還沒有在 FRP 服務端註冊任何內網服務的埠。

FRP 使用例項

下面我們就來看幾個常用的例子,通過這些例子來了解下 FRP 是如何實現內網服務穿透的。

通過 TCP 訪問內網機器

這裡以訪問 SSH 服務為例, 修改 FRP 客戶端配置檔案 frpc.ini 檔案並增加如下內容:

1
2
3
4
5
6
7
$ cat frpc.ini

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

啟動 FRP 客戶端

1
2
3
4
5
6
7
$ ./frpc -c ./frpc.ini
2018/01/25 12:21:23 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 12:21:23 [I] [proxy_manager.go:294] proxy added: [ssh]
2018/01/25 12:21:23 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 12:21:23 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 12:21:23 [I] [control.go:240] [3b468a55191341cb] login to server success, get run id [3b468a55191341cb], server udp port [0]
2018/01/25 12:21:23 [I] [control.go:165] [3b468a55191341cb] [ssh] start proxy success

這樣就在 FRP 服務端上成功註冊了一個埠為 6000 的服務,接下來我們就可以通過這個埠訪問內網機器上 SSH 服務,假設使用者名稱為 mike:

1
$ ssh -oPort=6000 mike@4.3.2.1

通過自定義域名訪問部署於內網的 Web 服務

有時需要在公有網路通過域名訪問我們在本地環境搭建的 Web 服務,但是由於本地環境機器並沒有公網 IP,無法將域名直接解析到本地的機器。

現在通過 FRP 就可以很容易實現這一功能,這裡以 HTTP 服務為例:首先修改 FRP 服務端配置檔案,通過 vhost_http_port 引數來設定 HTTP 訪問埠,這裡將 HTTP 訪問埠設為 8080。

1
2
3
4
$ vim frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080

啟動 FRP 服務端

1
2
3
4
5
$ ./frps -c ./frps.ini
2018/01/25 13:33:26 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
2018/01/25 13:33:26 [I] [service.go:125] http service listen on 0.0.0.0:8080
2018/01/25 13:33:26 [I] [main.go:112] Start frps success
2018/01/25 13:33:26 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

其次我們在修改 FRP 客戶端配置檔案並增加如下內容:

1
2
3
4
5
6
$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = mike.hi-linux.com

這裡通過 local_port 和 custom_domains 引數來設定本地機器上 Web 服務對應的埠和自定義的域名,這裡我們分別設定埠為 80,對應域名為 mike.hi-linux.com

啟動 FRP 客戶端

1
2
3
4
5
6
7
8
$ ./frpc -c ./frpc.ini
2018/01/25 13:56:11 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 13:56:11 [I] [proxy_manager.go:294] proxy added: [web ssh]
2018/01/25 13:56:11 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 13:56:11 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 13:56:11 [I] [control.go:240] [296fe9e31a551e07] login to server success, get run id [296fe9e31a551e07], server udp port [0]
2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [web] start proxy success
2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [ssh] start proxy success

最後將 mike.hi-linux.com 的域名 A 記錄解析到 FRP 伺服器的公網 IP 上,現在便可以通過 http://mike.hi-linux.com:8080 這個 URL 訪問到處於內網機器上對應的 Web 服務。

  • HTTPS 服務配置方法類似,只需將 vhost_http_port 替換為 vhost_https_port, type 設定為 https 即可。

通過密碼保護你的 Web 服務

由於所有客戶端共用一個 FRP 服務端的 HTTP 服務埠,任何知道你的域名和 URL 的人都能訪問到你部署在內網的 Web 服務,但是在某些場景下需要確保只有限定的使用者才能訪問。

FRP 支援通過 HTTP Basic Auth 來保護你的 Web 服務,使使用者需要通過使用者名稱和密碼才能訪問到你的服務。需要實現此功能主要需要在 FRP 客戶端的配置檔案中新增使用者名稱和密碼的設定。

1
2
3
4
5
6
7
8
9
10
$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = mike.hi-linux.com
# 設定認證的使用者名稱
http_user = abc
# 設定認證的密碼
http_pwd = abc

這時訪問 http://mike.hi-linux.com:8080 這個 URL 時就需要輸入配置的使用者名稱和密碼才能訪問。

  • 該功能目前僅限於 HTTP 型別的代理。

給 Web 服務增加自定義二級域名

在多人同時使用一個 FRP 服務端實現 Web 服務時,通過自定義二級域名的方式來使用會更加方便。

通過在 FRP 服務端的配置檔案中配置 subdomain_host引數就可以啟用該特性。之後在 FRP 客戶端的 http、https 型別的代理中可以不配置 custom_domains,而是配置一個 subdomain 引數。

然後只需要將 *.{subdomain_host} 解析到 FRP 服務端所在伺服器。之後使用者可以通過 subdomain 自行指定自己的 Web 服務所需要使用的二級域名,並通過 {subdomain}.{subdomain_host} 來訪問自己的 Web 服務。

首先我們在 FRP 服務端配置 subdomain_host 引數:

1
2
3
$ vim frps.ini
[common]
subdomain_host = hi-linux.com

其次在 FRP 客戶端配置檔案配置 subdomain 引數:

1
2
3
4
5
$ vim frpc.ini
[web]
type = http
local_port = 80
subdomain = test

然後將泛域名 *.hi-linux.com 解析到 FRP 服務端所在伺服器的公網 IP 地址。FRP 服務端 和 FRP 客戶端都啟動成功後,通過 test.hi-linux.com 就可以訪問到內網的 Web 服務。

  • 同一個 HTTP 或 HTTPS 型別的代理中 custom_domains 和 subdomain 可以同時配置。
  • 需要注意的是如果 FPR 服務端配置了 subdomain_host,則 custom_domains 中不能是屬於 subdomain_host 的子域名或者泛域名。

修改 Host Header

通常情況下 FRP 不會修改轉發的任何資料。但有一些後端服務會根據 HTTP 請求 header 中的 host 欄位來展現不同的網站,例如 Nginx 的虛擬主機服務,啟用 host-header 的修改功能可以動態修改 HTTP 請求中的 host 欄位。

實現此功能只需要在 FRP 客戶端配置檔案中定義 host_header_rewrite 引數。

1
2
3
4
5
6
$ vim frpc.ini
[web]
type = http
local_port = 80
custom_domains = test.hi-linux.com
host_header_rewrite = dev.hi-linux.com

原來 HTTP 請求中的 host 欄位 test.hi-linux.com 轉發到後端服務時會被替換為 dev.hi-linux.com

  • 該功能僅限於 HTTP 型別的代理。

URL 路由

FRP 支援根據請求的 URL 路徑路由轉發到不同的後端服務。要實現這個功能可通過 FRP 客戶端配置檔案中的 locations 欄位來指定。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ vim frpc.ini

[web01]
type = http
local_port = 80
custom_domains = web.hi-linux.com
locations = /

[web02]
type = http
local_port = 81
custom_domains = web.hi-linux.com
locations = /news,/about

按照上述的示例配置後,web.hi-linux.com 這個域名下所有以 /news 以及 /about 作為字首的 URL請求都會被轉發到後端 web02 所在的後端服務,其餘的請求會被轉發到 web01 所在的後端服務。

  • 目前僅支援最大字首匹配,之後會考慮支援正則匹配。

通過 UDP 訪問內網機器

DNS 查詢請求通常使用 UDP 協議,FRP 支援對內網 UDP 服務的穿透,配置方式和 TCP 基本一致。這裡以轉發到 Google 的 DNS 查詢伺服器 8.8.8.8 的 UDP 埠為例。

首先修改 FRP 客戶端配置檔案,並增加如下內容:

1
2
3
4
5
6
$ vim frpc.ini
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6001
  • 要轉發到內網 DNS 伺服器只需把 local_ip 改成對應 IP 即可。

其次重新啟動 FRP 客戶端:

1
2
3
4
5
6
7
8
9
$ ./frpc -c ./frpc.ini
2018/01/25 14:54:17 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 14:54:17 [I] [proxy_manager.go:294] proxy added: [ssh web dns]
2018/01/25 14:54:17 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 14:54:17 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 14:54:17 [I] [control.go:240] [33e1de8a771112a6] login to server success, get run id [33e1de8a771112a6], server udp port [0]
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [ssh] start proxy success
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [web] start proxy success
2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [dns] start proxy success

最後通過 dig 命令測試 UDP 包轉發是否成功,預期會返回 www.google.com 域名的解析結果:

1
2
3
4
5
6
7
8
9
10
$ dig @4.3.2.1 -p 6001 www.google.com
...

;; QUESTION SECTION:
;www.google.com.			IN	A

;; ANSWER SECTION:
www.google.com.		79	IN	A	69.63.184.30

...

轉發 Unix 域套接字

通過 TCP 埠訪問內網的 Unix 域套接字,這裡以和本地機器上的 Docker Daemon 通訊為例。

首先修改 FRP 客戶端配置檔案,並增加如下內容:

1
2
3
4
5
6
$ vim frpc.ini
[unix_domain_socket]
type = tcp
remote_port = 6002
plugin = unix_domain_socket
plugin_unix_path = /var/run/docker.sock

這裡主要是使用 plugin 和 plugin_unix_path 兩個引數啟用了 unix_domain_socket 外掛和配置對應的套接字路徑。

其次重新啟動 FRP 客戶端:

1
2
3
4
5
6
7
8
9
10
11
$ ./frpc -c ./frpc.ini

2018/01/25 15:09:33 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 15:09:33 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
2018/01/25 15:09:33 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 15:09:33 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 15:09:33 [I] [control.go:240] [f6424f0deb8b6ff7] login to server success, get run id [f6424f0deb8b6ff7], server udp port [0]
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [ssh] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [web] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [dns] start proxy success
2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [unix_domain_socket] start proxy success

最後通過 curl 命令檢視 Docker 版本資訊進行測試:

1
2
3
$ curl http://4.3.2.1:6002/version

{"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"17.12.0-ce","Details":{"ApiVersion":"1.35","Arch":"amd64","BuildTime":"2017-12-27T20:12:29.000000000+00:00","Experimental":"true","GitCommit":"c97c6d6","GoVersion":"go1.9.2","KernelVersion":"4.9.60-linuxkit-aufs","MinAPIVersion":"1.12","Os":"linux"}}],"Version":"17.12.0-ce","ApiVersion":"1.35","MinAPIVersion":"1.12","GitCommit":"c97c6d6","GoVersion":"go1.9.2","Os":"linux","Arch":"amd64","KernelVersion":"4.9.60-linuxkit-aufs","Experimental":true,"BuildTime":"2017-12-27T20:12:29.000000000+00:00"}
  • FRP 從 1.5 版本開始支援客戶端熱載入配置檔案,並不用每次都重啟客戶端程式。具體方法在後文 FRP 客戶端熱載入配置檔案部分講解。

FRP 高階進階

給 FRP 服務端增加一個 Dashboard

通過 Dashboard 可以方便的檢視 FRP 的狀態以及代理統計資訊展示,要使用這個功能首先需要在 FRP 服務端配置檔案中指定 Dashboard 服務使用的埠:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ vim frps.ini

[common]

# 指定 Dashboard 的監聽的 IP 地址
dashboard_addr = 0.0.0.0

# 指定 Dashboard 的監聽的埠
dashboard_port = 7500

# 指定訪問 Dashboard 的使用者名稱
dashboard_user = admin

# 指定訪問 Dashboard 的埠
dashboard_pwd = admin

其次重新啟動 FRP 服務端:

1
2
3
4
5
6
7
$ ./frps -c ./frps.ini

2018/01/25 16:39:29 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
2018/01/25 16:39:29 [I] [service.go:125] http service listen on 0.0.0.0:8080
2018/01/25 16:39:29 [I] [service.go:164] Dashboard listen on 0.0.0.0:7500
2018/01/25 16:39:29 [I] [main.go:112] Start frps success
2018/01/25 16:39:29 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

最後通過 http://[server_addr]:7500 訪問 Dashboard 介面,使用者名稱密碼預設都為 admin。

給 FRP 服務端加上身份驗證

預設情況下只要知道 FRP 服務端開放的埠,任意 FRP 客戶端都可以隨意在服務端上註冊埠對映,這樣對於在公網上的 FRP 服務來說顯然不太安全。FRP 提供了身份驗證機制來提高 FRP 服務端的安全性。要啟用這一特性也很簡單,只需在 FRP 服務端和 FRP 客戶端的 common 配置中啟用 privilege_token 引數就行。

1
2
[common]
privilege_token = 12345678

啟用這一特性後,只有 FRP 服務端和 FRP 客戶端的 common 配置中的 privilege_token 引數一致身份驗證才會通過,FRP 客戶端才能成功在 FRP 服務端註冊埠對映。否則就會註冊失敗,出現類似下面的錯誤:

1
2
3
4
5
6
7
2018/01/25 17:29:27 [I] [proxy_manager.go:284] proxy removed: []
2018/01/25 17:29:27 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
2018/01/25 17:29:27 [I] [proxy_manager.go:317] visitor removed: []
2018/01/25 17:29:27 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 17:29:27 [E] [control.go:230] authorization failed
2018/01/25 17:29:27 [W] [control.go:109] login to server failed: authorization failed
authorization failed

需要注意的是 FRP 客戶端所在機器和 FRP 服務端所在機器的時間相差不能超過 15 分鐘,因為時間戳會被用於加密驗證中,防止報文被劫持後被其他人利用。這個超時時間可以在配置檔案中通過 authentication_timeout 這個引數來修改,單位為秒,預設值為 900,即 15 分鐘。如果修改為 0,則 FRP 服務端將不對身份驗證報文的時間戳進行超時校驗。

FRP 客戶端熱載入配置檔案

當修改了 FRP 客戶端中的配置檔案,從 0.15 版本開始可以通過 frpc reload 命令來動態載入配置檔案,通常會在 10 秒內完成代理的更新。

啟用此功能需要在 FRP 客戶端配置檔案中啟用 admin 埠,用於提供 API 服務。配置如下:

1
2
3
4
5
$ vim frpc.ini

[common]
admin_addr = 127.0.0.1
admin_port = 7400

重啟 FRP 客戶端,以後就可通過熱載入方式進行 FRP 客戶端配置變更了。

1
2
3
4
5
6
7
8
9
10
11
$ ./frpc -c ./frpc.ini
2018/01/25 18:04:25 [I] [proxy_manager.go:326] visitor added: []
2018/01/25 18:04:25 [I] [control.go:240] [3653b9a878f8acc7] login to server success, get run id [3653b9a878f8acc7], server udp port [0]
2018/01/25 18:04:25 [I] [service.go:49] admin server listen on 127.0.0.1:7400
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [ssh] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [web] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [dns] start proxy success
2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [unix_domain_socket] start proxy success

$ ./frpc reload -c ./frpc.ini
reload success

等待一段時間後客戶端會根據新的配置檔案建立、更新、刪除代理。

  • 需要注意的是 [common] 中的引數除了 start 外目前無法被修改。

啟用 admin_addr 後,還可以通過 frpc status -c ./frpc.ini 命令在 FRP 客戶端很方便的檢視當前代理狀態資訊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./frpc status -c ./frpc.ini

Proxy Status...
TCP
Name                Status   LocalAddr     Plugin              RemoteAddr           Error
ssh                 running  127.0.0.1:22                      4.3.2.1:6000
unix_domain_socket  running                unix_domain_socket  4.3.2.1:6002

UDP
Name  Status   LocalAddr   Plugin  RemoteAddr           Error
dns   running  8.8.8.8:53          4.3.2.1:6001

HTTP
Name  Status   LocalAddr     Plugin  RemoteAddr              Error
web   running  127.0.0.1:80          mike.hi-linux.com:8080

給 FRP 服務端增加埠白名單

為了防止 FRP 埠被濫用,FRP 提供了指定允許哪些埠被分配的功能。可通過 FRP 服務端的配置檔案中 privilege_allow_ports 引數來指定:

1
2
3
4
$ vim frps.ini

[common]
privilege_allow_ports = 2000-3000,3001,3003,4000-5000

privilege_allow_ports 可以配置允許使用的某個指定埠或者是一個範圍內的所有埠,以 , 分隔,指定的範圍以 - 分隔。

當使用不允許的埠註冊時,就會註冊失敗。出現類似以下錯誤:

1
2
3
4
5
6
$ ./frpc status -c ./frpc.ini
Proxy Status...
TCP
Name                Status       LocalAddr     Plugin              RemoteAddr            Error
ssh                 start error  127.0.0.1:22                      4.3.2.1:60000  port not allowed
unix_domain_socket  start error                unix_domain_socket  4.3.2.1:60002  port not allowed

啟用 TCP 多路複用

從 v0.10.0 版本開始,客戶端和伺服器端之間的連線支援多路複用,不再需要為每一個使用者請求建立一個連線,使連線建立的延遲降低,並且避免了大量檔案描述符的佔用,使 FRP 可以承載更高的併發數。

該功能預設啟用,如需關閉可以在 FRP 服務端配置檔案和 FRP 客戶端配置檔案中配置,該配置項在服務端和客戶端必須一致:

1
2
3
# frps.ini 和 frpc.ini 中
[common]
tcp_mux = false

FRP 底層通訊啟用 KCP 協議

FRP 從 v0.12.0 版本開始,底層通訊協議支援選擇 KCP 協議,在弱網路環境下傳輸效率會提升明顯,但是會有一些額外的流量消耗。

要開啟 KCP 協議支援,首先要在 FRP 服務端配置檔案中啟用 KCP 協議支援:

1
2
3
4
5
$ vim frps.ini
[common]
bind_port = 7000
# 指定一個 UDP 埠用於接收客戶端請求 KCP 繫結的是 UDP 埠,可以和 bind_port 一樣
kcp_bind_port = 7000

其次是在 FRP 客戶端配置檔案指定需要使用的協議型別,目前只支援 TCP 和 KCP。其它代理配置不需要變更:

1
2
3
4
5
6
7
$ vim  frpc.ini
[common]
server_addr = 4.3.2.1
# server_port 指定為 FRP 服務端裡 kcp_bind_port 指定的埠
server_port = 7000
# 指定需要使用的協議型別,預設型別為 TCP
protocol = kcp
  • 需要注意開放相關機器上的 UDP 埠的訪問許可權。

給 FRP 服務端配置連線池

預設情況下,當使用者請求建立連線後,FRP 服務端才會請求 FRP 客戶端主動與後端服務建立一個連線。

當為指定的 FRP 服務端啟用連線池功能後,FRP 會預先和後端服務建立起指定數量的連線,每次接收到使用者請求後,會從連線池中取出一個連線和使用者連線關聯起來,避免了等待與後端服務建立連線以及 FRP 客戶端 和 FRP 服務端之間傳遞控制資訊的時間。

首先需要在 FRP 服務端配置檔案中設定每個代理可以建立的連線池上限,避免大量資源佔用,客戶端設定超過此配置後會被調整到當前值:

1
2
3
$ vim frps.ini
[common]
max_pool_count = 5

其次在 FRP 客戶端配置檔案中為客戶端啟用連線池,指定預建立連線的數量:

1
2
3
$ vim frpc.ini
[common]
pool_count = 1
  • 此功能比較適合有大量短連線請求時開啟。

加密與壓縮

如果公司內網防火牆對外網訪問進行了流量識別與遮蔽,例如禁止了 SSH 協議等,可通過設定 use_encryption = true,將 FRP 客戶端 與 FRP 服務端之間的通訊內容加密傳輸,將會有效防止流量被攔截。

如果傳輸的報文長度較長,通過設定 use_compression = true 對傳輸內容進行壓縮,可以有效減小 FRP 客戶端 與 FRP 服務端之間的網路流量,來加快流量轉發速度,但是會額外消耗一些 CPU 資源。

這兩個功能預設是不開啟的,需要在 FRP 客戶端配置檔案中通過配置來為指定的代理啟用加密與壓縮的功能,壓縮演算法使用的是 snappy。

1
2
3
4
5
6
7
8
$ vim frpc.ini

[ssh]
type = tcp
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true

通過 FRP 客戶端代理其它內網機器訪問外網

FRP 客戶端內建了 http_proxy 和 socks5 外掛,通過這兩個外掛可以使其它內網機器通過 FPR 客戶端的的網路訪問網際網路。

要啟用此功能,首先需要在 FRP 客戶端配置檔案中啟用相關外掛,這裡以 http_proxy 外掛為例:

1
2
3
4
5
6
7
8
9
10
$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000

[http_proxy]
type = tcp
remote_port = 6000
plugin = http_proxy

其次將需要通過這個代理訪問外網的內部機器的代理地址設定為 4.3.2.1:6000,這樣就可以通過 FRP 客戶端機器的網路訪問網際網路了。

  • http_proxy 外掛也支援認證機制,如果需要啟用認證可通過配置引數 plugin_http_user 和 plugin_http_passwd 啟用。
  • 如需啟用 Socks5 代理,只需將 plugin 的值更換為 socks5 即可。

通過代理連線 FRP 服務端

在只能通過代理訪問外網的環境內,FRP 客戶端支援通過 HTTP_PROXY 引數來配置代理和 FRP 服務端進行通訊。要使用此功能可以通過設定系統環境變數 HTTP_PROXY 或者通過在 FRP 客戶端的配置檔案中設定 http_proxy 引數來使用此功能。

1
2
3
4
5
6
7
$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000
protocol = tcp
http_proxy = http://user:pwd@4.3.2.2:8080
  • 僅在 protocol = tcp 時生效,暫時不支援 kcp 協議。

安全地暴露內網服務

對於一些比較敏感的服務如果直接暴露於公網上將會存在安全隱患,FRP 也提供了一種安全的轉發方式 STCP。使用 STCP (secret tcp) 型別的代理可以避免讓任何人都能訪問到穿透到公網的內網服務,要使用 STCP 模式訪問者需要單獨執行另外一個 FRP 客戶端。

下面就以建立一個只有自己能訪問到的 SSH 服務代理為例,FRP 服務端和其它的部署步驟相同,主要區別是在 FRP 客戶端上。

首先配置 FRP 客戶端,和常規 TCP 轉發不同的是這裡不需要指定遠端埠。

1
2
3
4
5
6
7
8
9
10
11
$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000

[secret_ssh]
type = stcp
# 只有 sk 一致的使用者才能訪問到此服務
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

其次在要訪問這個服務的機器上啟動另外一個 FRP 客戶端,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000

[secret_ssh_visitor]
type = stcp
# STCP 的訪問者
role = visitor
# 要訪問的 STCP 代理的名字,和前面定義的相同。
server_name = secret_ssh
# 和前面定義的要一致
sk = abcdefg
# 繫結本地埠用於訪問 ssh 服務
bind_addr = 127.0.0.1
bind_port = 6005

最後在本機啟動一個 FRP 客戶端,這樣就可以通過本機 6005 埠對內網機器 SSH 服務進行訪問,假設使用者名稱為 mike:

1
2
3
4
5
6
7
8
9
10
$ ./frpc -c ./frpc.ini
2018/01/26 15:03:24 [I] [proxy_manager.go:284] proxy removed: []
2018/01/26 15:03:24 [I] [proxy_manager.go:294] proxy added: []
2018/01/26 15:03:24 [I] [proxy_manager.go:317] visitor removed: []
2018/01/26 15:03:24 [I] [proxy_manager.go:326] visitor added: [secret_ssh_visitor]
2018/01/26 15:03:24 [I] [control.go:240] [60d2af2f68196537] login to server success, get run id [60d2af2f68196537], server udp port [0]
2018/01/26 15:03:24 [I] [proxy_manager.go:235] [60d2af2f68196537] try to start visitor [secret_ssh_visitor]
2018/01/26 15:03:24 [I] [proxy_manager.go:243] [secret_ssh_visitor] start visitor success

$ ssh -oPort=6005 mike@127.0.0.1

點對點內網穿透

在傳輸大量資料時如果都經過伺服器中轉的話,這樣會對伺服器端頻寬壓力比較大。FRP 提供了一種新的代理型別 XTCP 來解決這個問題,XTCP 模式下可以在傳輸大量資料時讓流量不經過伺服器中轉。

使用方式同 STCP 類似,需要在傳輸資料的兩端都部署上 FRP 客戶端上用於建立直接的連線。

首先在 FRP 服務端配置上增加一個 UDP 埠用於支援該型別的客戶端:

1
2
$ vim frps.ini
bind_udp_port = 7001

其次配置 FRP 客戶端,和常規 TCP 轉發不同的是這裡不需要指定遠端埠。

1
2
3
4
5
6
7
8
9
10
11
12
$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000

[p2p_ssh]
type = xtcp
# 只有 sk 一致的使用者才能訪問到此服務
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

然後在要訪問這個服務的機器上啟動另外一個 FRP 客戶端,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000

[p2p_ssh_visitor]
type = xtcp
# XTCP 的訪問者
role = visitor
# 要訪問的 XTCP 代理的名字
server_name = p2p_ssh
sk = abcdefg
# 繫結本地埠用於訪問 ssh 服務
bind_addr = 127.0.0.1
bind_port = 6006

最後在本機啟動一個 FRP 客戶端,這樣就可以通過本機 6006 埠對內網機器 SSH 服務進行訪問,假設使用者名稱為 mike:

1
2
3
4
5
6
7
8
9
10
$ ./frpc -c ./frpc.ini

2018/01/26 16:01:52 [I] [proxy_manager.go:326] visitor added: [p2p_ssh_visitor secret_ssh_visitor]
2018/01/26 16:01:52 [I] [control.go:240] [7c7e06878e11cc3c] login to server success, get run id [7c7e06878e11cc3c], server udp port [7001]
2018/01/26 16:01:52 [I] [proxy_manager.go:235] [7c7e06878e11cc3c] try to start visitor [p2p_ssh_visitor]
2018/01/26 16:01:52 [I] [proxy_manager.go:243] [p2p_ssh_visitor] start visitor success
2018/01/26 16:01:52 [I] [proxy_manager.go:235] [7c7e06878e11cc3c] try to start visitor [secret_ssh_visitor]
2018/01/26 16:01:52 [I] [proxy_manager.go:243] [secret_ssh_visitor] start visitor success

$ ssh -oPort=6006 mike@127.0.0.1
  • 目前 XTCP 模式還處於開發的初級階段,並不能穿透所有型別的 NAT 裝置,所以穿透成功率較低。穿透失敗時可以嘗試 STCP 的方式。

FRP 管理

FRP 的部署安裝比較簡單,專案官方也沒有提供相應的管理指令碼。不過好在開源專案總是有網友熱心提供部署和管理指令碼。如果你覺得手動部署太麻煩,還可以使用下面的一鍵安裝指令碼。

專案地址:https://github.com/clangcn/onekey-install-shell/

下載一鍵部署指令碼

1
2
$ wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-install-shell/master/frps/install-frps.sh -O ./install-frps.sh
$ chmod 700 ./install-frps.sh

安裝 FRP 服務端

這個一鍵部署指令碼比較好用,為了提高國內使用者下載安裝包速度還提供了阿里雲節點的安裝源。整個指令碼使用起來也比較簡單,對一些常用的 FRP 服務端配置引數都做了互動式選擇讓使用者可以方便的根據自己實際情況進行選擇。指令碼比較貼心的一點是對預設的公網地址進行了檢測,省去了手動輸入的麻煩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
$ ./install-frps.sh install

Please select frps download url:
[1].aliyun (default)
[2].github
Enter your choice (1, 2 or exit. default [aliyun]):
---------------------------------------
Your select: aliyun
---------------------------------------
Loading network version for frps, please wait...
frps Latest release file frp_0.15.1_linux_amd64.tar.gz
Loading You Server IP, please wait...
You Server IP:12.34.56.78
Please input your server setting:

Please input frps bind_port [1-65535](Default Server Port: 5443):7000
frps bind_port: 7000

Please input frps vhost_http_port [1-65535](Default vhost_http_port: 80):8080
frps vhost_http_port: 8080

Please input frps vhost_https_port [1-65535](Default vhost_https_port: 443):
frps vhost_https_port: 443

Please input frps dashboard_port [1-65535](Default dashboard_port: 6443):7500
frps dashboard_port: 7500

Please input dashboard_user (Default: admin):
frps dashboard_user: admin

Please input dashboard_pwd (Default: IY0p1bOg):admin
frps dashboard_pwd: admin

Please input privilege_token (Default: 9BqswPpd1R0TfGR5):mike
frps privilege_token: mike

Please input frps max_pool_count [1-200]
(Default max_pool_count: 50):
frps max_pool_count: 50

##### Please select log_level #####
1: info (default)
2: warn
3: error
4: debug
#####################################################
Enter your choice (1, 2, 3, 4 or exit. default [1]):
log_level: info

Please input frps log_max_days [1-30]
(Default log_max_days: 3 day):
frps log_max_days: 3

##### Please select log_file #####
1: enable (default)
2: disable
#####################################################
Enter your choice (1, 2 or exit. default [1]):
log_file: enable

##### Please select tcp_mux #####
1: enable (default)
2: disable
#####################################################
Enter your choice (1, 2 or exit. default [1]):
tcp_mux: true

##### Please select kcp support #####
1: enable (default)
2: disable
#####################################################
Enter your choice (1, 2 or exit. default [1]):
kcp support: true

============== Check your input ==============
You Server IP      : 12.34.56.78
Bind port          : 7000
kcp support        : true
vhost http port    : 8080
vhost https port   : 443
Dashboard port     : 7500
Dashboard user     : admin
Dashboard password : admin
Privilege token    : mike
tcp_mux            : true
Max Pool count     : 50
Log level          : info
Log max days       : 3
Log file           : enable
==============================================

Press any key to start...or Press Ctrl+c to cancel

frps install path:/usr/local/frps
config file for frps ... done
download frps ... done
download /etc/init.d/frps... done
setting frps boot... done

+--------------------------------------------------+
|        Manager for Frps, Written by Clang        |
+--------------------------------------------------+
| Intro: http://koolshare.cn/thread-65379-1-1.html |
+--------------------------------------------------+

Starting Frps(0.15.1)... done
Frps (pid 3325)is running.

+---------------------------------------------------------+
|        frps for Linux Server, Written by Clang          |
+---------------------------------------------------------+
|     A tool to auto-compile & install frps on Linux      |
+---------------------------------------------------------+
|    Intro: http://koolshare.cn/thread-65379-1-1.html     |
+---------------------------------------------------------+


Congratulations, frps install completed!
==============================================
You Server IP      : 12.34.56.78
Bind port          : 7000
KCP support        : true
vhost http port    : 8080
vhost https port   : 443
Dashboard port     : 7500
Privilege token    : mike
tcp_mux            : true
Max Pool count     : 50
Log level          : info
Log max days       : 3
Log file           : enable
==============================================
frps Dashboard     : http://12.34.56.78:7500/
Dashboard user     : admin
Dashboard password : admin
==============================================

配置 FRP 服務端

1
$ ./install-frps.sh config

更新 FRP 服務端

1
$ ./install-frps.sh update

解除安裝 FRP 服務端

1
$ ./install-frps.sh uninstall

FRP 服務端日常管理

FRP 服務端安裝完成後,一鍵部署指令碼還提供了一個日常管理 FRP 服務端的管理指令碼來進行日常的啟動、重啟、停止等操作,非常的方便。

1
Usage: /etc/init.d/frps {start|stop|restart|status|config|version}

參考文件

http://www.google.com
https://github.com/fatedier/frp
http://koolshare.cn/thread-65379-1-1.html

相關文章