Files
dev-notes/content/gateway-stack.md
2025-12-06 14:35:56 -06:00

7.9 KiB
Raw Blame History

title, section, summary, tags, nav
title section summary tags nav
Gateway Documentation docs Homelab Gateway — Traefik Reverse Proxy, Authelia SSO, LAN Routing, macvlan IP assignment, and Docker-managed services.
networking
traefik
authelia
infrastructure
docker
home-lab
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:

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

/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 Lets 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:

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.<service>.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 hosts bridge interfaces

Example (Sonarr):

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 machines actual LAN IP:

Example:

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:

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.

AUTHELIA_SESSION_SECRET=<hex>
AUTHELIA_STORAGE_ENCRYPTION_KEY=<hex>
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET=<hex>
AUTHELIA_NOTIFIER_SMTP_PASSWORD=<app-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:

docker logs Authelia

7.2 macvlan Gotcha (Critical)

Traefik on macvlan cannot reach the hosts own IP (192.168.2.9). Use container names on the proxy network for same-host services.

7.3 Debugging Backend Connectivity

To simulate Traefiks point of view:

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, its 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