Skip to content

Authelia SSO Authentication

Overview

Authelia is a robust authentication and authorization server providing Single Sign-On (SSO) capabilities for the mixi.cz infrastructure. It integrates with our existing LDAP directory and provides multi-factor authentication for secure access to services like Grafana and Home Assistant.

Key Features

  • LDAP Integration: Authenticates against LLDAP (it used to be OpenLDAP directory on julie in past)
  • Multi-Factor Authentication: TOTP (Google Authenticator) and WebAuthn/FIDO2 support
  • Network-Based Access Control: Internal network bypass, external authentication required
  • Session Management: Configurable session timeouts and remember-me functionality
  • Go-Based: Lightweight, fast, and secure implementation

Architecture

Infrastructure Components

  • Platform: k3s cluster with Traefik ingress controller
  • Storage: Longhorn persistent volumes, SQLite database
  • Load Balancer: Apache2 reverse proxy for internet-facing access
  • Network: Internal bypass for 192.168.0.0/22, external authentication required
  • LDAP: OpenLDAP server (julie-local.mixi.cz:389)

Authentication Flow

graph TB
    User[👤 User] --> Browser[🌐 Browser]
    Browser --> Apache[Apache Reverse Proxy 
    SSL Termination]
    Apache --> Traefik[Traefik Ingress
    piks01.intranet]

    Traefik --> AuthMiddleware{Authelia Middleware
    ForwardAuth}

    AuthMiddleware --> IPCheck{IP Address Check}
    IPCheck -->|192.168.0.0/22| Bypass[✅ Internal Bypass]
    IPCheck -->|External IP| AuthRequired[🔐 Authentication Required]

    AuthRequired --> AuthPage[Authelia Login Page
    auth.mixi.cz]
    AuthPage --> LDAP[OpenLDAP
    julie-local.mixi.cz:389]
    LDAP -->|Valid Credentials| MFA{Multi-Factor Auth}

    MFA --> TOTP[📱 TOTP Code
    Google Authenticator]
    MFA --> WebAuthn[🔑 WebAuthn/FIDO2
    YubiKey, Touch ID]

    TOTP --> Authenticated[✅ Authenticated]
    WebAuthn --> Authenticated
    Bypass --> Service[🎯 Target Service]
    Authenticated --> Service

    Service --> Grafana[📊 Grafana]
    Service --> HomeAssistant[🏠 Home Assistant]

    style User fill:#263345
    style AuthRequired fill:#423627
    style Authenticated fill:#26382d
    style Service fill:#362d3b

Traffic Flow Patterns

External Access (Internet → Services)

Internet User → Apache (SSL:443) → Traefik → Authelia → Authentication → Target Service

Internal Access (LAN → Services)

Internal User → Traefik → Authelia (IP Bypass) → Target Service

Configuration

Core Settings

Server Configuration

server:
  address: "tcp://0.0.0.0:9091"
  timeouts:
    read: 6s
    write: 6s
    idle: 30s

LDAP Authentication

authentication_backend:
  ldap:
    url: ldap://julie-local.mixi.cz:389
    base_dn: ou=People,dc=mixi,dc=cz
    username_attribute: mail
    users_filter: "(&({username_attribute}={input})(objectClass=inetOrgPerson))"
    user: cn=auth,dc=mixi,dc=cz

Access Control Rules

access_control:
  default_policy: deny
  rules:
    # Internal network bypass
    - domain: ["*.mixi.cz"]
      policy: bypass
      networks: ["192.168.0.0/22"]

    # External access requires 2FA
    - domain: ["grafana.mixi.cz", "ha.mixi.cz"]
      policy: two_factor

Session Management

session:
  domain: mixi.cz
  expiration: 16h      # Maximum session lifetime
  inactivity: 30m      # Idle timeout
  remember_me: 30d     # "Remember me" duration

Multi-Factor Authentication

TOTP (Time-based One-Time Password)

totp:
  issuer: mixi.cz
  algorithm: sha256
  digits: 6
  period: 30

Supported Apps: Google Authenticator, Authy, 1Password, Microsoft Authenticator

WebAuthn/FIDO2

webauthn:
  display_name: "mixinet přihlášení"
  timeout: 60s
  user_verification: preferred

Supported Devices: YubiKey, SoloKey, Touch ID, Face ID, Windows Hello

Deployment

