Everything between the internet and your origin
Ten layers of control, all configured from one dashboard and stored in one database you own.
Reverse proxy & TLS
Multi-site routing with automated certificates.
- Native HTTP and HTTPS listeners on ports 80 and 443
- Multi-site reverse proxy routing by hostname
- Automatic Let's Encrypt certificates via ACME HTTP-01 or DNS-01 (RFC 2136 dynamic updates), or upload your own PEM chain
- SNI certificate selection for multiple domains on one listener
- Transparent HTTP, HTTPS, WebSocket, and secure WebSocket proxying
- Incoming PROXY protocol v1 and v2 from trusted load balancers on HTTP and HTTPS, read before TLS or application data
- Original client IPs for policies, rate limiting, monitoring, and WebSockets, with direct connections allowed by default
- Signed
X-BurrowGate-*origin verification headers (HMAC-SHA256) - Hostname changes on a site with an active certificate can be scheduled for a chosen time instead of rebuilding the HTTPS listener immediately
-
Per-site HSTS (
Strict-Transport-Security) with optional includeSubDomains and preload, sent on every HTTPS response for that site
Bot & abuse protection
Keep automated traffic away from your application.
- 55 built-in search, social, SEO, archive, AI crawler, AI search, and AI assistant definitions
- Block a whole bot category or individual agents per site, with per-route inheritance or replacement
- User-Agent-first detection with IP-range verification where publishers provide feeds
- Recorded bot identity and verification details, per-bot graphs, and a Top bots traffic view
- Managed request protection (WAF) with monitor and block modes
- Per-route overrides, rule exclusions, and auditable outcomes
- Pluggable challenge providers with ordered challenge chains
- SHA-256 browser proof-of-work, hCaptcha, Cloudflare Turnstile, Google reCAPTCHA (v2 and v3), interactive Snake, drag-slider, and path-trace game challenges, a shared-password challenge, and a configurable multiple-choice quiz challenge with an admin-authored question pool, adjustable questions-per-round, and a pass-percentage threshold
- Per-site auto-ban after too many consecutive failed challenge attempts from the same IP, tracked across flows
- Opaque, revocable visitor sessions - only a SHA-256 hash is stored
CrowdSec
Act on a shared threat feed, and optionally on CrowdSec's WAF.
- Acts as a CrowdSec remediation component, pulling decisions from a Local API in stream mode
- Decisions are held in memory and indexed, so a lookup costs the same at half a million decisions as at ten thousand
- Nothing on the request path waits on the Local API, and an outage leaves the decisions already loaded in force
- Separate ban and captcha modes per site and per route, with captcha decisions served by the built-in challenge chain
- TCP and UDP streams enforce the same decisions, and live connections are re-checked when new ones arrive
- Optional CrowdSec AppSec (WAF) inspection, off by default and opted into per route because it costs a round-trip
- Explicit IP and ASN allow rules override CrowdSec, so a community-list false positive cannot lock you out
- Every site starts in identify-only mode, so matches are visible before anything is blocked
- Decisions are node-local and never replicated, so a replica keeps enforcing while the primary is unreachable
Network & access policies
Decide who reaches your origin, and how.
- IPv4, IPv6, CIDR, ASN, and country pass, bypass, block, and challenge rules
- Site-wide default IP and country actions for allow and blocklists (ASN rules apply directly, with no default ASN action needed)
- Per-route IP, ASN, and country rules that override the site's for one path, like allowing a single trusted IP on an API endpoint
- Per-route access modes: inherit, challenge, bypass, or block
- Opt-in Tor exit-node and dynamic ASN category detection (VPN, proxy, datacenter/hosting, ISP/telecom, mobile carrier, and more), discovered from a published category list and refreshed daily
- Disabled, identify-only, or identify-and-block modes per category, set independently for each site, route, or TCP/UDP Stream
- Explicit IP/CIDR and ASN allow rules take precedence over automatic privacy-category blocking
- Access lists with global users, Argon2id password hashing, and rate-limited logins
- TOTP and WebAuthn (security key) two-factor authentication, with per-site key scoping for access lists, plus OIDC SSO with back-channel logout
Rate limiting & request limits
Layered limits at the edge, not in your app.
- Fixed-window, sliding-window, and token-bucket rate limiters
- Identity by client IP, verified session, or a selected application header
- Counters shared across a policy or separated by path and method
- Request body, request-target, and combined header byte limits
- Violations rejected with
413,414, or431and logged as events - Per-site/per-route bandwidth-threshold auto-bans, independent of request-count limits
Load balancing & origin health
Multi-origin pools that heal themselves.
- Priority failover, round robin, and smooth weighted round robin
- Session affinity with deterministic client-IP fallback for sessionless requests
- Per-origin health checks, thresholds, and automatic unhealthy-origin removal
- Per-minute health-check latency graphs (min/average/max) with a timed-out-check percentage
- Optional 503 maintenance mode with
Retry-Afterwhen the whole pool is down - Per-origin trusted CA / BurrowGate-issued origin server certificate - works even when the origin can't verify client certificates
- Per-origin mTLS: BurrowGate can generate a client certificate for one-click download or use one from your own PKI, independent of origin certificate trust
-
Static file origins: serve a folder straight from disk instead of proxying to a backend, with a dashboard folder picker, clean URLs, SPA
fallback, range requests, and conditional
ETag/304responses - mixable with proxy origins in the same pool
Notifications
One dashboard for every site's and Stream's webhooks.
- Per-event-type subscriptions: origin up/down, pool up/down, host internet connectivity, system resource thresholds, and IP auto-bans
- ntfy, Slack, and Discord get rich, color-coded messages with structured fields and native timestamps. Anything else gets a signed generic JSON webhook
- Durable outbox with ordered exponential retries, so a stuck event can't be overtaken by a newer one to the same destination
- Paginated, filterable, sortable delivery log per site and per Stream, independent of whether delivery succeeded
Firewall Sync
Push BurrowGate's own IP blocks out to an external firewall.
- UniFi Controller (Zone-Based Firewall, via a managed Traffic Matching List), local nftables, OVH's per-IP edge firewall, and AWS VPC Network ACLs
- Global, deduplicated aggregation across every site and Stream, reconciled automatically every 10 seconds
- Per-provider entry cap with oldest-bans-first eviction when full
- Private/loopback ranges are never pushed, plus an admin-managed never-ban whitelist with one-click "use my current IP"
- Deleting a provider tears down its remote entries too - the nftables table, the UniFi traffic matching lists, the OVH firewall rules, or the AWS Network ACL entries
Safe static-asset caching
Bounded, process-memory caching with real safety checks.
- Entries isolated by site, route-policy version, URL query, and accepted encoding
- Per-site/per-route enable, TTL, object-size, and extension overrides
- Cookies, auth headers, range requests, and private responses bypass storage automatically
- Dashboard reports hit ratio, origin requests avoided, top paths, and memory usage
- Scoped purge by site, path prefix, or route policy
TCP & UDP streams
Proxy more than HTTP from the same gateway.
- Named streams shown throughout the dashboard instead of a bare port number
- Native TCP and UDP stream proxying independent of the HTTP path
- Optional incoming TCP TLS termination, or raw passthrough
- Incoming PROXY protocol v1 and v2 on TCP from configured load balancer IPs or CIDRs, including TLS connections
- Separate outgoing PROXY protocol forwarding to upstream servers, with v1 for TCP and v2 for TCP or UDP
- Live TCP connection lists and synthetic UDP peer sessions
- Connect, disconnect, and error logs with GeoIP-enriched client country and ASN
- Per-stream monitoring retention and bandwidth grouped by IP and port
- Optional per-stream TCP origin health checks with a connect-latency graph and webhook notifications
- Per-stream TCP/UDP bandwidth-threshold auto-bans, applied live without restarting the listener
- Port, forward target, certificate, and incoming or outgoing PROXY protocol changes can be scheduled along with TCP and UDP toggles
Monitoring & analytics
Full visibility, exportable to your existing stack.
- Paginated, filterable, sortable traffic, session, route, rule, and site monitoring
- Click any Recent Traffic row for full request detail, including captured bodies and headers when enabled, with a Resend action to replay it
- Optional per-site/per-route body capture, bounded by size and content type with a self-expiring window
- Optional per-site/per-route header capture, with default Authorization/Cookie/Set-Cookie redaction and a configurable extra redaction list
- Bandwidth split between client-side and upstream, by site, IP, protocol, and country
- Dedicated Host dashboard page with live-updating CPU, memory, disk, and network usage tiles (refresh rate configurable down to 1 second) alongside historical min/average/max graphs, working correctly in both bare-metal and Docker deployments
- Internet connectivity graph on the same page - pings public DNS resolvers directly from the host to tell a network blip from an origin problem, with threshold-based webhook alerts for both connectivity and resource usage
- Interactive GeoIP world map for requests and new sessions, plus a Top ASNs list by network provider
- Exact date-time range selection and drag-to-select directly on graphs, defaulting to the last 24 hours so opening the dashboard stays fast regardless of configured retention
- Prometheus and OpenTelemetry Collector export through an OpenMetrics endpoint
API access & automation
Use the same permission model outside the dashboard.
- Full-access bearer tokens authenticate as their owner and inherit that user's exact role and site/Stream permissions
- Administrators and members can create, list, and revoke their own full-access tokens, choosing an expiry when each token is created
- Live OpenAPI 3.2 JSON at
/_burrowgate/api/admin/openapi.json, with the requesting origin and complete admin paths - Separate administrator-created read-only tokens expose only aggregate site and system monitoring data
- Secrets are shown once, stored only as SHA-256 hashes, and replicated across High Availability nodes
Customization
Make BurrowGate's edge responses match your brand.
- Per-site HTML or JSON error responses with escaped, editable templates
- Custom HTML challenge pages, per challenge type as well as per site - each provider ships its own tailored default and documented hooks so controls can be restyled or remapped without forking the whole page
- Editable canvas colors and piece shape for the Snake, Slider, and Trace challenges, plus every visitor-facing challenge string translatable per site
- Per-provider Content-Security-Policy editor so a custom challenge page can load its own images, scripts, or fonts
- Request/response header policies with route-level overrides
- Per-site/per-route CORS policy, answering cross-origin preflight requests directly ahead of verification and access-list sign-in
- Custom responses cover network blocks, rate limits, and origin failures without touching successful traffic
Storage & deployment
Runs on infrastructure you already operate.
- SQLite by default, with PostgreSQL, MySQL, and MariaDB support via Bun.SQL
- Production-ready Docker Compose deployment with an optional GeoIP-updater profile
- Per-site traffic retention from 1 to 365 days with automatic maintenance cleanup
- Certificate and ACME private keys encrypted at rest with AES-256-GCM
- In-dashboard update notifications, checking GitHub Releases hourly for a newer stable version with release notes shown on click
High Availability
ExperimentalRun a cluster instead of a single instance, with no shared database.
- Primary/replica replication over an encrypted, certificate-pinned link - config changes reach every replica within about a second
- Every node keeps and serves from its own local database, so there's no network hop in the request hot path and no shared database to bottleneck or fail
- Automatic majority-quorum election and failover once a cluster has 3 or more nodes (a 2-node cluster promotes manually instead)
- Cluster epoch and quorum-loss self-fencing stop a stale or partitioned primary from staying writable once it's no longer authoritative
- Sessions, logins, and IP bans replicate from whichever node handles them, so the load balancer doesn't need sticky sessions
- Trusted incoming PROXY protocol keeps client IPs available behind a load balancer while allowing direct HA admin requests and health checks
- Add a node with a one-time join code from the Cluster dashboard tab - promote, forget, or monitor nodes from the same place, no env vars or restarts
One login for a separate frontend and API
Let BurrowGate handle passwords, TOTP/WebAuthn 2FA, and OIDC SSO while your frontend and backend consume a verified identity through a framework-neutral SDK.
Authenticate at the gateway
The browser signs in on the frontend site. BurrowGate applies its Access List, 2FA, and SSO policies before proxying the application.
Call the API normally
The browser SDK keeps a signed, short-lived assertion in memory. auth.fetch() refreshes it and adds the required header
automatically.
Verify on the backend
The backend SDK asks BurrowGate to validate the assertion and parent session, then exposes the verified user to application code.
Secure by design
The browser sees only an in-memory assertion. The site ID and verification token stay on the backend, cross-origin destinations are restricted, and logout revokes the BurrowGate session and clears local state.
Network policy precedence
When more than one rule could apply to a request, BurrowGate resolves it in a fixed, documented order.
The matching route's own rules
A route policy's IP/CIDR rules, ASN rules, country rules, and default actions are checked first, if it has any configured.
Longest matching IP or CIDR rule
The site's most specific network match, once the route has nothing to decide.
Explicit ASN rule
A configured rule for the request's network provider.
Explicit country rule
A configured rule for the request's GeoIP country.
Default country action
The site's fallback action when no explicit country rule matches.
Default IP action
The site's fallback action for unmatched IP addresses.
Route policy
Path and method-based access mode applies last, on top of network policy.
A route's rules can also loosen a site-wide block for that one path, such as letting a monitoring service through to a health check even though its IP is blocked everywhere else. Country and ASN policy each fail open independently when their database is unavailable - IP rules and the default IP action keep applying. Full precedence rules live in docs/NETWORK_POLICIES.md. Opt-in Tor/VPN/ASN privacy-network detection is evaluated as its own layer after this policy, with explicit IP/CIDR or ASN allow rules taking precedence over an automatic category block - see docs/NETWORK_PRIVACY.md.
Put BurrowGate in front of your first site
One Docker Compose file and a domain is all it takes to get started.