內網穿透工具--FRP

  1. 對於沒有公網 IP 的內網用戶來說,遠程管理或在外網訪問內網機器上的服務是一個問題。

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

FRP 項目地址:https://github.com/fatedier/frp

FRP 的作用

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

  2. 對於 HTTP, HTTPS 服務支持基於域名的虛擬主機,支持自定義域名綁定,使多個域名可以共用一個 80 端口。

  3. 利用處於內網或防火牆後的機器,對外網環境提供 TCP 和 UDP 服務,例如在家裏通過 SSH 訪問處於公司內網環境內的主機。

FRP 安裝

FRP 採用 Go 語言開發,支持 Windows、Linux、MacOS、ARM等多平臺部署。FRP 安裝非常容易,只需下載對應系統平臺的軟件包,並解壓就可用。

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

 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 服務端的前提條件是需要一臺具有**公網 IP **的設備,得益於 FRP 是 Go 語言開發的,具有良好的跨平臺特性。你可以在 Windows、Linux、MacOS、ARM等幾乎任何可聯網設備上部署。

這裏以 Linux 爲例,FRP 默認給出兩個服務端配置文件,一個是簡版的 frps.ini,另一個是完整版本 frps_full.ini。
我們先來看看簡版的 frps.ini,通過這個配置可以快速的搭建起一個 FRP 服務端。

$ cat frps.ini

[common]
bind_port = 7000 
默認配置中監聽的是 7000 端口,可根據自己實際情況修改。

啓動 FRP 服務端
$ ./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。

$ vim frpc.ini

[common]
# server_addr 爲 FRP 服務端的公網 IP
server_addr = 4.3.2.1
# server_port 爲 FRP 服務端監聽的端口
server_port = 7000
啓動 FRP 客戶端
$ ./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 文件並增加如下內容:

$ cat frpc.ini

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
啓動 FRP 客戶端
$ ./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:
$ ssh -oPort=6000 [email protected]

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

有時需要在公有網絡通過域名訪問我們在本地環境搭建的 Web 服務,但是由於本地環境機器並沒有公網 IP,無法將域名直接解析到本地的機器。
現在通過 FRP 就可以很容易實現這一功能,這裏以 HTTP 服務爲例:首先修改 FRP 服務端配置文件,通過 vhost_http_port 參數來設置 HTTP 訪問端口,這裏將 HTTP 訪問端口設爲 8080。

$ vim frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080
啓動 FRP 服務端
$ ./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 客戶端配置文件並增加如下內容:
$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = **.***.com
這裏通過 local_port 和 custom_domains 參數來設置本地機器上 Web 服務對應的端口和自定義的域名,這裏我們分別設置端口爲 80,對應域名爲 **.***.com。
啓動 FRP 客戶端
$ ./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

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

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

通過密碼保護你的 Web 服務

由於所有客戶端共用一個 FRP 服務端的 HTTP 服務端口,任何知道你的域名和 URL 的人都能訪問到你部署在內網的 Web 服務,但是在某些場景下需要確保只有限定的用戶才能訪問。
FRP 支持通過 HTTP Basic Auth 來保護你的 Web 服務,使用戶需要通過用戶名和密碼才能訪問到你的服務。需要實現此功能主要需要在 FRP 客戶端的配置文件中添加用戶名和密碼的設置。

$ vim frpc.ini

[web]
type = http
local_port = 80
custom_domains = **.***.com


## 設置認證的用戶名


http_user = abc


## 設置認證的密碼


http_pwd = abc

這時訪問 http://.*.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 參數:

$ vim frps.ini
[common]
subdomain_host = ***.com
其次在 FRP 客戶端配置文件配置 subdomain 參數:
$ vim frpc.ini
[web]
type = http
local_port = 80
subdomain = test

然後將泛域名 .com 解析到 FRP 服務端所在服務器的公網 IP 地址。FRP 服務端 和 FRP 客戶端都啓動成功後,通過 test.**.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 參數。

