Authentik

🎯 Objectifs :
  • Installer et exposer Authentik
  • Paramétrer le Multi-Facteur
  • Protéger une app native ou via reverse proxy

Authentik est un outil d'authentification unique permettant de vous logger une seule fois sur les plateformes compatibles OpenID. Il permet également de sécuriser l'accès aux services que vous exposez, en s'injectant via SWAG aux requetes vers vos services.

Ainsi, si vous exposez Dockge sur internet via dockge.mondomaine.fr, au moment de l'accès à cette page, vous tomberez sur une page de login d'authentik. Si vous avez déjà été identifié sur un autre service sécurisé par authentik auparavant, alors vous serez déjà identifié. cela permet d'avoir à vous identifiez qu'une seule fois par jour sur l'ensemble des services protégés par authentik.

Authentik permet aussi d'utiliser le multi-facteur, notamment par TOTP (code généré par une application d'authentification de votre choix. Enfin, authentik permet aussi de se connecter directement via un compte Microsoft ou Google, si vous avez configuré une application d'un de ces services.

C'est une bonne manière de se passer de VPN pour exposer vos services, et d'exposer des services qui ne sont pas protégés par du MFA voir pas protégés par des login (comme le dashboard de swag).

Authentik dipose d'une doc très fournie et des fabuleux tuto de Cooptonian. Ici, nous montrerons juste les bases, avec l'exemple de l'exposition de Dockge.

Deux modes principaux sont à connaitre:

  • Le premier permet à une application qui dispose nativement d'une intégration avec du SSO compatible OpenID de se connecter directement à Authentik. C'est la solution à privilégier car elle permet de laisser l'application décider de ce qui est public et de ce qui est protégé.

Picture

  • Le second permet d'injecter une authentification via authentik grace à SWAG avant d'arriver sur le service désiré.

Picture

Les deux modes son configurables application par application.

Installation


Structure des dossiers :

root
└── docker
    └── authentik
        ├── .env
        ├── compose.yml
        ├── media
        ├── certs
        ├── custom-template
        └── ssh

Créez les dossiers :

sudo mkdir -p /docker/authentik/media /docker/authentik/certs /docker/authentik/custom-template /docker/authentik/ssh

Positionnez vous dans le dossier authentik et générez un mot de passe et une clé secrete que l'on va intégrer dans le .env :

sudo echo "PG_PASS=$(openssl rand 36 | base64)" >> .env
sudo echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
  • Afin de générer la clé, nous avons créé les dossiers en amont du déploiement via Dockge. Dockge vous empechera de créer une stack du meme nom dans ces dossiers s'il n'existe pas de compose.yml. Il faut donc créer un compose.yml vide afin que ce dernier la reconnaisse comme existante dans les stacks inactives :
sudo vi /docker/authentik/compose.yml

Ouvrez dockge, et cherchez "authentik" dans les stack inactives. Nommez la stack authentik et collez la configuration suivante, en changeant les chiffres de {AUTHENTIK_TAG:-2024.2.3} par la dernière version de Authentik.

