Caddy et Authelia : publier ses sites en HTTPS avec une connexion sécurisée, expliqué simplement

Un reverse proxy, c'est quoi ? Caddy et son HTTPS automatique, Caddy ou Nginx Proxy Manager, Authelia pour une connexion unique avec double authentification, trois points d'attention, et caddy-hosts, un petit script open source pour gérer ses sites.

Quand on héberge soi-même plusieurs sites ou applications derrière une seule adresse IP, on se retrouve vite avec les mêmes questions : comment servir blog.example.com et wiki.example.com sur le même serveur ? Comment obtenir le petit cadenas HTTPS sans y penser ? Et comment réserver certaines pages à soi-même, avec un vrai mot de passe et une double authentification ? Deux outils libres répondent à ces trois questions : Caddy et Authelia. Voici comment ils fonctionnent, expliqué sans jargon, avec un petit script maison à la fin.

Schéma : un visiteur arrive sur Caddy, qui sert deux sites publics et interroge Authelia (mot de passe + 2FA) avant de donner accès à un site protégé

Un reverse proxy, c'est quoi ? #

Imaginez l'accueil d'un immeuble de bureaux. Les visiteurs ne se promènent pas dans les couloirs : ils donnent le nom de la personne qu'ils viennent voir, et l'hôtesse les oriente. Un reverse proxy joue ce rôle pour vos sites. Il reçoit toutes les requêtes sur les ports 80 et 443, regarde le nom de domaine demandé, et transmet la requête à la bonne application, qui tourne souvent sur un port interne ou dans un autre conteneur.

Il apporte trois choses :

  • une seule porte d'entrée à surveiller
  • le HTTPS géré à un seul endroit
  • la possibilité d'ajouter des protections (authentification, journaux, limitation) sans toucher aux applications.

Caddy : le HTTPS sans y penser #

Caddy est un serveur web et reverse proxy écrit en Go, distribué sous forme d'un seul binaire. Sa particularité : le HTTPS est automatique. Dès qu'un nom de domaine pointe vers votre serveur, Caddy obtient le certificat Let's Encrypt, l'installe et le renouvelle seul. Un site complet tient en quelques lignes :

blog.example.com {
	reverse_proxy 10.0.0.5:8080
}

wiki.example.com {
	encode zstd gzip
	reverse_proxy 10.0.0.6:3000
}

C'est tout : deux sites, deux certificats, la redirection de HTTP vers HTTPS, et HTTP/2 et HTTP/3 actifs. Le fichier de configuration, le Caddyfile, se lit presque comme une phrase.

Caddy ou Nginx Proxy Manager ? #

Nginx Proxy Manager (NPM) est l'autre réponse très populaire à ce besoin. C'est une interface web posée sur Nginx : on clique sur « Add Proxy Host », on saisit le domaine, l'adresse de destination, on coche « Request a new SSL certificate », et c'est en ligne. Aucun des deux n'est « meilleur » : ils ne s'adressent pas tout à fait aux mêmes habitudes.

CaddyNginx Proxy Manager
ConfigurationUn fichier texte lisibleInterface web (stockée dans une base de données)
HTTPSAutomatique,  rien à cocherUn certificat à demander par host dans l'interface
DémarrageUn binaire, ou un paquet systèmeDocker (application + base de données)
Sauvegarde et versionnageDes fichiers : Git, copie, diffExport de la base de données
AutomatisationFacile (fichiers, scripts, API)Surtout manuelle, via l'interface
Connexion centralisée (SSO, 2FA)Une directive, forward_authPossible, mais en écrivant de la configuration Nginx avancée
Trafic TCP/UDP (non web)Nécessite un module en plusIntégré (« Streams »)

Mon avis : NPM est parfait pour démarrer si vous préférez cliquer plutôt qu'écrire, ou si vous avez besoin de rediriger des flux TCP simplement. Caddy devient très agréable dès qu'on veut une configuration qu'on peut relire, versionner, copier d'un serveur à l'autre ou générer par script. C'est ce second profil qui me fait préférer Caddy.

Un fichier par site #

Avec le temps, le Caddyfile grossit. Une organisation simple consiste à ne garder qu'une ligne dans le fichier principal et un fichier par site :

