Nginx comme reverse proxy : routage, TLS et sécurité pour une infrastructure auto-hébergée
Dans une infrastructure auto-hébergée où cohabitent plusieurs services — Gitea, Nextcloud, CKAN, Keycloak, Grafana — la question du point d’entrée réseau se pose rapidement. Nginx, utilisé comme reverse proxy, permet de centraliser le routage, gérer les certificats TLS et appliquer des règles de sécurité communes à l’ensemble des services. C’est une brique fondamentale, souvent sous-estimée, qui conditionne la fiabilité et la sécurité de toute l’infrastructure.
Pourquoi un reverse proxy ?
Un reverse proxy se place entre les clients (navigateurs, API consumers) et vos services internes. Il remplit plusieurs rôles essentiels :
- Routage par nom de domaine : un seul serveur avec une seule IP publique peut distribuer le trafic vers différents services internes selon le nom d’hôte demandé (git.mondomaine.fr, cloud.mondomaine.fr, data.mondomaine.fr).
- Terminaison TLS : les certificats SSL/TLS sont gérés en un point unique. Les services internes communiquent en HTTP simple sur le réseau local, ce qui simplifie leur configuration.
- Sécurité périmétrique : filtrage des en-têtes, limitation de débit (rate limiting), protection contre certaines attaques courantes (slowloris, requêtes malformées).
- Performances : mise en cache de contenu statique, compression gzip/brotli, gestion des connexions persistantes.
Architecture type avec Nginx
Dans un déploiement classique basé sur Docker, Nginx s’installe comme conteneur dédié (ou directement sur l’hôte) et redirige chaque requête entrante vers le bon conteneur en fonction du virtual host. Voici un schéma simplifié :
Internet
│
▼
┌─────────────────────┐
│ Nginx (port 443) │
│ Terminaison TLS │
│ Routage vhosts │
└──────┬──────┬───────┘
│ │
┌────▼──┐ ┌─▼──────┐
│ Gitea │ │Nextcloud│ ...autres services
│ :3000 │ │ :8080 │
└───────┘ └────────┘
Chaque service écoute sur un port interne, inaccessible depuis l’extérieur. Seul Nginx expose les ports 80 (redirection) et 443 (HTTPS).
Configuration d’un virtual host
La configuration Nginx pour un service type suit un patron récurrent. Voici un exemple pour Gitea :
server {
listen 443 ssl http2;
server_name git.mondomaine.fr;
ssl_certificate /etc/letsencrypt/live/git.mondomaine.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.mondomaine.fr/privkey.pem;
# En-têtes de sécurité
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Referrer-Policy strict-origin-when-cross-origin;
location / {
proxy_pass http://gitea:3000;
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;
}
}
Ce bloc se duplique pour chaque service, en adaptant le server_name et le proxy_pass. L’avantage : chaque service n’a besoin de connaître que son propre port interne.
Automatiser les certificats avec Let’s Encrypt
La gestion manuelle des certificats TLS est fastidieuse et source d’erreurs. Certbot, le client officiel de Let’s Encrypt, s’intègre directement avec Nginx pour obtenir et renouveler automatiquement les certificats :
# Obtenir un certificat certbot --nginx -d git.mondomaine.fr # Renouvellement automatique (cron ou timer systemd) certbot renew --quiet
Avec un timer systemd ou une tâche cron quotidienne, le renouvellement devient transparent. Certbot modifie directement la configuration Nginx et recharge le service sans interruption.
Durcissement : aller plus loin que la configuration par défaut
La configuration par défaut de Nginx est fonctionnelle mais insuffisante en production. Quelques ajustements importants :
- Protocoles TLS : désactiver TLS 1.0 et 1.1, ne conserver que TLS 1.2 et 1.3 (
ssl_protocols TLSv1.2 TLSv1.3;). - Suites de chiffrement : utiliser une liste restrictive de ciphers modernes pour éviter les algorithmes vulnérables.
- Rate limiting : limiter le nombre de requêtes par IP pour atténuer les attaques par force brute, notamment sur les pages de connexion.
- Taille des requêtes : configurer
client_max_body_sizeselon les besoins (upload Nextcloud vs API légère). - Logs structurés : formater les logs en JSON pour faciliter leur ingestion par un stack d’observabilité (Loki, Elasticsearch).
# Rate limiting sur la page de login
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
server {
...
location /user/login {
limit_req zone=login burst=3 nodelay;
proxy_pass http://gitea:3000;
}
}
Nginx et Docker Compose : un duo naturel
Dans un environnement Docker Compose, Nginx peut résoudre les noms de services directement via le réseau Docker interne. Il suffit de placer Nginx et les services dans le même réseau :
# docker-compose.yml (extrait)
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certbot/conf:/etc/letsencrypt
networks:
- frontend
gitea:
image: gitea/gitea:latest
networks:
- frontend
expose:
- "3000"
networks:
frontend:
driver: bridge
Avec expose au lieu de ports, les services restent accessibles uniquement via le réseau Docker interne — jamais directement depuis l’extérieur.
Alternatives et compléments
Nginx n’est pas la seule option. Traefik, par exemple, offre une découverte automatique des services Docker et une gestion intégrée de Let’s Encrypt via des labels. Caddy propose une configuration minimaliste avec HTTPS automatique par défaut. Cependant, Nginx reste le choix le plus répandu, le mieux documenté, et le plus flexible pour des configurations avancées (réécriture d’URL, authentification par sous-requête, streaming WebSocket).
Pour les infrastructures plus complexes, HAProxy apporte des fonctionnalités avancées de load balancing (algorithmes round-robin pondérés, health checks actifs) qui complètent bien un Nginx en frontal.
En résumé
Nginx en reverse proxy est le point de départ de toute infrastructure auto-hébergée sérieuse. Il centralise la gestion TLS, simplifie le routage multi-services, et offre un premier niveau de sécurité indispensable. Combiné à Let’s Encrypt et Docker Compose, il permet de monter une architecture solide avec un minimum de friction. L’investissement initial dans une bonne configuration Nginx se rentabilise à chaque nouveau service ajouté à l’infrastructure.
