A lightweight HTTP plugin backend for frp that adds simple username/password policies with fine-grained proxy restrictions. It runs as a standalone FastAPI service, so credentials and rules stay on your infrastructure.
- YAML-driven policy file (
auth.yml) with hot-reload support - Global deny-lists for proxy types, ports, and domains
- User-level allowlists for proxy types, TCP/UDP port ranges, and HTTP(S) domains (wildcards supported)
- FastAPI endpoints compatible with frp’s HTTP plugin (
/handler,/health,/reload) - File watcher +
SIGHUPhandling for zero-downtime config updates - Environment-variable overrides for listen host/port and config path
- Multi-arch Docker images (linux/amd64, linux/arm64)
Get up and running quickly by mounting your policy file and letting Docker handle the runtime.
docker run --rm \
-p 7005:7005 \
-v "$(pwd)/auth.yml:/app/auth.yml:ro" \
-e FRP_AUTH_LISTEN_HOST=0.0.0.0 \
ghcr.io/<your-org>/frp-simple-auth:latestThe container bundles the PyInstaller binary and expects auth.yml in /app.
services:
frp-auth:
image: spaleks/frp-simple-auth:latest
# or quay.io/spaleks/frp-simple-auth:latest
container_name: frp-simple-auth
restart: unless-stopped
environment:
- FRP_AUTH_LISTEN_HOST=0.0.0.0
- FRP_AUTH_LISTEN_PORT=7005
- FRP_AUTH_CONFIG=/app/auth.yml
volumes:
- ./auth.yml:/app/auth.yml:ro
ports:
- "7005:7005"- Edit
auth.ymland define users, passwords, and allowed policies. - Start the service (locally or via Docker).
- Configure your frp server to use the HTTP plugin pointing to
/handler. - Reload the service by editing
auth.yml— changes auto-apply thanks to the file watcher. - Monitor
/healthto confirm active users or POST to/reloadif you need a manual refresh.
bindAddr: "0.0.0.0"
bindPort: 7000
vhostHTTPPort: 80
vhostHTTPSPort: 443
webServer:
addr: "0.0.0.0"
port: 7500
user: "admin"
password: "change-me"
httpPlugins:
- name: "auth"
addr: "127.0.0.1:7005" # frp-simple-auth service
path: "/handler"
ops:
- Login
- NewProxyglobalDeny:
proxyTypes: ["udp"]
remotePorts: ["1-1023"]
domains:
- "*.blocked.example"
users:
- user: "alice"
password: "s3cret"
allow:
proxyTypes: ["http", "https"]
remotePorts: ["2000-2100", "5432"]
domains:
- "example.com"
- "*.internal.example.com"globalDeny– Hard bans evaluated before user-level policies (proxy types, port ranges, domains).proxyTypes– Allowed frp proxy types (tcp,udp,http,https, …).remotePorts– Single ports or ranges for TCP/UDP proxies.domains– Allowed HTTP(S) domains; wildcards start with*..
Changes to auth.yml are applied instantly via watchdog and SIGHUP.
- Clone this repository
- Copy
.env.exampleto.envand adjust settings - Copy
auth.yml.exampletoauth.ymland configure users & policies
Run locally:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python src/frp_simple_auth.pyThe service listens on 127.0.0.1:7005 by default. Point your frp server’s HTTP plugin to http://127.0.0.1:7005/handler.
FRP_AUTH_CONFIG– Path to the YAML config (default:./auth.yml)FRP_AUTH_LISTEN_HOST– Host/IP to bind (default:127.0.0.1)FRP_AUTH_LISTEN_PORT– Port to bind (default:7005)
LOGLEVEL– Python log level (INFO,DEBUG, …)
.envsupport viapython-dotenv; any key in.envoverrides runtime defaults.
- Create a virtualenv & install dependencies.
- Run
uvicorn frp_simple_auth:app --reloadfor live FastAPI reloading. - Use
pytestor add unit tests for policy helpers as needed.
PyInstaller builds emit outputs into dist/; temporary build artifacts live in build/ (both ignored via .gitignore).
Optional helper scripts:
bin/buildCurrentPlatform.shbuilds a PyInstaller binary for your current machine.bin/buildAnyPlatform.shcross-builds Linux binaries via Docker (amd64, arm64).
MIT