version: "3.4"
services:

  postgresql:
    image: docker.io/library/postgres:12-alpine
    container_name: authentik-postgresql
    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:
      - swag

  redis:
    image: docker.io/library/redis:alpine
    container_name: authentik-redis
    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:
      - swag
  
  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.2.3}
    container_name: authentik-server
    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
      - ./auth.css:/web/dist/custom.css
      - ./ssh:/authentik/.ssh
    env_file:
      - .env
    ports:
      - ${COMPOSE_PORT_HTTP:-9000}:9000
      - ${COMPOSE_PORT_HTTPS:-9443}:9443
    depends_on:
      - postgresql
      - redis
    networks:
      - swag

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.2.3}
    container_name: authentik-worker
    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` and the docker socket volume are optional.
    # See more for the docker socket integration here:
    # https://goauthentik.io/docs/outposts/integrations/docker
    # Removing `user: root` also prevents the worker from fixing the permissions
    # on the mounted folders, so when removing this make sure the folders have the correct UID/GID
    # (1000:1000 by default)
    user: root
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./media:/media
      - ./certs:/certs
      - ./custom-templates:/templates
      - ./auth.css:/web/dist/custom.css
      - ./ssh:/authentik/.ssh
    env_file:
      - .env
    depends_on:
      - postgresql
      - redis
    networks:
      - swag

volumes:
  database:
    driver: local
  redis:
    driver: local
  • Ici nous partons du principe que le réseau de Swag est swag_default.

Dans le point .env, les variables PG_PASS et AUTHENTIK_SECRET_KEY sont déjà remplies. Déployez la stack.

Vous pouvez alors commencer le set-up d'authentik en tappant http://ipduserveur:9000/if/flow/initial-setup/.

  • Attention : il est conseillé de créer un nouveau compte admin, et de désactiver le compte admin de base akadmin.

Exposer authentik


Pour être utilisable hors de chez vous, vous devez exposer authentik.

📋 Au préalable :

Nous partons du principe quer vous avez créé dans votre zone DNS un sous domaine du type auth.mondomaine.fr avec pour CNAME mondomaine.fr et, à moins que vous utilisiez Cloudflare Zero Trust, vous avez déjà redirigé le port 443 de votre box vers le 443 de votre serveur dans les règles NAT.

Ouvrez le fichier authentik-server.conf.

Astuce pour les allergiques au terminal : vous pouvez utiliser File Browser pour naviguer dans vos fichier et éditer vos documents au lieu d'utiliser les commandes du terminal.
sudo vi /docker/swag/config/nginx/authentik-server.conf

Vérifiez que dans chaque cas les variables ci-dessous sont correctes :

set $upstream_authentik authentik-server;
proxy_pass http://$upstream_authentik:9000;

Si ce n'est pas le cas, passez en mode modification en tapant i et éditez les. Sauvegardez et quittez en tapant sur Echap puis :x.

Créez le fichier auth.subdomain.conf

sudo vi /docker/swag/config/nginx/proxy-confs/auth.subdomain.conf

Appuyez sur i pour rentrer en mode modification puis collez la configuration suivante :

## Version 2023/05/31
# make sure that your authentik container is named authentik-server
# make sure that your dns has a cname set for authentik

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name auth.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app authentik-server;
        set $upstream_port 9000;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }

    location ~ (/authentik)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app authentik-server;
        set $upstream_port 9000;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

Sauvegardez et quittez en appuyant sue Echap puis en tapant :x

Et voilà ! Vous pouvez accéder à authentik via https://auth.mondomaine.fr

Activer le multifacteur


Tout l'intérêt de authentik c'est de disposer du multifacteur pour toutes les apps que l'on protègera.

  • Rendez vous sur https://auth.mondomaine.fr
  • Identifiez-vous
  • Rendez-vous dans paramètres
  • Cliquez sur la section MFA
  • Cliquez sur s'inscrire
  • Choisissez une méthode comme TOTP device ( dans ce cas vous devrez utilisez une app d'authentification telle que Google Authenticator par exemple)
  • Suivez les étapes

Et voilà, vous serez invité à saisir un code à usage unique à chaque connexion.

Protéger une app native


Authentik est compatible nativement avec un certain nombre d'application, vous retrouverez la liste et le support ici

Protéger une app par reverse proxy


Swag permet d'intercaler la page d'authentik entre la requête et l'accès à votre service. Pour cela il va falloir :

  • Configurer le service d'authentification dans authentik.
  • Configurer le fichier proxy du domaine pour que swag puisse intercaler la page.

Pourquoi le faire alors que Dockge a déjà une page d'authentification ? Tout simplement parce que l'authentification HTTP utilisée par Dockge est faible. Avec Authentik, vous aurez directement une authentification forte par MFA, et vous serez loggé automatiquement à toutes vos apps déjà protégées par authentik. Cela permet de sécuriser l'accès à Dockge et aux autres apps que vous protégerez, sans avoir à passer par un VPN.

Configuration de Authentik

  • Rendez vous dans Authentik
  • Allez dans le panneau d'administration
  • Sélectionnez application puis créer avec l'assistant
  • Renseignez les champs comme suit :

Picture

  • Puis à l'étape suivante choisissez "Transférer l'authentification (application unique)" et éditez comme suit (attention aux flow, c'est important) :

Picture

  • Ensuite, allez dans le menu à gauche dans Avant-poste et éditez authentik Embedded Outpost

Picture

  • Ajoutez l'application dockge en la faisant passer à droite et validez.

Configuration de SWAG

Ensuite rendez-vous dans le fichier dockge.mondomaine.fr.

sudo vi /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf

Puis entrez en modification en appuyant sur i et enlevez les # des deux lignes #include /config/nginx/authentik-server.conf;.

Appuyez sur Echap puis tapez :x et appuyez sur Entrée pour sauvegarder et quitter.

Et voilà ! En tapant https://dockge.mondomaine.fr, vous tomberez à présent sur la mire d'authentification de authentik.

Astuce : dans Dockge, dans les paramètres, vous pouvez désactiver l'authentification de Dockge afin de ne pas avoir à vous identifier deux fois. Attention, cela voudra dire que si vous avez exposé un port sur votre réseau local, il n'y aura plus aucune authentification.
  • Vous pouvez répétez l'opération pour chaque application que vous souhaitez protéger (si elle ne dipose pas d'intégration directe avec Authentik).

Voilà votre nouvelle architecture :

Picture

Protéger un service sur un serveur distant


Dans le cas d'une application native (via OAuth 2.0 ou autre), rien ne change.

Dans le cas d'une application non native à protéger derrière un reverse proxy, vous devrez déployer un avant-poste. Un avant-poste est un conteneur qui jouera le rôle de proxy local, c'est à dire que c'est vers ce conteneur que les requêtes d'authentification de vos applications seront redirigées. C'est le seul qui est autorisé à dialoguer avec l'API de votre instance authentik.

Pré-requis :
  • Avoir installé docker sur votre machine distante hébergeant le service à protéger.
  • Si l'application n'a pas d'intégration native, avoir un reverse proxy compatible. Comme partout ici, nous utiliserons SWAG.

Ce conteneur redirigera ensuite les requetes vers votre instance Authentik principale, à travers le web (ou votre réseau local). Le serveur executera les controle et renverra la réponse à l'avant-poste, qui bloquera ou non la connexion à l'app protégée.

auth-outpost

Configuration d'Authentik

Créez vos fournisseurs et applications comme nous l'avons vu plus haut.

Puis, dans votre panneau admin, allez dans la rubrique Applications > Avant-postes, puis créez un nouvel avant-poste.

Remplissez comme suit :

ChampsValeur
NomLe nom que vous souhaitez
TypeProxy
IntégrationLaissez vide
ApplicationsSélectionnez le ou les applications que vous avez créées précédemment

Dans la section Paramètres avancés, supprimez l'existant, et complétez comme suit :

log_level: info
docker_labels: null
authentik_host: https://domaine_de_votre_serveur_authentik/
object_naming_template: ak-outpost-%(name)s
authentik_host_insecure: false
container_image:
docker_network: null
docker_map_ports: true
docker_labels: null

Enrtegistrez et quittez.

Sur l'écran affichant les avant-postes créés, vous verrez le nouvel avant-poste que vous venez de créer. A la fin de la ligne, cliquez sur afficher les informations, et copiez précieusement le jeton d'accès.

Configuration de la machine distante

Nous partons du principe que vous avez déjà installé Docker et SWAG sur cette machine distante.

Sur votre machine distante, à l'aide de Dockge, créez une stack authentik-outpost.

Si vous n'avez pas installé Dockge, créez un dossier /docker/authentik-outpost, ou directement en ligne de commande :

sudo mkdir -P /docker/authentik-outpost
Astuce pour les allergiques au terminal : vous pouvez utiliser File Browser pour naviguer dans vos fichier et éditer vos documents au lieu d'utiliser les commandes du terminal.

Créez le fichier compose.yaml ou copiez la configuration directement dans le champs si vous avez Dockge

En ligne de commande :

sudo vi /docker/authentik-outpost/compose.yaml

Entrez en mode modification avec i et collez la configuration suivante, en changeant les chiffres de {AUTHENTIK_TAG:proxy:2024.2.3} par la meme version que celle de votre serveur Authentik.

version: "3.5"
services:
  authentik_proxy:
    container_name: authentik-outpost
    image: ghcr.io/goauthentik/proxy:2024.2.3
    # Optionally specify which networks the container should be
    # might be needed to reach the core authentik server
    restart: unless-stopped
    env_file:
      - .env
    networks:
      - swag_default
    #   - foo
    ports:
      - 9000:9000
      - 9443:9443
    environment:
      AUTHENTIK_HOST: ${HOST}
      AUTHENTIK_INSECURE: "false"
      AUTHENTIK_TOKEN: ${TOKEN}
      # Starting with 2021.9, you can optionally set this too
      # when authentik_host for internal communication doesn't match the public URL
      # AUTHENTIK_HOST_BROWSER: https://external-domain.tld
networks:
  swag_default:
    name: swag_default
    external: true

Appuyez sur Echap puis tapez :x et appuyez sur Entrée pour sauvegarder et quitter.

  • Ici nous partons du principe que le réseau de Swag est swag_default.

Creez (ou remplissez directement si vous avez Dockge) le fichier .env dans le même dossier.

En ligne de commande :

sudo vi /docker/authentik-outpost/.env

Entrez en mode modification avec i et collez la configuration suivante

HOST=
TOKEN=

Remplissez comme suit

VariableValeurExemple
HOSTL'url de votre serveur authentikhttps://auth.domaine.fr
TOKENLe token que vous avez précédemment copié précieusementQ2pVEqsTNRkJSO9SkJzU3KZ2

Appuyez sur Echap puis tapez :x et appuyez sur Entrée pour sauvegarder et quitter.

Si vous avez Dockge, déployez la stack.

Sinon, via le terminal :

cd /docker/authentik-outpost/
sudo docker compose up -d

Le conteneur est en route, vous pouvez vérifier son état dans votre panneau admin de votre instance Authentik, section Applications > Avant-postes.

Nous allons a présent configurer SWAG.

Ouvrez le fichier authentik-server.conf.

sudo vi /docker/swag/config/nginx/authentik-server.conf

Dans le fichier, passez en mode modification en tapant i et changez authentik-server par authentik-outpost comme suit :

set $upstream_authentik authentik-outpost;
proxy_pass http://$upstream_authentik:9000;

Sauvegardez et quittez en tapant sur Echap puis :x et sur Entrée.

Ensuite, configurez les applications à protéger selon si elles sont natives ou par proxy comme vous l'avez fait sur votre serveur principal.

Migrer une base authentik


Sur la machine d'origine, dumper la bdd :

sudo docker exec authentik-postgres pg_dump -U authentik -F t authentik > /path/to/mydb.tar

Puis l'envoyer sur la machine cible. Sur la machine cible, copier le fichier dans le container docker

cp /path/to/mydb.tar authentik-postgres:/path/to/wherever

(Optionnel) Purgez les tables existantes :

sudo docker exec -i authentik-postgres psql -U authentik -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'authentik' AND pid <> pg_backend_pid();" && \
sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "DROP DATABASE IF EXISTS authentik;" && \
sudo docker exec -i authentik-postgres psql -U authentik -d postgres -c "CREATE DATABASE authentik;" && \

Restaurez la bdd

sudo docker exec authentik-postgresql pg_restore -U authentik -d authentik /path/to/wherever/mydb.tar