Aller au contenu

Authentik (+ Traefik & Crowdsec)

Ce guide vous explique comment déployer Authentik dans Docker, protégé derrière le reverse proxy Traefik et le bouclier de sécurité CrowdSec.

Pourquoi cette architecture ?

  • Surface d’exposition minimale : seuls les ports 80 (HTTP) et 443 (HTTPS) de Traefik sont ouverts sur Internet, la base PostgreSQL, Redis et les conteneurs Authentik restent cantonnés au réseau interne Docker.

  • Certificats TLS sans effort : Traefik obtient et renouvelle automatiquement les certificats Let’s Encrypt, vous n’avez plus à gérer la couche HTTPS manuellement.

  • Protection active des services : CrowdSec surveille les journaux d’accès de Traefik afin de détecter différents comportements malveillants (brute-force, scans automatisés, fuzzing, reconnaissance de services, etc.). Lorsqu’une menace est identifiée, l’adresse IP concernée est automatiquement bannie pendant une durée configurable.

En suivant ce guide, vous disposerez donc :

  • d’un SSO moderne avec Authentik;

  • d’un HTTPS entièrement automatisé;

  • d’un mécanisme de protection dynamique capable de détecter et bloquer automatiquement les comportements malveillants observés sur vos services exposés.

Architecture

L'architecture mise en oeuvre dans ce guide est la suivante :

                           Internet
                    Ports 80 / 443 ouverts
                         +-----------+
                         |  Traefik  |
                         +-----------+
               ┌───────────────┴───────────────┐
               │                               │
               ▼                               ▼
        +---------------+             Access Logs
        |   Authentik   |                   │
        +---------------+                   ▼
               │                    +---------------+
               │                    |   CrowdSec    |
               │                    +---------------+
               │                           │
               ▼                           ▼
      +----------------+         +------------------+
      | PostgreSQL     |         | Firewall Bouncer |
      | (utilisateurs) |         +------------------+
      +----------------+                   │
               │                           ▼
               ▼                    Blocage des IP
         +-----------+
         |   Redis   |
         | (cache)   |
         +-----------+

Flux réseau

  • Seuls les ports 80 (HTTP) et 443 (HTTPS) sont exposés sur Internet.
  • Traefik agit comme reverse proxy et gère automatiquement les certificats TLS Let's Encrypt.
  • Authentik fournit les services d'authentification (SSO, LDAP, OAuth2, OpenID Connect, SAML, etc.).
  • PostgreSQL stocke les utilisateurs, groupes, applications et configurations.
  • Redis est utilisé pour le cache et les tâches asynchrones.
  • CrowdSec analyse les journaux d'accès générés par Traefik et le Firewall Bouncer applique les décisions de blocage directement sur le serveur.

Installation via Docker

Installez le docker-compose et générez le mot de passe de la base de données et la clé secrète de Authentik en suivant la partie Preparation# de la documentation officielle.

Configuration Docker

Je fournis ici des exemples de fichiers de configuration à adapter :

Fichier .env

N'oubliez pas de générer le mot de passe de la base de données et la clé secrète de Authentik
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> .env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> .env

Exemple de fichier .env avec notifications SMTP :

# Les secrets
PG_PASS=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
AUTHENTIK_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxx

# LOG des erreurs
AUTHENTIK_ERROR_REPORTING__ENABLED=true

# Version cible d’Authentik (vérifiez la dernière version stable disponible sur le registre officiel avant le déploiement).
AUTHENTIK_TAG=2025.6.0 

#########################
# NOTIFICATIONS SMTP
#########################

# SMTP Host Emails are sent to
AUTHENTIK_EMAIL__HOST=mail.domaine.fr
AUTHENTIK_EMAIL__PORT=587
# Optionally authenticate (don't add quotation marks to your password)
AUTHENTIK_EMAIL__USERNAME=smtp@domaine.fr
AUTHENTIK_EMAIL__PASSWORD=xxxxxxxxx
# Use StartTLS
AUTHENTIK_EMAIL__USE_TLS=true
# Use SSL
AUTHENTIK_EMAIL__USE_SSL=false
AUTHENTIK_EMAIL__TIMEOUT=10
# Email address authentik will send from, should have a correct @domain
AUTHENTIK_EMAIL__FROM=authentik@domaine.fr