# /etc/caddy/Caddyfile
import sites/*.caddy

Ajouter ou retirer un site revient alors à créer ou supprimer un fichier dans /etc/caddy/sites/. Pour éviter de le faire à la main (et de rater une accolade), j'ai écrit un petit script en Bash, caddy-hosts, que j'ai publié en open source :

caddy-hosts add app.example.com 10.0.0.5:8080 "mon appli"
caddy-hosts list
caddy-hosts show app.example.com
caddy-hosts del app.example.com

Ce qu'il apporte : chaque modification est validée avant d'être appliquée (caddy validate), et annulée automatiquement si elle est invalide, donc une faute de frappe ne coupe jamais vos sites. Chaque site reçoit aussi son propre journal d'accès au format JSON, pratique pour les outils d'analyse comme CrowdSec. Le code et le mode d'emploi sont sur github.com/xavfmp/caddy-hosts.

Authelia : une seule connexion pour tout #

Certaines applications n'ont pas de système de connexion, ou un système faible : une interface d'administration, un tableau de bord, un outil interne. Authelia règle ce problème une fois pour toutes. C'est un portail d'authentification qui se place devant vos applications et propose :

  • une connexion unique (SSO) pour tous vos sous-domaines : on se connecte une fois, on est reconnu partout ;

la double authentification (application TOTP, clé de sécurité WebAuthn…) ;

  • des règles d'accès fines : tel domaine ou tel chemin demande un mot de passe et un second facteur, tel autre est public.

Le principe, côté Caddy, tient en une directive, forward_auth. Avant de laisser passer une requête vers l'application, Caddy demande à Authelia : « cette personne a-t-elle le droit ? ». Si oui, la requête continue. Sinon, le visiteur est redirigé vers le portail de connexion, puis renvoyé à la page qu'il voulait voir.

admin.example.com {
	forward_auth authelia:9091 {
		uri /api/authz/forward-auth
		copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
	}
	reverse_proxy 10.0.0.7:3000
}

Avec caddy-hosts, on obtient le même résultat en ajoutant l'option --protect :

AUTHELIA_UPSTREAM=authelia:9091 caddy-hosts add admin.example.com 10.0.0.7:3000 --protect

Trois points d'attention #

Ces points ne sont pas des défauts : ce sont des choses à connaître, parce que l'outil fait exactement ce qu'on lui demande, ni plus ni moins.

1. La protection se déclare à deux endroits #

Une règle d'accès côté Authelia ne protège rien toute seule : elle ne s'applique qu'aux requêtes qui arrivent réellement jusqu'à Authelia. C'est donc le site, côté Caddy, qui doit appeler forward_auth. Retenez la règle : Authelia dit qui a le droit, Caddy décide d'envoyer la question. Quand on vérifie qu'un site est bien protégé, on regarde donc la destination de la redirection :

curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" https://admin.example.com/

Un code 302 seul ne prouve rien : une application peut aussi rediriger vers sa propre page de connexion. La bonne réponse est une redirection vers votre portail Authelia, avec le paramètre rd= qui indique la page d'origine.

Dernier détail : le portail Authelia lui-même ne doit pas être placé derrière forward_auth, sinon personne ne pourrait plus se connecter.

2. Avec un Authelia sur un autre serveur, il faut faire confiance au proxy #

On peut très bien utiliser un Authelia hébergé ailleurs. Le Caddy qui est devant lui doit alors être informé qu'il peut faire confiance aux en-têtes X-Forwarded-* envoyés par votre propre serveur. Par prudence, Caddy les ignore et les remplace par défaut, et Authelia croirait alors que la page visée est le portail lui-même. On le déclare une fois, dans la configuration globale du Caddy distant :

{
	servers {
		trusted_proxies static 203.0.113.10
	}
}

où 203.0.113.10 est l'adresse publique de votre serveur. Sur le même réseau, rien de tel n'est nécessaire. Côté Authelia, pensez aussi à déclarer les domaines protégés dans ses règles d'accès, et à régler le domaine du cookie de session pour qu'il couvre tous vos sous-domaines.

3. Si Authelia est indisponible, les pages protégées le sont aussi #

C'est voulu : si le service qui vérifie les droits ne répond pas, Caddy préfère refuser l'accès que le laisser ouvert. C'est le bon comportement pour la sécurité, mais cela fait d'Authelia un point de dépendance. Une petite supervision (une sonde sur son adresse de santé, /api/health) évite de découvrir la panne le jour où l'on a besoin de son tableau de bord.

Par où commencer ?
Installez Caddy, pointez un nom de domaine vers votre serveur, et publiez un premier site avec trois lignes de Caddyfile.  Passez à un fichier par site, à la main ou avec caddy-hosts. Ajoutez Authelia quand vous avez une première page à protéger, en commençant par un seul site.

Si vous préférez les interfaces graphiques, Nginx Proxy Manager reste un excellent point de départ. Et si vous essayez caddy-hosts, les retours et les contributions sont les bienvenus sur GitHub.

https://github.com/xavfmp/caddy-hosts

Pour ne rien manquer : le flux RSS du blog.

À lire aussi