自述文件 | 中文文档
frp 是一个开源项目,其持续开发完全是在我们出色的赞助商的支持下实现的。如果您想加入他们,请考虑赞助 frp 的发展。
frp 是一种快速反向代理,允许您将位于 NAT 或防火墙后面的本地服务器公开到 Internet。目前支持TCP和UDP ,以及HTTP和HTTPS协议,可以将请求通过域名转发到内部服务。
frp还提供P2P连接模式。
发展现状
关于V2
建筑学
用法示例
通过 SSH 访问 LAN 网络中的计算机
多个 SSH 服务共享同一端口
在 LAN 中使用自定义域访问内部 Web 服务
转发 DNS 查询请求
转发 Unix 域套接字
暴露一个简单的HTTP文件服务器
为本地 HTTP(S) 服务启用 HTTPS
私下公开您的服务
P2P模式
特征
HTTP X-转发-For
代理协议
对于每个代理
传输层安全协议
令牌认证
OIDC认证
普罗米修斯
配置文件
使用环境变量
将配置拆分为不同的文件
服务器仪表板
客户端管理界面
监视器
验证客户端身份
加密和压缩
热重载 frpc 配置
从客户端获取代理状态
只允许服务器上的某些端口
端口复用
带宽限制
TCP 流复用
支持KCP协议
支持QUIC协议
连接池
负载均衡
服务健康检查
重写 HTTP 主机标头
设置其他 HTTP 标头
获取真实IP
Web 服务需要 HTTP 基本身份验证(密码)
自定义子域名
URL路由
TCP 端口复用
通过 PROXY 连接到 frps
端口范围映射
客户端插件
服务器管理插件
SSH 隧道网关
相关项目
贡献
捐款
GitHub 赞助商
贝宝
玻璃钢目前正在开发中。您可以在master
分支中尝试最新的发布版本,或者使用dev
分支访问当前正在开发的版本。
我们目前正在开发版本 2,并尝试进行一些代码重构和改进。但请注意,它与版本 1 不兼容。
我们将在适当的时候从版本 0 过渡到版本 1,并且只接受错误修复和改进,而不接受大的功能请求。
v2版本的复杂度和难度远高于预期。我只能在碎片化的时间段内进行开发,而不断的中断极大地影响了生产力。鉴于这种情况,我们将继续对当前版本进行优化和迭代,直到我们有更多的空闲时间来进行大版本大修。
v2 背后的概念是基于我在云原生领域,特别是 K8s 和 ServiceMesh 领域多年的经验和反思。它的核心是现代化的四层和七层代理,类似于envoy。该代理本身具有很强的可扩展性,不仅能够实现内网穿透的功能,而且还适用于其他各种域。建立在这个高度可扩展的核心之上,我们的目标是实现 frp v1 的所有功能,同时解决以前无法实现或难以以优雅的方式实现的功能。此外,我们将保持高效的开发和迭代能力。
另外,我设想frp本身会成为一个高度可扩展的系统和平台,类似于我们基于K8s提供一系列的扩展能力。在K8s中,我们可以根据企业需求进行定制开发,利用CRD、控制器模式、webhook、CSI、CNI等特性。在frp v1中,我们引入了服务器插件的概念,它实现了一些基本的扩展性。然而,它依赖于简单的HTTP协议,需要用户启动独立的进程并自行管理。这种方式不够灵活方便,而且现实需求差异很大。指望一个由少数人维护的非营利性开源项目能够满足所有人的需求是不现实的。
最后,我们承认目前配置管理、权限验证、证书管理、API管理等模块的设计还不够现代。虽然我们可能会在 v1 版本中进行一些优化,但确保兼容性仍然是一个具有挑战性的问题,需要付出相当大的努力来解决。
我们衷心感谢您对frp的支持。
首先,从发布页面下载适合您的操作系统和体系结构的最新程序。
接下来,将frps
二进制文件和服务器配置文件放置在具有公共 IP 地址的服务器 A 上。
最后,将frpc
二进制文件和客户端配置文件放置在服务器 B 上,该服务器位于无法从公共互联网直接访问的 LAN 上。
一些防病毒软件错误地将 frpc 标记为恶意软件并将其删除。这是因为 frp 是一种能够创建反向代理的网络工具。防病毒软件有时会标记反向代理,因为它们能够绕过防火墙端口限制。如果您使用防病毒软件,则可能需要在防病毒设置中将 frpc 列入白名单/排除,以避免意外隔离/删除。有关更多详细信息,请参阅问题 3637。
修改服务器A上的frps.toml
,设置frp客户端连接的bindPort
:
# frps.tomlbindPort = 7000
在服务器A上启动frps
:
./frps -c ./frps.toml
修改服务器B上的frpc.toml
并将serverAddr
字段设置为您的frps服务器的公共IP地址:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "ssh"type = "tcp"localIP = "127.0.0.1"localPort = 22remotePort = 6000
注意localPort
(在客户端监听)和remotePort
(在服务器暴露)用于进出frp系统的流量,而serverPort
用于frps和frpc之间的通信。
在服务器B上启动frpc
:
./frpc -c ./frpc.toml
要从另一台机器通过服务器 A 通过 SSH 访问服务器 B(假设用户名是test
),请使用以下命令:
ssh -oPort=6000 test@xxxx
此示例使用 tcpmux 类型的代理实现通过同一端口公开的多个 SSH 服务。同样,只要客户端支持HTTP Connect代理连接方式,就可以通过这种方式实现端口复用。
在有公网IP的机器上部署frps,并修改frps.toml文件。这是一个简化的配置:
绑定端口 = 7000tcpmuxHTTPConnectPort = 5002
在内部机器A上部署frpc,配置如下:
serverAddr =“xxxx”serverPort = 7000[[proxies]]name =“ssh1”type =“tcpmux”多路复用器 =“httpconnect”customDomains = [“machine-a.example.com”]localIP =“127.0.0.1”localPort = 22 号
在内部机器B上部署另一台frpc,配置如下:
serverAddr =“xxxx”serverPort = 7000[[proxies]]name =“ssh2”type =“tcpmux”多路复用器 =“httpconnect”customDomains = [“machine-b.example.com”]localIP =“127.0.0.1”localPort = 22 号
使用 SSH ProxyCommand 访问内部机器 A,假设用户名是“test”:
ssh -o 'proxycommand socat - PROXY:xxxx:%h:%p,proxyport=5002' [email protected]
访问内部机器B,唯一的区别是域名,假设用户名是“test”:
ssh -o 'proxycommand socat - PROXY:xxxx:%h:%p,proxyport=5002' [email protected]
有时我们需要将 NAT 网络后面的本地 Web 服务公开给其他人,以便使用我们自己的域名进行测试。
不幸的是,我们无法将域名解析为本地IP。但是,我们可以使用 frp 来公开 HTTP(S) 服务。
修改frps.toml
并将vhost的HTTP端口设置为8080:
# frps.tomlbindPort = 7000vhostHTTPPort = 8080
如果要配置 https 代理,则需要设置vhostHTTPSPort
。
启动frps
:
./frps -c ./frps.toml
修改frpc.toml
,将serverAddr
设置为远程frps服务器的IP地址。指定 Web 服务的localPort
:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "web"type = "http"localPort = 80customDomains = ["www.example.com"]
启动frpc
:
./frpc -c ./frpc.toml
将www.example.com
的 A 记录映射到远程 frps 服务器的公共 IP 或指向您原始域的 CNAME 记录。
使用 URL http://www.example.com:8080
访问本地 Web 服务。
修改frps.toml
:
# frps.tomlbindPort = 7000
启动frps
:
./frps -c ./frps.toml
修改frpc.toml
,将serverAddr
设置为远程frps服务器的IP地址。将 DNS 查询请求转发到 Google 公共 DNS 服务器8.8.8.8:53
:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "dns"type = "udp"localIP = "8.8.8.8"localPort = 53remotePort = 6000
启动frpc:
./frpc -c ./frpc.toml
使用dig
命令测试 DNS 解析:
dig @xxxx -p 6000 www.google.com
将 Unix 域套接字(例如 Docker 守护程序套接字)公开为 TCP。
如上配置frps
。
使用以下配置启动frpc
:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "unix_domain_socket"type = "tcp"remotePort = 6000[proxies.plugin]type = "unix_domain_socket"unixPath = "/var/run/docker.sock ”
通过使用curl
获取docker版本来测试配置:
curl http://xxxx:6000/version
公开一个简单的 HTTP 文件服务器,以便从公共 Internet 访问存储在 LAN 中的文件。
按照上述配置frps
,然后:
使用以下配置启动frpc
:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "test_static_file"type = "tcp"remotePort = 6000[proxies.plugin]type = "static_file"localPath = "/tmp/files"stripPrefix = "静态"httpUser = "abc"httpPassword = "abc"
从浏览器访问http://xxxx:6000/static/
并指定正确的用户名和密码即可查看frpc
机器上/tmp/files
中的文件。
您可以用https2https
替换该插件,并将localAddr
指向 HTTPS 端点。
使用以下配置启动frpc
:
# frpc.tomlserverAddr = "xxxx"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-来自哪里=“frp”
访问https://test.example.com
。
为了降低将某些服务直接暴露到公共网络相关的风险,STCP(秘密 TCP)模式需要使用预共享密钥来从其他客户端访问该服务。
配置frps
同上。
使用以下配置在机器 B 上启动frpc
。此示例用于公开 SSH 服务(端口 22),并注意预共享密钥的secretKey
字段,并且此处删除了remotePort
字段:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "secret_ssh"type = "stcp"secretKey = "abcdefg"localIP = "127.0.0.1"localPort = 22
使用以下配置启动另一台frpc
(通常在另一台机器 C 上),以使用安全密钥( secretKey
字段)访问 SSH 服务:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[visitors]]name = "secret_ssh_visitor"type = "stcp"serverName = "secret_ssh"secretKey = "abcdefg"bindAddr = "127.0.0.1"bindPort = 6000
在计算机 C 上,使用以下命令连接到计算机 B 上的 SSH:
ssh -oPort=6000 127.0.0.1
xtcp旨在在客户端之间直接传输大量数据。还是需要一个frps服务器,这里的P2P只是指实际的数据传输。
请注意,它可能不适用于所有类型的 NAT 设备。如果 xtcp 不起作用,您可能需要回退到 stcp。
在机器B上启动frpc
,并公开SSH端口。请注意, remotePort
字段已被删除:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000# 如果默认的 stun 服务器不可用,则设置一个新的 stun 服务器。# natHoleStunServer = "xxx"[[proxies]]name = "p2p_ssh"type = "xtcp"secretKey = " abcdefg"本地IP = "127.0.0.1"本地端口 = 22
启动另一台frpc
(通常在另一台机器C上),配置为使用P2P模式连接到SSH:
# frpc.tomlserverAddr = "xxxx"serverPort = 7000# 如果默认的 stun 服务器不可用,则设置一个新的 stun 服务器。# natHoleStunServer = "xxx"[[visitors]]name = "p2p_ssh_visitor"type = "xtcp"serverName = " p2p_ssh"secretKey = "abcdefg"bindAddr = "127.0.0.1"bindPort = 6000#需要自动隧道持久化时,设置为truekeepTunnelOpen = false
在计算机 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.tomlserverAddr = "{{ .Envs.FRP_SERVER_ADDR }}"serverPort = 7000[[proxies]]name = "ssh"type = "tcp"localIP = "127.0.0.1"localPort = 22remotePort = "{{ .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
将使用操作系统环境变量渲染配置文件模板。请记住在您的引用中添加前缀.Envs
。
您可以将多个代理配置拆分为不同的文件并将它们包含在主文件中。
# frpc.tomlserverAddr = "xxxx"serverPort = 7000includes = ["./confd/*.toml"]
# ./confd/test.toml[[代理]]name = "ssh"type = "tcp"localIP = "127.0.0.1"localPort = 22remotePort = 6000
通过Dashboard查看frp的状态和代理的统计信息。
为仪表板配置端口以启用此功能:
# 默认值为127.0.0.1。如果想从公网访问,则改为0.0.0.0。 webServer.addr = "0.0.0.0"webServer.port = 7500#dashboard的用户名和密码都是可选的webServer.user = "admin"webServer.password = "行政”
然后访问http://[serverAddr]:7500
查看仪表板,用户名和密码均为admin
。
此外,您可以通过使用域通配符或普通 SSL 证书来使用 HTTPS 端口:
webServer.port = 7500#仪表板的用户名和密码都是可选的webServer.user = "admin"webServer.password = "admin"webServer.tls.certFile = "server.crt"webServer.tls.keyFile = "server.key"
然后访问https://[serverAddr]:7500
以安全 HTTPS 连接查看仪表板,用户名和密码均为admin
。
客户端管理 UI 可帮助您检查和管理 frpc 的配置。
配置管理 UI 的地址以启用此功能:
webServer.addr = "127.0.0.1"webServer.port = 7400webServer.user = "admin"webServer.password = "admin"
然后访问http://127.0.0.1:7400
即可看到管理界面,用户名和密码均为admin
。
当启用Web服务器时,frps会将监控数据在缓存中保存7天。进程重新启动后它将被清除。
还支持普罗米修斯。
先启用dashboard,然后在frps.toml
中配置enablePrometheus = true
。
http://{dashboard_addr}/metrics
将提供 prometheus 监控数据。
frpc与frps的认证有2种认证方式。
您可以通过在frpc.toml
和frps.toml
中配置auth.method
来决定使用哪一种,默认是 token。
配置auth.additionalScopes = ["HeartBeats"]
将使用配置的身份验证方法在 frpc 和 frps 之间的每个心跳上添加和验证身份验证。
配置auth.additionalScopes = ["NewWorkConns"]
将对 frpc 和 frps 之间的每个新工作连接执行相同的操作。
在frpc.toml
和frps.toml
中指定auth.method = "token"
时 - 将使用基于令牌的身份验证。
确保在frps.toml
和frpc.toml
中指定相同的auth.token
,以便frpc通过frps验证
在frpc.toml
和frps.toml
中指定auth.method = "oidc"
时 - 将使用基于 OIDC 的身份验证。
OIDC 代表 OpenID Connect,所使用的流程称为客户端凭据授予。
要使用此身份验证类型 - 配置frpc.toml
和frps.toml
如下所示:
# frps.tomlauth.method = "oidc"auth.oidc.issuer = "https://example-oidc-issuer.com/"auth.oidc.audience = "https://oidc-audience.com/.default"
# frpc.tomlauth.method = "oidc"auth.oidc.clientID = "98692467-37de-409a-9fac-bb2585826f18" # 替换为 OIDC 客户端 IDauth.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[[代理]]name = "ssh"type = "tcp"localPort = 22remotePort = 6000transport.useEncryption = truetransport.useCompression = true
从v0.50.0开始, transport.tls.enable
和transport.tls.disableCustomTLSFirstByte
的默认值已更改为true,并且默认启用tls。
对于端口复用,frp 发送第一个字节0x17
来拨打 TLS 连接。仅当您将transport.tls.disableCustomTLSFirstByte
设置为 false 时,此操作才会生效。
要强制frps
仅接受 TLS 连接 - 在frps.toml
中配置transport.tls.force = true
。这是可选的。
frpc
TLS 设置:
Transport.tls.enable = truetransport.tls.certFile = "certificate.crt"transport.tls.keyFile = "certificate.key"transport.tls.trustedCaFile = "ca.crt"
frps
TLS 设置:
Transport.tls.force = truetransport.tls.certFile = "certificate.crt"transport.tls.keyFile = "certificate.key"transport.tls.trustedCaFile = "ca.crt"
您将需要一个根 CA 证书和至少一个 SSL/TLS 证书。它可以是自签名的或常规的(例如 Let's Encrypt 或其他 SSL/TLS 证书提供商)。
如果您通过 IP 地址而不是主机名使用frp
,请确保在生成 SSL/TLS 证书时在主题备用名称 (SAN) 区域中设置适当的 IP 地址。
举个例子:
准备 openssl 配置文件。 Linux系统中它位于/etc/pki/tls/openssl.cnf
中位于/System/Library/OpenSSL/openssl.cnf
,您可以将其复制到当前路径,例如cp /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
构建 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
启用 HTTP API 需要webServer
字段:
# frpc.tomlwebServer.addr = "127.0.0.1"webServer.port = 7400
然后运行命令frpc reload -c ./frpc.toml
并等待大约 10 秒让frpc
创建或更新或删除代理。
请注意,除了“start”之外,全局客户端参数不会被修改。
您可以在重新加载之前运行命令frpc verify -c ./frpc.toml
检查是否存在配置错误。
使用frpc status -c ./frpc.toml
获取所有代理的状态。启用 HTTP API 需要webServer
字段。
frps.toml
中的allowPorts
用于避免端口滥用:
# frps.tomlallowPorts = [ { 开始 = 2000,结束 = 3000 }, { 单= 3001 }, { 单= 3003 }, { 开始 = 4000,结束 = 50000 } ]
frps 中的vhostHTTPPort
和vhostHTTPSPort
可以与bindPort
使用相同的端口。 frps 将检测连接的协议并进行相应的处理。
需要注意的是,如果要将vhostHTTPSPort
和bindPort
配置为同一个端口,需要先将transport.tls.disableCustomTLSFirstByte
设置为false。
我们希望将来尝试允许多个代理使用不同的协议绑定同一远程端口。
# frpc.toml[[代理]]name = "ssh"type = "tcp"localPort = 22remotePort = 6000transport.bandwidthLimit = "1MB"
在每个代理的配置中设置transport.bandwidthLimit
以启用此功能。支持的单位是MB
和KB
。
将transport.bandwidthLimitMode
设置为client
或server
以限制客户端或服务器端的带宽。默认为client
。
frp 从 v0.10.0 开始支持 tcp 流复用,就像 HTTP2 复用一样,在这种情况下,到同一 frpc 的所有逻辑连接都会复用到同一个 TCP 连接中。
您可以通过修改frps.toml
和frpc.toml
来禁用此功能:
# frps.toml 和 frpc.toml,必须相同transport.tcpMux = false
KCP是一种快速可靠的协议,可以达到平均延迟降低30%~40%、最大延迟降低3倍的传输效果,但代价是增加10%~20%的带宽浪费比 TCP。
KCP 模式使用 UDP 作为底层传输。在frp中使用KCP:
在 frps 中启用 KCP:
# frps.tomlbindPort = 7000# 为KCP指定UDP端口.kcpBindPort = 7000
kcpBindPort
编号可以与bindPort
相同,因为bindPort
字段指定 TCP 端口。
配置frpc.toml
以使用KCP连接frps:
# frpc.tomlserverAddr = "xxxx"# 与 frps.tomlserverPort = 7000transport.protocol = "kcp" 中的'kcpBindPort'相同
QUIC 是一种建立在 UDP 之上的新型多路复用传输。
在frp中使用QUIC:
在 frps 中启用 QUIC:
# frps.tomlbindPort = 7000#为QUIC指定UDP端口.quicBindPort = 7000
quicBindPort
编号可以与bindPort
相同,因为bindPort
字段指定TCP 端口。
配置frpc.toml
以使用 QUIC 连接 frps:
# frpc.tomlserverAddr = "xxxx"# 与 frps.tomlserverPort = 7000transport.protocol = "quic" 中的 'quicBindPort' 相同
默认情况下,frps 根据用户请求创建到后端服务的新 frpc 连接。通过连接池,frps 保留一定数量的预先建立的连接,减少建立连接所需的时间。
该功能适合大量短连接的情况。
在frps.toml
中配置每个代理可以使用的池计数限制:
# frps.tomltransport.maxPoolCount = 5
启用并指定连接池数量:
# frpc.tomltransport.poolCount = 1
负载均衡由group
支持。
此功能现在仅适用于tcp
、 http
、 tcpmux
类型。
# frpc.toml[[proxies]]name = "test1"type = "tcp"localPort = 8080remotePort = 80loadBalancer.group = "web"loadBalancer.groupKey = "123"[[proxies]]name = "test2"type = " tcp"localPort = 8081remotePort = 80loadBalancer.group = "web"loadBalancer.groupKey = "123"
loadBalancer.groupKey
用于身份验证。
到端口 80 的连接将随机分配给同一组中的代理。
对于tcp
类型,同一组中的remotePort
应该相同。
对于类型http
、 customDomains
、 subdomain
, locations
应该相同。
健康检查功能可以帮助您通过负载均衡实现高可用性。
添加healthCheck.type = "tcp"
或healthCheck.type = "http"
以启用健康检查。
使用健康检查类型tcp ,将 ping 服务端口 (TCPing):
# frpc.toml[[proxies]]name = "test1"type = "tcp"localPort = 22remotePort = 6000# 启用 TCP 健康检查 healthCheck.type = "tcp"# TCPing 超时秒数 healthCheck.timeoutSeconds = 3# 如果健康检查失败 3 次连续,代理将从 frpshealthCheck.maxFailed = 3# 每 10 秒进行一次健康检查 healthCheck.intervalSeconds = 10
使用运行状况检查类型http ,将向服务发送 HTTP 请求,并预期 HTTP 2xx OK 响应:
# frpc.toml[[proxies]]name = "web"type = "http"localIP = "127.0.0.1"localPort = 80customDomains = ["test.example.com"]# 启用HTTP健康检查healthCheck.type = "http" # frpc 将向 '/status' 发送 GET 请求# 并期望 HTTP 2xx OK 响应healthCheck.path = "/status"healthCheck.timeoutSeconds = 3healthCheck.maxFailed = 3healthCheck.intervalSeconds = 10
默认情况下,frp 根本不会修改隧道 HTTP 请求,因为它是逐字节复制。
然而,说到 Web 服务器和 HTTP 请求,您的 Web 服务器可能依赖Host
HTTP 标头来确定要访问的网站。 frp在转发HTTP请求时可以重写Host
头,其中hostHeaderRewrite
字段:
# frpc.toml[[proxies]]name = "web"type = "http"localPort = 80customDomains = ["test.example.com"]hostHeaderRewrite = "dev.example.com"
当 HTTP 请求到达实际的 Web 服务器时, Host
标头将被重写为Host: dev.example.com
,尽管来自浏览器的请求可能具有Host: test.example.com
。
与Host
类似,您可以使用代理类型http
覆盖其他 HTTP 请求和响应标头。
# frpc.toml[[proxies]]name = "web"type = "http"localPort = 80customDomains = ["test.example.com"]hostHeaderRewrite = "dev.example.com"requestHeaders.set.x-from-where =“frp”responseHeaders.set.foo =“酒吧”
在此示例中,它将在 HTTP 请求中设置标头x-from-where: frp
,并在 HTTP 响应中设置标头foo: bar
。
此功能适用于http
代理或启用了https2http
和https2https
插件的代理。
您可以从 HTTP 请求标头X-Forwarded-For
获取用户的真实 IP。
frp 支持代理协议将用户的真实 IP 发送到本地服务。它支持除 UDP 之外的所有类型。
以下是 https 服务的示例:
# frpc.toml[[proxies]]name = "web"type = "https"localPort = 443customDomains = ["test.example.com"]# 现在支持 v1 和 v2transport.proxyProtocolVersion = "v2"
您可以在 nginx 中启用代理协议支持,以在 HTTP 标头X-Real-IP
中公开用户的真实 IP,然后在 Web 服务中读取X-Real-IP
标头以获取真实 IP。
任何能够猜出您的隧道 URL 的人都可以访问您的本地 Web 服务器,除非您使用密码对其进行保护。
这将使用 frpc 配置文件中指定的用户名和密码对所有请求强制执行 HTTP 基本身份验证。
仅当代理类型为 http 时才能启用。
# frpc.toml[[proxies]]name = "web"type = "http"localPort = 80customDomains = ["test.example.com"]httpUser = "abc"httpPassword = "abc"
在浏览器中访问http://test.example.com
,现在系统会提示您输入用户名和密码。
当多人共享一台frps服务器时,使用http和https类型的subdomain
配置会很方便。
# frps.tomlsubDomainHost = "frps.com"
将*.frps.com
解析为 frps 服务器的 IP。这通常称为通配符 DNS 记录。
# frpc.toml[[代理]]name = "web"type = "http"localPort = 80subdomain = "test"
现在您可以在test.frps.com
上访问您的 Web 服务。
请注意,如果subdomainHost
不为空,则customDomains
不应是subdomainHost
的子域。
frp 支持通过 url 路由将 HTTP 请求转发到不同的后端 Web 服务。
locations
指定用于路由的 URL 前缀。 frps 首先搜索由文字字符串给出的最具体的前缀位置,无论列出的顺序如何。
# frpc.toml[[proxies]]name = "web01"type = "http"localPort = 80customDomains = ["web.example.com"]locations = ["/"] [[proxies]]名称=“web02”类型=“http”localPort=81customDomains=[“web.example.com”]位置=[“/news”,“/about”]
URL 前缀为/news
或/about
的 HTTP 请求将转发到web02 ,其他请求将转发到web01 。
frp 支持在 frps 上的单个端口上接收定向到不同代理的 TCP 套接字,类似于vhostHTTPPort
和vhostHTTPSPort
。
目前唯一受支持的 TCP 端口复用方法是httpconnect
- HTTP CONNECT 隧道。
当在 frps 中将tcpmuxHTTPConnectPort
设置为 0 以外的任何值时,frps 将在此端口上侦听 HTTP CONNECT 请求。
HTTP CONNECT 请求的主机将用于匹配 frps 中的代理。当multiplexer = "httpconnect"
时,可以通过在tcpmux
代理下配置customDomains
和/或subdomain
来在 frpc 中配置代理主机。
例如:
# frps.tomlbindPort = 7000tcpmuxHTTPConnectPort = 1337
# frpc.tomlserverAddr = "xxxx"serverPort = 7000[[proxies]]name = "proxy1"type = "tcpmux"多路复用器 = "httpconnect"customDomains = ["test1"]localPort = 80[[proxies]]name = "proxy2 “类型=”tcpmux”多路复用器=“httpconnect”customDomains=[“test2”]localPort=8080
在上面的配置中 - frps 可以通过 HTTP CONNECT 标头在端口 1337 上进行联系,例如:
CONNECT test1 HTTP/1.1rnrn
连接将被路由到proxy1
。
如果您设置了操作系统环境变量HTTP_PROXY
,或者在 frpc.toml 文件中设置了transport.proxyURL
,则 frpc 可以通过代理连接到 frps 。
仅当协议为 tcp 时才有效。
# frpc.tomlserverAddr = "xxxx"serverPort = 7000transport.proxyURL = "http://user:[email protected]:8080"
v0.56.0 中添加
我们可以使用Go模板的range语法结合内置的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_socket
、 http_proxy
、 socks5
、 static_file
、 http2https
、 https2http
、 https2https
,您可以查看示例用法。
使用插件http_proxy :
# frpc.toml[[proxies]]name = "http_proxy"type = "tcp"remotePort = 6000[proxies.plugin]type = "http_proxy"httpUser = "abc"httpPassword = "abc"
httpUser
和httpPassword
是http_proxy
插件中使用的配置参数。
阅读文档。
在 gofrp/plugin 中查找更多插件。
v0.53.0 中添加
frp支持监听frps端的SSH端口,并通过SSH -R协议实现TCP协议代理,无需依赖frpc。
# frps.tomlsshTunnelGateway.bindPort = 2200
运行./frps -c frps.toml
时,会在当前工作目录中自动创建一个名为.autogen_ssh_key
的私钥文件。这个生成的私钥文件将被frps中的SSH服务器使用。
执行命令
ssh -R :80:127.0.0.1:8080 v0@{frp 地址} -p 2200 tcp --proxy_name "test-tcp" --remote_port 9090
在frps上设置代理,将本地8080服务转发到9090端口。
frp(通过 SSH)(Ctrl+C 退出) 用户: 代理名称:test-tcp 类型:TCP 远程地址: :9090
这相当于:
frpc tcp --proxy_name“test-tcp”--local_ip 127.0.0.1 --local_port 8080 --remote_port 9090
请参阅此文档以获取更多信息。
gofrp/plugin - frp插件仓库,包含多种基于frp扩展机制实现的插件,满足不同场景的定制需求。
gofrp/tiny-frpc - 使用 ssh 协议实现的 frp 客户端的轻量级版本(至少约 3.5MB),支持一些最常用的功能,适合资源有限的设备。
有兴趣参与吗?我们很乐意帮助您!
查看我们的问题列表并考虑向dev 分支发送 Pull 请求。
如果您想添加新功能,请先创建一个issue来描述新功能以及实现方式。提案被接受后,创建新功能的实现并将其作为拉取请求提交。
抱歉我的英语不好。欢迎对该文档进行改进,甚至修复一些拼写错误。
如果您有好的想法,请发送电子邮件至 [email protected]。
注:我们希望您在问题中给出您的建议,以便其他有相同问题的人可以快速搜索,我们不需要重复回答。
如果frp对您有很大帮助,您可以通过以下方式支持我们:
通过 Github 赞助商支持我们。
您可以将您公司的徽标放置在该项目的自述文件中。
通过 PayPal 向我的帐户[email protected]捐款。