flykey
发布于 2026-01-14 / 12 阅读
0

frp(Fast Reverse Proxy)

产品介绍

frp(Fast Reverse Proxy) 是一款开源的高性能反向代理工具,它允许您在不同网络之间建立安全的通信通道,用于实现端口映射、内网穿透和远程访问等多种网络连接需求。

主要功能

  • 反向代理服务:frp 允许您将外部流量转发到内部网络中的应用程序或服务,使外部用户可以访问您的内部资源,如Web服务器、数据库或其他应用程序。

  • 端口映射:您可以使用 frp 轻松设置端口映射,将外部请求转发到内部设备的特定端口,这对于在不同网络之间共享服务非常有用。

  • 内网穿透:frp 支持内网穿透,使您可以通过公共互联网轻松访问位于受限网络中的设备或服务,无需复杂的网络配置。

  • TCP/UDP 支持:frp 不仅支持 TCP 流量的代理,还支持 UDP 流量,适用于各种应用场景,如在线游戏或实时通信。

  • 安全性:frp 支持使用加密协议来保护数据传输的安全性,如TLS/SSL,以确保通信过程中的数据保密性和完整性。

  • 多用户支持:frp 允许您配置多个用户和权限,以细粒度控制对代理服务的访问权限,增强安全性。

  • 跨平台:frp 可在多个操作系统上运行,包括Linux、Windows和macOS,因此适用于各种不同的环境。

  • 开源和自定义配置:frp 是开源软件,允许您根据特定需求自定义配置,以满足各种使用情况。

  • 活跃的社区支持:frp 有一个积极的开发社区,提供广泛的文档和支持,以帮助用户快速入门和解决问题。

项目地址:https://github.com/fatedier/frp?tab=readme-ov-file

通过SSH访问局域网中的电脑

  1. 在服务器A上修改,设置FRP客户端连接:frps.tomlbindPort

# frps.toml
bindPort = 7000
  1. 从服务器A开始:frps

./frps -c ./frps.toml

  1. 在服务器B上修改,并将字段设置为你frps服务器的公共IP地址:frpc.tomlserverAddr

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

注意,(客户端监听)和(服务器上暴露)用于进出 FRP 系统的流量,而 用于 FRP 与 FRPC 之间的通信。localPortremotePortserverPort

  1. 从服务器B开始:frpc

./frpc -c ./frpc.toml

  1. 通过SSH从另一台机器访问服务器B(假设用户名为 ),请使用以下命令:test

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

多个SSH服务共用同一端口

本示例通过 tcpmux 类型的代理实现了通过同一端口暴露的多个 SSH 服务。同样,只要客户端支持 HTTP Connect 代理连接方式,端口重用就可以通过这种方式实现。

  1. 在拥有公共IP的机器上部署frps,并修改frps.toml文件。以下是简化的配置:

bindPort = 7000
tcpmuxHTTPConnectPort = 5002
  1. 在内部机器A上部署frpc,配置如下:

serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "ssh1"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["machine-a.example.com"]
localIP = "127.0.0.1"
localPort = 22
  1. 在内部机器B上部署另一个FRPC,配置如下:

serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "ssh2"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["machine-b.example.com"]
localIP = "127.0.0.1"
localPort = 22
  1. 使用SSH ProxyCommand访问内部机器A,假设用户名为“test”:

ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-a.example.com

  1. 访问内部机器B的唯一区别是域名,假设用户名是“test”:

ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-b.example.com

在局域网中访问带有自定义域的内部Web服务

有时我们需要将NAT网络背后的本地Web服务暴露给其他人,以便测试使用我们自己的域名。

很遗憾,我们无法将域名解析为本地IP。不过,我们可以用 frp 来暴露 HTTP(S) 服务。

  1. 修改并将vhost的HTTP端口设置为8080:frps.toml

# frps.toml
bindPort = 7000
vhostHTTPPort = 8080

如果你想配置一个 https 代理,你需要设置 .vhostHTTPSPort

  1. 开始:frps

./frps -c ./frps.toml

  1. 修改并设置为远程FRPS服务器的IP地址。请指定您的网络服务:frpc.tomlserverAddrlocalPort

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]
  1. 开始:frpc