Fichier docker-compose.yaml

Voici un exemple complet et fonctionnel du fichier docker-compose.yaml. Il permet de déployer les services suivants :

  • Traefik comme reverse proxy qui s’occupe de gérer les connexions web (HTTP/HTTPS) et les certificats de sécurité TLS grâce à Let's Encrypt;

  • Authentik pour la gestion de l’authentification avec PostgreSQL comme base de données et Redis pour la gestion des files de tâches (cache);

  • CrowdSec pourra aussi y être connecté pour analyser les logs de Traefik et détecter les comportements suspects. Ce fichier configure les volumes nécessaires, notamment pour que CrowdSec puisse lire les journaux d’accès générés par Traefik.

services:
  ################################################################
  # Traefik (reverse proxy + Let's Encrypt)
  ################################################################
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    command:
      # --- Entrypoints (HTTP :80, HTTPS :443) ---
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"

      # --- API/Dashboard (optionnel) Le dashboard Traefik est activé mais n’est pas publié dans cet exemple. Aucun accès externe n’est possible tant qu’aucun routeur Traefik ne pointe vers le service interne api@internal. Si vous choisissez de l’exposer, protégez-le impérativement (Authentification, IP whitelist, VPN, etc.).---
      - "--api.dashboard=true"

      # --- Configuration du resolver Let's Encrypt (ACME) ---
      - "--certificatesresolvers.myresolver.acme.email=EMAIL@DOMAINE.FR"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web"

      # --- Activation du provider Docker ---
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"

      # --- LOG au format JSON pour parser CrowdSec ---
      - "--accesslog.filepath=/var/log/traefik/access.log"   # chemin dans le conteneur
      - "--accesslog.format=json"                            # format le plus simple à parser

    ports:
      - "80:80"
      - "443:443"
    volumes:
      # Monte acme.json en lecture/écriture (pour stocker les certificats)
      - ./acme.json:/letsencrypt/acme.json
      # Accès en lecture seule au socket Unix Docker (pour lire les labels et accès docker)
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # Monte le dossier de logs sur l'hôte (pour permettre à CrowdSec de les analyser)
      - /var/log/traefik:/var/log/traefik

    networks:
      - authentik_net

  ################################################################
  # PostgreSQL
  ################################################################
  postgresql:
    image: docker.io/library/postgres:16-alpine
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - database:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
      POSTGRES_USER: ${PG_USER:-authentik}
      POSTGRES_DB: ${PG_DB:-authentik}
    env_file:
      - .env
    networks:
      - authentik_net

  ################################################################
  # Redis : est utilisé par Authentik pour le cache et la gestion des tâches asynchrones. Les données utilisateurs et la configuration restent stockées dans PostgreSQL. Une perte du volume Redis n’entraîne donc pas de perte des comptes ou des configurations Authentik.
  ################################################################
  redis:
    image: docker.io/library/redis:alpine
    command: --save 60 1 --loglevel warning
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    volumes:
      - redis:/data
    networks:
      - authentik_net

  ################################################################
  # Authentik Server
  ################################################################
  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG}
    restart: unless-stopped
    command: server
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
    env_file:
      - .env
    depends_on:
      postgresql:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - authentik_net
    labels:
      # On active explicitement la publication via Traefik
      - "traefik.enable=true"

      # Redirection HTTP -> HTTPS
      - "traefik.http.routers.authentikserver-web.rule=Host(`FQDN`)"
      - "traefik.http.routers.authentikserver-web.entrypoints=web"
      - "traefik.http.routers.authentikserver-web.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"

      # Routage HTTPS vers le port 9000 interne
      - "traefik.http.routers.authentikserver.rule=Host(`FQDN`)"
      - "traefik.http.routers.authentikserver.entrypoints=websecure"
      - "traefik.http.routers.authentikserver.tls=true"
      - "traefik.http.routers.authentikserver.tls.certresolver=myresolver"
      - "traefik.http.services.authentikserver.loadbalancer.server.port=9000"

  ################################################################
  # Authentik Worker : il exécute les tâches asynchrones d'Authentik (synchronisations LDAP, envoi d'e-mails, traitements d'événements, gestion des Outposts, etc.).
  ################################################################
  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG}
    restart: unless-stopped
    command: worker
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    user: root
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./media:/media
      - ./certs:/certs
      - ./custom-templates:/templates
    env_file:
      - .env
    depends_on:
      postgresql:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - authentik_net

