frp官方中文文檔


frp 是一個可用於內網穿透的高性能的反向代理應用,支持 tcp, udp, http, https 協議。

目錄

  • frp 的作用
  • 開發狀態
  • 架構
  • 使用示例
    • 通過 ssh 訪問公司內網機器
    • 通過自定義域名訪問部署於內網的 web 服務
    • 轉發 DNS 查詢請求
    • 轉發 Unix域套接字
    • 對外提供簡單的文件訪問服務
    • 安全地暴露內網服務
    • 點對點內網穿透
    • 通過 frpc 所在機器訪問外網
  • 功能說明
    • 配置文件
    • Dashboard
    • 身份驗證
    • 加密與壓縮
    • 客戶端熱加載配置文件
    • 客戶端查看代理狀態
    • 特權模式
      • 端口白名單
    • TCP 多路復用
    • 底層通信可選 kcp 協議
    • 連接池
    • 修改 Host Header
    • 獲取用戶真實 IP
    • 通過密碼保護你的 web 服務
    • 自定義二級域名
    • URL 路由
    • 通過代理連接 frps
    • 范圍端口映射
    • 插件
  • 開發計划
  • 為 frp 做貢獻
  • 捐助
    • 支付寶掃碼捐贈
    • 微信支付捐贈
    • Paypal 捐贈

frp 的作用

  • 利用處於內網或防火牆后的機器,對外網環境提供 http 或 https 服務。
  • 對於 http, https 服務支持基於域名的虛擬主機,支持自定義域名綁定,使多個域名可以共用一個80端口。
  • 利用處於內網或防火牆后的機器,對外網環境提供 tcp 和 udp 服務,例如在家里通過 ssh 訪問處於公司內網環境內的主機。

開發狀態

frp 仍然處於前期開發階段,未經充分測試與驗證,不推薦用於生產環境。

master 分支用於發布穩定版本,dev 分支用於開發,您可以嘗試下載最新的 release 版本進行測試。

目前的交互協議可能隨時改變,不保證向后兼容,升級新版本時需要注意公告說明同時升級服務端和客戶端。

架構

architecture

使用示例

根據對應的操作系統及架構,從 Release 頁面下載最新版本的程序。

將 frps 及 frps.ini 放到具有公網 IP 的機器上。

將 frpc 及 frpc.ini 放到處於內網環境的機器上。

通過 ssh 訪問公司內網機器

  1. 修改 frps.ini 文件,這里使用了最簡化的配置:
# frps.ini [common] bind_port = 7000
  1. 啟動 frps:

./frps -c ./frps.ini

  1. 修改 frpc.ini 文件,假設 frps 所在服務器的公網 IP 為 x.x.x.x;
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000
  1. 啟動 frpc:

./frpc -c ./frpc.ini

  1. 通過 ssh 訪問內網機器,假設用戶名為 test:

ssh -oPort=6000 test@x.x.x.x

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

有時想要讓其他人通過域名訪問或者測試我們在本地搭建的 web 服務,但是由於本地機器沒有公網 IP,無法將域名解析到本地的機器,通過 frp 就可以實現這一功能,以下示例為 http 服務,https 服務配置方法相同, vhost_http_port 替換為 vhost_https_port, type 設置為 https 即可。

  1. 修改 frps.ini 文件,設置 http 訪問端口為 8080:
# frps.ini [common] bind_port = 7000 vhost_http_port = 8080
  1. 啟動 frps;

./frps -c ./frps.ini

  1. 修改 frpc.ini 文件,假設 frps 所在的服務器的 IP 為 x.x.x.x,local_port 為本地機器上 web 服務對應的端口, 綁定自定義域名 www.yourdomain.com:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [web] type = http local_port = 80 custom_domains = www.yourdomain.com
  1. 啟動 frpc:

./frpc -c ./frpc.ini

  1. 將 www.yourdomain.com 的域名 A 記錄解析到 IP x.x.x.x,如果服務器已經有對應的域名,也可以將 CNAME 記錄解析到服務器原先的域名。

  2. 通過瀏覽器訪問 http://www.yourdomain.com:8080 即可訪問到處於內網機器上的 web 服務。

轉發 DNS 查詢請求

DNS 查詢請求通常使用 UDP 協議,frp 支持對內網 UDP 服務的穿透,配置方式和 TCP 基本一致。

  1. 修改 frps.ini 文件:
# frps.ini [common] bind_port = 7000
  1. 啟動 frps:

./frps -c ./frps.ini

  1. 修改 frpc.ini 文件,設置 frps 所在服務器的 IP 為 x.x.x.x,轉發到 Google 的 DNS 查詢服務器 8.8.8.8 的 udp 53 端口:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [dns] type = udp local_ip = 8.8.8.8 local_port = 53 remote_port = 6000
  1. 啟動 frpc:

