服务端插件

frp 服务端插件的作用是在不侵入自身代码的前提下,扩展 frp 服务端的能力。

frp 服务端插件会以单独进程的形式运行,并且监听在一个端口上,对外提供 RPC 接口,响应 frps 的请求。

frps 在执行某些操作前,会根据配置向服务端插件发送 RPC 请求,根据插件的响应来执行相应的操作。

RPC 请求

服务端插件接收到操作请求后,可以给出三种回应。

  • 拒绝操作,需要返回拒绝操作的原因。
  • 允许操作,不需要修改操作内容。
  • 允许操作,对操作请求进行修改后,返回修改后的内容。

接口

接口路径可以在 frps 配置中为每个插件单独配置,这里以 /handler 为例。

Request

  1. POST /handler?version=0.1.0&op=Login
  2. {
  3. "content": {
  4. ... // 具体的操作信息
  5. }
  6. }
  7. 请求 Header
  8. X-Frp-Reqid: 用于追踪请求

Response

非 200 的返回都认为是请求异常。

拒绝执行操作

  1. {
  2. "reject": true,
  3. "reject_reason": "invalid user"
  4. }

允许且内容不需要变动

  1. {
  2. "reject": false,
  3. "unchange": true
  4. }

允许且需要替换操作内容

  1. {
  2. "unchange": "false",
  3. "content": {
  4. ... // 替换后的操作信息,格式必须和请求时的一致
  5. }
  6. }

操作类型

目前插件支持管理的操作类型有 LoginNewProxyPingNewWorkConnNewUserConn

Login

用户登录操作信息

  1. {
  2. "content": {
  3. "version": <string>,
  4. "hostname": <string>,
  5. "os": <string>,
  6. "arch": <string>,
  7. "user": <string>,
  8. "timestamp": <int64>,
  9. "privilege_key": <string>,
  10. "run_id": <string>,
  11. "pool_count": <int>,
  12. "metas": map<string>string
  13. }
  14. }

NewProxy

创建代理的相关信息

  1. {
  2. "content": {
  3. "user": {
  4. "user": <string>,
  5. "metas": map<string>string
  6. "run_id": <string>
  7. },
  8. "proxy_name": <string>,
  9. "proxy_type": <string>,
  10. "use_encryption": <bool>,
  11. "use_compression": <bool>,
  12. "group": <string>,
  13. "group_key": <string>,
  14. // tcp and udp only
  15. "remote_port": <int>,
  16. // http and https only
  17. "custom_domains": []<string>,
  18. "subdomain": <string>,
  19. "locations": <string>,
  20. "http_user": <string>,
  21. "http_pwd": <string>,
  22. "host_header_rewrite": <string>,
  23. "headers": map<string>string,
  24. // stcp only
  25. "sk": <string>,
  26. // tcpmux only
  27. "multiplexer": <string>
  28. "metas": map<string>string
  29. }
  30. }

Ping

心跳相关信息

  1. {
  2. "content": {
  3. "user": {
  4. "user": <string>,
  5. "metas": map<string>string
  6. "run_id": <string>
  7. },
  8. "timestamp": <int64>,
  9. "privilege_key": <string>
  10. }
  11. }

NewWorkConn

创建工作连接

  1. {
  2. "content": {
  3. "user": {
  4. "user": <string>,
  5. "metas": map<string>string
  6. "run_id": <string>
  7. },
  8. "run_id": <string>
  9. "timestamp": <int64>,
  10. "privilege_key": <string>
  11. }
  12. }

NewUserConn

创建用户连接 (支持 tcpstcphttpstcpmux 协议)。

  1. {
  2. "content": {
  3. "user": {
  4. "user": <string>,
  5. "metas": map<string>string
  6. "run_id": <string>
  7. },
  8. "proxy_name": <string>,
  9. "proxy_type": <string>,
  10. "remote_addr": <string>
  11. }
  12. }

frps 中插件配置

  1. [common]
  2. bind_port = 7000
  3. [plugin.user-manager]
  4. addr = 127.0.0.1:9000
  5. path = /handler
  6. ops = Login
  7. [plugin.port-manager]
  8. addr = https://127.0.0.1:9001
  9. path = /handler
  10. ops = NewProxy
  11. tls_verify = true

addr: 插件监听的网络地址,支持 HTTP 和 HTTPS,默认为 HTTP。 path: 插件监听的请求路径。 ops: 插件需要处理的操作列表,多个 op 以英文逗号分隔。 tls_verify: 如果是 HTTPS 协议,支持忽略 TLS 身份验证。

元数据

为了减少 frps 的代码修改,同时提高管理插件的扩展能力,在 frpc 的配置文件中引入自定义元数据的概念。元数据会在调用 RPC 请求时发送给插件。

元数据以 meta_ 开头,可以配置多个,元数据分为两种,一种配置在 common 下,一种配置在各个 proxy 中。

  1. # frpc.ini
  2. [common]
  3. server_addr = 127.0.0.1
  4. server_port = 7000
  5. user = fake
  6. meta_token = fake
  7. meta_version = 1.0.0
  8. [ssh]
  9. type = tcp
  10. local_port = 22
  11. remote_port = 6000
  12. meta_id = 123

最后修改 March 19, 2021: update docs (f1b297a)