volumes:
  database:
    driver: local
  redis:
    driver: local

networks:
  authentik_net:
    driver: bridge
CrowdSec n'est pas déployé dans ce fichier docker-compose.yaml. Seule la génération et l’exposition des journaux Traefik sont préparées afin qu’une installation CrowdSec existante puisse les analyser.

Lancement

1) Avant de démarrer les conteneurs, exécutez touch acme.json && chmod 600 acme.json dans le même répertoire que le fichier docker-compose.yaml. Traefik utilisera ce fichier pour stocker sa clé ACME ainsi que les certificats Let's Encrypt. Les permissions restrictives sont requises pour des raisons de sécurité.

2) Y'a plus qu'à lancer les conteneurs !

docker compose pull
docker compose up -d

3) vérification :

docker compose ps
Résultat attendu :

server      Up
worker      Up
postgresql  Up (healthy)
redis       Up (healthy)

Sécurisation CrowdSec

  1. Dans le fichier /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml, ajoutez ou décommentez la chaîne DOCKER-USER dans la section iptables_chains. Cette chaîne est évaluée avant les règles générées automatiquement par Docker et permet à CrowdSec de bloquer efficacement le trafic destiné aux conteneurs.
iptables_chains:
  - INPUT          # Trafic entrant vers l'hôte
  - DOCKER-USER    # Trafic entrant vers les conteneurs Docker
# - FORWARD        # Optionnel selon votre architecture réseau
  1. Traefik écrit ses journaux d'accès au format JSON dans le dossier monté /var/log/traefik sur l'hôte.

Vérifiez que la collection Traefik est installée :

cscli collections install crowdsecurity/traefik

Créez ensuite un fichier d'acquisition dédié :

nano /etc/crowdsec/acquis.d/traefik.yaml

Contenu :

filenames:
  - /var/log/traefik/access.log
labels:
  type: traefik

Redémarrez CrowdSec :

systemctl restart crowdsec
  1. La collection crowdsecurity/traefik analyse les journaux d'accès de Traefik afin de détecter différents comportements malveillants (brute-force, scans automatisés, reconnaissance de services, énumération de répertoires, etc.) sur l'ensemble des applications exposées derrière le reverse proxy, y compris Authentik.

Vous pouvez vérifier que les logs sont correctement analysés :

cscli metrics

Vous devez notamment retrouver :

Acquisition Metrics
file:/var/log/traefik/access.log

Parser Metrics
crowdsecurity/traefik-logs

Ainsi que des scénarios HTTP tels que :

crowdsecurity/http-probing
crowdsecurity/http-technology-probing
crowdsecurity/http-admin-interface-probing
  1. Le bouncer pare-feu applique automatiquement les décisions prises par CrowdSec. Par défaut, les adresses IP malveillantes sont bannies pendant 4 heures. Cette durée peut être modifiée dans le fichier /etc/crowdsec/profiles.yaml.

  2. Vérification du fonctionnement

Contrôlez que CrowdSec lit correctement les journaux Traefik :

cscli metrics

Contrôlez les alertes générées :

cscli alerts list

Contrôlez les décisions appliquées :

cscli decisions list

Si des alertes HTTP apparaissent et que les métriques affichent le fichier /var/log/traefik/access.log, alors l'intégration Traefik x CrowdSec est opérationnelle.

Configuration Authentik

Configuration initiale

Pour lancer l'assistant de configuration, naviguez à l'adresse https://IP_ou_FQDN/if/flow/initial-setup/

Provider

Suivez la doc officielle qui est complète et régulièrement mise à jour pour configurer vos providers !

https://docs.goauthentik.io/integrations/services/

Notification

  • Notifications transport
  • Notification rules personnalisées.

Références

https://une-tasse-de.cafe/blog/goauthentik/