frp 是一個可用于內網穿透的高性能的反向代理應用,支持 tcp, udp 協議,為 http 和 https 應用協議提供了額外的能力,且嘗試性支持了點對點穿透。可以用它進行小程序開發。
將 frps 及 frps.ini 放到具有公網 IP 的機器上。
將 frpc 及 frpc.ini 放到處于內網環境的機器上。
通過 ssh 訪問公司內網機器
- 修改 frps.ini 文件,這里使用了最簡化的配置,設置了 frp 服務器端接收客戶端流量的端口:
# frps.ini
[common]
bind_port = 7000
- 啟動 frps:
./frps -c ./frps.ini
- 修改 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
注意,local_port(客戶端偵聽)和 remote_port(服務器端暴露)是用來出入 frp 系統的兩端,server_port 則是服務器用來與客戶端通訊的。
- 啟動 frpc:
./frpc -c ./frpc.ini
- 通過 ssh 訪問內網機器,假設用戶名為 test:
ssh -oPort=6000 [email protected]
通過自定義域名訪問部署于內網的 web 服務
有時想要讓其他人通過域名訪問或者測試我們在本地搭建的 web 服務,但是由于本地機器沒有公網 IP,無法將域名解析到本地的機器,通過 frp 就可以實現這一功能,以下示例為 http 服務,https 服務配置方法相同, vhost_http_port 替換為 vhost_https_port, type 設置為 https 即可。
- 修改 frps.ini 文件,設置 http 訪問端口為 8080:
# frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080
- 啟動 frps:
./frps -c ./frps.ini
- 修改 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
- 啟動 frpc:
./frpc -c ./frpc.ini
- 將 www.yourdomain.com 的域名 A 記錄解析到 IP x.x.x.x,如果服務器已經有對應的域名,也可以將 CNAME 記錄解析到服務器原先的域名。
- 通過瀏覽器訪問 http://www.yourdomain.com:8080 即可訪問到處于內網機器上的 web 服務。
對外提供簡單的文件訪問服務
通過 static_file 插件可以對外提供一個簡單的基于 HTTP 的文件訪問服務。
frps 的部署步驟同上。
- 啟動 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
- 通過瀏覽器訪問 http://x.x.x.x:6000/static/ 來查看位于 /tmp/file 目錄下的文件,會要求輸入已設置好的用戶名和密碼。
為本地 HTTP 服務啟用 HTTPS
通過 https2http 插件可以讓本地 HTTP 服務轉換成 HTTPS 服務對外提供。
- 啟用 frpc,啟用 https2http 插件,配置如下:
# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
[test_htts2http]
type = https
custom_domains = test.yourdomain.com
plugin = https2http
plugin_local_addr = 127.0.0.1:80
# HTTPS 證書相關的配置
plugin_crt_path = ./server.crt
plugin_key_path = ./server.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp
- 通過瀏覽器訪問 https://test.yourdomain.com 即可。
安全地暴露內網服務
對于某些服務來說如果直接暴露于公網上將會存在安全隱患。
使用 stcp(secret tcp) 類型的代理可以避免讓任何人都能訪問到要穿透的服務,但是訪問者也需要運行另外一個 frpc。
以下示例將會創建一個只有自己能訪問到的 ssh 服務代理。
frps 的部署步驟同上。
- 啟動 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
- 在要訪問這個服務的機器上啟動另外一個 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
- 通過 ssh 訪問內網機器,假設用戶名為 test:
ssh -oPort=6000 [email protected]
點對點內網穿透
frp 提供了一種新的代理類型 xtcp 用于應對在希望傳輸大量數據且流量不經過服務器的場景。
使用方式同 stcp 類似,需要在兩邊都部署上 frpc 用于建立直接的連接。
目前處于開發的初級階段,并不能穿透所有類型的 NAT 設備,所以穿透成功率較低。穿透失敗時可以嘗試 stcp 的方式。
- frps 除正常配置外需要額外配置一個 udp 端口用于支持該類型的客戶端:
bind_udp_port = 7001
- 啟動 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
- 在要訪問這個服務的機器上啟動另外一個 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
- 通過 ssh 訪問內網機器,假設用戶名為 test:
ssh -oPort=6000 [email protected]
Dashboard
通過瀏覽器查看 frp 的狀態以及代理統計信息展示。
注:Dashboard 尚未針對大量的 proxy 數據展示做優化,如果出現 Dashboard 訪問較慢的情況,請不要啟用此功能。
需要在 frps.ini 中指定 dashboard 服務使用的端口,即可開啟此功能:
[common]
dashboard_port = 7500
# dashboard 用戶名密碼,默認都為 admin
dashboard_user = admin
dashboard_pwd = admin
打開瀏覽器通過 http://[server_addr]:7500 訪問 dashboard 界面,用戶名密碼默認為 admin。
Admin UI
Admin UI 可以幫助用戶通過瀏覽器來查詢和管理客戶端的 proxy 狀態和配置。
需要在 frpc.ini 中指定 admin 服務使用的端口,即可開啟此功能:
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
打開瀏覽器通過 http://127.0.0.1:7400 訪問 Admin UI,用戶名密碼默認為 admin。
如果想要在外網環境訪問 Admin UI,將 7400 端口映射出去即可,但需要重視安全風險。
監控
frps 當啟用 Dashboard 后,會默認開啟內部的監控,數據存放在內存中,每次重啟進程后會清空,監控數據可以通過 dashboard 的地址發送 HTTP 請求獲取。
目前還支持 Prometheus 作為可選的監控系統。
Prometheus
在 frps.ini 中啟用 Dashboard,并且設置 enable_prometheus = true,則通過 http://{dashboard_addr}/metrics 可以獲取到 Prometheus 的監控數據。
客戶端身份驗證
目前 frpc 和 frps 之間支持兩種身份驗證方式,token 和 oidc。
通過 frpc.ini 和 frps.ini 中 [common] section 的 authentication_method 參數配置需要使用的驗證方法。
authenticate_heartbeats = true 將會在每一個心跳包中附加上鑒權信息。
authenticate_new_work_conns = true 將會在每次建立新的工作連接時附加上鑒權信息。
Token
當 authentication_method = token,將會啟用基于 token 的驗證方式。
需要在 frpc.ini 和 frps.ini 的 [common] section 中設置相同的 token。
OIDC
當 authentication_method = oidc,將會啟用基于 OIDC 的身份驗證。
驗證流程參考 Client Credentials Grant
啟用這一驗證方式,配置 frpc.ini 和 frps.ini 如下:
# frps.ini
[common]
authentication_method = oidc
oidc_issuer = https://example-oidc-issuer.com/
oidc_audience = https://oidc-audience.com/.default
[common]
authentication_method = oidc
oidc_client_id = 98692467-37de-409a-9fac-bb2585826f18 # Replace with OIDC client ID
oidc_client_secret = oidc_secret
oidc_audience = https://oidc-audience.com/.default
oidc_token_endpoint_url = https://example-oidc-endpoint.com/oauth2/v2.0/token
加密與壓縮
這兩個功能默認是不開啟的,需要在 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 資源。
TLS
從 v0.25.0 版本開始 frpc 和 frps 之間支持通過 TLS 協議加密傳輸。通過在 frpc.ini 的 common 中配置 tls_enable = true 來啟用此功能,安全性更高。
為了端口復用,frp 建立 TLS 連接的第一個字節為 0x17。
通過將 frps.ini 的 [common] 中 tls_only 設置為 true,可以強制 frps 只接受 TLS 連接。
注意: 啟用此功能后除 xtcp 外,不需要再設置 use_encryption。
客戶端熱加載配置文件
當修改了 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 外目前無法被修改。
通過密碼保護你的 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,需要輸入配置的用戶名和密碼才能訪問。