Je vous ai présenté, à travers plusieurs articles, Keycloak, comme étant une solution de SSO pour des applications, utilisant notamment le standard OIDC (OpenID Connect).
Nous allons voir aujourd'hui une solution similaire, que je trouve, pour ma part, plus léger et plus simple à mettre en place. Et cette solution se nomme : Authelia !
Authelia agit comme une "extension" à un reverse proxy, en voici les principaux :
-
Traefik
-
Nginx
-
HAProxy
À l'heure actuelle l'intégration avec Apache2 n'est malheureusement pas possible, voici l'explication fournie par la documentation :
Apache has no module that supports this kind of authentication method. It’s not certain this would even be possible, however if anyone did something like this in the past we’d be interested in a contribution.
Dans cet article nous allons installer Authelia en conteneur, avec Traefik. À noter que la version de Traefik utilisée est la suivante : traefik:2.4.
Installation
Vous aurez besoin de quatre entrées DNS à faire, pointant sur votre instance :
-
authelia.yourdomain.fr.
-
public.yourdomain.fr.
-
traefik.yourdomain.fr.
-
secure.yourdomain.fr.
Cloner le projet GitHub :
git clone https://github.com/authelia/authelia.git
cd authelia/examples/compose/lite
git checkout $(git describe --tags 'git rev-list --tags --max-count=1')
Préparer le fichier de configuration authelia/examples/compose/lite/authelia/configuration.yml
avec notamment :
default_redirection_url: https://public.yourdomain.fr
...
access_control:
default_policy: deny
rules:
# Rules applied to everyone
- domain: public.yourdomain.fr
policy: bypass
- domain: traefik.yourdomain.fr
policy: one_factor
- domain: secure.yourdomain.fr
policy: two_factor
...
session:
...
domain: yourdomain.fr
...
### Si vous n'avez pas de SMTP configuré :
notifier:
disable_startup_check: false
filesystem:
filename: /config/notification.txt
Et voici le joli docker-compose.yml
:
---
version: '3.3'
networks:
net:
driver: bridge
services:
authelia:
image: authelia/authelia
container_name: authelia
volumes:
- ./authelia:/config
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.authelia.rule=Host(`authelia.yourdomain.fr`)'
- 'traefik.http.routers.authelia.entrypoints=https'
- 'traefik.http.routers.authelia.tls=true'
- 'traefik.http.routers.authelia.tls.certresolver=letsencrypt'
- 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/verify?rd=https://authelia.yourdomain.fr' # yamllint disable-line rule:line-length
- 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
- 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email' # yamllint disable-line rule:line-length
expose:
- 9091
restart: unless-stopped
healthcheck:
disable: true
environment:
- TZ=Australia/Melbourne
redis:
image: redis:alpine
container_name: redis
volumes:
- ./redis:/data
networks:
- net
expose:
- 6379
restart: unless-stopped
environment:
- TZ=Australia/Melbourne
traefik:
image: traefik:2.4
container_name: traefik
volumes:
- ./traefik:/etc/traefik
- /var/run/docker.sock:/var/run/docker.sock
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.api.rule=Host(`traefik.yourdomain.fr`)'
- 'traefik.http.routers.api.entrypoints=https'
- 'traefik.http.routers.api.service=api@internal'
- 'traefik.http.routers.api.tls=true'
- 'traefik.http.routers.api.tls.certresolver=letsencrypt'
- 'traefik.http.routers.api.middlewares=authelia@docker'
ports:
- 80:80
- 443:443
command:
- '--api'
- '--providers.docker=true'
- '--providers.docker.exposedByDefault=false'
- '--entrypoints.http=true'
- '--entrypoints.http.address=:80'
- '--entrypoints.http.http.redirections.entrypoint.to=https'
- '--entrypoints.http.http.redirections.entrypoint.scheme=https'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:443'
- '--certificatesResolvers.letsencrypt.acme.email=email@yourdomain.fr'
- '--certificatesResolvers.letsencrypt.acme.storage=/etc/traefik/acme.json'
- '--certificatesResolvers.letsencrypt.acme.httpChallenge.entryPoint=http'
- '--log=true'
- '--log.level=DEBUG'
secure:
image: traefik/whoami
container_name: secure
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.secure.rule=Host(`secure.yourdomain.fr`)'
- 'traefik.http.routers.secure.entrypoints=https'
- 'traefik.http.routers.secure.tls=true'
- 'traefik.http.routers.secure.tls.certresolver=letsencrypt'
- 'traefik.http.routers.secure.middlewares=authelia@docker'
expose:
- 80
restart: unless-stopped
public:
image: traefik/whoami
container_name: public
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.public.rule=Host(`public.yourdomain.fr`)'
- 'traefik.http.routers.public.entrypoints=https'
- 'traefik.http.routers.public.tls=true'
- 'traefik.http.routers.public.tls.certresolver=letsencrypt'
- 'traefik.http.routers.public.middlewares=authelia@docker'
expose:
- 80
restart: unless-stopped
Concrètement, voici le rôle des différents services :
-
Authelia : Le gestionnaire d'authentification
-
Redis : Stockage de données en mode clé-valeur
-
Traefik : Le reverse-proxy pour conteneur(s)
-
Secure : Exemple d'application (en l'occurence Whoami (https://hub.docker.com/r/containous/whoami) pour démontrer l'authentification 'two_factor')
-
Public : Exemple d'application (en l'occurence Whoami (https://hub.docker.com/r/containous/whoami) pour démontrer l'authentification 'one_factor')
On démarre le conteneur :
cd authelia/examples/compose/lite
docker-compose up -d
Allons tout d'abord sur le panel Authelia :
Les identifiants par défaut sont : authelia / authelia
.
Vous êtes alors invité à configurer l'authentification en deux facteurs. Nous avons testé via OTP (à travers l'application Authy) et via YubiKey (notamment avec la version biométrique). Cliquez sur Register device, le lien pour ajouter l'appareil vous sera soit envoyé par email, ou dans le fichier suivant : authelia/examples/compose/lite/authemlia/notification.txt
:
Date: 2021-11-04 01:33:11.592220184 +1100 AEDT m=+3124.704944362
Recipient: authelia@authelia.com
Subject: Register your mobile
Body:
This email has been sent to you in order to validate your identity.
If you did not initiate the process your credentials might have been compromised. You should reset your password and contact an administrator.
To setup your 2FA please visit the following URL: https://authelia.yourdomain.fr/one-time-password/register?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJBdXRoZWxpYSIsImV4cCI6MTYzNTk1MDI5MSwiYWN0aW9uIjoiUmVnaXN0ZXJUT1RQRGV2aWNlIiwidXNlcm5hbWUiOiJhdXRoZWxpYSJ9.8DNABo4Z7ftH9Y25d3mtqzjPRpOZi6GdpriVSCAbT5M
Please contact an administrator if you did not initiate the process.
Ajouter une application
Supposons que nous avons une application web toute simple, on va ajouter un conteneur web Nginx utilisant cette image : https://hub.docker.com/r/yeasy/simple-web/
On va devoir rajouter une entrée DNS pour cette app : app1.yourdomain.fr par exemple. Puis rajouter ceci dans le docker-compose.yml
:
app1:
image: yeasy/simple-web
container_name: app1
networks:
- net
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.app1.rule=Host(`app1.yourdomain.fr`)'
- 'traefik.http.routers.app1.entrypoints=https'
- 'traefik.http.routers.app1.tls=true'
- 'traefik.http.routers.app1.tls.certresolver=letsencrypt'
- 'traefik.http.routers.app1.middlewares=authelia@docker'
Ensuite, il faut choisir le mode d'authentification pour cette nouvelle application (voir : https://www.authelia.com/docs/configuration/access-control.html) ; pour l'exemple nous allons choisir two_factor. Dans authelia/examples/compose/lite/authelia/configuration.yml
:
access_control:
...
rules:
...
- domain: app1.yourdomain.fr
policy: two_factor
Et c'est tout ! Redémarrer les services :
docker-compose down && docker-compose up -d
En lecture complémentaire, voici les précédents articles émanant de l'approche du SSO :
- Comment nous avons créé une architecture SSO : Nextcloud + Keycloak + YubiKey
- Les différents modes d'authentification sous Keycloak