$ vim frpc.ini
[web]
type = http
local_port = 80
custom_domains = test.***.com
host_header_rewrite = dev.***.com
原來 HTTP 請求中的 host 字段 test.***.com 轉發到後端服務時會被替換爲 dev.***.com。

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

URL 路由

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

$ vim frpc.ini

[web01]
type = http
local_port = 80
custom_domains = web.***.com
locations = /

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

按照上述的示例配置後,web.***.com 這個域名下所有以 /news 以及 /about 作爲前綴的 URL 請求都會被轉發到後端 web02 所在的後端服務,其餘的請求會被轉發到 web01 所在的後端服務。
目前僅支持最大前綴匹配,之後會考慮支持正則匹配。

通過 UDP 訪問內網機器

DNS 查詢請求通常使用 UDP 協議,FRP 支持對內網 UDP 服務的穿透,配置方式和 TCP 基本一致。這裏以轉發到 Google 的 DNS 查詢服務器 8.8.8.8 的 UDP 端口爲例。
首先修改 FRP 客戶端配置文件,並增加如下內容:

$ vim frpc.ini
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6001

要轉發到內網 DNS 服務器只需把 local_ip 改成對應 IP 即可。

其次重新啓動 FRP 客戶端:

$ ./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 域名的解析結果:

$ 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 客戶端配置文件,並增加如下內容:

$ 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 客戶端:

$ ./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 版本信息進行測試:

$ 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 服務使用的端口:

$ 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 服務端:
$ ./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 參數就行。

[common]
privilege_token = 12345678

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

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 服務。配置如下:
$ vim frpc.ini

[common]
admin_addr = 127.0.0.1
admin_port = 7400
重啓 FRP 客戶端,以後就可通過熱加載方式進行 FRP 客戶端配置變更了。

$ ./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 客戶端很方便的查看當前代理狀態信息。

$ ./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 .*.com:8080

給 FRP 服務端增加端口白名單

爲了防止 FRP 端口被濫用,FRP 提供了指定允許哪些端口被分配的功能。可通過 FRP 服務端的配置文件中 privilege_allow_ports 參數來指定:

$ vim frps.ini

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

privilege_allow_ports 可以配置允許使用的某個指定端口或者是一個範圍內的所有端口,以 , 分隔,指定的範圍以 - 分隔。
當使用不允許的端口註冊時,就會註冊失敗。出現類似以下錯誤:

$ ./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 客戶端配置文件中配置,該配置項在服務端和客戶端必須一致:

# frps.ini 和 frpc.ini 中
[common]
tcp_mux = falseFRP 

底層通信啓用 KCP 協議

FRP 從 v0.12.0 版本開始,底層通信協議支持選擇 KCP 協議,在弱網絡環境下傳輸效率會提升明顯,但是會有一些額外的流量消耗。
要開啓 KCP 協議支持,首先要在 FRP 服務端配置文件中啓用 KCP 協議支持:

$ vim frps.ini
[common]
bind_port = 7000
# 指定一個 UDP 端口用於接收客戶端請求 KCP 綁定的是 UDP 端口,可以和 bind_port 一樣
kcp_bind_port = 7000
其次是在 FRP 客戶端配置文件指定需要使用的協議類型,目前只支持 TCP 和 KCP。其它代理配置不需要變更:
$ 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 服務端配置文件中設置每個代理可以創建的連接池上限,避免大量資源佔用,客戶端設置超過此配置後會被調整到當前值:

$ vim frps.ini
[common]
max_pool_count = 5
其次在 FRP 客戶端配置文件中爲客戶端啓用連接池,指定預創建連接的數量:
$ vim frpc.ini
[common]
pool_count = 1
    * 

此功能比較適合有大量短連接請求時開啓。

加密與壓縮

