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. À la moindre tentative d’attaque (scan, brute-force…), l’adresse IP fautive est bannie automatiquement pour 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 pare-feu dynamique qui réagit en temps réel aux menaces.
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
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
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) ---
- "--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 LOG sur l'hôte (pour parser Crowdsdec)
- /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
################################################################
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
################################################################
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
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 docker-compose
afin de fournir à Traefik un fichier ACME déjà présent et restreint en lecture/écriture root. C’est dans ce fichier protégé qu’il enregistre sa clé de compte et les certificats Let’s Encrypt.
2) Y'a plus qu'à lancer !
Securisation Crowdsec
1) Dans le fichier /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml
, décommentez la ligne DOCKER-USER
dans la section iptables_chains
.
2) Traefik écrit son access-log JSON dans le dossier monté /var/log/traefik
sur l’hôte. CrowdSec lit ce fichier grâce à /etc/crowdsec/acquis.yaml
Exemple de fichier acquis.yaml
:
#Generated acquisition file - wizard.sh (service: ssh) / files :
journalctl_filter:
- _SYSTEMD_UNIT=ssh.service
labels:
type: syslog
---
# Lecture des LOG Traefik (format JSON)
filenames:
- /var/log/traefik/access.log
labels:
type: traefik
3) La collection crowdsecurity/traefik
détecte les bruteforce sur Authentik.
4) Le bouncer pare-feu bloque automatiquement l’IP (tous ports) pendant 4 h par défaut.
Configuration Authentik
Configuration initiale
Pour lancer l'assistant de configuration, naviguez à l'adresse http://IP_ou_FQDNx/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/