diff --git a/README.md b/README.md index 0a23164..905ccab 100644 --- a/README.md +++ b/README.md @@ -42,54 +42,22 @@ ### 2. Start the gateway ```bash +mkdir aegis && cd aegis + +curl -O https://raw.githubusercontent.com/axieyangb/aegis/main/docker-compose.yml +mkdir envoy +curl -o envoy/envoy.yaml https://raw.githubusercontent.com/axieyangb/aegis/main/envoy/envoy.yaml +``` + +Edit `docker-compose.yml` and change `ADMIN_PASSWORD=changeme` to something secure, then: + +```bash docker compose up -d ``` -* Open **`http://localhost:8765`** β€” default login: `admin` / `changeme` (Change `ADMIN_PASSWORD` in `docker-compose.yml`, or change it in **Settings β†’ Auth** after logging in!). +Open **`http://localhost:8765`** β€” default login: `admin` / `changeme` (or the password you set). -### 3. Import the baseline configuration - -* Go to the **Gateway** page in the dashboard. -* Click the **Import** button at the top right. -* Upload the `configs/starter.json` file you downloaded. -* You should see the `http_listener` and `https_listener` appear, and the xDS sync status turn green! - - ---- - -## Simulating Traffic & Live Demo - -If you are running Aegis locally without real traffic, you can use our built-in **Traffic Demo Generator** script. We provide a pre-configured **`configs/demo.json`** database baseline that has the **PROXY Protocol enabled out-of-the-box** so you can run the demo with zero manual setup! - -### 1. Start the Gateway & Import Demo Configuration -1. Ensure your containers are running (`docker compose up -d`). -2. Open the Aegis Dashboard (`http://localhost:8765`). -3. Go to the **Gateway** page, click the **Import** button (top right), and upload **`configs/demo.json`** (instead of `starter.json`). - * *(Optional: If you downloaded the quick-start files via curl, you can download the demo config using: `curl -o configs/demo.json https://raw.githubusercontent.com/axieyangb/aegis/main/configs/demo.json`)* - * This automatically configures Envoy's HTTP listener to accept spoofed client IPs via PROXY Protocol. - -### 2. Download and Run the Generator - -If you didn't clone the repository, you can download the self-contained Python script first: -```bash -mkdir -p scripts -curl -o scripts/demo_generator.py https://raw.githubusercontent.com/axieyangb/aegis/main/scripts/demo_generator.py -``` - -Then, run the generator from the repository root: -```bash -python3 scripts/demo_generator.py -``` - - -### 3. Watch the Dashboard Live! -Open your dashboard and watch: -* **World Traffic Map:** populating with requests flowing in from USA, Japan, Germany, Brazil, and Australia. -* **Charts:** Device breakdowns, User-Agents, and HTTP Status codes filling up dynamically. -* **Scanner Bot:** A simulated bot crawler probing admin endpoints (like `/wp-admin` or `/.env`), raising the anomaly charts. -* **AI Auto-Blocking in Action:** An attacker (`99.99.99.99`) will launch a SQL injection attack. You will see Aegis's AI engine detect it, trigger an alert, and **push a dynamic xDS block rule to Envoy**. Instantly, all subsequent requests from `99.99.99.99` will start failing (dropped connections) on the dashboard! - -πŸ‘‰ **For a detailed breakdown of how the generator simulates traffic and auto-blocking under the hood, see the [Traffic Generator Guide](scripts/README.md).** +On first boot, Aegis automatically seeds a working gateway baseline β€” HTTP listener (port 10080) and HTTPS listener (port 10443) β€” ready to accept filter chains. No file import required. --- @@ -145,7 +113,7 @@ | πŸ“Š | **Real-time Analytics** | Live request feed, top IPs, world map, device + status breakdown | | πŸ€– | **AI Threat Analysis** | Background IP classification using Gemini / Claude / GPT / Ollama. Auto-blocks attackers | | πŸ¦‰ | **Owl AI Assistant** | Chat with your gateway β€” ask about traffic, threats, config, anything | -| πŸ”’ | **TLS Automation** | ACME (Let's Encrypt, ZeroSSL), HTTP-01 & DNS-01 challenges, auto-renewal via Envoy SDS | +| πŸ”’ | **TLS Automation** | ACME (Let's Encrypt, ZeroSSL), HTTP-01 & DNS-01, auto-renewal via Envoy SDS. Built-in Local CA for internal services β€” no domain or open ports required | | πŸ”” | **Notifications** | Telegram, Discord, Slack webhooks β€” alert on blocks, anomalies, daily digest | | 🌍 | **Geo Analytics** | Country-level traffic breakdown, remote or local MaxMind GeoIP | | πŸ”‘ | **Auth & SSO** | Built-in login + optional OIDC/SSO (Google, Authentik, Keycloak, etc.) | @@ -167,22 +135,30 @@ β”‚ xDS CP β”‚ controls Envoy live β”‚ Analyticsβ”‚ reads Envoy ALS logs β”‚ AI Engineβ”‚ classifies IPs - β”‚ Cert Mgr β”‚ ACME β†’ Envoy SDS + β”‚ Cert Mgr β”‚ ACME + Local CA β†’ Envoy SDS β”‚ Dashboardβ”‚ web UI + REST API β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` --- -## Deployment Options (Exposing Envoy) +## TLS Certificates -Depending on your network environment, Aegis supports three main deployment architectures to expose Envoy to the public internet: +### ACME (Let's Encrypt / ZeroSSL) -1. **Direct Exposure (Port Forwarding):** Best for environments with a static public IP. WAN ports `80`/`443` are forwarded directly from your home router to the host. -2. **VPS Relay Tunnel (PROXY Protocol):** Recommended for home labs, CGNAT, or privacy. Hides your home IP by tunneling traffic from a public VPS to Envoy, using the PROXY Protocol to safely preserve client IPs. -3. **Cloudflare Tunnel (HTTP Headers):** Best for zero-port-forwarding setups behind Cloudflare. Preserves client IPs by extracting custom Cloudflare HTTP headers. +For internet-exposed domains. Aegis handles the full ACME lifecycle β€” issue, challenge, and auto-renew β€” and pushes the certificate directly to Envoy SDS. Supports HTTP-01 and DNS-01 challenges (Cloudflare, Route 53, GoDaddy). -πŸ‘‰ **See the full [Deployment Architectures Guide](docs/deployment-architectures.md) for detailed diagrams, configuration, and setup instructions.** +### Local CA for internal / lab use + +No domain, no open ports, no external CA required. Aegis generates a self-signed ECDSA Root CA on first use and issues 1-year leaf certificates instantly. Ideal for: + +- Internal services and home lab setups +- Development and staging environments +- Proxying local services over TLS without exposing ports + +Go to **Certificates β†’ Signing Providers β†’ Add Provider**, choose **Local CA**, and issue a cert in seconds. Download the Root CA from the Certificates page to install it in your browser or OS trust store. + +**Bring your own CA**: If you already have a corporate or internal CA, you can import it β€” go to **Certificates β†’ Local CA β†’ Import CA** and upload your CA cert and private key. Aegis will use your CA to sign all leaf certs going forward. --- @@ -196,8 +172,8 @@ | `XDS_PORT` | `18000` | Envoy gRPC xDS port | | `DATA_DIR` | `/data` | Persistent data directory | | `ADMIN_USERNAME` | `admin` | Admin username | -| `ADMIN_PASSWORD` | `aegis` | Admin password β€” **change this** | -| `AUTH_ENABLED` | `true` | Require login. Set to `false` to bypass authentication (anonymous mode) | +| `ADMIN_PASSWORD` | `aegis` | Admin password (docker-compose.yml ships with `changeme`) β€” **change this** | +| `AUTH_ENABLED` | `true` | Require login | | `BLOCK_ENABLED` | `true` | Enable auto IP blocking | | `NODE_ID` | `home` | Envoy node ID (must match envoy.yaml) | @@ -216,10 +192,11 @@ ## Docs -* [Getting started](docs/getting-started.md) -* [Deployment Architectures (Exposing Envoy)](docs/deployment-architectures.md) -* [Sequence Diagrams (Flow References)](docs/sequence-diagrams.md) -* [Envoy configuration](docs/envoy-config.md) +- [Getting started](docs/getting-started.md) +- [Envoy configuration](docs/envoy-config.md) +- [Tutorial: Local HTTPS with whoami](docs/tutorial-whoami-local-https.md) +- [AI setup (Owl chat + threat analysis)](docs/ai-setup.md) +- [Notifications (Telegram, Discord, webhooks)](docs/notifications.md) --- diff --git a/configs/README.md b/configs/README.md new file mode 100644 index 0000000..fe0c208 --- /dev/null +++ b/configs/README.md @@ -0,0 +1,17 @@ +# Example Configurations + +This directory contains example Aegis database snapshots that can be imported via **Gateway β†’ Import**. + +> **Note**: On first boot, Aegis automatically seeds a working baseline configuration β€” an HTTP listener (port 10080), HTTPS listener (port 10443), and the `acme-renewer` cluster. You do not need to import any file to get started. + +These snapshots are useful when you need a non-standard starting point or want to replicate a specific topology. + +## After importing + +1. **Add your TLS certificates** β€” Certificates β†’ issue via ACME or Local CA +2. **Update filter chains** β€” edit `https_listener` to add your domain's SNI match, cluster, and TLS secret +3. **Point clusters at your services** β€” add clusters for each upstream service + +## Secrets are not included + +TLS private keys are never exported or committed to source control. Add them via the Certificates page after importing. diff --git a/configs/starter.json b/configs/starter.json deleted file mode 100644 index 76607b0..0000000 --- a/configs/starter.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": 1, - "exported_at": "2026-01-01T00:00:00Z", - "listeners": [ - { - "name": "http_listener", - "json_body": "{\"name\": \"http_listener\", \"address\": {\"socketAddress\": {\"address\": \"0.0.0.0\", \"portValue\": 10080}}, \"filterChains\": [{\"filters\": [{\"name\": \"envoy.filters.network.http_connection_manager\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\", \"statPrefix\": \"ingress_http\", \"routeConfig\": {\"virtualHosts\": [{\"name\": \"redirect_to_https\", \"domains\": [\"*\"], \"routes\": [{\"match\": {\"prefix\": \"/.well-known/acme-challenge\"}, \"route\": {\"cluster\": \"acme-renewer\"}}, {\"match\": {\"prefix\": \"/\"}, \"redirect\": {\"httpsRedirect\": true}}]}]}, \"httpFilters\": [{\"name\": \"envoy.filters.http.router\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.filters.http.router.v3.Router\"}}]}}]}]}", - "enabled": true, - "updated_at": 0 - }, - { - "name": "https_listener", - "json_body": "{\"name\": \"https_listener\", \"address\": {\"socketAddress\": {\"address\": \"0.0.0.0\", \"portValue\": 10443}}, \"listenerFilters\": [{\"name\": \"envoy.filters.listener.tls_inspector\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector\"}}], \"filterChains\": [{\"filterChainMatch\": {\"serverNames\": [\"app.yourdomain.com\"]}, \"filters\": [{\"name\": \"envoy.filters.network.http_connection_manager\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\", \"statPrefix\": \"ingress_https\", \"routeConfig\": {\"virtualHosts\": [{\"name\": \"app_service\", \"domains\": [\"app.yourdomain.com\"], \"routes\": [{\"match\": {\"prefix\": \"/\"}, \"route\": {\"cluster\": \"my-service\", \"timeout\": \"0s\"}}]}]}, \"httpFilters\": [{\"name\": \"envoy.filters.http.router\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.filters.http.router.v3.Router\"}}], \"upgradeConfigs\": [{\"upgradeType\": \"websocket\"}]}}], \"transportSocket\": {\"name\": \"envoy.transport_sockets.tls\", \"typedConfig\": {\"@type\": \"type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext\", \"commonTlsContext\": {\"tlsCertificateSdsSecretConfigs\": [{\"name\": \"app_yourdomain_com\", \"sdsConfig\": {\"apiConfigSource\": {\"apiType\": \"GRPC\", \"transportApiVersion\": \"V3\", \"grpcServices\": [{\"envoyGrpc\": {\"clusterName\": \"xds_cluster\"}}]}, \"resourceApiVersion\": \"V3\"}}]}}}}]}", - "enabled": true, - "updated_at": 0 - } - ], - "clusters": [ - { - "name": "my-service", - "json_body": "{\"name\": \"my-service\", \"type\": \"STATIC\", \"connectTimeout\": \"0.25s\", \"loadAssignment\": {\"clusterName\": \"my-service\", \"endpoints\": [{\"lbEndpoints\": [{\"endpoint\": {\"address\": {\"socketAddress\": {\"address\": \"192.168.1.100\", \"portValue\": 8080}}}}]}]}}", - "enabled": true, - "updated_at": 0 - }, - { - "name": "acme-renewer", - "json_body": "{\"name\": \"acme-renewer\", \"type\": \"STRICT_DNS\", \"connectTimeout\": \"5s\", \"loadAssignment\": {\"clusterName\": \"acme-renewer\", \"endpoints\": [{\"lbEndpoints\": [{\"endpoint\": {\"address\": {\"socketAddress\": {\"address\": \"aegis-gateway\", \"portValue\": 8765}}}}]}]}}", - "enabled": true, - "updated_at": 0 - } - ], - "secrets": [], - "extension_configs": [] -} diff --git a/docker-compose.yml b/docker-compose.yml index 6e8db70..ebfcfb1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,7 @@ ports: - "80:10080" # HTTP β€” listeners in Aegis UI should bind to port 10080 - "443:10443" # HTTPS β€” listeners in Aegis UI should bind to port 10443 + - "9901:9901" # Envoy admin UI volumes: - ./envoy/envoy.yaml:/etc/envoy/envoy.yaml:ro command: @@ -31,14 +32,6 @@ - /etc/envoy/envoy.yaml - --log-level - warn - networks: - default: - aliases: - - envoy - -networks: - default: - driver: bridge volumes: aegis_data: diff --git a/docs/envoy-config.md b/docs/envoy-config.md index bbcc32e..ddb1439 100644 --- a/docs/envoy-config.md +++ b/docs/envoy-config.md @@ -1,49 +1,44 @@ # Envoy Configuration -Aegis controls Envoy via xDS (specifically using the ADS - Aggregated Discovery Service - protocol). You configure everything through the Aegis UI β€” no manual YAML editing required. +Aegis controls Envoy via xDS (specifically using the ADS β€” Aggregated Discovery Service β€” protocol). You configure everything through the Aegis UI β€” no manual YAML editing required. ## How it works -1. Envoy starts using a static bootstrap file (`envoy.yaml`) pointing it to Aegis. -2. Envoy connects to Aegis at `aegis:18000` (gRPC ADS). -3. Aegis pushes listeners, clusters, and secrets dynamically from its database. -4. Changes made in the Aegis UI take effect in Envoy within ~1 second. +1. Envoy starts using a static bootstrap file (`envoy.yaml`) pointing it to Aegis. +2. Envoy connects to Aegis at `aegis:18000` (gRPC ADS). +3. Aegis pushes listeners, clusters, and secrets dynamically from its database. +4. Changes made in the Aegis UI take effect in Envoy within ~1 second. ## Static bootstrap (`envoy.yaml`) Envoy needs a static bootstrap file to know where to find the xDS server. The provided `envoy/envoy.yaml` configures: -* **xDS server:** `aegis:18000` (using gRPC). -* **Node ID:** `home` (must match `NODE_ID` env var in Aegis). -* **Admin interface:** bound to port `9901` (internal or public as mapped in docker-compose). +- **xDS server:** `aegis:18000` (using gRPC ADS) +- **Node ID:** `home` (must match `NODE_ID` env var in Aegis) +- **Admin interface:** bound to port `9901` -**Do not add listeners or clusters to this bootstrap file.** They should be managed entirely through the Aegis Gateway UI (and are stored in Aegis's database). +**Do not add listeners or clusters to this bootstrap file.** They are managed entirely through the Aegis Gateway UI and stored in Aegis's database. -## Dynamic configuration (`starter.json`) +## Auto-bootstrap on first run -The `configs/starter.json` is **not** read by Envoy. It is an export of the Aegis database structure. When imported via the Aegis UI, it configures: +When Aegis starts with an empty database, it automatically seeds a standard baseline configuration: -* `http_listener` (port 10080): Redirects all standard HTTP traffic to HTTPS, but routes `/.well-known/acme-challenge` to the `acme-renewer` cluster. -* `https_listener` (port 10443): Placeholder for your SSL traffic with SNI matching. -* `acme-renewer` cluster: Points to Aegis's built-in ACME challenge responder. -* `my-service` cluster: Placeholder for your actual backend application. +| Resource | Name | Purpose | +|---|---|---| +| Listener | `http_listener` | Port 10080 β€” redirects HTTP to HTTPS, routes `/.well-known/acme-challenge/` to `acme-renewer` | +| Listener | `https_listener` | Port 10443 β€” SNI-based TLS termination, ready for filter chains | +| Cluster | `acme-renewer` | Routes ACME HTTP-01 challenge traffic back to Aegis | -Once imported, Aegis dynamically translates these into Envoy-native config and pushes them to Envoy over the xDS channel. +This means on first boot you get a working gateway skeleton immediately β€” no file import required. -## Exposing Envoy to Public Traffic (Port Mapping) +## Adding your own resources -To make your gateway accept real public traffic from the internet, you must understand how ports are mapped between your host machine and the Envoy container. +After the baseline is seeded, add your configuration through the Aegis UI: -### The Port Flow -``` -Internet ──► Host Port 80 ──────(Docker Map)─────► Container Port 10080 (Envoy HTTP Listener) -Internet ──► Host Port 443 ──────(Docker Map)─────► Container Port 10443 (Envoy HTTPS Listener) -``` +- **Gateway β†’ Clusters** β€” add upstream services +- **Gateway β†’ Listeners β†’ https_listener** β€” add filter chains (SNI + cluster + TLS secret) per domain +- **Certificates** β€” issue certs via ACME or Local CA; they are pushed to Envoy as SDS secrets automatically -1. **Docker Port Mapping:** In `docker-compose.yml`, the `envoy` service exposes ports `80` and `443` on the host, mapping them to `10080` and `10443` inside the container respectively. - * This is done because binding to privileged ports (< 1024) directly inside a container is restricted by default for security. -2. **UI Port Binding:** When you create or edit Listeners in the **Aegis UI**, you must bind them to the **container port**, NOT the host port: - * Your HTTP listener (handling redirects and ACME challenge) must bind to **`10080`**. - * Your HTTPS listener (handling secure SSL traffic) must bind to **`10443`**. -3. **Public Access:** Once the containers are running, simply point your domain's DNS `A` or `AAAA` records to your host machine's public IP address. Traffic arriving at port 80/443 will automatically flow through Envoy. +## Advanced: importing a custom baseline +If you need a non-standard starting configuration (e.g. a VPS relay setup with PROXY protocol), you can import a JSON configuration snapshot via **Gateway β†’ Import**. The `configs/` directory in the repo contains example configurations. diff --git a/docs/getting-started.md b/docs/getting-started.md index c0504a1..b30a527 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -3,9 +3,8 @@ ## Requirements - Docker and Docker Compose -- A domain pointing to your server (for TLS / ACME) - Port 8765 accessible on your local network (dashboard) -- Ports 80 and 443 open if you want Envoy to handle public traffic +- Ports 80 and 443 open if you want Envoy to handle public internet traffic ## 1. Download the starter files @@ -20,10 +19,6 @@ # Download Envoy bootstrap configuration mkdir envoy curl -o envoy/envoy.yaml https://raw.githubusercontent.com/axieyangb/aegis/main/envoy/envoy.yaml - -# Download baseline database configuration -mkdir configs -curl -o configs/starter.json https://raw.githubusercontent.com/axieyangb/aegis/main/configs/starter.json ``` ## 2. Set your admin password @@ -36,27 +31,62 @@ docker compose up -d ``` -* Aegis dashboard: `http://localhost:8765` -* Default login: `admin` / (your password) +- Aegis dashboard: `http://localhost:8765` +- Default login: `admin` / `changeme` (or the password you set in `ADMIN_PASSWORD`) -## 4. Connect Envoy to Aegis (Importing baseline) +On first boot, Aegis automatically seeds the database with a working baseline configuration β€” an HTTP listener (port 10080) that redirects to HTTPS and handles ACME challenges, and an HTTPS listener (port 10443) ready for SNI-based TLS routing. No file import required. -1. Open the Aegis dashboard in your browser. -2. Go to **Gateway** page. -3. Click the **Import** button at the top right. -4. Upload the `configs/starter.json` file you downloaded in Step 1. +## 4. Add your first service -This will seed Aegis's database with a standard baseline configuration (a port 80 listener that redirects to HTTPS and handles ACME challenges). Aegis will immediately generate the correct Envoy configuration and push it to Envoy via xDS. +**Configure a backend cluster:** -You should see **"xDS synced"** in green on the Gateway page, confirming Envoy has successfully connected and loaded the configuration! +Go to **Gateway β†’ Clusters** and add a cluster pointing to your upstream service (hostname/IP + port). -## 5. Add your first service +**Configure TLS:** -Go to **Gateway β†’ Clusters** to configure your backend services, and **Gateway β†’ Listeners** to edit the `https_listener` filter chains to route your domain to your new cluster. +- For an **internet-facing domain**: go to **Certificates β†’ Signing Providers**, add an ACME provider (Let's Encrypt), then issue a cert for your domain. See [TLS with ACME](#tls-with-acme-lets-encrypt) below. +- For an **internal or lab service**: use the built-in Local CA β€” no domain, no open ports required. See [Local CA](#local-ca-for-internal-use) below. -## 6. Expose your Gateway to the Internet +**Wire your domain to the listener:** -To accept public traffic from the internet, you need to expose Envoy's ports. Refer to the [Deployment Architectures Guide](deployment-architectures.md) to choose and configure your setup: -* **Direct Exposure (Port Forwarding):** For static public IP setups. -* **VPS Relay Tunnel (PROXY Protocol):** For CGNAT, home labs, or privacy-focused setups (highly recommended to preserve client IPs and prevent auto-blocking your own tunnel!). +Go to **Gateway β†’ Listeners β†’ https_listener** and add a filter chain for your domain: set the SNI match, point it to your cluster, and attach the TLS certificate secret. +You should see **"xDS synced"** in green on the Gateway page, confirming Envoy has loaded the configuration. + +--- + +## TLS with ACME (Let's Encrypt) + +For domains that are publicly reachable: + +1. Go to **Certificates β†’ Signing Providers β†’ Add Provider** +2. Choose **ACME**, select **Let's Encrypt**, set your email, and pick a challenge type: + - **HTTP-01** β€” easiest; requires port 80 open and domain pointing here + - **DNS-01** β€” works behind NAT; requires Cloudflare / Route 53 / GoDaddy API access +3. Go to **Certificates β†’ Managed Certs β†’ Issue Certificate**, choose your provider and domain +4. Aegis solves the challenge and pushes the cert to Envoy SDS automatically +5. Auto-renewal runs 30 days before expiry β€” no action needed + +--- + +## Local CA for internal use + +For internal services, home lab, or dev environments where you don't have a public domain: + +1. Go to **Certificates β†’ Signing Providers β†’ Add Provider**, choose **Local CA** +2. Go to **Certificates β†’ Managed Certs β†’ Issue Certificate**, select the Local CA provider and enter any hostname (e.g. `homelab.local`) +3. The cert is issued instantly and pushed to Envoy β€” no domain validation, no open ports +4. Download the **Root CA certificate** from the Certificates page and install it in your browser or OS trust store so the cert is trusted + +By default Aegis auto-generates a 10-year ECDSA Root CA on first use. If you already have your own CA (corporate PKI, internal CA), you can import it instead: go to **Certificates β†’ Local CA β†’ Import CA** and upload your CA certificate and private key in PEM format. Aegis will use your CA to sign all subsequent leaf certificates. + +All certs issued by the Local CA auto-renew via Aegis before expiry. + +--- + +## What's next + +- **Try the Local CA tutorial** β€” [Tutorial: Local HTTPS with whoami](tutorial-whoami-local-https.md) walks through adding a service, issuing a cert, and accessing it over HTTPS from your browser β€” a good end-to-end test of your setup +- **IP Intelligence** β€” enable AI classification in Settings β†’ AI to automatically profile and classify every IP that hits your gateway +- **Notifications** β€” connect Telegram, Slack, or a webhook in Settings β†’ Integrations to get alerted on threats and anomalies +- **Owl AI** β€” click the owl icon to chat with your gateway in plain language diff --git a/docs/tutorial-whoami-local-https.md b/docs/tutorial-whoami-local-https.md new file mode 100644 index 0000000..14b7fd8 --- /dev/null +++ b/docs/tutorial-whoami-local-https.md @@ -0,0 +1,170 @@ +# Tutorial: Local HTTPS with a whoami service + +> **Prerequisite:** Before starting this tutorial, make sure your Aegis gateway and Envoy are up and running. Follow the [Getting Started](getting-started.md) guide first β€” this tutorial picks up from a working gateway. + +This tutorial walks through deploying a simple whoami web service and exposing it over HTTPS through Envoy, using Aegis's built-in Local CA β€” no public domain or open ports required. + +**You will:** +1. Run a `whoami` container alongside Aegis + Envoy +2. Add a cluster and filter chain in Aegis +3. Issue a TLS certificate from the Local CA +4. Add a `/etc/hosts` entry +5. Access `https://whoami.local` from your browser + +--- + +## Prerequisites + +- Docker and Docker Compose installed +- Aegis + Envoy already running and accessible at `http://localhost:8765` +- Admin access to add an `/etc/hosts` entry on your machine + +--- + +## Step 1 β€” Run the whoami container + +Open your `docker-compose.yml` and add the `whoami` service under the `services:` block, alongside the existing `aegis` and `envoy` entries: + +```yaml + whoami: + image: traefik/whoami + container_name: whoami + restart: unless-stopped +``` + +No ports need to be published β€” Envoy will reach `whoami` over the internal Docker network. + +Apply the change: + +```bash +docker compose up -d whoami +``` + +--- + +## Step 2 β€” Add a cluster in Aegis + +Open the Aegis dashboard β†’ **Gateway β†’ Clusters β†’ Add Cluster**. + +| Field | Value | +|---|---| +| Name | `whoami` | +| Type | `STRICT_DNS` | +| Host | `whoami` _(Docker service name)_ | +| Port | `80` | +| Connect timeout | `5s` | + +Save β€” Aegis pushes the cluster to Envoy immediately. + +--- + +## Step 3 β€” Issue a Local CA certificate + +### 3a β€” Create a Local CA provider (first time only) + +Go to **Certificates β†’ Signing Providers β†’ Add Provider**, choose **Local CA**, give it a name (e.g. `Local CA`), and save. + +### 3b β€” Issue the certificate + +Go to **Certificates β†’ Managed Certs β†’ Issue Certificate**: + +| Field | Value | +|---|---| +| Domain | `whoami.local` | +| Provider | `Local CA` | +| Auto-renew | on | + +Click **Issue**. The cert is generated and pushed to Envoy SDS within a second. Note the **secret name** shown (e.g. `tls-whoami-local`). + +--- + +## Step 4 β€” Add a filter chain to the HTTPS listener + +Go to **Gateway β†’ Listeners β†’ `https_listener` β†’ Edit**. + +Click **Add Filter Chain** and fill in: + +| Field | Value | +|---|---| +| Domain(s) | `whoami.local` | +| Backend Cluster | `whoami` | +| TLS Secret | `tls-whoami-local` _(or the name shown on the cert page)_ | + +Leave Route Prefix as `/` and click **Add**. Envoy picks up the new filter chain within ~1 second. + +--- + +## Step 5 β€” Trust the Root CA + +Download the Root CA certificate: **Certificates β†’ Local CA β†’ Download CA** (saves `aegis-local-ca.crt`). + +**macOS:** +```bash +sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain aegis-local-ca.crt +``` + +**Linux:** +```bash +sudo cp aegis-local-ca.crt /usr/local/share/ca-certificates/aegis-local-ca.crt +sudo update-ca-certificates +``` + +**Windows:** double-click the `.crt` file β†’ Install Certificate β†’ Local Machine β†’ Trusted Root Certification Authorities. + +After installing the CA you may need to restart your browser. + +--- + +## Step 6 β€” Add an `/etc/hosts` entry + +Map `whoami.local` to the IP address of the machine running Envoy: + +- **Running on your local machine** β€” use `127.0.0.1` +- **Running on a NAS or remote server** β€” use that machine's LAN IP (e.g. `192.168.1.100`) + +```bash +# Local machine +echo "127.0.0.1 whoami.local" | sudo tee -a /etc/hosts + +# Or remote host (replace with actual IP) +echo "192.168.1.100 whoami.local" | sudo tee -a /etc/hosts +``` + +On Windows, edit `C:\Windows\System32\drivers\etc\hosts` as Administrator. + +--- + +## Step 7 β€” Open in browser + +Navigate to **`https://whoami.local`**. + +You should see the whoami response β€” hostname, IP, headers β€” served over HTTPS with a valid (locally trusted) certificate and no browser warning. + +--- + +## What just happened + +``` +Browser β†’ https://whoami.local:443 + β”‚ SNI = whoami.local + β–Ό + Envoy (port 10443) + β”‚ filter chain match: whoami.local + β”‚ TLS: cert from Aegis SDS (signed by Local CA) + β–Ό + whoami container (port 80) +``` + +Aegis issued the cert from its internal Root CA, pushed it to Envoy via xDS SDS, and Envoy presented it during the TLS handshake. Your browser trusted it because you installed the Root CA. + +--- + +## Cleanup + +To remove the setup: + +1. Delete the managed cert in Aegis β†’ Certificates +2. Remove the filter chain from `https_listener` +3. Delete the `whoami` cluster +4. Remove the `/etc/hosts` line +5. Stop the whoami container: `docker compose stop whoami` diff --git a/envoy/envoy.yaml b/envoy/envoy.yaml index fe0fd3f..7d5cb49 100644 --- a/envoy/envoy.yaml +++ b/envoy/envoy.yaml @@ -35,7 +35,7 @@ - endpoint: address: socket_address: - address: aegis-gateway + address: aegis port_value: 18000 admin: