Aller au contenu

Configurer ZeroTrust HTTP auth (Authelia & Nginx)

Quand j’ai commencé l’auto-hébergement, j’ai rapidement fait face à un dilemme de sécurité : comment accéder à mes services (Home Assistant, *Arrs, Nextcloud) depuis l’extérieur sans ouvrir mon réseau domestique aux quatre vents ?

La méthode classique consiste à ouvrir les ports 80/443 de sa box. J’ai toujours refusé cette approche, car elle exposerait mon IP résidentielle (et donc ma localisation) et augmenterait considérablement ma surface d’attaque.

Dans cet article, je détaille l’architecture que j’ai mise en place : aucun port entrant sur le routeur domestique. J’utilise un VPS public pour gérer TLS et l’authentification (Authelia) puis je proxifie le trafic via un tunnel WireGuard vers mon LAN.

Architecture cible

  • VPS (public) : héberge Nginx (reverse proxy) et Authelia — seule machine exposée à Internet.
  • Tunnel VPN (WireGuard) : relie le VPS à mon serveur domestique.
  • LAN (privé) : les services (Home Assistant, Sonarr, etc.) tournent ici ; le serveur domestique initie la connexion VPN.

1) Tunnel VPN (la colonne vertébrale)

J’ai choisi WireGuard pour sa simplicité et ses performances. Voici des exemples de configuration.

Sur le VPS (serveur WireGuard)

Fichier /etc/wireguard/wg0.conf :

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <VPS_PRIVATE_KEY>
# Règles iptables pour autoriser le forwarding
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <HOME_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32

Sur le serveur domestique (client WireGuard)

Fichier /etc/wireguard/wg0.conf :

[Interface]
Address = 10.100.0.2/24
PrivateKey = <HOME_PRIVATE_KEY>
[Peer]
PublicKey = <VPS_PUBLIC_KEY>
Endpoint = <IP_PUBLIQUE_DU_VPS>:51820
AllowedIPs = 10.100.0.1/32
PersistentKeepalive = 25

Après activation, vérifiez la connectivité :

Fenêtre de terminal
# Sur le VPS
ping -c 3 10.100.0.2

2) Authelia (authentification / SSO)

Authelia sert de guardien : il valide les sessions et gère le 2FA. Je l’ai déployé en Docker sur le VPS.

Arborescence recommandée

/opt/authelia/
├── config/
│ └── configuration.yml
└── docker-compose.yml

Exemple docker-compose.yml

version: '3.8'
services:
authelia:
image: authelia/authelia
container_name: authelia
volumes:
- ./config:/config
ports:
- 9091:9091
restart: always
environment:
- TZ=Europe/Paris

Extrait de configuration.yml (accès)

# ... JWT, session, storage, notifier ...
access_control:
default_policy: deny
rules:
# Autoriser l'accès à Authelia lui-même
- domain: 'auth.mon-domaine.com'
policy: bypass
# Protéger tous les services du domaine avec 2FA
- domain: '*.mon-domaine.com'
policy: two_factor

3) Nginx (le chef d’orchestre)

Nginx sur le VPS gère TLS (Let’s Encrypt), interroge Authelia via auth_request et proxifie le trafic vers l’IP WireGuard du serveur domestique.

Snippet Authelia (/etc/nginx/snippets/authelia.conf)

# Endpoint interne pour la vérification
location /authelia {
internal;
proxy_pass http://127.0.0.1:9091/api/verify;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
# Redirection vers le portail d'authentification si non autorisé
error_page 401 =302 https://auth.mon-domaine.com/?rd=$target_url;

Exemple de configuration d’un site (Sonarr)

Fichier /etc/nginx/sites-available/sonarr.mon-domaine.com :

server {
listen 443 ssl http2;
server_name sonarr.mon-domaine.com;
# Certificat (géré par Certbot)
ssl_certificate /etc/letsencrypt/live/mon-domaine.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mon-domaine.com/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# --- Authentification via Authelia ---
include /etc/nginx/snippets/authelia.conf;
auth_request /authelia;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
set $target_url $scheme://$http_host$request_uri;
location / {
# Proxy vers le service sur le LAN via WireGuard
proxy_pass http://10.100.0.2:8989;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

Flux de requête (résumé)

  1. Le client DNS résout sonarr.mon-domaine.com vers l’IP publique du VPS.
  2. Nginx reçoit la requête et appelle Authelia (auth_request /authelia).
  3. Si l’utilisateur n’est pas authentifié → redirection vers auth.mon-domaine.com.
  4. Si authentifié → Nginx proxifie la requête vers 10.100.0.2 (interface WireGuard).
  5. Le serveur domestique reçoit la requête via le tunnel et la transmet au service (ex. Sonarr sur localhost:8989).

Avantages de cette approche

  • Le réseau domestique reste complètement privé : seule l’IP du VPS est exposée.
  • Contrôle fin des accès via Authelia (2FA, règles par sous-domaine).
  • Portable : le client domestique initie la connexion (fonctionne derrière CGNAT ou réseaux mobiles).

Si tu veux, je peux :

  • Te fournir des fichiers de configuration prêts à l’emploi (WireGuard / Authelia / Nginx).
  • T’aider à adapter les exemples à ton domaine et à ton réseau.

Veux-tu que je génère les fichiers de configuration adaptés (avec placeholders sécurisés) ?