Skip to main content

Documentation Index

Fetch the complete documentation index at: https://wiki.krkn.tech/llms.txt

Use this file to discover all available pages before exploring further.

Transparent GIF

Aegis — Web Application Firewall & Reverse Proxy Manager

Aegis is a production-grade Web Application Firewall (WAF) and Reverse Proxy Manager written in Go. It combines the host management experience of Nginx Proxy Manager with a full WAF engine that evaluates a customizable set of rules including the OWASP Top 10 and other malicious payloads on every proxied request. Single binary. SQLite storage. Zero dependencies. Aegis ships as a single static binary with an embedded admin UI, uses SQLite (WAL mode) for all persistent storage, and binds the admin dashboard to 127.0.0.1:9443 by default for security. No Nginx, no Docker, no external database required — just run the binary and start adding hosts. Image

Design Principles

  • NPM replacement — domain-based routing, load balancing, SSL/TLS termination, health checks, and WebSocket proxying without needing a separate reverse proxy
  • Per-host WAF profiles — each proxy host independently runs in off, detect, or enforce mode with its own rule chain
  • Zero-lock hot path — atomic pointer swaps for config, channel-buffered log writes, per-bucket rate limiters; no mutex on the request path
  • First-run setup wizard — no default credentials; forces secure initialization on first launch

WAF Paranoia Level

The paranoia level is a global setting that controls which WAF rules are active across all proxy hosts. Every built-in and imported rule is tagged with a paranoia level from 1 to 4. When you set the global paranoia level, all rules at or below that level are automatically enabled, and all rules above it are automatically disabled.

Paranoia Levels

LevelSensitivityDescription
1LowCore detection rules only — minimal false positives, catches obvious attacks
2Standard (default)Balanced detection — recommended for most deployments
3HighAggressive detection — catches more sophisticated attack variants, may produce false positives on complex applications
4MaximumAll rules enabled — highest sensitivity, expect false positives that require tuning

How It Works

When the paranoia level is changed (via Settings or during initial setup), Aegis executes a bulk update across all rules:
  • Rules with paranoia <= level are enabled
  • Rules with paranoia > level are disabled
  • This only affects rules in inherit mode (the default)
At runtime, the WAF engine skips any rule whose paranoia level exceeds the host’s configured level, so the rule chain only evaluates rules that should be active.

Per-Rule Override (Manual Mode)

Individual rules can be switched to manual paranoia mode, which opts them out of the global paranoia system entirely. A manual rule’s enabled/disabled state is controlled only by its own toggle — changing the global paranoia level will not affect it. This is useful for:
  • Keeping a specific high-paranoia rule enabled even when the global level is low
  • Disabling a rule that causes false positives without lowering the global paranoia level
  • Custom rules that should always be active regardless of the global setting
Paranoia ModeBehavior
inherit (default)Rule follows the global paranoia level — enabled when rule.paranoia <= global_level
manualRule ignores the global paranoia level — enabled/disabled by its own toggle only

Configuration

  • Location: Admin UI -> Settings -> WAF Paranoia Level
  • Setting key: waf_paranoia_level
  • Default: 2
  • Range: 1–4
  • API: PUT /api/v1/settings with {"waf_paranoia_level": "3"}
Changing the paranoia level takes effect immediately — Aegis updates all inherited rules in SQLite and reloads the proxy rule chains without a restart.

Feature Overview

Reverse Proxy

NPM-equivalent multi-host routing, load balancing, SSL/TLS, WebSocket proxying

WAF Engine

26 built-in OWASP rules, rate limiting, IP blacklists/whitelists, CORS enforcement

Allow Lists

IP/CIDR, local auth, OAuth/OIDC SSO, Active Directory access control

DDoS Protection

Kernel-level XDP/eBPF packet filtering — ban maps, rate limiting, SYN flood protection

Bot & AI Protection

AI crawler blocking, robots.txt generation, scanner detection

Aegis Shield

Built-in challenge system — proof-of-work, browser verification, interactive checkbox

Mnemos

Stateful multi-request correlation engine for detecting attack campaigns

Custom Rules

Condition builder, raw regex, and correlated rule authoring with live testing

Certificates

Let’s Encrypt, Cloudflare Origin CA, custom upload, SNI routing, key encryption

mTLS Upstream

Mutual TLS for upstream connections — client certificates, custom CAs, zero-trust backends

Canary Deployments

Gradual traffic splitting with automatic rollback based on error rates and latency

Defense Schemas

Ingest OpenAPI 3.x or Swagger 2.0 specs to auto-generate per-endpoint defense rules

HA Sync

Automatic failover between two Aegis instances with virtual IP and real-time config replication

Protocol Streams

TCP/UDP streaming proxy with TLS termination, bandwidth limits, and access control

CLI & Operations

CLI reference, configuration, service management, environment variables

API Reference

Full REST API for hosts, rules, traffic, analytics, SMTP, and system management

Quick Start

Build from source

git clone https://github.com/KrakenTech-LLC/aegis.git
cd aegis
go build -o aegis ./cmd/aegis/

First run

./aegis run
On first launch, Aegis starts in setup mode. Open http://127.0.0.1:9443 in your browser to run the setup wizard, which prompts for:
  1. Admin username and password (minimum 12 characters)
  2. Email address (for magic link authentication, optional)
  3. SMTP configuration (optional, enables passwordless login and alerts)
After setup completes, the default WAF rules are seeded into SQLite and the proxy begins listening.

Default Listeners

ServiceDefault AddressDescription
Admin UI127.0.0.1:9443Dashboard and API (localhost only)
HTTP Proxy:80Inbound HTTP traffic + ACME HTTP-01 challenges
HTTPS Proxy:443Inbound HTTPS traffic with TLS termination

