FastGateway is a self-hosted reverse-proxy and tunnel gateway. It combines a JWT-protected management API, a React dashboard, dynamically managed HTTP/HTTPS gateways, TCP/UDP L4 forwarding, TunnelClient-based access to private services, and optional Master/Worker clustering.
Document Language: English | 简体中文
See CHANGELOG.md for release notes.
FastGateway is a single deployable control plane and proxy runtime. src/FastGateway hosts the management API and dashboard, and creates one in-process Kestrel/YARP gateway for each enabled Server configuration. TunnelClient is an independent outbound agent for private services. Multiple FastGateway instances can form a cluster: the Master owns configuration, Workers apply snapshots locally and can relay traffic to a designated access node.
┌─────────────────────────────┐
Browser / clients ──HTTP(S)/H2/H3►│ FastGateway │
│ management host │
│ JWT API + React dashboard │
└──────────────┬──────────────┘
│
┌──────────────────────────┬──────────────┼──────────────────────────┐
▼ ▼ ▼ ▼
per-Server Kestrel + YARP Tunnel manager L4 stream manager Cluster
domain/path routes HTTP/2 CONNECT TCP / UDP / Both Master / Worker
service/cluster/static/ / WebSocket upstream pool config sync +
tunnel / access-node ⇄ TunnelClient data-plane relay
│ │ │ │
▼ ▼ ▼ ▼
HTTP services and files local services TCP/UDP services peer gateways
| Path | Responsibility |
|---|---|
src/FastGateway |
Main ASP.NET Core host, JWT API, static dashboard hosting, dynamic HTTP gateways, certificates, access control, rate limiting, statistics, file storage, and tunnel management. |
src/FastGateway/Gateway |
Per-server YARP route/cluster construction and the TCP/UDP StreamProxyManager. |
src/FastGateway/Services |
Minimal API endpoint groups and configuration-backed business services. |
src/FastGateway/Middleware |
Client-IP resolution, statistics, timeout, access-control, failover, proxy-error, and abnormal-IP middleware. |
src/FastGateway/Tunnels |
Server-side tunnel registration, agent lifecycle, control channels, and per-request tunnel streams. |
src/FastGateway/Cluster |
Master/Worker clustering: invite/join, WebSocket config sync, MessagePack protocol, and data-plane relay. |
src/TunnelClient |
Standalone tunnel agent. Reads tunnel.json, connects to the gateway over HTTP/2 or WebSocket, and forwards traffic to local services through YARP. |
src/Core |
Shared stream wrappers and gateway entities/enums used by the server and agent. |
src/Certes |
Vendored, Newtonsoft.Json/BouncyCastle-free, AOT-compatible ACME client used for Let's Encrypt certificates. |
web |
React 19 + TypeScript + Vite dashboard. Docker and release builds copy its dist output into src/FastGateway/wwwroot. |
PrograminitializesFastGatewayOptions, JWT authentication, background services,ConfigurationService, andClusterStateService.- The configuration service loads
data/gateway.config(creating it when absent) and atomically writes changes back to disk. Cluster role and node membership live indata/cluster.json. - Enabled
Serverrecords create independent Kestrel/YARP gateway instances. EnabledStreamForwardrecords start TCP/UDP listeners inStreamProxyManager. - Each domain route is compiled into an in-memory YARP route and cluster. A route can target one service, a service cluster, a local static-file root, or a registered tunnel node (
node_<name>). In a cluster, a route may also name an access node so other gateways relay instead of connecting upstream themselves. - Gateway middleware resolves the client IP, handles ACME HTTP-01 challenges and HTTPS redirects, collects statistics, applies timeouts/rate limits/blacklists, performs failover and error handling, then forwards through YARP.
- The explicit reload APIs and tunnel registration update the in-memory route provider without requiring a process restart. On a Master, configuration changes are debounced and pushed to online Workers.
TunnelClient is started with -c <config-file>, registers its node with /internal/gateway/Server/register, and maintains a control connection to /internal/gateway/Server. The transport type is h2 (HTTP/2 CONNECT) or ws (WebSocket); both use the FastGateway sub-protocol. When a public request matches a tunnel route, the server allocates a tunnel ID, the agent opens the corresponding data stream, and the two sides copy bytes bidirectionally to the local service.
The backend uses ASP.NET Core Minimal APIs. The main groups are /api/v1/authorization, /server, /domain, /cert, /tunnel, /stream-forward, /cluster, /black-and-white, /rate-limit, /abnormal-ip, /statistics, /qps, /filestorage, /setting, and /system. Most management groups require the JWT issued by POST /api/v1/authorization. Cluster join/register/sync endpoints authenticate with invite or node tokens rather than JWT.
All paths below are relative to the application directory; in the Docker image that directory is /app.
| Path | Purpose |
|---|---|
data/gateway.config |
Persistent gateway, domain, certificate, access-control, rate-limit, setting, and L4 forwarding configuration. |
data/cluster.json |
Cluster role, invite tokens, and Master/Worker membership. |
data/stats.db |
SQLite request-statistics database used by the statistics background service. |
data/keys/ |
ACME account keys cached by email for certificate renewal. |
certs/ |
Generated or uploaded PFX certificates selected by SNI. |
gateway.pfx |
Packaged fallback certificate used when no matching certificate is available. |
ip2region.xdb |
Optional offline IP geolocation database used for traffic analysis. |
- Login authorization
- Automatic HTTPS certificate application (Let's Encrypt / HTTP-01)
- Automatic HTTPS certificate renewal
- Wildcard domain certificates (Let's Encrypt / DNS-01)
- Upload custom HTTPS certificates (PFX / PEM)
- Dashboard monitoring
- Static file service (ETag / Last-Modified, 304)
- Single service proxy
- Cluster proxy
- TCP/UDP L4 port forwarding
- TunnelClient-based private service forwarding
- Master/Worker clustering with config sync and traffic relay
- Per-route access node (which cluster member reaches the upstream)
- Per-server client IP source (
X-Forwarded-For/X-Real-IP/CF-Connecting-IP) - Upstream health checks and request-level failover
- Traffic statistics and IP geolocation
- Request source analysis
- Configurable request-log retention (1 / 7 / 15 / 30 days)
- Custom rate-limit policies (per-IP fixed window)
- Black and white lists
- Abnormal-IP detection
- In-process file manager with chunked upload
Open Cluster in the dashboard. A new instance starts as Standalone. Clustering is optional: a single node keeps working exactly as before.
-
Create a Master — On the gateway that should own configuration, enter a management URL that Workers can reach (for example
https://gw-a.example.com:8080) and generate an invite code. The code is valid for 24 hours. Generating the first invite promotes the node to Master. -
Join as a Worker — On another FastGateway, paste the invite code, optionally set a node name, and join. The Worker registers with the Master, then keeps a WebSocket control channel open. The Master immediately pushes a full configuration snapshot (servers, domain routes, black/white lists, rate-limit policies, L4 forwards, certificates, and PFX files). Later edits on the Master are pushed automatically; local Worker edits are overwritten on the next sync.
-
Access node — On a domain route, the Master can choose which member should reach the upstream: the receiving node (default), the Master, or a named Worker. Requests that land on a different member are relayed (Worker → Master over the Master's business port; Master → Worker over an outbound cluster tunnel; Worker → other Worker in two hops via the Master).
-
Operations — The Master shows node online status and synced version, and can push config immediately, remove a node, or dissolve the cluster. A Worker can leave and keep the last synced config as a standalone gateway. Workers do not run ACME issuance or renewal; certificates are issued on the Master and distributed with the snapshot.
The node-to-node protocol is WebSocket binary frames: 1-byte version + MessagePack with LZ4 compression, serialized by a source-generated resolver so Native AOT stays reflection-free.
FastGateway supports three ways to provide HTTPS certificates for your domains, all managed from the Certificate Management page:
-
Automatic (Let's Encrypt, HTTP-01) — For a normal domain (e.g.
example.com), add the domain and email, then click Apply. The gateway completes the ACME HTTP-01 challenge automatically (an enabled port-80 service is required) and renews the certificate before it expires. -
Wildcard domain (Let's Encrypt, DNS-01) — For a wildcard domain (e.g.
*.example.com), HTTP-01 cannot be used. Add the domain, then click DNS Verify: the gateway generates a_acme-challengeTXT record for you to add at your DNS provider. Once the record has propagated, click Verify & Issue to complete the challenge. Wildcard certificates issued this way are not auto-renewed — re-run the DNS verification before they expire. -
Upload your own certificate — Click Upload Certificate to use a certificate you already own. Two formats are supported:
- PFX / P12 — upload the
.pfx/.p12file together with its password (leave empty if it has none). - PEM / CRT — upload the certificate (
.pem/.crt) and its private key (.key) separately.
Uploaded certificates (including wildcard ones) are matched by SNI and do not participate in automatic renewal; upload a new file before expiry. Uploaded certificates are converted to and stored as
.pfxunder thecertsdirectory. - PFX / P12 — upload the
- .NET 10 and ASP.NET Core Minimal APIs
- Kestrel with HTTP/1.1, HTTP/2, and HTTP/3 support for configured HTTPS gateways
- YARP 2.3 for reverse proxy routing, clusters, health checks, and forwarding
- JWT Bearer authentication for the management API
- JSON file persistence for gateway configuration (
data/gateway.config) and cluster state (data/cluster.json) - Microsoft.Data.Sqlite for request statistics (
data/stats.db) System.Threading.RateLimitingfor per-IP partitioned fixed-window rate limits- MessagePack (LZ4) for AOT-safe cluster snapshots and certificate file transfer
- Certes ACME client for Let's Encrypt HTTP-01/DNS-01 certificate workflows
- IP2Region.Net and
ip2region.xdbfor offline IP attribution
- React 19, TypeScript, and Vite
- React Router for dashboard routing and lazy-loaded pages
- Ant Design and Radix UI for controls and interaction primitives
- Tailwind CSS v4 for styling
- ECharts/Recharts for traffic and dashboard visualizations
The container uses port 8080 for the management UI/API. HTTP/HTTPS listener ports are opened by enabled Server records in the dashboard.
mkdir -p data certs
docker run -d --restart=always --name=fast-gateway \
--user 0:0 \
-e PASSWORD='change-this-password' \
-e TunnelToken='change-this-tunnel-token' \
-p 8080:8080 \
-p 80:80/tcp \
-p 443:443/tcp \
-p 443:443/udp \
-v "$(pwd)/data:/app/data" \
-v "$(pwd)/certs:/app/certs" \
aidotnet/fast-gateway:latestOpen http://localhost:8080 after the container starts. If no password is supplied, the current fallback is Aa123456; replace it before exposing the management endpoint. 443/udp is required for HTTP/3.
The published image is a Native AOT build on a chiseled base (no shell). The base image defaults to UID 1654; this repo's image and Compose run as user: "0:0" so bind-mounted data/certs stay writable. aidotnet/fast-gateway is a multi-arch image for linux/amd64 and linux/arm64.
The checked-in docker-compose.yml builds src/FastGateway/Dockerfile, persists data and certs, maps the management endpoint to port 8000, and tags the image as registry.cn-shenzhen.aliyuncs.com/token-ai/fast-gateway:
docker compose -f docker-compose.yml up -d --buildIt maps 8000:8080, 80:80, and both 443/tcp and 443/udp for HTTP/3. For a pre-built multi-architecture image, set image: aidotnet/fast-gateway:latest and remove the build section. Set PASSWORD and TunnelToken in the Compose environment for production deployments.
Download the Linux archive from Releases, extract it (for example to /opt/fastgateway), then create fastgateway.service:
nano /etc/systemd/system/fastgateway.serviceReplace paths and secrets in the unit file:
[Unit]
Description=FastGateway
[Service]
WorkingDirectory=/opt/fastgateway
ExecStart=/opt/fastgateway/FastGateway
Restart=always
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-fastgateway
User=root
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=PASSWORD=change-this-password
Environment=TunnelToken=change-this-tunnel-token
[Install]
WantedBy=multi-user.targetReload systemd and start the service:
systemctl daemon-reload
systemctl start fastgateway.service
systemctl enable fastgateway.service
systemctl status fastgateway.serviceStop or restart with systemctl stop fastgateway.service and systemctl restart fastgateway.service.
Requirements: .NET 10 SDK, Node.js 20+ with npm, and the native toolchain required by the target build. The default project settings enable Native AOT analysis/publishing for the main applications; use -p:PublishAot=false when producing a portable single-file artifact as the release workflow does.
# Build the .NET solution
dotnet build FastGateway.sln
# Build the dashboard
cd web
npm install
npm run build
cd ..
# Run the management host with the launch profile (http://localhost:5202)
dotnet run --project src/FastGateway/FastGateway.csproj
# Run a tunnel client; -c is required by the client entry point
dotnet run --project src/TunnelClient/TunnelClient.csproj -- -c ./src/TunnelClient/tunnel.jsonFor dashboard-only development, run npm run dev in web; Vite proxies /api to the backend at http://localhost:5202. Docker builds the dashboard in a Node 22 stage, then publishes the FastGateway Native AOT image for linux/amd64 and linux/arm64. The Release workflow publishes self-contained single-file FastGateway and TunnelClient archives for Linux, Windows, and macOS on x64 and ARM64.
Pre-built, self-contained binaries are published on the Releases page for the following platforms:
| OS | x64 | ARM64 |
|---|---|---|
| Linux | fastgateway-linux-x64.tar.gz |
fastgateway-linux-arm64.tar.gz |
| Windows | fastgateway-win-x64.zip |
fastgateway-win-arm64.zip |
| macOS | fastgateway-osx-x64.tar.gz |
fastgateway-osx-arm64.tar.gz |
The TunnelClient component is published for the same set of platforms (tunnelclient-<runtime> archives).
The Docker image aidotnet/fast-gateway is a multi-arch image supporting both linux/amd64 and linux/arm64, so docker run/docker compose automatically pulls the right variant for your host.
- ip2region.xdb for offline IP attribution