./frpc -c ./frpc.ini

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

dig @x.x.x.x -p 6000 www.google.com

轉發 Unix域套接字

通過 tcp 端口訪問內網的 unix域套接字(例如和 docker daemon 通信)。

frps 的部署步驟同上。

  1. 啟動 frpc,啟用 unix_domain_socket 插件,配置如下:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [unix_domain_socket] type = tcp remote_port = 6000 plugin = unix_domain_socket plugin_unix_path = /var/run/docker.sock
  1. 通過 curl 命令查看 docker 版本信息

curl http://x.x.x.x:6000/version

對外提供簡單的文件訪問服務

通過 static_file 插件可以對外提供一個簡單的基於 HTTP 的文件訪問服務。

frps 的部署步驟同上。

  1. 啟動 frpc,啟用 static_file 插件,配置如下:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [test_static_file] type = tcp remote_port = 6000 plugin = static_file # 要對外暴露的文件目錄 plugin_local_path = /tmp/file # 訪問 url 中會被去除的前綴,保留的內容即為要訪問的文件路徑 plugin_strip_prefix = static plugin_http_user = abc plugin_http_passwd = abc
  1. 通過瀏覽器訪問 http://x.x.x.x:6000/static/ 來查看位於 /tmp/file 目錄下的文件,會要求輸入已設置好的用戶名和密碼。

安全地暴露內網服務

對於某些服務來說如果直接暴露於公網上將會存在安全隱患。

使用 stcp(secret tcp) 類型的代理可以避免讓任何人都能訪問到要穿透的服務,但是訪問者也需要運行另外一個 frpc。

以下示例將會創建一個只有自己能訪問到的 ssh 服務代理。

frps 的部署步驟同上。

  1. 啟動 frpc,轉發內網的 ssh 服務,配置如下,不需要指定遠程端口:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [secret_ssh] type = stcp # 只有 sk 一致的用戶才能訪問到此服務 sk = abcdefg local_ip = 127.0.0.1 local_port = 22
  1. 在要訪問這個服務的機器上啟動另外一個 frpc,配置如下:
# frpc.ini [common] server_addr = x.x.x.x 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 = 6000
  1. 通過 ssh 訪問內網機器,假設用戶名為 test:

ssh -oPort=6000 test@127.0.0.1

點對點內網穿透

frp 提供了一種新的代理類型 xtcp 用於應對在希望傳輸大量數據且流量不經過服務器的場景。

使用方式同 stcp 類似,需要在兩邊都部署上 frpc 用於建立直接的連接。

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

  1. frps 除正常配置外需要額外配置一個 udp 端口用於支持該類型的客戶端:
bind_udp_port = 7001
  1. 啟動 frpc,轉發內網的 ssh 服務,配置如下,不需要指定遠程端口:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [p2p_ssh] type = xtcp # 只有 sk 一致的用戶才能訪問到此服務 sk = abcdefg local_ip = 127.0.0.1 local_port = 22
  1. 在要訪問這個服務的機器上啟動另外一個 frpc,配置如下:
# frpc.ini [common] server_addr = x.x.x.x 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 = 6000
  1. 通過 ssh 訪問內網機器,假設用戶名為 test:

ssh -oPort=6000 test@127.0.0.1

通過 frpc 所在機器訪問外網

frpc 內置了 http proxy 和 socks5 插件,可以使其他機器通過 frpc 的網絡訪問互聯網。

frps 的部署步驟同上。

  1. 啟動 frpc,啟用 http_proxy 或 socks5 插件(plugin 換為 socks5 即可), 配置如下:
# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 [http_proxy] type = tcp remote_port = 6000 plugin = http_proxy
  1. 瀏覽器設置 http 或 socks5 代理地址為 x.x.x.x:6000,通過 frpc 機器的網絡訪問互聯網。

功能說明

配置文件

由於 frp 目前支持的功能和配置項較多,未在文檔中列出的功能可以從完整的示例配置文件中發現。

frps 完整配置文件

frpc 完整配置文件

Dashboard

通過瀏覽器查看 frp 的狀態以及代理統計信息展示。

需要在 frps.ini 中指定 dashboard 服務使用的端口,即可開啟此功能:

[common]
dashboard_port = 7500 # dashboard 用戶名密碼,默認都為 admin dashboard_user = admin dashboard_pwd = admin

打開瀏覽器通過 http://[server_addr]:7500 訪問 dashboard 界面,用戶名密碼默認為 admin

dashboard

身份驗證

從 v0.10.0 版本開始,所有 proxy 配置全部放在客戶端(也就是之前版本的特權模式),服務端和客戶端的 common 配置中的 privilege_token 參數一致則身份驗證通過。