Architecture

                  +-------------------------------------+
   Clients -----►|            Aegis (Go)               |
                  |                                     |
                  |  +-----------+   +---------------+  |
                  |  |  Reverse  |   |   WAF Engine  |  |
                  |  |  Proxy    |◄-|  (per-host    |  |
                  |  |  Router   |   |  rule chains) |  |
                  |  +-----+-----+   +---------------+  |
                  |        |                            |
                  |  +-----v-----+   +---------------+  |
                  |  |  Upstream |   |  Admin Web UI |  |
                  |  |  Backends |   |  (localhost)  |  |
                  |  +-----------+   +---------------+  |
                  |        |                            |
                  |  +-----v-------------------------+  |
                  |  |        SQLite Storage         |  |
                  |  +-------------------------------+  |
                  +-------------------------------------+

Request Lifecycle

Client
  |
  v
TLS Termination (autocert / custom cert via SNI)
  |
  v
Host Lookup (domain -> runtimeHost via atomic.Pointer)
  |
  v
Aegis Shield Challenge (if enabled, check aegis_shield cookie)
  |
  v
WAF Mode Check ──► "off" ──► skip directly to Reverse Proxy
  |
  v (detect / enforce)
IP Whitelist ──► match ──► suppress enforcement (detect-only)
  |
  v
IP Timeouts ──► active timeout ──► block (temporary auto-block)
  |
  v
IP Blacklist ──► match ──► block (enforce) or log (detect)
  |
  v
Method Restriction
  |
  v
Body Size Check
  |
  v
CORS Origin Validation
  |
  v
Rate Limiting (token bucket)
  |
  v
Rule Chain Evaluation (26 compiled regex rules)
  |
  v
Mnemos Correlation (multi-request campaign detection)
  |
  v
Reverse Proxy (httputil.ReverseProxy with load balancing)
  |
  v
Response Filtering (strip headers, inject security headers, SameSite cookies)
  |
  v
Client Response

Concurrency Model

  • Goroutine per request — Go’s net/http.Server default model
  • Atomic config readsatomic.Pointer[map[string]*runtimeHost] for zero-lock host lookups
  • Per-bucket rate limitingsync.Map of token buckets with per-bucket sync.Mutex
  • Buffered log writes — request logs sent to a buffered channel, batch-inserted by a background goroutine
  • Background health checks — periodic goroutine checks upstream health without blocking requests

Building

From source

go build -o aegis ./cmd/aegis/

With version injection

go build -ldflags "-X main.version=1.0.0" -o aegis ./cmd/aegis/

Requirements

  • Go 1.22 or later
  • No CGO required (uses modernc.org/sqlite, a pure Go SQLite implementation)

Dependencies

ModulePurpose
modernc.org/sqlitePure Go SQLite driver (no CGO)
golang.org/x/cryptobcrypt password hashing, ACME/autocert for Let’s Encrypt
gopkg.in/yaml.v3YAML configuration file parsing
github.com/cilium/ebpfeBPF program management for kernel-level DDoS protection
github.com/oschwald/maxminddb-golang/v2Embedded GeoLite2 database reader for geolocation

Logs & Retention

Aegis stores traffic request logs and admin audit logs in SQLite. A background rotation cycle runs hourly to manage log retention, optional archiving, and cleanup.
Image

Retention Settings

SettingKeyDefaultDescription
Traffic log retentionlogging.traffic_retention_days30Days to keep traffic/request logs before deletion or archiving
Audit log retentionlogging.audit_retention_days30Days to keep admin audit log entries
Archive enabledlogging.traffic_archive_enabledfalseArchive expired traffic logs to ZIP files instead of deleting directly
Archive retentionlogging.traffic_archive_retention_days90Days to keep archived ZIP files before deletion
All settings are configurable in Admin UI -> Settings.

How Log Rotation Works

Every hour, the log rotation cycle runs:
  1. Traffic logs older than retention period — either archived to ZIP (if archiving enabled) or deleted directly
  2. Archived ZIP files older than archive retention — deleted from disk
  3. Audit logs older than retention period — pruned from SQLite
When archiving is enabled, expired traffic logs are batch-exported (500 records per batch) to traffic-{date}-{timestamp}.zip files containing traffic.jsonl (newline-delimited JSON). This preserves a compressed historical record while keeping the SQLite database lean.

Log Types

LogContentsStorage
Traffic logEvery proxied request — host, source IP, method, path, status, action, matched rule, headers, WAF details, latencySQLite request_log table
Audit logEvery admin action — user, action type, resource ID, description, timestampSQLite audit_log table
Structured application logServer runtime events — JSON output via slogstdout/stderr

Authentication

  • Password-based login with bcrypt hashing (minimum 12 characters)
  • Passwordless magic link authentication via email
  • Backup email address support
  • Per-session CSRF token protection
  • Session cookies with HttpOnly, Secure, SameSite=Strict

Notifications

  • SMTP sending profile management (create, update, delete, test connection)
  • Encrypted SMTP password storage (AES-256-GCM)
  • Magic link authentication emails
  • Alert notification emails
  • Configurable From name and address

Admin Dashboard

  • Real-time traffic analytics (request counts, block rates, 24h stats)
  • Top attacker IPs with request and block counts
  • Top attacked hosts breakdown
  • Attack trend timeline with allowed/blocked/detected bucketing
  • Rule effectiveness stats (hits per rule)
  • Geographic analytics with country enrichment and local cache
  • Live traffic streaming via Server-Sent Events (SSE)
  • Audit log of all admin actions