Prerequisites

  1. k3s cluster with Traefik ingress controller
  2. Longhorn storage class available
  3. OpenLDAP server accessible from cluster
  4. Apache reverse proxy configured for SSL termination
  5. DNS records for auth.mixi.cz, grafana.mixi.cz, ha.mixi.cz

Deployment Steps

  1. Generate Secrets

    # Generate random secrets (32+ characters)
    openssl rand -hex 32  # JWT_SECRET
    openssl rand -hex 32  # SESSION_SECRET
    openssl rand -hex 32  # STORAGE_ENCRYPTION_KEY
    

  2. Configure Secrets

    # Edit authelia-secret.yaml with generated secrets
    # Add LDAP and SMTP passwords
    kubectl apply -f authelia-secret.yaml
    

  3. Deploy Authelia Components

    kubectl apply -f authelia-deployment.yaml  # Namespace, PVC, Deployment, Service
    kubectl apply -f authelia-config.yaml      # ConfigMap with configuration
    kubectl apply -f authelia-middleware.yaml  # Traefik ForwardAuth middleware
    

  4. Configure Services

    # Apply service-specific ingress configurations
    kubectl apply -f grafana-ingress.yaml
    kubectl apply -f home-assistant-ingress.yaml
    

  5. Enable Authentication (Gradual Migration)

    # Uncomment middleware annotation in ingress files:
    # traefik.ingress.kubernetes.io/router.middlewares: authelia-authelia@kubernetescrd
    

Health Check

# Port forward to test Authelia health
kubectl port-forward -n authelia svc/authelia 9091:80
curl http://localhost:9091/api/health

# Expected response: {"status":"UP"}

User Experience

First-Time Setup

  1. User navigates to grafana.mixi.cz from external network
  2. Redirected to auth.mixi.cz login page
  3. Enters credentials (email + password)
  4. Sets up 2FA: Scans QR code with authenticator app or registers security key
  5. Access granted to Grafana with session valid for 16 hours

Daily Usage

Internal Network (192.168.0.0/22)

  • Direct access to all services
  • No authentication required
  • Seamless experience for home users

External Network (Internet)

  • Authentication required for each service
  • 2FA prompt on new devices/sessions
  • Remember me option for 30-day sessions
  • Session sharing across mixi.cz services

Session Behavior

Scenario Experience
Active browsing Session valid for 16 hours maximum
Idle for 30min Automatic logout, re-authentication required
Remember me checked 30-day session on trusted device
Multiple services Single login for grafana.mixi.cz + ha.mixi.cz

Security Features

Network-Based Access Control

  • Internal bypass: 192.168.0.0/22 network automatically trusted
  • External enforcement: Internet users always require authentication
  • Real IP detection: Apache forwards X-Real-IP headers for accurate detection

Multi-Factor Authentication

  • TOTP codes: Time-based, 6-digit codes rotating every 30 seconds
  • Hardware keys: FIDO2/WebAuthn support for YubiKey, security keys
  • Biometric authentication: Touch ID, Face ID, Windows Hello support

Session Security

  • Secure cookies: HttpOnly, Secure, SameSite=Lax
  • Session encryption: AES encryption with rotating keys
  • Automatic expiration: Both absolute and inactivity timeouts
  • Cross-site protection: Domain-scoped sessions

Troubleshooting

Common Issues

Authentication Failures

Symptom: "Invalid credentials" despite correct password

# Check LDAP connectivity
kubectl logs -n authelia -l app=authelia | grep -i ldap

# Verify LDAP user search
ldapsearch -H ldap://julie-local.mixi.cz:389 \
  -D "cn=auth,dc=mixi,dc=cz" -W \
  -b "ou=People,dc=mixi,dc=cz" \
  "(&(mail=user@mixi.cz)(objectClass=inetOrgPerson))"

Session Issues

Symptom: Frequent logouts or "session expired"

# Check session configuration
kubectl get configmap -n authelia authelia-config -o yaml | grep -A 5 session

# Verify session storage
kubectl exec -n authelia deployment/authelia -- ls -la /config/

TOTP Setup Problems

Symptom: QR code not working or codes rejected

# Check TOTP configuration
kubectl logs -n authelia -l app=authelia | grep -i totp

# Verify time synchronization
kubectl exec -n authelia deployment/authelia -- date

Health Monitoring

Service Status

# Check Authelia pod status
kubectl get pods -n authelia

