diff --git a/README.md b/README.md index 2890d645355..9ca3a4d539e 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,8 @@ frp also has a P2P connect mode. * [URL routing](#url-routing) * [Connecting to frps via HTTP PROXY](#connecting-to-frps-via-http-proxy) * [Range ports mapping](#range-ports-mapping) - * [Plugins](#plugins) + * [Client Plugins](#client-plugins) + * [Server Manage Plugins](#server-manage-plugins) * [Development Plan](#development-plan) * [Contributing](#contributing) * [Donation](#donation) @@ -806,7 +807,7 @@ remote_port = 6000-6006,6007 frpc will generate 8 proxies like `test_tcp_0`, `test_tcp_1`, ..., `test_tcp_7`. -### Plugins +### Client Plugins frpc only forwards requests to local TCP or UDP ports by default. @@ -828,6 +829,10 @@ plugin_http_passwd = abc `plugin_http_user` and `plugin_http_passwd` are configuration parameters used in `http_proxy` plugin. +### Server Manage Plugins + +Read the [document](/doc/server_plugin.md). + ## Development Plan * Log HTTP request information in frps. diff --git a/README_zh.md b/README_zh.md index 6f62e38717e..a7c4524254d 100644 --- a/README_zh.md +++ b/README_zh.md @@ -50,7 +50,8 @@ frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp * [URL 路由](#url-路由) * [通过代理连接 frps](#通过代理连接-frps) * [范围端口映射](#范围端口映射) - * [插件](#插件) + * [客户端插件](#客户端插件) + * [服务端管理插件](#服务端管理插件) * [开发计划](#开发计划) * [为 frp 做贡献](#为-frp-做贡献) * [捐助](#捐助) @@ -858,11 +859,11 @@ remote_port = 6000-6006,6007 实际连接成功后会创建 8 个 proxy,命名为 `test_tcp_0, test_tcp_1 ... test_tcp_7`。 -### 插件 +### 客户端插件 默认情况下,frpc 只会转发请求到本地 tcp 或 udp 端口。 -插件模式是为了在客户端提供更加丰富的功能,目前内置的插件有 `unix_domain_socket`、`http_proxy`、`socks5`、`static_file`。具体使用方式请查看[使用示例](#使用示例)。 +客户端插件模式是为了在客户端提供更加丰富的功能,目前内置的插件有 `unix_domain_socket`、`http_proxy`、`socks5`、`static_file`。具体使用方式请查看[使用示例](#使用示例)。 通过 `plugin` 指定需要使用的插件,插件的配置参数都以 `plugin_` 开头。使用插件后 `local_ip` 和 `local_port` 不再需要配置。 @@ -880,6 +881,10 @@ plugin_http_passwd = abc `plugin_http_user` 和 `plugin_http_passwd` 即为 `http_proxy` 插件可选的配置参数。 +### 服务端管理插件 + +[使用说明](/doc/server_plugin_zh.md) + ## 开发计划 计划在后续版本中加入的功能与优化,排名不分先后,如果有其他功能建议欢迎在 [issues](https://github.com/fatedier/frp/issues) 中反馈。 diff --git a/doc/server_plugin.md b/doc/server_plugin.md new file mode 100644 index 00000000000..7d9be1202c3 --- /dev/null +++ b/doc/server_plugin.md @@ -0,0 +1,171 @@ +### Manage Plugin + +frp manage plugin is aim to extend frp's ability without modifing self code. + +It runs as a process and listen on a port to provide RPC interface. Before frps doing some operations, frps will send RPC requests to manage plugin and do operations by it's response. + +### RPC request + +Support HTTP first. + +When manage plugin accept the operation request, it can give three different responses. + +* Reject operation and return the reason. +* Allow operation and keep original content. +* Allow operation and return modified content. + +### Interface + +HTTP path can be configured for each manage plugin in frps. Assume here is `/handler`. + +Request + +``` +POST /handler +{ + "version": "0.1.0", + "op": "Login", + "content": { + ... // Operation info + } +} + +Request Header +X-Frp-Reqid: for tracing +``` + +Response + +Error if not return 200 http code. + +Reject opeartion + +``` +{ + "reject": true, + "reject_reason": "invalid user" +} +``` + +Allow operation and keep original content + +``` +{ + "reject": false, + "unchange": true +} +``` + +Allow opeartion and modify content + +``` +{ + "unchange": "false", + "content": { + ... // Replaced content + } +} +``` + +### Operation + +Now it supports `Login` and `NewProxy`. + +#### Login + +Client login operation + +``` +{ + "content": { + "version": , + "hostname": , + "os": , + "arch": , + "user": , + "timestamp": , + "privilege_key": , + "run_id": , + "pool_count": , + "metas": mapstring + } +} +``` + +#### NewProxy + +Create new proxy + +``` +{ + "content": { + "user": { + "user": , + "metas": mapstring + }, + "proxy_name": , + "proxy_type": , + "use_encryption": , + "use_compression": , + "group": , + "group_key": , + + // tcp and udp only + "remote_port": , + + // http and https only + "custom_domains": [], + "subdomain": , + "locations": , + "http_user": , + "http_pwd": , + "host_header_rewrite": , + "headers": mapstring, + + "metas": mapstring + } +} +``` + +### manage plugin configure + +```ini +[common] +bind_port = 7000 + +[plugin.user-manager] +addr = 127.0.0.1:9000 +path = /handler +ops = Login + +[plugin.port-manager] +addr = 127.0.0.1:9001 +path = /handler +ops = NewProxy +``` + +addr: plugin listen on. +path: http request url path. +ops: opeartions plugin needs handle. + +### meta data + +Meta data will be sent to manage plugin in each RCP request. + +Meta data start with `meta_`. It can be configured in `common` and each proxy. + +``` +# frpc.ini +[common] +server_addr = 127.0.0.1 +server_port = 7000 +user = fake +meta_token = fake +meta_version = 1.0.0 + +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +meta_id = 123 +``` diff --git a/doc/server_plugin_zh.md b/doc/server_plugin_zh.md new file mode 100644 index 00000000000..78b71a32553 --- /dev/null +++ b/doc/server_plugin_zh.md @@ -0,0 +1,171 @@ +### 服务端管理插件 + +frp 管理插件的作用是在不侵入自身代码的前提下,扩展 frp 服务端的能力。 + +frp 管理插件会以单独进程的形式运行,并且监听在一个端口上,对外提供 RPC 接口,响应 frps 的请求。 + +frps 在执行某些操作前,会根据配置向管理插件发送 RPC 请求,根据管理插件的响应来执行相应的操作。 + +### RPC 请求 + +管理插件接收到操作请求后,可以给出三种回应。 + +* 拒绝操作,需要返回拒绝操作的原因。 +* 允许操作,不需要修改操作内容。 +* 允许操作,对操作请求进行修改后,返回修改后的内容。 + +### 接口 + +接口路径可以在 frps 配置中为每个插件单独配置,这里以 `/handler` 为例。 + +Request + +``` +POST /handler +{ + "version": "0.1.0", + "op": "Login", + "content": { + ... // 具体的操作信息 + } +} + +请求 Header +X-Frp-Reqid: 用于追踪请求 +``` + +Response + +非 200 的返回都认为是请求异常。 + +拒绝执行操作 + +``` +{ + "reject": true, + "reject_reason": "invalid user" +} +``` + +允许且内容不需要变动 + +``` +{ + "reject": false, + "unchange": true +} +``` + +允许且需要替换操作内容 + +``` +{ + "unchange": "false", + "content": { + ... // 替换后的操作信息,格式必须和请求时的一致 + } +} +``` + +### 操作类型 + +目前插件支持管理的操作类型有 `Login` 和 `NewProxy`。 + +#### Login + +用户登录操作信息 + +``` +{ + "content": { + "version": , + "hostname": , + "os": , + "arch": , + "user": , + "timestamp": , + "privilege_key": , + "run_id": , + "pool_count": , + "metas": mapstring + } +} +``` + +#### NewProxy + +创建代理的相关信息 + +``` +{ + "content": { + "user": { + "user": , + "metas": mapstring + }, + "proxy_name": , + "proxy_type": , + "use_encryption": , + "use_compression": , + "group": , + "group_key": , + + // tcp and udp only + "remote_port": , + + // http and https only + "custom_domains": [], + "subdomain": , + "locations": , + "http_user": , + "http_pwd": , + "host_header_rewrite": , + "headers": mapstring, + + "metas": mapstring + } +} +``` + +### frps 中插件配置 + +```ini +[common] +bind_port = 7000 + +[plugin.user-manager] +addr = 127.0.0.1:9000 +path = /handler +ops = Login + +[plugin.port-manager] +addr = 127.0.0.1:9001 +path = /handler +ops = NewProxy +``` + +addr: 插件监听的网络地址。 +path: 插件监听的 HTTP 请求路径。 +ops: 插件需要处理的操作列表,多个 op 以英文逗号分隔。 + +### 元数据 + +为了减少 frps 的代码修改,同时提高管理插件的扩展能力,在 frpc 的配置文件中引入自定义元数据的概念。元数据会在调用 RPC 请求时发送给插件。 + +元数据以 `meta_` 开头,可以配置多个,元数据分为两种,一种配置在 `common` 下,一种配置在各个 proxy 中。 + +``` +# frpc.ini +[common] +server_addr = 127.0.0.1 +server_port = 7000 +user = fake +meta_token = fake +meta_version = 1.0.0 + +[ssh] +type = tcp +local_port = 22 +remote_port = 6000 +meta_id = 123 +```