Releases: jbarwick/Gatesentry
v2.0.0-alpha.15
Architecture 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:8080v1.20.6.3: fix: SSE zombie goroutine leak causing CPU/RAM spiral
fix: SSE zombie goroutine leak causing CPU/RAM spiral
The DNS events SSE handler (GET /api/dns/events) had no mechanism to
detect silently disconnected TCP connections. When a browser tab closed
without a clean TCP FIN (laptop sleep, network drop, browser crash),
the handler goroutine blocked forever on the channel select — becoming
a zombie. Each browser reconnect spawned a new goroutine while old ones
accumulated, causing 250%+ CPU and excessive RAM usage.
Fix:
- Add 30-second heartbeat writer (SSE comment) that detects dead
connections via write error, allowing the goroutine to exit - Add 4-hour max duration timer that forces a clean reconnect,
preventing indefinite goroutine lifetime - Backported from v2 branch
Version bump to 1.20.6.3
v1.20.6.2 - DNS Cache Performance & Test Coverage
DNS Cache & Testing Infrastructure Improvements
Version: 1.20.6.2
Date: February 11, 2026
Overview
This PR delivers DNS cache performance improvements, comprehensive test coverage, and critical bug fixes that make GateSentry production-ready. Filter reload bugs have been fixed, and the test suite now covers all critical functionality.
Key Features
1. DNS Cache Infrastructure
Cache Hit Rate Improvements
- Implemented per-minute cache statistics recording to BuntDB
- Added real-time SSE event streaming for live cache monitoring
- New
/api/dns/cache/stats/historyendpoint for historical data - Cache snapshots persist across restarts (24-hour retention)
Live Monitoring Dashboard
- New DNS Cache tab in Stats view with real-time updates
- Visualizations: hit rate, entries, evictions, expired entries
- Rolling 1-hour metrics with per-minute granularity
- Stacked area chart showing hits vs misses over time
Technical Implementation:
recorder.go: Periodic snapshot writer (1-minute intervals)- Per-minute counters reset after each snapshot
- Sliding window query support (1h, 24h, 7d views)
- Zero extra file handles (reuses existing BuntDB instance)
2. Critical Bug Fixes
Filter Reload Bug (CRITICAL)
- Issue: Filter updates via API were saved to disk but never reloaded
- Root Cause:
R.Init()created a new slice, breaking webserver's pointer reference - Fix: Modified runtime reload to clear and repopulate existing slice
- Impact: Keywords, URL blocks, and all filter updates now work correctly
- Files Changed: application/runtime.go
Port Configuration
- Changed Makefile to use port 8080 (non-privileged) for testing
- Added
GS_ADMIN_PORT=8080environment variable support - Fixes test failures when running without root privileges
Certificate Naming
- Updated auto-generated certificate to use "GateSentry CA" common name
- Fixed test expectations in both test suites
- Consistent with new certificate auto-generation feature
3. Certificate Management
One-Click CA Generation
- New
/api/certificate/generateendpoint - 4096-bit RSA certificates, 10-year validity
- Admin UI button for certificate regeneration
- Automatic PEM saving to settings storage
- Immediate proxy certificate reload on update
Enhanced Download Experience
- Certificate downloads as
.crtfile with proper MIME type - Updated UI with certificate status badges (Valid/Expiring/Expired)
- Expiry warnings when < 90 days remain
- Comprehensive installation instructions for Windows/macOS/Linux
Files Changed:
4. WPAD/PAC Auto-Configuration
Automatic Proxy Discovery
- WPAD DNS interception toggle (responds to
wpad.*queries) - PAC file generation and serving at
/wpad.datand/proxy.pac - Admin-configurable proxy host and port
- Auto-detection of proxy host from admin login
- Unauthenticated PAC file access (required by WPAD spec)
PAC File Features:
- Bypass proxy for localhost and RFC 1918 private networks
- Bypass proxy for GateSentry admin UI itself
- Safe fallback to DIRECT when not configured
Admin UI:
- New WPAD settings section with configuration form
- Live PAC file preview
- Setup guide for automatic and manual configuration
- Status indicators (configured/not configured)
Files Changed:
- handler_wpad.go (NEW)
- wpadSettings.svelte (NEW)
- handler_settings.go
5. Comprehensive Test Coverage
New Test: Keyword Content Blocking
- End-to-end test for HTML keyword filtering (310 lines)
- Tests filter POST → save → reload → actual blocking
- Proper cleanup and state restoration
- Files: tests/keyword_content_blocking_test.go
Test Infrastructure Improvements:
- Fixed port configuration for non-root testing
- All 8 test suites now pass (100% pass rate)
- External server tests properly configured
- Certificate name expectations updated
Test Results:
✓ auth_filters_test.go - Authentication & filter API access
✓ keyword_content_blocking_test.go - End-to-end keyword blocking (NEW)
✓ proxy_filtering_test.go - URL blocking filters
✓ integration_test.go - DNS server functionality
✓ integration_test.go - Statistics & logging
✓ integration_test.go - MIME type filtering
✓ user_management_test.go - User CRUD operations
✓ setup_test.go - Certificate validation
6. Enhanced Statistics API
Time-Scale Support:
/api/stats/byUrlnow acceptssecondsandgroupparameters- Granularity options: day (7d), hour (24h), minute (1h)
- Local-time bucket keys prevent UTC/timezone mismatches
- Frontend can request matching data for any time scale
Real-Time Event Streaming:
- SSE endpoint serves DNS queries and cache events
- Event types:
request,query,hit,miss,evict,expire - Frontend subscribes once, receives all event types
- Automatic pruning of events older than 7 days
Chart Improvements:
- Fixed x-axis domain to always show full time window
- Proper handling of sparse data (shows empty buckets)
- Sliding window for cache chart (last 60 minutes)
- Color-coded series (green for hits, red for misses/blocks)
Files Changed:
7. Status API Enhancements
Improved Network Detection:
- New
detectLanIP()function returns first non-loopback IPv4 address - Falls back to
wpad_proxy_hostsetting (preferred) - Last resort uses legacy bound address
- Fixes issues with incorrect
127.0.1.1reporting on some systems
Extended Status Response:
- Returns separate
dns_address,dns_port,proxy_port,proxy_url - Frontend displays "Host: X — DNS port Y, Proxy port Z"
- Clearer separation of DNS vs proxy configuration
Files Changed:
8. CORS Middleware
Cross-Origin Support:
- New CORS middleware echoes
Originheader - Allows access from multiple device hostnames
- Required for accessing GateSentry from different addresses
(e.g.,monster-jj,monster-jj.local,192.168.1.x, etc.) - Handles preflight
OPTIONSrequests
Files Changed:
9. Build & Runtime Improvements
Build Script Optimization:
build.shnow usesfind -deleteto preserve data files- Only removes binaries, keeps log databases and filter state
- Prevents accidental data loss during rebuilds
Makefile Updates:
- Port 8080 default for non-root development
GS_ADMIN_PORTenvironment variable support- Health check URL matches configured port
Script Improvements:
- New
restart.shfor graceful server restarts - Proper process detection and cleanup
- Environment variable preservation
Files Changed:
- build.sh
- run.sh
- Makefile (port configuration)
- restart.sh (NEW)
10. UI Polish
Logs View:
- DNS response types now shown with proper tags
- Cached queries display with teal badge
- Improved handling of DNS vs proxy events
- Raspberry Pi SD card warning converted to inline notification
Settings View:
- Integrated WPAD configuration section
- Certificate management improvements
- Better visual hierarchy and spacing
Home View:
- Status display shows separate DNS and proxy ports
- Clearer "starting..." state vs configured state
- Improved server address presentation
Files Changed:
Breaking Changes
None. All changes are backward compatible.
Migration Notes
- Existing filters and configuration will be preserved
- Cache statistics begin accumulating after upgrade
- Certificate regeneration is optional (existing certificates continue working)
- WPAD is disabled by default until configured
Testing
All tests pass:
$ make test
=== RUN TestAuthAndFilters
--- PASS: TestAuthAndFilters (2.34s)
=== RUN TestKeywordContentBlocking
--- PASS: TestKeywordContentBlocking (8.12s)
=== RUN TestProxyFiltering
--- PASS: TestProxyFiltering (3.45s)
=== RUN TestDNSServer
--- PASS: TestDNSServer (1.23s)
=== RUN TestStatisticsAndLogging
--- PASS: TestStatisticsAndLogging (2.01s)
=== RUN TestMIMETypeFiltering
--- PASS: TestMIMETypeFiltering (1.89s)
=== RUN TestUserManagement
--- PASS: TestUserManagement (1.67s)
=== RUN TestCertificateValidation
--- PASS: TestCertificateValidation (0.56s)
PASS
ok bitbucket.org/abdullah_irfan/gatesentryf/tests 21.27sDocumentation Updates
- README.md: Unchanged (existing installation instructions remain valid)
- CHANGELOG.md: Entry added for v1.20.6.2
- This document (DNS_CACHE_FEATURE.md): Comprehensive feature documentation
Files Changed Summary
Backend (Go):
application/dns/cache/recorder.go(NEW) - Cache statistics recorderapplication/dns/cache/recorder_test.go(NEW) - Recorder testsapplication/runtime.go- Fixed filter reload bugapplication/webserver/endpoints/handler_certificate.go- CA generation- `application/webserver/endpoints/handler_dns...
v1.20.6.1 — Device Discovery Service
What's New in v1.20.6.1
Based on upstream v1.20.6 with the following additions:
DNS Server Improvements
- Fixed concurrent query blocking and data races
- TCP query forwarding and truncated UDP retry over TCP
- IPv6 resolver and listen address support
- Environment-configurable DNS resolver (
DNS_RESOLVER)
Device Discovery Service (Issue #1)
- Passive discovery — automatically tracks devices from DNS queries
- mDNS/Bonjour browser — discovers devices on the LAN via multicast DNS
- RFC 2136 Dynamic DNS UPDATE — accepts dynamic DNS registrations with optional TSIG auth
- Device data model with hostname, IP, MAC, vendor, and source tracking
- Thread-safe record store with TTL-based expiry
Docker Deployment
- Production-ready Dockerfile and docker-compose.yml
- Configurable base path via
GATESENTRY_BASE_PATH - Admin port consolidation (single port for proxy admin + web UI)
Admin UI
- New Devices page for viewing discovered network devices
/api/devicesREST endpoint- Base path support for reverse proxy deployments
Testing
- 30+ new unit tests for device store, DNS handler, and mDNS browser
- Cross-platform test script improvements