Network Security¶
This document details the network security architecture for Project Aegis.
Network Topology¶
Internet (0.0.0.0/0)
│
└─> Proxmox Host (157.180.63.15)
│
├─> Dockerhost LXC (10.10.10.10)
│ └─> Traefik Proxy (TCP Passthrough)
│ │
│ └─> Aegis LXC (10.10.10.103)
│ └─> Traefik Proxy (TLS Termination)
│ │
│ ├─> Dashboard (port 8080)
│ ├─> VS Code (port 8081)
│ ├─> VNC (port 5900 → 80)
│ ├─> FalkorDB Browser (port 3001)
│ └─> Playwright (port 3002)
│
└─> Tailscale VPN (100.114.189.93)
IP Address Allocation¶
| Host | IP Address | Network | Purpose |
|---|---|---|---|
| Proxmox (external) | 157.180.63.15 | Public | Hypervisor (public-facing) |
| Dockerhost LXC | 10.10.10.10 | Internal | Main Traefik reverse proxy |
| Aegis LXC | 10.10.10.103 | Internal | Aegis agent environment |
| Aegis (Tailscale) | 100.114.189.93 | VPN | Secure remote access |
Traffic Flow¶
Inbound HTTPS Request¶
1. User → 157.180.63.15:443 (Proxmox)
2. Proxmox → 10.10.10.10:443 (Dockerhost Traefik)
3. Dockerhost Traefik → 10.10.10.103:443 (Aegis Traefik, TCP passthrough)
4. Aegis Traefik → Terminates TLS, routes to backend (e.g., 8080)
5. Backend (dashboard) → Processes request
6. Response follows reverse path
Dockerhost Traefik Configuration¶
Purpose: TCP passthrough for SNI-based routing to Aegis LXC.
Configuration: /srv/dockerdata/traefik/dynamic/aegis-passthrough.yml (on Dockerhost)
tcp:
routers:
aegis-passthrough:
rule: "HostSNI(`aegisagent.ai`) || HostSNI(`*.aegisagent.ai`) || HostSNI(`aegis.rbnk.uk`) || HostSNI(`*.rbnk.uk`)"
entrypoints:
- websecure
service: aegis-lxc
tls:
passthrough: true
services:
aegis-lxc:
loadBalancer:
servers:
- address: "10.10.10.103:443"
Key Points:
- No TLS termination on Dockerhost (passthrough only)
- SNI inspection routes traffic based on hostname
- All aegisagent.ai and rbnk.uk traffic goes to Aegis LXC
Aegis Traefik Configuration¶
Purpose: TLS termination and HTTP routing to Docker containers.
Configuration: Traefik runs inside Aegis LXC, reads labels from docker-compose.yml.
Entrypoints:
Certificate Resolver:
certificatesResolvers:
cf:
acme:
email: aegis@aegisagent.ai
storage: /acme.json
dnsChallenge:
provider: cloudflare
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Example Service Labels (from docker-compose.yml):
labels:
- "traefik.enable=true"
- "traefik.http.routers.aegis.rule=Host(`aegisagent.ai`)"
- "traefik.http.routers.aegis.entrypoints=websecure"
- "traefik.http.routers.aegis.tls.certresolver=cf"
- "traefik.http.services.aegis.loadbalancer.server.port=8080"
Container Isolation¶
Docker Network¶
Network Name: traefik_proxy
Type: Bridge network (external)
Configuration:
Isolation:
- Containers on traefik_proxy can communicate with each other
- Containers without network cannot reach external network
- Host network access via host.docker.internal (PostgreSQL, FalkorDB, Ollama)
Container Security¶
User Privileges:
Security Considerations:
- root required to bind to docker.sock (container management)
- Volume mounts are read-only where possible (:ro suffix)
- No privileged mode enabled
- No host network mode (isolated via bridge)
Volume Mounts:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Read-only Docker access
- /home/agent/memory:/home/agent/memory # Read-write memory
- /home/agent/.secure:/home/agent/.secure:ro # Read-only credentials
Inter-Container Communication¶
Containers can communicate via Docker DNS:
# From dashboard container
curl http://playwright:3000/screenshot
curl http://falkordb:6379 # Redis protocol
Security: No authentication required between containers (trusted network).
TLS Configuration¶
Certificate Provisioning¶
Provider: Let's Encrypt via Cloudflare DNS-01 challenge
Domains Covered:
- aegisagent.ai
- *.aegisagent.ai (wildcard)
- rbnk.uk
- *.rbnk.uk (wildcard)
Renewal: Automatic via Traefik (checks daily, renews 30 days before expiry)
Storage: /acme.json in Traefik container (persists across restarts)
TLS Version and Ciphers¶
Minimum TLS Version: TLS 1.2 (Traefik default)
Cipher Suites: Mozilla Intermediate profile (Traefik default)
Example ciphers: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
HSTS: Not enabled (TODO: add middleware)
Recommended HSTS Configuration:
# Add to Traefik dynamic config
http:
middlewares:
hsts:
headers:
stsSeconds: 31536000
stsIncludeSubdomains: true
stsPreload: true
Certificate Monitoring¶
Manual Check:
# Check certificate expiry
echo | openssl s_client -connect aegisagent.ai:443 -servername aegisagent.ai 2>/dev/null | \
openssl x509 -noout -dates
# Expected output:
# notBefore=Jan 15 12:00:00 2026 GMT
# notAfter=Apr 15 12:00:00 2026 GMT
Automated Monitoring: Traefik logs certificate renewals.
Alert on Expiry: Consider adding to /monitor skill or cron job.
Firewall Rules¶
Proxmox Host Firewall¶
Status: Not managed by Aegis (host-level configuration)
Expected Rules:
- Allow 80/tcp (HTTP, redirect to HTTPS)
- Allow 443/tcp (HTTPS)
- Allow 22/tcp (SSH, restricted to admin IPs)
- Drop all other inbound traffic
Verification:
LXC Container Firewall¶
Status: No firewall configured (relies on Proxmox host)
Rationale: Aegis LXC is behind Proxmox host firewall (defense in depth).
Recommendation: Enable ufw for additional layer:
# Enable UFW on Aegis LXC
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
Docker Container Firewall¶
Status: Not applicable (containers use host network stack via bridge)
Network Policy: Docker bridge network provides isolation (containers cannot reach external network directly).
Internal Network (10.10.10.0/24)¶
Subnet Details¶
Network: 10.10.10.0/24 Gateway: 10.10.10.1 (Proxmox bridge) DHCP: Not used (static IPs)
Host List¶
| IP | Hostname | Services |
|---|---|---|
| 10.10.10.10 | dockerhost | Traefik, portainer, monitoring |
| 10.10.10.103 | aegis | Aegis agent, dashboard, Docker containers |
Inter-Host Communication¶
Aegis LXC can reach Dockerhost LXC directly:
Security: SSH key-based authentication only (no passwords).
SSH Config (~/.ssh/config):
Public vs Internal Services¶
Public Services (Internet-Facing)¶
| Service | URL | Port | TLS | Auth |
|---|---|---|---|---|
| Dashboard | https://aegisagent.ai | 8080 | Yes | None |
| Intel Dashboard | https://intel.aegisagent.ai | 8080 | Yes | None (free tier) |
| VS Code | https://code.aegisagent.ai | 8081 | Yes | Password |
| VNC | https://vnc.aegisagent.ai | 5900 | Yes | VNC password |
| Open Notebook | https://notebooks.aegisagent.ai | External | Yes | None |
| Notebook API | https://api.notebooks.aegisagent.ai | External | Yes | API key |
Internal Services (Localhost Only)¶
| Service | Port | Access | Purpose |
|---|---|---|---|
| PostgreSQL | 5432 | host.docker.internal | Database |
| FalkorDB | 6379 | host.docker.internal | Knowledge graph |
| FalkorDB Browser | 3001 | Localhost | Graph visualization |
| Ollama | 11434 | Localhost | Local LLM inference |
| Playwright | 3002 | Docker network | Screenshot API |
Security: Internal services are not routable from external network.
Docker Access Pattern:
Tailscale VPN¶
Configuration¶
Tailnet: rickoslyder@ Device Name: aegis IP Address: 100.114.189.93
Installation:
Status Check:
Access Control¶
ACLs: Managed in Tailscale admin console (not on Aegis LXC)
Default Policy: Allow all traffic within tailnet (devices can reach each other)
Use Cases:
- Secure remote SSH access (ssh agent@aegis from Tailscale device)
- Bypass public IP for internal services
- Access internal ports (e.g., PostgreSQL on 5432)
Example Remote Access:
Security Considerations¶
- Tailscale provides end-to-end encryption (WireGuard)
- No public port exposure required (NAT traversal)
- Device authentication via Tailscale Identity Provider (Google/GitHub)
- Consider enabling MagicDNS (
aegis.tailnet-name.ts.net)
DDoS Protection¶
Cloudflare Proxy¶
Status: NOT enabled for Aegis domains
Rationale: Direct Let's Encrypt certificate provisioning via DNS-01 challenge (no Cloudflare proxy)
Recommendation: Enable Cloudflare proxy for DDoS protection:
- In Cloudflare DNS settings, click orange cloud icon (proxied)
- Update Traefik cert resolver to use Cloudflare API for DNS-01
- Benefit: DDoS protection, WAF, caching
Trade-offs: - Adds latency (traffic routes through Cloudflare edge) - Cloudflare sees unencrypted traffic (TLS termination at edge) - Rate limits apply (free tier: 100k req/day)
Rate Limiting¶
Status: Not implemented
Recommendation: Add Traefik rate limiting middleware:
Apply to public routes:
Network Security Best Practices¶
1. Defense in Depth¶
- Layer 1: Proxmox host firewall (iptables)
- Layer 2: LXC container isolation
- Layer 3: Docker network isolation
- Layer 4: Application-level authentication (API keys, passwords)
2. Principle of Least Privilege¶
- Services only listen on required ports
- Internal services not exposed publicly
- Containers use minimal necessary permissions
- Volume mounts read-only where possible
3. Encrypted Communication¶
- TLS 1.2+ for all external traffic
- Tailscale WireGuard for VPN access
- SSH key-based authentication (no passwords)
4. Network Segmentation¶
- Public services (dashboard, VS Code) on separate routes
- Internal services (PostgreSQL, FalkorDB) not routable externally
- Docker bridge network isolates containers
5. Monitoring and Logging¶
- Traefik access logs:
/var/log/traefik/access.log(TODO: implement) - MCP audit logs:
~/memory/security/mcp-audit.jsonl - Docker logs:
docker logs <container>
Security Audit Checklist¶
Perform quarterly:
- Verify TLS certificate expiry (should auto-renew)
- Review Traefik access logs for anomalies
- Check for unauthorized inbound connections:
netstat -tuln - Verify firewall rules on Proxmox host
- Test Tailscale VPN access from external device
- Review Docker container isolation (no privileged mode)
- Verify internal services not publicly accessible
- Check for exposed credentials in environment variables
- Review Dockerhost passthrough config for unauthorized domains
- Test DDoS resilience with load testing (with Cloudflare proxy)
Network Troubleshooting¶
Cannot Reach Service Externally¶
-
Check DNS: Does domain resolve to 157.180.63.15?
-
Check Dockerhost Traefik: Is SNI rule configured?
-
Check Aegis Traefik: Is service labeled correctly?
-
Check container health:
-
Check TLS certificate:
Cannot Reach Internal Service from Container¶
-
Check Docker network:
-
Check host.docker.internal:
-
Check service port:
-
Check container DNS:
Tailscale Not Working¶
-
Check Tailscale status:
-
Check ACLs: Login to Tailscale admin console, verify device has access.
-
Re-authenticate:
Future Enhancements¶
Planned (v2.0)¶
- Enable Cloudflare proxy for DDoS protection
- Implement rate limiting on public routes
- Add HSTS middleware for all HTTPS routes
- Configure UFW firewall on Aegis LXC
- Implement Traefik access logs and monitoring
- Set up network intrusion detection (Suricata/Snort)
- Add IP allowlisting for VS Code and VNC
Under Consideration¶
- VPN-only access for admin services (VS Code, VNC)
- Separate Docker networks for public/internal services
- Network policies for container-to-container communication
- Zero-trust network architecture (mutual TLS between containers)
- Web Application Firewall (ModSecurity)
- Network traffic analysis (Wireshark, tcpdump)