需要注意的是 frpc 所在機器和 frps 所在機器的時間相差不能超過 15 分鍾,因為時間戳會被用於加密驗證中,防止報文被劫持后被其他人利用。

這個超時時間可以在配置文件中通過 authentication_timeout 這個參數來修改,單位為秒,默認值為 900,即 15 分鍾。如果修改為 0,則 frps 將不對身份驗證報文的時間戳進行超時校驗。

加密與壓縮

這兩個功能默認是不開啟的,需要在 frpc.ini 中通過配置來為指定的代理啟用加密與壓縮的功能,壓縮算法使用 snappy:

# frpc.ini [ssh] type = tcp local_port = 22 remote_port = 6000 use_encryption = true use_compression = true

如果公司內網防火牆對外網訪問進行了流量識別與屏蔽,例如禁止了 ssh 協議等,通過設置 use_encryption = true,將 frpc 與 frps 之間的通信內容加密傳輸,將會有效防止流量被攔截。

如果傳輸的報文長度較長,通過設置 use_compression = true 對傳輸內容進行壓縮,可以有效減小 frpc 與 frps 之間的網絡流量,加快流量轉發速度,但是會額外消耗一些 cpu 資源。

客戶端熱加載配置文件

當修改了 frpc 中的代理配置,可以通過 frpc reload 命令來動態加載配置文件,通常會在 10 秒內完成代理的更新。

啟用此功能需要在 frpc 中啟用 admin 端口,用於提供 API 服務。配置如下:

# frpc.ini [common] admin_addr = 127.0.0.1 admin_port = 7400

之后執行重啟命令:

frpc reload -c ./frpc.ini

等待一段時間后客戶端會根據新的配置文件創建、更新、刪除代理。

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

客戶端查看代理狀態

frpc 支持通過 frpc status -c ./frpc.ini 命令查看代理的狀態信息,此功能需要在 frpc 中配置 admin 端口。

特權模式

由於從 v0.10.0 版本開始,所有 proxy 都在客戶端配置,原先的特權模式是目前唯一支持的模式。

端口白名單

為了防止端口被濫用,可以手動指定允許哪些端口被使用,在 frps.ini 中通過 privilege_allow_ports 來指定:

# frps.ini [common] privilege_allow_ports = 2000-3000,3001,3003,4000-50000

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

TCP 多路復用

從 v0.10.0 版本開始,客戶端和服務器端之間的連接支持多路復用,不再需要為每一個用戶請求創建一個連接,使連接建立的延遲降低,並且避免了大量文件描述符的占用,使 frp 可以承載更高的並發數。

該功能默認啟用,如需關閉,可以在 frps.ini 和 frpc.ini 中配置,該配置項在服務端和客戶端必須一致:

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

底層通信可選 kcp 協議

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

開啟 kcp 協議支持:

  1. 在 frps.ini 中啟用 kcp 協議支持,指定一個 udp 端口用於接收客戶端請求:
# frps.ini [common] bind_port = 7000 # kcp 綁定的是 udp 端口,可以和 bind_port 一樣 kcp_bind_port = 7000
  1. 在 frpc.ini 指定需要使用的協議類型,目前只支持 tcp 和 kcp。其他代理配置不需要變更:
# frpc.ini [common] server_addr = x.x.x.x # server_port 指定為 frps 的 kcp_bind_port server_port = 7000 protocol = kcp
  1. 像之前一樣使用 frp,需要注意開放相關機器上的 udp 的端口的訪問權限。

連接池

默認情況下,當用戶請求建立連接后,frps 才會請求 frpc 主動與后端服務建立一個連接。當為指定的代理啟用連接池后,frp 會預先和后端服務建立起指定數量的連接,每次接收到用戶請求后,會從連接池中取出一個連接和用戶連接關聯起來,避免了等待與后端服務建立連接以及 frpc 和 frps 之間傳遞控制信息的時間。

這一功能比較適合有大量短連接請求時開啟。

  1. 首先可以在 frps.ini 中設置每個代理可以創建的連接池上限,避免大量資源占用,客戶端設置超過此配置后會被調整到當前值:
# frps.ini [common] max_pool_count = 5
  1. 在 frpc.ini 中為客戶端啟用連接池,指定預創建連接的數量:
# frpc.ini [common] pool_count = 1

修改 Host Header

通常情況下 frp 不會修改轉發的任何數據。但有一些后端服務會根據 http 請求 header 中的 host 字段來展現不同的網站,例如 nginx 的虛擬主機服務,啟用 host-header 的修改功能可以動態修改 http 請求中的 host 字段。該功能僅限於 http 類型的代理。

# frpc.ini [web] type = http local_port = 80 custom_domains = test.yourdomain.com host_header_rewrite = dev.yourdomain.com

原來 http 請求中的 host 字段 test.yourdomain.com 轉發到后端服務時會被替換為 dev.yourdomain.com

獲取用戶真實 IP

目前只有 http 類型的代理支持這一功能,可以通過用戶請求的 header 中的 X-Forwarded-For 和 X-Real-IP 來獲取用戶真實 IP。

需要注意的是,目前只在每一個用戶連接的第一個 HTTP 請求中添加了這兩個 header。

通過密碼保護你的 web 服務

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

frp 支持通過 HTTP Basic Auth 來保護你的 web 服務,使用戶需要通過用戶名和密碼才能訪問到你的服務。

該功能目前僅限於 http 類型的代理,需要在 frpc 的代理配置中添加用戶名和密碼的設置。

# frpc.ini [web] type = http local_port = 80 custom_domains = test.yourdomain.com http_user = abc http_pwd = abc

通過瀏覽器訪問 http://test.yourdomain.com,需要輸入配置的用戶名和密碼才能訪問。

自定義二級域名

在多人同時使用一個 frps 時,通過自定義二級域名的方式來使用會更加方便。

通過在 frps 的配置文件中配置 subdomain_host,就可以啟用該特性。之后在 frpc 的 http、https 類型的代理中可以不配置 custom_domains,而是配置一個 subdomain 參數。

只需要將 *.{subdomain_host} 解析到 frps 所在服務器。之后用戶可以通過 subdomain 自行指定自己的 web 服務所需要使用的二級域名,通過 {subdomain}.{subdomain_host} 來訪問自己的 web 服務。

# frps.ini [common] subdomain_host = frps.com

將泛域名 *.frps.com 解析到 frps 所在服務器的 IP 地址。

# frpc.ini [web] type = http local_port = 80 subdomain = test

frps 和 fprc 都啟動成功后,通過 test.frps.com 就可以訪問到內網的 web 服務。

需要注意的是如果 frps 配置了 subdomain_host,則 custom_domains 中不能是屬於 subdomain_host 的子域名或者泛域名。

同一個 http 或 https 類型的代理中 custom_domains 和 subdomain 可以同時配置。

URL 路由

frp 支持根據請求的 URL 路徑路由轉發到不同的后端服務。

通過配置文件中的 locations 字段指定一個或多個 proxy 能夠匹配的 URL 前綴(目前僅支持最大前綴匹配,之后會考慮正則匹配)。例如指定 locations = /news,則所有 URL 以 /news 開頭的請求都會被轉發到這個服務。

# frpc.ini [web01] type = http local_port = 80 custom_domains = web.yourdomain.com locations = / [web02] type = http local_port = 81 custom_domains = web.yourdomain.com locations = /news,/about

按照上述的示例配置后,web.yourdomain.com 這個域名下所有以 /news 以及 /about 作為前綴的 URL 請求都會被轉發到 web02,其余的請求會被轉發到 web01。

通過代理連接 frps

在只能通過代理訪問外網的環境內,frpc 支持通過 HTTP PROXY 和 frps 進行通信。

可以通過設置 HTTP_PROXY 系統環境變量或者通過在 frpc 的配置文件中設置 http_proxy 參數來使用此功能。

僅在 protocol = tcp 時生效。

# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 http_proxy = http://user:pwd@192.168.1.128:8080

范圍端口映射

在 frpc 的配置文件中可以指定映射多個端口,目前只支持 tcp 和 udp 的類型。

這一功能通過 range: 段落標記來實現,客戶端會解析這個標記中的配置,將其拆分成多個 proxy,每一個 proxy 以數字為后綴命名。

例如要映射本地 6000-6005, 6007 這6個端口,主要配置如下:

# frpc.ini [range:test_tcp] type = tcp local_ip = 127.0.0.1 local_port = 6000-6006,6007 remote_port = 6000-6006,6007

實際連接成功后會創建 6 個 proxy,命名為 test_tcp_0, test_tcp_1 ... test_tcp_5

插件

默認情況下,frpc 只會轉發請求到本地 tcp 或 udp 端口。

插件模式是為了在客戶端提供更加豐富的功能,目前內置的插件有 unix_domain_sockethttp_proxysocks5static_file。具體使用方式請查看使用示例

通過 plugin 指定需要使用的插件,插件的配置參數都以 plugin_ 開頭。使用插件后 local_ip 和 local_port 不再需要配置。

使用 http_proxy 插件的示例:

# frpc.ini [http_proxy] type = tcp remote_port = 6000 plugin = http_proxy plugin_http_user = abc plugin_http_passwd = abc

plugin_http_user 和 plugin_http_passwd 即為 http_proxy 插件可選的配置參數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM