Client plugins extend the frp client's functionality by intercepting and transforming connections before forwarding them to local services. Each plugin implements a specific protocol transformation or service type, allowing frpc to act as more than a simple port forwarder.
Client plugins operate between the frp work connection and the local service. When a plugin is configured for a proxy, the plugin's Handle() method receives each incoming connection and processes it according to the plugin's logic. This enables protocol conversion, authentication, file serving, and other transformations without requiring changes to the local service.
Plugin Lifecycle Overview
Sources: pkg/plugin/client/plugin.go1-113
All client plugins implement the Plugin interface defined in pkg/plugin/client/plugin.go.
Sources: pkg/plugin/client/plugin.go31-71
Plugins self-register during package initialization using the Register() function. The Create() function looks up the appropriate creator function by plugin name.
| Function | Purpose | Location |
|---|---|---|
Register(name, fn) | Registers a plugin creator function | pkg/plugin/client/plugin.go41-46 |
Create(pluginName, pluginCtx, options) | Instantiates a plugin by name | pkg/plugin/client/plugin.go48-55 |
Registration Pattern
Each plugin file includes an init() function that calls Register():
Sources: pkg/plugin/client/plugin.go36-55 pkg/plugin/client/unix_domain_socket.go29-31
Forwards TCP connections to a Unix domain socket. This is commonly used to expose Unix socket services like the Docker daemon over TCP.
Key Implementation Details:
UnixDomainSocketPlugin pkg/plugin/client/unix_domain_socket.go33-35net.ResolveUnixAddr pkg/plugin/client/unix_domain_socket.go40-44net.DialUnix pkg/plugin/client/unix_domain_socket.go54libio.Join() for bidirectional forwarding pkg/plugin/client/unix_domain_socket.go65Sources: pkg/plugin/client/unix_domain_socket.go1-78
Provides HTTP/HTTPS proxy functionality with optional authentication. Handles both standard HTTP requests and the CONNECT method for HTTPS tunneling.
Key Implementation Details:
HTTPProxy pkg/plugin/client/http_proxy.go41-46CONNECT vs regular HTTP by reading the first few bytes pkg/plugin/client/http_proxy.go76-81libnet.NewSharedConn to replay buffered bytes for standard HTTP requests pkg/plugin/client/http_proxy.go75ServeHTTP and HTTPHandler pkg/plugin/client/http_proxy.go109-136CONNECT is handled in handleConnectReq pkg/plugin/client/http_proxy.go166-191Auth() pkg/plugin/client/http_proxy.go138-164Sources: pkg/plugin/client/http_proxy.go1-226
Implements a SOCKS5 proxy server using the armon/go-socks5 library.
Key Implementation Details:
Socks5Plugin pkg/plugin/client/socks5.go34-36gosocks5.StaticCredentials pkg/plugin/client/socks5.go44-46sp.Server.ServeConn(wrapConn) pkg/plugin/client/socks5.go56Sources: pkg/plugin/client/socks5.go1-66
Serves static files from a local directory over HTTP with optional authentication and gzip compression.
Key Implementation Details:
StaticFilePlugin pkg/plugin/client/static_file.go34-39gorilla/mux for routing and netpkg.NewHTTPAuthMiddleware for security pkg/plugin/client/static_file.go58-59http.StripPrefix pkg/plugin/client/static_file.go60netpkg.MakeHTTPGzipHandler for response compression pkg/plugin/client/static_file.go60Sources: pkg/plugin/client/static_file.go1-85
These plugins provide protocol bridging between the frp tunnel and the local service. They utilize a httpBridgePlugin base and httputil.ReverseProxy.
| Plugin | Source Protocol | Destination Protocol | Source File |
|---|---|---|---|
http2http | HTTP | HTTP | pkg/plugin/client/http2http.go |
http2https | HTTP | HTTPS | pkg/plugin/client/http2https.go |
https2http | HTTPS | HTTP | pkg/plugin/client/https2http.go |
https2https | HTTPS | HTTPS | pkg/plugin/client/https2https.go |
Common Bridge Features:
rewriteHTTPPluginRequest to modify Host headers and inject custom RequestHeaders pkg/plugin/client/http2https.go54X-Forwarded-For and other standard proxy headers pkg/plugin/client/https2http.go44-45https2 use newHTTPSBridgePluginServer to handle TLS handshakes with provided CrtPath and KeyPath pkg/plugin/client/https2http.go52http2https and https2https typically set InsecureSkipVerify: true when connecting to the local HTTPS service pkg/plugin/client/http2https.go45Sources: pkg/plugin/client/http2http.go1-57 pkg/plugin/client/http2https.go1-66 pkg/plugin/client/https2http.go1-65 pkg/plugin/client/https2https.go1-70
Terminates a TLS connection and forwards the raw decrypted data to a local TCP service.
Key Implementation Details:
TLS2RawPlugin pkg/plugin/client/tls2raw.go36-40transport.NewServerTLSConfig pkg/plugin/client/tls2raw.go49tlsConn.Handshake() before dialing the local address pkg/plugin/client/tls2raw.go63-68ProxyProtocolHeader to the local service if available pkg/plugin/client/tls2raw.go75-82libio.Join(tlsConn, rawConn) for data transfer pkg/plugin/client/tls2raw.go84Sources: pkg/plugin/client/tls2raw.go1-94
Many built-in plugins (like https2http) share a common architecture for bridging HTTP/HTTPS traffic.
Sources: pkg/plugin/client/https2http.go35-59 pkg/plugin/client/plugin.go73-112
Plugins that handle TLS (like tls2raw and https2http) utilize the transport package for configuration.
transport.NewServerTLSConfig(certPath, keyPath, caPath): Creates a tls.Config for the server side of the plugin. If paths are empty, it can generate random self-signed certificates pkg/transport/tls.go96-126transport.NewClientTLSConfig(...): Used when the plugin acts as a client to a local HTTPS service pkg/transport/tls.go128-155Sources: pkg/transport/tls.go1-168