./frpc -c ./frpc.toml

  1. 将 的 A 记录映射到远程 FRPS 服务器的公网 IP 或指向你原始域名的 CNAME 记录。www.example.com

  2. 使用网址访问您的本地网络服务。http://www.example.com:8080

前向DNS查询请求

  1. 修改:frps.toml

# frps.toml
bindPort = 7000
  1. 开始:frps

./frps -c ./frps.toml

  1. 修改并设置为远程FRPS服务器的IP地址。转发 DNS 查询请求到 Google 公共 DNS 服务器:frpc.tomlserverAddr8.8.8.8:53

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "dns"
type = "udp"
localIP = "8.8.8.8"
localPort = 53
remotePort = 6000
  1. 开始FRPC:

./frpc -c ./frpc.toml

  1. 使用以下命令测试DNS解析:dig

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

前向Unix域套接字

将一个 Unix 域套接字(例如 Docker 守护进程套接字)作为 TCP 暴露。

配置如上。frps

  1. 从以下配置开始:frpc

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "unix_domain_socket"
type = "tcp"
remotePort = 6000
[proxies.plugin]
type = "unix_domain_socket"
unixPath = "/var/run/docker.sock"
  1. 通过获取 docker 版本测试配置:curl

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

暴露一个简单的 HTTP 文件服务器

开放一个简单的HTTP文件服务器,用于访问公共互联网存储在局域网中的文件。

然后按照上述描述配置:frps

  1. 从以下配置开始:frpc

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "test_static_file"
type = "tcp"
remotePort = 6000
[proxies.plugin]
type = "static_file"
localPath = "/tmp/files"
stripPrefix = "static"
httpUser = "abc"
httpPassword = "abc"
  1. 从浏览器访问,输入正确的用户名和密码以便在机器上查看文件。http://x.x.x.x:6000/static//tmp/filesfrpc

为本地 HTTP(S) 服务启用 HTTPS。

你可以用插件替代,指向HTTPS端点。https2httpslocalAddr

  1. 从以下配置开始:frpc

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "test_https2http"
type = "https"
customDomains = ["test.example.com"]

[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:80"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
requestHeaders.set.x-from-where = "frp"
  1. 访问。https://test.example.com

私下曝光你的服务

为了降低直接向公共网络暴露某些服务的风险,STCP(秘密TCP)模式要求使用预共享密钥以便其他客户端访问该服务。

配置方式和上面一样。frps

  1. 从机器B开始,配置如下。本示例用于暴露SSH服务(端口22),请注意预共享密钥字段,该字段在此被移除:frpcsecretKeyremotePort

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "secret_ssh"
type = "stcp"
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22
  1. 再启动另一台(通常是在另一台机器C上),使用以下配置访问SSH服务,使用安全密钥(字段):frpcsecretKey

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
bindPort = 6000
  1. 在机器C上,使用以下命令连接到机器B的SSH:

ssh -oPort=6000 127.0.0.1

P2P模式

XTCP设计用于直接在客户端之间传输大量数据。仍然需要 FRPS 服务器,因为这里的 P2P 仅指实际的数据传输。

请注意,它可能不适用于所有类型的NAT设备。如果 xtcp 不行,你可能想退回 stcp。

  1. 从机器B开始,暴露SSH端口。注意该字段被移除:frpcremotePort

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
# set up a new stun server if the default one is not available.
# natHoleStunServer = "xxx"

[[proxies]]
name = "p2p_ssh"
type = "xtcp"
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22
  1. 在另一台机器C上启动另一个配置,设置使用P2P模式连接到SSH:frpc

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
# set up a new stun server if the default one is not available.
# natHoleStunServer = "xxx"

[[visitors]]
name = "p2p_ssh_visitor"
type = "xtcp"
serverName = "p2p_ssh"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
bindPort = 6000
# when automatic tunnel persistence is required, set it to true
keepTunnelOpen = false
  1. 在机器C上,使用以下命令连接到机器B的SSH:

ssh -oPort=6000 127.0.0.1

特色

配置文件

自 v0.52.0 起,我们支持 TOML、YAML 和 JSON 进行配置。请注意,INI已被弃用,未来版本中将被移除。新功能将仅提供 TOML、YAML 或 JSON 版本。需要这些新功能的用户应相应调整配置格式。

阅读完整的示例配置文件,了解更多这里未描述的功能。

示例使用TOML格式,但你仍然可以使用YAML或JSON。

这些配置文件仅供参考。请不要直接使用此配置运行程序,因为它可能存在各种问题。

FRPS(服务器)的完整配置文件

frpc(客户端)的完整配置文件

使用环境变量

环境变量可以在配置文件中引用,使用 Go 的标准格式:

# frpc.toml
serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}"
serverPort = 7000

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = {{ .Envs.FRP_SSH_REMOTE_PORT }}

