Repository navigation
v2.0.0-alpha.15
Pre-releaseArchitecture Shift: Global β Per-User Rule-Based Filtering
The most significant change in v2 is moving away from global filter lists toward a fully rule-based filtering system.
In v1, proxy rules could already be defined for a user, and the rule system provided per-user targeting β that foundation was solid. However, the primary filtering mechanisms β blocked sites, exception lists, keyword filters, and DNS blocklists β operated as global pipelines that applied to everyone on the network identically. The per-user rules and the global filters were essentially two separate systems. Additionally, rules in v1 were strictly block rules β they could only deny access, not explicitly grant it.
In v2, those global filtering pipelines have been consolidated into the per-user rule system. There are no longer separate global blocked-site lists or global keyword filters running outside of rules. Instead, every filtering decision flows through the rule pipeline:
- Everything is a rule now β Blocked domains, URL patterns, content-type filtering, and keyword scanning are all configured as properties of individual rules rather than global lists. What was previously a global "blocked sites" list becomes a rule referencing a Domain List with action "block."
- Rules are match + action, not just block lists β Rules are no longer strictly "block" rules. Each rule is a matching rule with a configurable action: Allow or Block. Combined with priority ordering (lower number = higher priority, first match wins), this enables patterns that weren't possible before. For example, a high-priority "Allow" rule can grant a specific user access to
educational-site.comeven when a lower-priority "Block" rule blocks the entire category for everyone else. Exception lists become simply higher-priority Allow rules. - Per-user filtering becomes natural β Since all filtering is rule-scoped, targeting specific users is just a field on the rule. A "kids" rule can block adult content while an "adults" rule allows it. An empty user list means "all users."
- DNS filtering is now optional β Domain blocking no longer requires the DNS server. All filtering can be handled entirely by proxy rules. DNS blocking is still available for users who want network-wide domain-level filtering, but it's no longer the only mechanism.
- Reusable Domain Lists β Both DNS filtering and proxy rules share the same
DomainListManagerand in-memory index. A single curated list (StevenBlack, Hagezi, etc.) can be referenced by multiple rules and by DNS simultaneously.
8-Step Rule Pipeline
Each proxy request is evaluated through a well-defined pipeline, rule by rule in priority order. The first rule that fully matches is applied β subsequent rules are skipped:
- Rule status β Enabled/disabled, active hours schedule
- User match β Does the requesting user match the rule's user list?
- Domain match β Hostname checked against domain patterns (glob wildcards) and domain lists (by list ID)
- MITM resolution β Per-rule MITM setting:
enable,disable, ordefault(fall back to global setting). Determines whether steps 5β7 can inspect HTTPS traffic. - URL regex β Match against the full request URL (requires MITM for HTTPS)
- Content-type β Match against response Content-Type header (requires MITM for HTTPS)
- Keyword filter β Scan response body for blocked keywords with score watermark (requires MITM for HTTPS)
- Action β Allow or Block
If no rule matches after evaluating all rules, the request is allowed (default-allow). Because Allow rules participate in the same priority-ordered pipeline as Block rules, administrators can build layered policies: a broad Block rule at priority 100 blocking a category, with targeted Allow exceptions at priority 10 for specific users or domains.
Domain List System
A new DomainListManager provides CRUD operations, an O(1) in-memory index (map[domain] β set of list IDs), and support for both local lists and URL-sourced blocklists (StevenBlack, Hagezi, AdGuard, Firebog, etc.). DNS and proxy filtering share the same index. Includes automatic migration from the old blocklist format. Full API endpoints and a management UI at /domainlists.
Device Discovery (Foundation)
A new device discovery system using mDNS/Bonjour browsing and passive DNS observation lays the groundwork for per-device filtering in a future release. Devices are identified, tracked, and exposed via API. The data model and record store are in place (with 30+ tests), and the DNS handler already performs passive discovery. The next step would be allowing rules to target devices in addition to users.
Server-Side Rule Tester
Two new API endpoints (POST /api/test/rule-match, POST /api/test/domain-lookup) simulate the full 8-step pipeline against a rule definition without affecting live traffic. The rule editor UI has a built-in tester panel with optional live fetch to verify that a rule behaves as expected before saving.
Real-Time Stats and Logs via SSE
The stats page now uses Server-Sent Events for near-real-time updates, replacing the previous 5-second polling approach. DNS request events are emitted from the handler and streamed to the browser as they happen.
Proxy Hardening
- Streaming 3-path content router (small buffer / scan / stream-through) with configurable
GS_MAX_SCAN_SIZE_MB - Graceful shutdown with in-flight request draining
- Proxy loop detection (Via header + X-GateSentry-Loop + XFF depth limit)
- SSRF protection blocking proxy requests to the admin UI
- HTTPS block page delivery (MITM-signed error page for blocked HTTPS requests)
- WebSocket tunnel support
TRACEmethod blocking, response header sanitization
DNS Improvements
- Sharded response cache with configurable TTL and negative caching
- TCP query support (large responses > 512 bytes)
- RFC 2136 dynamic DNS update handler
- WPAD/PAC auto-configuration endpoints
- IPv6 listener support
- All settings configurable via environment variables
UI Overhaul
- Complete Svelte/Carbon rewrite of the rule form matching the 8-step pipeline layout
- New Domain Lists management page (
/domainlists) - DNS page with allow/block domain list assignment sections
- Configurable base path support for reverse proxy deployments
- Docker deployment support with
docker-compose.ymland publish script
Test Coverage
- 19 rule-tester endpoint unit tests, 19 domain list unit tests
- Comprehensive proxy deep test script (
scripts/proxy_deep_tests.sh) covering MITM, content filtering, keyword scanning, loop detection, and more
Breaking Changes from v1
- Admin UI default port:
10786β8080(configurable viaGS_ADMIN_PORT) - Rule struct expanded:
domain_patterns,domain_lists,mitm_action,url_regex_patterns,blocked_content_types,keyword_filter_enabled,active_hours,users - Settings keys added:
dns_domain_lists,dns_whitelist_domain_lists - Old global
blockedDomainsmap replaced by sharedDomainListIndex
How to Try It
git remote add jbarwick https://github.com/jbarwick/Gatesentry.git
git fetch jbarwick v2
git checkout jbarwick/v2
./build.sh && cd bin && ../run.sh
# Admin UI at http://localhost:8080