如果公司內網防火牆對外網訪問進行了流量識別與屏蔽,例如禁止了 SSH 協議等,可通過設置 use_encryption = true,將 FRP 客戶端 與 FRP 服務端之間的通信內容加密傳輸,將會有效防止流量被攔截。
如果傳輸的報文長度較長,通過設置 use_compression = true 對傳輸內容進行壓縮,可以有效減小 FRP 客戶端 與 FRP 服務端之間的網絡流量,來加快流量轉發速度,但是會額外消耗一些 CPU 資源。
這兩個功能默認是不開啓的,需要在 FRP 客戶端配置文件中通過配置來爲指定的代理啓用加密與壓縮的功能,壓縮算法使用的是 snappy。

$ 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 插件爲例:

$ 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 參數來使用此功能。

$ vim frpc.ini

[common]
server_addr = 4.3.2.1
server_port = 7000
protocol = tcp
http_proxy = http://user:[email protected]:8080

僅在 protocol = tcp 時生效,暫時不支持 kcp 協議。

安全地暴露內網服務

對於一些比較敏感的服務如果直接暴露於公網上將會存在安全隱患,FRP 也提供了一種安全的轉發方式 STCP。使用 STCP (secret tcp) 類型的代理可以避免讓任何人都能訪問到穿透到公網的內網服務,要使用 STCP 模式訪問者需要單獨運行另外一個 FRP 客戶端。
下面就以創建一個只有自己能訪問到的 SSH 服務代理爲例,FRP 服務端和其它的部署步驟相同,主要區別是在 FRP 客戶端上。
首先配置 FRP 客戶端,和常規 TCP 轉發不同的是這裏不需要指定遠程端口。


$ 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 客戶端,配置如下:

$ 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:

$ ./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 [email protected]

點對點內網穿透

在傳輸大量數據時如果都經過服務器中轉的話,這樣會對服務器端帶寬壓力比較大。FRP 提供了一種新的代理類型 XTCP 來解決這個問題,XTCP 模式下可以在傳輸大量數據時讓流量不經過服務器中轉。
使用方式同 STCP 類似,需要在傳輸數據的兩端都部署上 FRP 客戶端上用於建立直接的連接。
首先在 FRP 服務端配置上增加一個 UDP 端口用於支持該類型的客戶端:

$ vim frps.ini
bind_udp_port = 7001
其次配置 FRP 客戶端,和常規 TCP 轉發不同的是這裏不需要指定遠程端口。
$ 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 客戶端,配置如下:
$ 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:
$ ./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 [email protected]

目前 XTCP 模式還處於開發的初級階段,並不能穿透所有類型的 NAT 設備,所以穿透成功率較低。穿透失敗時可以嘗試 STCP 的方式。

FRP 的部署安裝比較簡單,項目官方也沒有提供相應的管理腳本。不過好在開源項目總是有網友熱心提供部署和管理腳本。如果你覺得手動部署太麻煩,還可以使用.

一鍵安裝腳本

項目地址:https://github.com/clangcn/onekey-install-shell/下載一鍵部署腳本
$ 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 服務端配置參數都做了交互式選擇讓用戶可以方便的根據自己實際情況進行選擇。腳本比較貼心的一點是對默認的公網地址進行了檢測,省去了手動輸入的麻煩。

$ ./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

$ ./install-frps.sh config更新 FRP 服務端
$ ./install-frps.sh update卸載 FRP 服務端
$ ./install-frps.sh uninstallFRP 服務端日常管理
FRP 服務端安裝完成後,一鍵部署腳本還提供了一個日常管理 FRP 服務端的管理腳本來進行日常的啓動、重啓、停止等操作,非常的方便。
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

https://mp.weixin.qq.com/s?__biz=MzI3MTI2NzkxMA==&mid=2247485670&idx=1&sn=df62f2df93f112a7bc0b8d7e843bbc16&chksm=eac529cfddb2a0d9b0fb22324f3eaf5cffeb8e0a56d16efb87ad97d3cca6479e96e12c68eb88&mpshare=1&scene=23&srcid=0131VDjF0WIqduxU6j5sc9sg#rd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章