frp/doc/server_plugin.md

266 lines
5.6 KiB
Markdown
Raw Normal View History

### Server Plugin
2020-01-03 11:35:12 +08:00
frp server plugin is aimed to extend frp's ability without modifying the Golang code.
2020-01-03 11:35:12 +08:00
An external server should run in a different process receiving RPC calls from frps.
Before frps is doing some operations, it will send RPC requests to notify the external RPC server and act according to its response.
2020-01-03 11:35:12 +08:00
### RPC request
RPC requests are based on JSON over HTTP.
2020-01-03 11:35:12 +08:00
When a server plugin accepts an operation request, it can respond with three different responses:
2020-01-03 11:35:12 +08:00
* Reject operation and return a reason.
2020-01-03 11:35:12 +08:00
* Allow operation and keep original content.
* Allow operation and return modified content.
### Interface
HTTP path can be configured for each manage plugin in frps. We'll assume for this example that it's `/handler`.
2020-01-03 11:35:12 +08:00
A request to the RPC server will look like:
2020-01-03 11:35:12 +08:00
```
POST /handler?version=0.1.0&op=Login
2020-01-03 11:35:12 +08:00
{
"version": "0.1.0",
"op": "Login",
"content": {
... // Operation info
}
}
Request Header:
2020-01-03 11:35:12 +08:00
X-Frp-Reqid: for tracing
```
The response can look like any of the following:
2020-01-03 11:35:12 +08:00
* Non-200 HTTP response status code (this will automatically tell frps that the request should fail)
2020-01-03 11:35:12 +08:00
* Reject operation:
2020-01-03 11:35:12 +08:00
```
{
"reject": true,
"reject_reason": "invalid user"
}
```
* Allow operation and keep original content:
2020-01-03 11:35:12 +08:00
```
{
"reject": false,
"unchange": true
}
```
* Allow operation and modify content
2020-01-03 11:35:12 +08:00
```
{
"unchange": "false",
"content": {
... // Replaced content
}
}
```
### Operation
Currently `Login`, `NewProxy`, `CloseProxy`, `Ping`, `NewWorkConn` and `NewUserConn` operations are supported.
2020-01-03 11:35:12 +08:00
#### Login
Client login operation
```
{
"content": {
"version": <string>,
"hostname": <string>,
"os": <string>,
"arch": <string>,
"user": <string>,
"timestamp": <int64>,
"privilege_key": <string>,
"run_id": <string>,
"pool_count": <int>,
2022-01-11 16:36:56 +08:00
"metas": map<string>string,
"client_address": <string>
2020-01-03 11:35:12 +08:00
}
}
```
#### NewProxy
Create new proxy
```
{
"content": {
"user": {
"user": <string>,
"metas": map<string>string
"run_id": <string>
2020-01-03 11:35:12 +08:00
},
"proxy_name": <string>,
"proxy_type": <string>,
"use_encryption": <bool>,
"use_compression": <bool>,
"bandwidth_limit": <string>,
"bandwidth_limit_mode": <string>,
2020-01-03 11:35:12 +08:00
"group": <string>,
"group_key": <string>,
// tcp and udp only
"remote_port": <int>,
// http and https only
"custom_domains": []<string>,
"subdomain": <string>,
"locations": <string>,
"http_user": <string>,
"http_pwd": <string>,
"host_header_rewrite": <string>,
"headers": map<string>string,
// stcp only
"sk": <string>,
// tcpmux only
"multiplexer": <string>
2020-01-03 11:35:12 +08:00
"metas": map<string>string
}
}
```
#### CloseProxy
A previously created proxy is closed.
Please note that one request will be sent for every proxy that is closed, do **NOT** use this
if you have too many proxies bound to a single client, as this may exhaust the server's resources.
```
{
"content": {
"user": {
"user": <string>,
"metas": map<string>string
"run_id": <string>
},
"proxy_name": <string>
}
}
```
#### Ping
Heartbeat from frpc
```
{
"content": {
"user": {
"user": <string>,
"metas": map<string>string
"run_id": <string>
},
"timestamp": <int64>,
"privilege_key": <string>
}
}
```
#### NewWorkConn
New work connection received from frpc (RPC sent after `run_id` is matched with an existing frp connection)
```
{
"content": {
"user": {
"user": <string>,
"metas": map<string>string
"run_id": <string>
},
"run_id": <string>
"timestamp": <int64>,
"privilege_key": <string>
}
}
```
#### NewUserConn
New user connection received from proxy (support `tcp`, `stcp`, `https` and `tcpmux`) .
```
{
"content": {
"user": {
"user": <string>,
"metas": map<string>string
"run_id": <string>
},
"proxy_name": <string>,
"proxy_type": <string>,
"remote_addr": <string>
}
}
```
### Server Plugin Configuration
2020-01-03 11:35:12 +08:00
```toml
# frps.toml
bindPort = 7000
[[httpPlugins]]
name = "user-manager"
addr = "127.0.0.1:9000"
path = "/handler"
ops = ["Login"]
[[httpPlugins]]
name = "port-manager"
addr = "127.0.0.1:9001"
path = "/handler"
ops = ["NewProxy"]
2020-01-03 11:35:12 +08:00
```
- addr: the address where the external RPC service listens. Defaults to http. For https, specify the schema: `addr = "https://127.0.0.1:9001"`.
- path: http request url path for the POST request.
- ops: operations plugin needs to handle (e.g. "Login", "NewProxy", ...).
- tlsVerify: When the schema is https, we verify by default. Set this value to false if you want to skip verification.
### Metadata
2020-01-03 11:35:12 +08:00
Metadata will be sent to the server plugin in each RPC request.
2020-01-03 11:35:12 +08:00
There are 2 types of metadata entries - global one and the other under each proxy configuration.
Global metadata entries will be sent in `Login` under the key `metas`, and in any other RPC request under `user.metas`.
Metadata entries under each proxy configuration will be sent in `NewProxy` op only, under `metas`.
2020-01-03 11:35:12 +08:00
This is an example of metadata entries:
```toml
# frpc.toml
serverAddr = "127.0.0.1"
serverPort = 7000
user = "fake"
metadatas.token = "fake"
metadatas.version = "1.0.0"
[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
metadatas.id = "123"
2020-01-03 11:35:12 +08:00
```