# View logs
kubectl logs -n authelia -l app=authelia -f

# Test health endpoint
kubectl port-forward -n authelia svc/authelia 9091:80
curl http://localhost:9091/api/health

Performance Metrics

# Check resource usage
kubectl top pods -n authelia

# Database size
kubectl exec -n authelia deployment/authelia -- du -h /config/db.sqlite3

Log Analysis

Authentication Events

# Recent authentication attempts
kubectl logs -n authelia -l app=authelia --tail=100 | grep -i "authentication"

# Failed login attempts
kubectl logs -n authelia -l app=authelia | grep -i "failed\|error"

# Session creation/destruction
kubectl logs -n authelia -l app=authelia | grep -i "session"

Maintenance

Regular Tasks

Secret Rotation (Quarterly)

# Generate new secrets
openssl rand -hex 32 > new_session_secret

# Update secret
kubectl patch secret -n authelia authelia-secret -p='{"stringData":{"SESSION_SECRET":"'$(cat new_session_secret)'"}}'

# Restart Authelia
kubectl rollout restart -n authelia deployment/authelia

Database Maintenance (Monthly)

# Backup database
kubectl exec -n authelia deployment/authelia -- sqlite3 /config/db.sqlite3 ".backup /tmp/backup.db"
kubectl cp authelia/$(kubectl get pods -n authelia -l app=authelia -o name | cut -d/ -f2):/tmp/backup.db ./authelia-backup-$(date +%Y%m%d).db

# Vacuum database
kubectl exec -n authelia deployment/authelia -- sqlite3 /config/db.sqlite3 "VACUUM;"

Log Rotation (Weekly)

# Check log size
kubectl logs -n authelia -l app=authelia | wc -l

# Archive old logs if needed
kubectl logs -n authelia -l app=authelia --previous > authelia-logs-$(date +%Y%m%d).log

Updates

Authelia Version Updates

# Check current version
kubectl get deployment -n authelia authelia -o jsonpath='{.spec.template.spec.containers[0].image}'

# Update image version in authelia-deployment.yaml
# Apply updated deployment
kubectl apply -f authelia-deployment.yaml

# Monitor rollout
kubectl rollout status -n authelia deployment/authelia

Configuration Changes

# Update configuration
kubectl apply -f authelia-config.yaml

# Restart to reload config
kubectl rollout restart -n authelia deployment/authelia

Integration Examples

Adding New Services

New Application with Authentication

# my-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: authelia-authelia@kubernetescrd
  name: my-app
spec:
  rules:
  - host: myapp.mixi.cz
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-app
            port:
              number: 80

Access Control Rules

# Add to authelia-config.yaml access_control.rules
- domain: ["myapp.mixi.cz"]
  policy: two_factor
  # Optional: restrict to specific users
  # subject: ["user:admin@mixi.cz"]

Apache Virtual Host Template

# myapp.mixi.cz.conf
<VirtualHost *:443>
    ServerName myapp.mixi.cz

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/mixi.cz/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mixi.cz/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/mixi.cz/fullchain.pem

    # Forward real client IP for Authelia
    RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
    RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
    RequestHeader set X-Forwarded-Proto "https"

    ProxyPass / https://piks01.intranet/
    ProxyPassReverse / https://piks01.intranet/

    SSLProxyEngine On
    SSLProxyVerify none
</VirtualHost>

File Structure

Configuration files are located in /home/mixi/pg/home/automation/kube/auth/:

Core Files

  • authelia-config.yaml - Main configuration (ConfigMap)
  • authelia-deployment.yaml - Kubernetes deployment, service, PVC
  • authelia-middleware.yaml - Traefik ForwardAuth middleware
  • authelia-secret.yaml - Sensitive data (excluded from git)

Service Files

  • grafana-ingress.yaml - Grafana ingress with authentication
  • home-assistant-ingress.yaml - Home Assistant ingress with authentication
  • optional-middlewares.yaml - Additional security middlewares

Apache Configuration

  • auth.mixi.cz.conf - Apache virtual host for Authelia
  • *.mixi.cz.conf - Apache virtual hosts for individualapplications

Documentation

  • MIGRATION_GUIDE.md - Step-by-step deployment instructions
  • .gitignore - Excludes sensitive files from git

References


Last updated: 2025-01-29 Deployment: mixi.cz k3s cluster