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/24ListenPort = 51820PrivateKey = <VPS_PRIVATE_KEY>
# Règles iptables pour autoriser le forwardingPostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEPostDown = 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/32Sur le serveur domestique (client WireGuard)
Fichier /etc/wireguard/wg0.conf :
[Interface]Address = 10.100.0.2/24PrivateKey = <HOME_PRIVATE_KEY>
[Peer]PublicKey = <VPS_PUBLIC_KEY>Endpoint = <IP_PUBLIQUE_DU_VPS>:51820AllowedIPs = 10.100.0.1/32PersistentKeepalive = 25Après activation, vérifiez la connectivité :
# Sur le VPSping -c 3 10.100.0.22) 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.ymlExemple 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/ParisExtrait 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_factor3) 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érificationlocation /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é)
- Le client DNS résout
sonarr.mon-domaine.comvers l’IP publique du VPS. - Nginx reçoit la requête et appelle Authelia (
auth_request /authelia). - Si l’utilisateur n’est pas authentifié → redirection vers
auth.mon-domaine.com. - Si authentifié → Nginx proxifie la requête vers
10.100.0.2(interface WireGuard). - 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) ?