--- title: Gateway Documentation section: docs summary: Homelab Gateway — Traefik Reverse Proxy, Authelia SSO, LAN Routing, macvlan IP assignment, and Docker-managed services. tags: [networking, traefik, authelia, infrastructure, docker, home-lab] nav: 2 --- ## Homelab Gateway Stack (Traefik + Authelia) This document describes the architecture and configuration of the homelab gateway stack — the system responsible for HTTPS termination, reverse proxying, SSO-protected internal services, LAN-to-LAN routing, and stable external exposure. This documentation intentionally mirrors the SoloForge Gitea documentation format for consistency across the infrastructure stack. --- ## 1. Overview The Gateway Stack provides: - **Reverse proxying via Traefik v3** - **Authentication & SSO via Authelia v4** - **Per-service routing with Docker labels or file-provider YAML** - **macvlan-based static IP assignment (Traefik appears as its own LAN host)** - **Secure exposure of internal services to the outside world** - **ForwardAuth protection for otherwise unauthenticated apps** - **Ability to proxy both Docker-based and remote LAN-based services** This system replaces the previous Traefik + YAML editor stack and centralizes the “front door” of the homelab under a configuration that is fully self-documented, reproducible, and Git-tracked. --- ## 2. System Layout ### 2.1 Host Machine - Bare-metal machine (temporarily — will migrate back into Proxmox) - Debian/Ubuntu-based environment - Docker + Docker Compose v2+ - macvlan network configured so Traefik has a **dedicated LAN IP** (`192.168.2.253`) ### 2.2 Static Network Assignment (macvlan) Traefik receives its own IP on the LAN: ```bash docker network create -d macvlan \ --subnet=192.168.2.0/24 \ --gateway=192.168.2.1 \ -o parent=eth0 \ traefik_macvlan ``` **Rationale:** - Makes Traefik behave like a true router on the network - Allows the router to port-forward directly to Traefik instead of the host - Eliminates host→Traefik conflicts - Clean separation once this stack eventually lives in a VM or LXC again ### 2.3 Directory Structure ```bash /gateway/ ├── traefik/ │ ├── traefik.yml # Static config │ ├── config/ # File provider configs (GUI writes here) │ ├── cert/ # ACME cert store │ └── logs/ # Traefik logs ├── authelia/ │ ├── config/ # Authelia configuration.yml + users file │ ├── secrets/ # Env-based secrets, if used │ └── logs/ # Authelia logs ├── traefik-gui/ │ └── db/ # GUI internal sqlite db └── traefik-stack.yml # Main stack ``` --- ## 3. Traefik Deployment ### 3.1 Traefik Service Launched via Compose with two network attachments: - `traefik_macvlan` → gives Traefik its LAN IP - `proxy` → internal Docker network for app connectivity Traefik is responsible for: - HTTPS certificates via Let’s Encrypt (DNS-01 with Cloudflare) - Routing per-service via hostnames - Applying Authelia ForwardAuth checks - Proxying internal Docker services and remote LAN machines ### 3.2 File Provider The file provider watches: `/traefik/config/` Traefik GUI writes dynamic route definitions into this folder. ### 3.3 Docker Provider Configured with: ```yaml providers: docker: endpoint: "unix:///var/run/docker.sock" exposedByDefault: false network: proxy ``` Allows Traefik to auto-discover containers with labels on the `proxy` network. --- ## 4. Authelia (SSO / Authentication) ### 4.1 Purpose Authelia handles: - Single-sign-on for internal apps - Multi-factor auth (optional) - Protecting services with ForwardAuth (even those without native authentication) - Login portal at `auth.keithsolomon.net` ### 4.2 Configuration Notes - Config lives at `/authelia/config/configuration.yml` - Secrets (session, storage encryption, reset-password JWT) supplied via environment variables - SMTP notifier is required — missing credentials cause Authelia to crash-loop - Logging set to stdout during debugging, file logging available once stable ### 4.3 ForwardAuth Middleware Exposed to Traefik via labels: `traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth` Any protected service adds: `traefik.http.routers..middlewares=authelia@docker` --- ## 5. LAN Services & Routing ### 5.1 Dockerized Services (local to gateway) Containers running on the same host as Traefik should: 1. Join the `proxy` network 2. Use Traefik Docker labels 3. NOT be accessed via the host IP (192.168.2.9) when Traefik is on macvlan - macvlan cannot reliably reach the host’s bridge interfaces Example (Sonarr): ```yaml labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.sonarr.rule=Host(`sonarr.keithsolomon.net`)" - "traefik.http.services.sonarr.loadbalancer.server.port=8989" ``` Traefik will connect to `http://sonarr:8989` over the internal Docker network. ### 5.2 Remote LAN Services (other machines) These should be added via the Traefik GUI (file provider), using the machine’s actual LAN IP: Example: ```yaml services: docs: loadBalancer: servers: - url: "http://192.168.2.51:8083" ``` These are not affected by the macvlan limitation. --- ## 6. Gateway Compose Stack **Services included:** - traefik - authelia - traefik-gui - eventually all internal homelab UIs **Networks:** ```yaml networks: traefik_macvlan: external: true proxy: name: proxy driver: bridge ``` **Important: .env File** Stores secrets such as Authelia session keys and SMTP passwords. Generate strong random hex values for the secrets using `openssl rand -hex 64`. ```bash AUTHELIA_SESSION_SECRET= AUTHELIA_STORAGE_ENCRYPTION_KEY= AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET= AUTHELIA_NOTIFIER_SMTP_PASSWORD= ``` --- ## 7. Operational Notes ### 7.1 Authelia Startup Failures Authelia will crash-loop if: - SMTP notifier missing password - storage encryption key missing - identity_validation.reset_password.jwt_secret missing - configuration.yml malformed Always check: ```bash docker logs Authelia ``` ### 7.2 macvlan Gotcha (Critical) Traefik on macvlan **cannot reach the host’s own IP (192.168.2.9)**. Use container names on the `proxy` network for same-host services. ### 7.3 Debugging Backend Connectivity To simulate Traefik’s point of view: ```bash docker run --rm -it --network=proxy alpine sh apk add curl curl -v http://sonarr:8989 curl -v http://192.168.2.51:8083 ``` If container → hostIP fails, but container → container works, it’s macvlan isolation. ### 7.4 Traefik Dashboard Available at `https://tfk.keithsolomon.net` Protected by Authelia. Check: - Routers → status, errors, middlewares - Services → backend URLs - Middlewares → ensure authelia@docker exists --- ## 8. Future Improvements - Migrate gateway stack into Proxmox VM/LXC - Replace Traefik-GUI with a cleaner UI (or maintain YAML by hand) - Add Prometheus metrics for request/latency monitoring - Add fail2ban or rate-limiting middleware - Add OIDC provider configuration to Authelia for full single sign-on - Automate propagation of routes from remote hosts (pull or push model) --- ## TL;DR Cheat Sheet **Traefik not routing?** - → Check router → check service → check backend URL - → If backend is on the same machine: use container name, not host IP **Authelia crash-loop?** - → Missing SMTP password - → Missing storage/session/jwt secrets - → Look inside /authelia/logs/authelia.log **Adding a remote LAN service?** - → Use Traefik GUI - → Backend = `http://192.168.2.X:PORT` - → Protect via Authelia middleware as needed **Adding a local Docker service?** - → Put it on the `proxy` network - → Add Traefik labels - → Use `loadbalancer.server.port`, not host IP - → Do NOT use `192.168.2.9` when Traefik is on macvlan