一、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 頁面下載最新版本的程序。

frpsfrps.ini 放到具有公網 IP 的機器上。

frpcfrpc.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-ForX-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_domainssubdomain 可以同時配置。

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_iplocal_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_userplugin_http_passwd 即為 http_proxy 插件可選的配置參數。

開發計划

計划在后續版本中加入的功能與優化,排名不分先后,如果有其他功能建議歡迎在 issues 中反饋。

  • frps 記錄 http 請求日志。
  • frps 支持直接反向代理,類似 haproxy。
  • frpc 支持負載均衡到后端不同服務。
  • 集成對 k8s 等平台的支持。

為 frp 做貢獻

frp 是一個免費且開源的項目,我們歡迎任何人為其開發和進步貢獻力量。

  • 在使用過程中出現任何問題,可以通過 issues 來反饋。
  • Bug 的修復可以直接提交 Pull Request 到 dev 分支。
  • 如果是增加新的功能特性,請先創建一個 issue 並做簡單描述以及大致的實現方法,提議被采納后,就可以創建一個實現新特性的 Pull Request。
  • 歡迎對說明文檔做出改善,幫助更多的人使用 frp,特別是英文文檔。
  • 貢獻代碼請提交 PR 至 dev 分支,master 分支僅用於發布穩定可用版本。
  • 如果你有任何其他方面的問題,歡迎反饋至 fatedier@gmail.com 共同交流。

提醒:和項目相關的問題最好在 issues 中反饋,這樣方便其他有類似問題的人可以快速查找解決方法,並且也避免了我們重復回答一些問題。

捐助

如果您覺得 frp 對你有幫助,歡迎給予我們一定的捐助來維持項目的長期發展。

frp 交流群:606194980 (QQ 群號)

支付寶掃碼捐贈

donate-alipay

微信支付捐贈

donate-wechatpay

Paypal 捐贈

海外用戶推薦通過 Paypal 向我的賬戶 fatedier@gmail.com 進行捐贈。


免責聲明!

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



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