通过上述配置,变量可以像这样传递到程序中:frpc

export FRP_SERVER_ADDR=x.x.x.x
export FRP_SSH_REMOTE_PORT=6000
./frpc -c ./frpc.toml

frpc将使用 OS 环境变量渲染配置文件模板。记得在引用前加上 。.Envs

将配置拆分成不同的文件

你可以把多个代理配置拆分成不同的文件,并包含在主文件中。

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
includes = ["./confd/*.toml"]
# ./confd/test.toml

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

服务器仪表盘

通过仪表盘查看 frp 的状态和代理的统计信息。

配置仪表盘端口以启用此功能:

# The default value is 127.0.0.1. Change it to 0.0.0.0 when you want to access it from a public network.
webServer.addr = "0.0.0.0"
webServer.port = 7500
# dashboard's username and password are both optional
webServer.user = "admin"
webServer.password = "admin"

然后访问仪表盘,用户名和密码均为 。http://[serverAddr]:7500admin

此外,你可以通过使用你域名的万用字符或普通SSL证书来使用HTTPS端口:

webServer.port = 7500
# dashboard's username and password are both optional
webServer.user = "admin"
webServer.password = "admin"
webServer.tls.certFile = "server.crt"
webServer.tls.keyFile = "server.key"

然后访问仪表盘,显示安全HTTPS连接,用户名和密码均为。https://[serverAddr]:7500admin

仪表盘

客户端管理界面

客户端管理员界面帮助你检查和管理 frpc 的配置及代理。

为管理员界面配置一个地址以启用此功能:

webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"

然后访问管理员界面,用户名和密码都是 。http://127.0.0.1:7400admin

动态代理管理(存储)

你可以通过Web UI或API在运行时动态创建、更新和删除代理和访问者,而无需重启frpc。

要启用此功能,请配置指定一个文件以持久化配置:store.path

[store]
path = "./db.json"

通过商店管理的代理和访客会保存到磁盘,并在 frpc 重启时自动恢复。它们与配置文件中定义的代理一起工作——当名称冲突时,存储条目优先。

监视器

启用网页服务器后,FRPS会将监控数据保存到缓存中7天。进程重启后会被清除。

普罗米修斯也被支持。

普罗米修斯

先启用仪表盘,然后在 .enablePrometheus = truefrps.toml

http://{dashboard_addr}/metrics将提供普罗米修斯监测数据。

客户端认证

用FRP认证FRPC有两种认证方法。

你可以在 和 中配置,决定用哪个,默认是令牌。auth.methodfrpc.tomlfrps.toml

配置将使用配置的认证方法,在FRPC和FRPS之间的每个心跳中添加并验证认证。auth.additionalScopes = ["HeartBeats"]

配置会对FRPC和FRP之间每个新的工作连接做同样的操作。auth.additionalScopes = ["NewWorkConns"]

令牌认证

在 和 中指定时,将使用基于令牌的认证。auth.method = "token"frpc.tomlfrps.toml

确保在 和 中指定相同的内容,才能让 frpc 通过 frps 验证auth.tokenfrps.tomlfrpc.toml

代币来源

FRP支持通过该配置从外部来源读取认证令牌。目前支持基于文件的令牌源。tokenSource

基于文件的令牌来源:

# frpc.toml
auth.method = "token"
auth.tokenSource.type = "file"
auth.tokenSource.file.path = "/path/to/token/file"

令牌将在启动时从指定文件中读取。这对于由外部系统管理令牌或出于安全原因需要与配置文件分开的场景非常有用。

OIDC认证

在 和 中指定时,将使用基于 OIDC 的认证。auth.method = "oidc"frpc.tomlfrps.toml

OIDC 代表 OpenID Connect,所使用的流程称为客户端凭证授权(Client Credentials Grant)。

使用此认证类型——配置 和 如下:frpc.tomlfrps.toml

# frps.toml
auth.method = "oidc"
auth.oidc.issuer = "https://example-oidc-issuer.com/"
auth.oidc.audience = "https://oidc-audience.com/.default"
# frpc.toml
auth.method = "oidc"
auth.oidc.clientID = "98692467-37de-409a-9fac-bb2585826f18" # Replace with OIDC client ID
auth.oidc.clientSecret = "oidc_secret"
auth.oidc.audience = "https://oidc-audience.com/.default"
auth.oidc.tokenEndpointURL = "https://example-oidc-endpoint.com/oauth2/v2.0/token"

加密与压缩

这些功能默认是关闭的。你可以开启加密和/或压缩:

# frpc.toml

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.useEncryption = true
transport.useCompression = true

TLS

自 v0.50.0 起,默认值 和 已改为 true,且 TLS 默认启用。transport.tls.enabletransport.tls.disableCustomTLSFirstByte

对于端口复用,frp 发送第一个字节用于拨号 TLS 连接。只有当你设置为false时才会生效。0x17transport.tls.disableCustomTLSFirstByte

强制只接受TLS连接——在 中配置。这是可选的。frpstransport.tls.force = truefrps.toml

FRPCTLS设置:

transport.tls.enable = true
transport.tls.certFile = "certificate.crt"
transport.tls.keyFile = "certificate.key"
transport.tls.trustedCaFile = "ca.crt"

联邦动力系统TLS设置:

transport.tls.force = true
transport.tls.certFile = "certificate.crt"
transport.tls.keyFile = "certificate.key"
transport.tls.trustedCaFile = "ca.crt"

你需要一份根CA证书至少一份SSL/TLS证书它可以是自签名的,也可以是常规的(比如Let's Encrypt或其他SSL/TLS证书提供商)。

如果你使用的是通过IP地址而非主机名,生成SSL/TLS证书时,请务必在主题备用名称(SAN)区域设置合适的IP地址。frp

举个例子:

  • 准备openssl配置文件。它存在于 Linux 系统和 MacOS 中,你可以复制到当前路径,比如 。如果没有,你可以自己组装,比如:/etc/pki/tls/openssl.cnf/System/Library/OpenSSL/openssl.cnfcp /etc/pki/tls/openssl.cnf ./my-openssl.cnf

cat > my-openssl.cnf << EOF
[ ca ]
default_ca = CA_default
[ CA_default ]
x509_extensions = usr_cert
[ req ]
default_bits        = 2048
default_md          = sha256
default_keyfile     = privkey.pem
distinguished_name  = req_distinguished_name
attributes          = req_attributes
x509_extensions     = v3_ca
string_mask         = utf8only
[ req_distinguished_name ]
[ req_attributes ]
[ usr_cert ]
basicConstraints       = CA:FALSE
nsComment              = "OpenSSL Generated Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer
[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints       = CA:true
EOF
  • Build CA证书:

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt
  • 构建FRPS证书:

openssl genrsa -out server.key 2048

openssl req -new -sha256 -key server.key \
    -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=server.com" \
    -reqexts SAN \
    -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com")) \
    -out server.csr

openssl x509 -req -days 365 -sha256 \
	-in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
	-extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com") \
	-out server.crt
  • 构建FRPC证书:

openssl genrsa -out client.key 2048
openssl req -new -sha256 -key client.key \
    -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=client.com" \
    -reqexts SAN \
    -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:client.com,DNS:example.client.com")) \
    -out client.csr

openssl x509 -req -days 365 -sha256 \
    -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
	-extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \
	-out client.crt

热装填FRPC配置

启用HTTP API所需的字段:webServer

# frpc.toml
webServer.addr = "127.0.0.1"
webServer.port = 7400

然后运行命令,等待大约10秒,让它们创建、更新或移除代理。frpc reload -c ./frpc.tomlfrpc

注意,除了“start”之外,全局客户端参数不会被修改。

start是所有源合并后(配置文件/包含/存储)后评估的全局允许列表。 如果 不是空的,任何未被列入的代理或访客将不会被启动,包括 通过Store API创建的条目。start

start主要是为了兼容性而保留,通常不建议用于新配置。 建议使用每个代理/每个访客,除非你明确想要,否则保持空 全局允许列表行为。enabledstart

你可以在重新加载前运行命令检查配置错误。frpc verify -c ./frpc.toml

从客户端获取代理状态

用于获取所有代理的状态。这些字段是启用HTTP API所必需的。frpc status -c ./frpc.tomlwebServer

服务器上只允许特定的端口

allowPorts用于避免端口滥用:frps.toml

# frps.toml
allowPorts = [
  { start = 2000, end = 3000 },
  { single = 3001 },
  { single = 3003 },
  { start = 4000, end = 50000 }
]

港口再利用

vhostHTTPPort在FRP中可以使用同一个端口。FRPS会检测连接的协议并相应处理。vhostHTTPSPortbindPort

你需要注意的是,如果你想配置和连接到同一个端口,首先需要设置为 false。vhostHTTPSPortbindPorttransport.tls.disableCustomTLSFirstByte

我们希望未来允许多个代理绑定同一远程端口,使用不同的协议。

带宽限制

对于每个代理

# frpc.toml

[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.bandwidthLimit = "1MB"

在每个代理的配置中设置以启用此功能。支持单位为 和 。transport.bandwidthLimitMBKB

设置为或限制客户端或服务器端的带宽。默认是。transport.bandwidthLimitModeclientserverclient

TCP流复用

自v0.10.0起,FRP支持TCP流复用,类似于HTTP2复用,在这种情况下,所有指向同一FRPC的逻辑连接都会复用到同一个TCP连接中。

你可以通过修改和 来禁用该功能:frps.tomlfrpc.toml

# frps.toml and frpc.toml, must be same
transport.tcpMux = false

支持 KCP 协议

KCP是一种快速且可靠的协议,能够实现平均延迟减少30%至40%,最大延迟减少三倍的传输效果,但带宽浪费比TCP多10%至20%。

KCP模式使用UDP作为底层传输。在FRP中使用KCP:

  1. 在FRP中启用KCP:

# frps.toml
bindPort = 7000
# Specify a UDP port for KCP.
kcpBindPort = 7000

该数字可以与 相同,因为字段指定了 TCP 端口。kcpBindPortbindPortbindPort

  1. 配置为使用 KCP 连接 FRPS:frpc.toml

# frpc.toml
serverAddr = "x.x.x.x"
# Same as the 'kcpBindPort' in frps.toml
serverPort = 7000
transport.protocol = "kcp"

支持 QUIC 协议

QUIC是一种基于UDP构建的新复用传输。

在FRP中使用QUIC:

  1. 在FRP中启用QUIC:

# frps.toml
bindPort = 7000
# Specify a UDP port for QUIC.
quicBindPort = 7000

该数字可以与 相同,因为字段指定了 TCP 端口。quicBindPortbindPortbindPort

  1. 配置为使用 QUIC 连接 FRPS:frpc.toml

# frpc.toml
serverAddr = "x.x.x.x"
# Same as the 'quicBindPort' in frps.toml
serverPort = 7000
transport.protocol = "quic"

连接池

默认情况下,frps会在用户请求时为后端服务创建一个新的frpc连接。通过连接池,FRPS保留一定数量的预设连接,从而缩短建立连接所需的时间。

该特性适用于大量短连接。

  1. 配置每个代理可用的池数限制:frps.toml

# frps.toml
transport.maxPoolCount = 5
  1. 启用并指定连接池数量:

# frpc.toml
transport.poolCount = 1

负载均衡

负载均衡由 支持 。group

该功能目前仅适用于类型 , , 。tcphttptcpmux

# frpc.toml

[[proxies]]
name = "test1"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "123"

[[proxies]]
name = "test2"
type = "tcp"
localPort = 8081
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "123"

loadBalancer.groupKey用于认证。

连接到80端口的连接会随机分配到同一组中的代理。

对于类型,同一组中应是相同的。tcpremotePort

对于类型,,,应当相同。httpcustomDomainssubdomainlocations

服务健康检查

健康检查功能可以帮助你实现负载均衡的高可用性。

添加或以启用健康检查。healthCheck.type = "tcp"healthCheck.type = "http"

使用健康检查类型 TCP,服务端口将被 ping 通(TCPing):

# frpc.toml

[[proxies]]
name = "test1"
type = "tcp"
localPort = 22
remotePort = 6000
# Enable TCP health check
healthCheck.type = "tcp"
# TCPing timeout seconds
healthCheck.timeoutSeconds = 3
# If health check failed 3 times in a row, the proxy will be removed from frps
healthCheck.maxFailed = 3
# A health check every 10 seconds
healthCheck.intervalSeconds = 10

使用健康检查类型 http,会向服务发送 HTTP 请求,期望收到 HTTP 2xx OK 响应:

# frpc.toml

[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["test.example.com"]
# Enable HTTP health check
healthCheck.type = "http"
# frpc will send a GET request to '/status'
# and expect an HTTP 2xx OK response
healthCheck.path = "/status"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10

重写HTTP主机头部

默认情况下,frp 不会修改隧道后的 HTTP 请求,因为它是逐字节复制。

不过,说到网页服务器和HTTP请求,你的网页服务器可能依赖HTTP头来确定要访问的网站。FRP可以在转发HTTP请求时重写头部,字段如下:HostHosthostHeaderRewrite

# frpc.toml

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["test.example.com"]
hostHeaderRewrite = "dev.example.com"

HTTP 请求到达实际 Web 服务器时,头部会被重写为 ,尽管浏览器请求很可能有 。HostHost: dev.example.comHost: test.example.com

设置其他HTTP头部

类似于 ,你可以用代理类型 覆盖其他 HTTP 请求和响应头。Hosthttp

# frpc.toml

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["test.example.com"]
hostHeaderRewrite = "dev.example.com"
requestHeaders.set.x-from-where = "frp"
responseHeaders.set.foo = "bar"

在这个例子中,它会在 HTTP 请求和 HTTP 响应中设置头部。x-from-where: frpfoo: bar

获取真实知识产权

HTTP X-转发-For(HTTP X-转发-For)

这个功能适用于代理或启用了 和 插件的代理。httphttps2httphttps2https

你可以从 HTTP 请求头获取用户的真实 IP 。X-Forwarded-For

代理协议

frp 支持代理协议,将用户的真实 IP 发送到本地服务。

这里有一个https服务的示例:

# frpc.toml

[[proxies]]
name = "web"
type = "https"
localPort = 443
customDomains = ["test.example.com"]

# now v1 and v2 are supported
transport.proxyProtocolVersion = "v2"

你可以在nginx中启用代理协议支持,在HTTP首部暴露用户的真实IP,然后在你的Web服务中读取真实IP的首部。X-Real-IPX-Real-IP

要求 HTTP 基本认证(密码)用于 Web 服务

任何能猜到你隧道URL的人都可以访问你的本地服务器,除非你用密码保护它。

这会强制所有请求使用FRPC配置文件中指定的用户名和密码的HTTP基本认证。

只有当代理类型为 http 时才能启用。

# frpc.toml

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["test.example.com"]
httpUser = "abc"
httpPassword = "abc"

在浏览器中访问,现在会提示你输入用户名和密码。http://test.example.com

自定义子域名

当多人共享一个FRPS服务器时,使用config处理http和HTTPS类型非常方便。subdomain

# frps.toml
subDomainHost = "frps.com"

解析到FRPS服务器的IP。这通常称为通配符DNS记录。*.frps.com

# frpc.toml

[[proxies]]
name = "web"
type = "http"
localPort = 80
subdomain = "test"

现在你可以访问你的网络服务。test.frps.com

注意,如果 不是空的,则不应是 的子整环。subdomainHostcustomDomainssubdomainHost

URL 路由

FRP支持通过URL路由将HTTP请求转发到不同的后端Web服务。

locations指定用于路由的URL前缀。FRPS 首先搜索由字面字符串给出的最具体前缀位置,无论排序为何。

# frpc.toml

[[proxies]]
name = "web01"
type = "http"
localPort = 80
customDomains = ["web.example.com"]
locations = ["/"]

[[proxies]]
name = "web02"
type = "http"
localPort = 81
customDomains = ["web.example.com"]
locations = ["/news", "/about"]

带有URL前缀的HTTP请求或将转发到web02,其他请求则转发到web01/news/about

TCP端口复用

FRP支持在FRPS上的单一端口接收指向不同代理的TCP套接字,类似于和。vhostHTTPPortvhostHTTPSPort

目前唯一支持的TCP端口复用方法是——HTTP CONNECT隧道。httpconnect

当 FRPS 中设置为非 0 时,FRPS 会监听该端口的 HTTP CONNECT 请求。tcpmuxHTTPConnectPort

HTTP CONNECT 请求的主机将用于匹配 FRPS 中的代理。代理主机可以通过配置和/或在代理下配置,在 时配置 。customDomainssubdomaintcpmuxmultiplexer = "httpconnect"

例如:

# frps.toml
bindPort = 7000
tcpmuxHTTPConnectPort = 1337
# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "proxy1"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["test1"]
localPort = 80

[[proxies]]
name = "proxy2"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["test2"]
localPort = 8080

在上述配置中——可以通过端口1337访问FRP,使用HTTP CONNECT头,例如:

CONNECT test1 HTTP/1.1\r\n\r\n

连接将路由到。proxy1

通过代理连接到FRPS。

如果你设置了操作系统环境变量,或者在frpc.toml文件中设置了,frpc可以通过代理连接到FRP。HTTP_PROXYtransport.proxyURL

只有协议是TCP时才有效。

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
transport.proxyURL = "http://user:pwd@192.168.1.128:8080"

端口范围映射

新增于 v0.56.0

我们可以结合 Go 模板的范围语法和内置函数来实现端口范围映射。parseNumberRangePair

以下示例运行时,将创建8个名为 的代理,每个代理将远程端口映射到本地端口。test-6000, test-6001 ... test-6007

{{- range $_, $v := parseNumberRangePair "6000-6006,6007" "6000-6006,6007" }}
[[proxies]]
name = "tcp-{{ $v.First }}"
type = "tcp"
localPort = {{ $v.First }}
remotePort = {{ $v.Second }}
{{- end }}

客户端插件

frpc默认只将请求转发到本地TCP或UDP端口。

插件用于提供丰富的功能。内置插件如 、 、 、 、 ,你可以看到示例使用情况。unix_domain_sockethttp_proxysocks5static_filehttp2httpshttps2httphttps2https

使用插件http_proxy

# frpc.toml

[[proxies]]
name = "http_proxy"
type = "tcp"
remotePort = 6000
[proxies.plugin]
type = "http_proxy"
httpUser = "abc"
httpPassword = "abc"

httpUser和 是插件中使用的配置参数。httpPasswordhttp_proxy

服务器管理插件

请阅读文件

gofrp/plugin 中查找更多插件。

SSH 隧道网关

在 v0.53.0 中添加

frp 支持在 frps 端监听 SSH 端口,并通过 SSH -R 协议实现 TCP 协议代理,无需依赖 frpc。

# frps.toml
sshTunnelGateway.bindPort = 2200

运行时,将自动在当前工作目录中创建一个名为私钥的文件。生成的私钥文件将被 SSH 服务器在 FRPS 中使用。./frps -c frps.toml.autogen_ssh_key

执行命令

ssh -R :80:127.0.0.1:8080 v0@{frp address} -p 2200 tcp --proxy_name "test-tcp" --remote_port 9090

在FRPS上设置一个代理,将本地8080服务转发到9090端口。

frp (via SSH) (Ctrl+C to quit)

User:
ProxyName: test-tcp
Type: tcp
RemoteAddress: :9090

这等价于:

frpc tcp --proxy_name "test-tcp" --local_ip 127.0.0.1 --local_port 8080 --remote_port 9090

更多信息请参阅本文档

虚拟网络(VirtualNet)

Alpha 功能于 v0.62.0 中添加

VirtualNet 功能使 FRP 能够通过 TUN 接口创建和管理客户端与访客之间的虚拟网络连接。这使得机器之间实现了IP级路由,将frp扩展到超越简单端口转发,支持完整的网络连接。

有关配置和使用情况的详细信息,请参阅 VirtualNet 文档

特色门

FRP支持功能门以启用或禁用实验性功能。这让用户在新功能被认为稳定之前可以尝试。

可用功能门

名称

舞台

默认

描述

虚拟网

阿尔法

错误

FRP的虚拟网络能力

启用功能门

要启用实验性功能,请在配置中添加功能门:

featureGates = { VirtualNet = true }

功能生命周期

特征通常经历三个阶段:

  1. ALPHA:默认禁用,可能不稳定

  2. 测试版:可能默认启用,更稳定但仍在不断演进

  3. GA(普遍可用):默认启用,准备生产环境使用