- HTML 60.7%
- JavaScript 39%
- Dockerfile 0.3%
|
All checks were successful
Docker Build on Tag / build-and-push (push) Successful in 7s
|
||
|---|---|---|
| .forgejo/workflows | ||
| nginx-dashboard | ||
| CHANGELOG.md | ||
| docker-compose.yml | ||
| README.md | ||
| sample.env | ||
Nginx Reverse Proxy Stack
Stack Docker complète pour un reverse proxy Nginx avec dashboard de monitoring intégré, authentification, API REST, déploiement Git, sauvegardes, générateur de vhost, et intégrations CrowdSec + GoAccess.
Fonctionnalités
Nginx
- Image officielle Nginx (trixie) avec modules compilés
- Génération dynamique de
nginx.confvia variables d'environnement - Modules : GeoIP2, headers-more, subs-filter, VTS, stream TCP/UDP
Dashboard
- Interface web sombre, temps réel, bilingue EN/FR
- Authentification login/mot de passe avec système de rôles
- API REST complète avec Bearer token
- Webhooks HTTP sur événements
- Zéro port supplémentaire à exposer (proxy interne)
Intégrations optionnelles
- GeoIP2 — filtrage géographique MaxMind (profil
geo) - Certbot — SSL wildcard via DNS Cloudflare (profil
ssl) - CrowdSec — dashboard Prometheus (décisions locales vs CAPI, alertes, parser)
- GoAccess — analyse des logs par vhost, rapport HTML temps réel intégré
Modules Nginx inclus
| Module | Usage |
|---|---|
ngx_http_geoip2_module |
Filtrage par pays (MaxMind GeoLite2) |
ngx_http_headers_more_filter_module |
Suppression/modification des headers HTTP |
ngx_http_subs_filter_module |
Substitution de contenu à la volée |
ngx_http_vhost_traffic_status_module (VTS) |
Métriques temps réel par virtual host |
stream + stream_ssl_module |
Proxy TCP/UDP |
Structure des répertoires
.
├── conf/ → /etc/nginx/conf.d/*.conf
├── sites/ → /etc/nginx/sites/*.conf
├── snippets/ → /etc/nginx/snippets/*.conf
├── streams/ → /etc/nginx/streams/*.conf
├── ssl/ → certificats manuels (.cer, .key)
├── certs/ → Let's Encrypt / Certbot
├── geoip_data/ → bases MaxMind
├── logs/ → logs nginx (access, error, vhosts, par vhost)
├── backups/ → sauvegardes ZIP locales
├── goaccess/
│ ├── conf/ → goaccess-combined.conf, goaccess-vhost.conf (générés)
│ ├── db/ → persistance GoAccess par vhost
│ └── reports/ → rapports HTML générés
├── modules/ → modules .so nginx externes
├── cache/ → /var/cache/nginx/
├── cloudflare/ → credentials DNS (certbot)
├── nginx-dashboard/
│ ├── Dockerfile
│ ├── server.js
│ ├── public/index.html
│ └── config/users.yml
├── docker-compose.yml
└── sample.env
Format de log nginx — configuration requise
Le dashboard, GoAccess et CrowdSec se basent sur des formats de log précis. Deux formats sont supportés.
Format combined_vhost (recommandé — log global)
Inclut le nom du vhost en préfixe. Utilisé dans logging-config.conf :
log_format combined_vhost '$server_name $remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
Exemple de ligne générée :
example.com 1.2.3.4 - - [19/May/2026:10:00:00 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
Déclaration dans un virtualhost (log global) :
access_log /var/log/nginx/vhosts_access.log combined_vhost if=$is_not_static;
Format combined (standard — log dédié par vhost)
Format nginx standard, sans préfixe vhost. À utiliser quand chaque vhost a son propre fichier de log :
# Pas besoin de déclarer log_format combined — c'est le format par défaut nginx
access_log /var/log/nginx/example.com.access.log combined if=$is_not_static;
Exemple de ligne générée :
1.2.3.4 - - [19/May/2026:10:00:00 +0000] "GET / HTTP/1.1" 200 1234 "-" "Mozilla/5.0"
Détection automatique par GoAccess
Le dashboard détecte automatiquement le format en lisant la première ligne du fichier de log :
- Premier token = IP (
1.2.3.4) → formatcombined - Premier token = hostname (
example.com) → formatcombined_vhost
Aucune configuration manuelle nécessaire côté GoAccess.
Variable $is_not_static (optionnel)
Pour ne logger que les requêtes dynamiques (exclure JS/CSS/images) :
# Dans conf/logging-config.conf
map $request_uri $is_not_static {
~*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?|ttf|otf|map)(\?|$) 0;
~*\/robots\.txt 0;
default 1;
}
Installation
1. Prérequis
- Docker + Docker Compose v2
- Compte MaxMind (optionnel — GeoIP)
- Compte Cloudflare (optionnel — certbot DNS)
2. Configurer l'environnement
cp sample.env .env
Générer les secrets :
echo "NGINX_DASHBOARD_API_TOKEN=$(openssl rand -hex 32)" >> .env
echo "NGINX_DASHBOARD_SESSION_SECRET=$(openssl rand -hex 32)" >> .env
echo "NGINX_DASHBOARD_WEBHOOK_SECRET=$(openssl rand -hex 32)" >> .env
Important — ne pas mettre de guillemets autour des valeurs dans
.env
3. Créer la structure de dossiers
mkdir -p conf sites snippets streams ssl certs geoip_data logs \
backups goaccess/{conf,db,reports} modules cache cloudflare
4. Configurer les utilisateurs
Éditer nginx-dashboard/config/users.yml — les mots de passe en clair sont hashés automatiquement au premier démarrage :
users:
- username: admin
password: mon-mot-de-passe
role: admin
name: Administrateur
enabled: true
5. Activer les modules nginx
# VTS (requis pour le dashboard)
cp conf/vts-settings_conf.DISABLE conf/vts-settings.conf
cp nginx-dashboard/vts-status.conf sites/vts-status.conf
# GeoIP (si compte MaxMind)
cp conf/geoip2-load-database_conf.DISABLE conf/geoip2-load-database.conf
# Filtrage géographique (optionnel)
cp snippets/allow-visit-001_conf.DISABLE snippets/allow-visit-001.conf
6. Build et lancement
docker compose build nginx-dashboard
docker compose up -d
Dashboard : http://serveur:3000 — login par défaut admin / admin (à changer immédiatement)
Dashboard — Pages et fonctionnalités
Monitoring
| Page | Contenu |
|---|---|
| Overview | Stat cards (requêtes, connexions, erreurs, trafic), graphique historique |
| Virtual Hosts | Stats VTS par vhost — requêtes, codes HTTP, trafic |
| Upstreams | Backends avec temps de réponse |
Configuration
| Page | Contenu |
|---|---|
| Config files | Explorateur sites/conf/snippets/streams avec coloration syntaxique nginx |
| SSL Certificates | Analyse certs manuels + Let's Encrypt — expiration, SANs, fingerprint |
| Live logs | Stream SSE par fichier .log, filtres, pause, auto-scroll |
Déploiement et sauvegardes
| Page | Contenu |
|---|---|
| Git Deployment | Pull, diff, test éphémère, pipeline complet, gestion branche backup |
| Backups | ZIP locaux (configs + certs LE), téléchargement, restauration, backup manuel |
Configuration
| Page | Contenu |
|---|---|
| VHost Generator | Générateur de config reverse proxy avec brouillons localStorage |
Contrôle
| Page | Contenu |
|---|---|
| Nginx Control | Test config via conteneur éphémère, reload, statut |
| Events | Journal chronologique de toutes les actions |
Intégrations
| Page | Contenu |
|---|---|
| REST API | Documentation interactive avec test en direct |
| Webhooks | CRUD webhooks, test manuel |
| CrowdSec | Décisions locales vs CAPI, alertes, sources, santé parser (si configuré) |
| GoAccess | Analyse logs par vhost, rapport HTML temps réel (si configuré) |
Administration
| Page | Contenu |
|---|---|
| Users | Gestion utilisateurs, matrice permissions, sessions actives |
Authentification et rôles
| Permission | admin | operator | viewer |
|---|---|---|---|
| Métriques / VH / Upstreams | ✓ | ✓ | ✓ |
| Configs / SSL / Logs | ✓ | ✓ | ✓ |
| CrowdSec / GoAccess | ✓ | ✓ | ✓ |
| Reload / Test nginx | ✓ | ✓ | — |
| Déploiement Git / Sauvegardes | ✓ | ✓ | — |
| Webhooks | ✓ | — | — |
| Gestion utilisateurs | ✓ | — | — |
Snippets — métadonnées
Les snippets peuvent déclarer des métadonnées dans leur en-tête pour contrôler leur utilisation dans le générateur de vhost :
# name: proxy-common
# description: Headers proxy standard
# emplacement: server,location
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
| Champ | Valeurs | Défaut si absent |
|---|---|---|
name |
Libellé affiché | Nom du fichier sans .conf |
description |
Description courte | (vide) |
emplacement |
server, location, ou les deux |
server,location (universel) |
Les snippets ssl-*.conf sont automatiquement considérés comme emplacement: server uniquement.
Générateur de VHost
Le générateur produit une config reverse proxy nginx complète.
Sources SSL disponibles :
- Snippets
ssl-*.confdu dossiersnippets/— génèreinclude snippets/ssl-xxx.conf - Certificats manuels du dossier
ssl/— pré-remplitssl_certificateetssl_certificate_key - Certificats Let's Encrypt dans
certs/live/— pré-remplit avec les chemins Certbot
Mode Docker : coche "Docker container" pour générer :
set $backend http://mon-conteneur:3000;
resolver 127.0.0.11 valid=30s;
Brouillons : stockés dans localStorage, plusieurs nommés, téléchargement direct en .conf.
Déploiement : télécharger le fichier généré et le placer dans sites/ (manuellement ou via le déploiement Git).
Déploiement Git
Configuration
GIT_REPO_URL=https://github.com/user/nginx-configs.git
GIT_BRANCH=main
GIT_TOKEN=ghp_xxxxx
NGINX_IMAGE=forge.rdr-it.com/dockerfiles/nginx-reverse-proxy:1.30.1
HOST_LOGS=/containers/nginx-rproxy/logs
HOST_GOACCESS=/containers/nginx-rproxy/goaccess
Structure du dépôt attendue
nginx-configs/
├── conf/
├── sites/
├── snippets/
├── streams/
└── ssl/
Pipeline de déploiement
Pull Git → Test conteneur éphémère → Backup ZIP + Git → Copie configs → Reload nginx
Le test éphémère copie les certs Let's Encrypt pour éviter les erreurs sur les vhosts SSL.
Première utilisation
Cliquer "Initialize backup branch" dans la page Deployment (crée une branche orpheline backup sur le dépôt distant).
Sauvegardes
Les ZIP incluent sites/ conf/ snippets/ streams/ ssl/ et les certs Let's Encrypt (certs/live/).
| Mode | ZIP local | Push Git |
|---|---|---|
| Local uniquement | ✓ | — |
| Git uniquement | — | ✓ |
| Local + Git | ✓ | ✓ |
Rotation automatique configurable via BACKUP_KEEP (défaut : 20).
CrowdSec
Mode Prometheus (recommandé)
Métriques moteur complètes, distinction local vs CAPI :
# Générer une clé API (nécessaire pour la liste des IPs)
cscli bouncers add nginx-dashboard
CROWDSEC_PROMETHEUS_URL=http://crowdsec:6060
CROWDSEC_LOCAL_ONLY=true # masquer les décisions CAPI
# Optionnel — pour la liste des IPs bannies avec détails
CROWDSEC_URL=http://crowdsec:8080
CROWDSEC_API_KEY=votre-cle-api
Le mode Prometheus expose :
- Décisions actives par origine (local
crowdsecvs communautéCAPI) - Top scénarios déclenchés localement (
cs_alerts) - Sources de logs surveillées (
cs_filesource_hits_total) - Santé du parser (
cs_parser_hits_ok_total/cs_parser_hits_ko_total)
Filtre des décisions
La liste des décisions actives est filtrable par origine via les tabs All / crowdsec / CAPI.
L'onglet CrowdSec est masqué si aucune variable n'est configurée.
GoAccess
Le dashboard découvre automatiquement les .log dans ./logs/ et démarre un conteneur GoAccess dédié par vhost via l'API Docker socket.
Variables obligatoires :
GOACCESS_IMAGE=allinurl/goaccess:latest
NGINX_NETWORK=nginx-net # docker network ls
HOST_LOGS=/containers/nginx-rproxy/logs # chemin absolu hôte
HOST_GOACCESS=/containers/nginx-rproxy/goaccess
Format de log dans nginx :
# Log dédié par vhost (format combined — détecté auto)
access_log /var/log/nginx/example.com.access.log;
# Log global tous vhosts (format combined_vhost — détecté auto)
access_log /var/log/nginx/vhosts_access.log combined_vhost;
GoAccess détecte automatiquement le format en lisant la première ligne du fichier — aucune configuration manuelle.
Reset d'un conteneur GoAccess :
docker stop ngx-goaccess-example-com
docker rm ngx-goaccess-example-com
# Puis Démarrer depuis le dashboard
Rapport temps réel : GoAccess pousse les mises à jour via WebSocket. Le rapport est accessible directement dans le dashboard sans port exposé — le WebSocket est proxifié via /api/goaccess/ws/{sourceId}.
API REST
Auth : cookie de session (UI) ou Authorization: Bearer <API_TOKEN>.
| Méthode | Route | Description |
|---|---|---|
GET |
/api/status |
Résumé global nginx |
GET |
/api/metrics |
VTS + historique |
GET |
/api/zones |
Stats par virtual host |
GET |
/api/upstreams |
Backends upstream |
GET |
/api/configs |
Fichiers de configuration |
GET |
/api/ssl |
Certificats parsés |
GET |
/api/nginx-logs |
Fichiers de log |
GET |
/api/nginx-logs/stream |
Stream SSE live |
POST |
/api/nginx/test |
Test config (conteneur éphémère) |
POST |
/api/nginx/reload |
Reload nginx |
GET |
/api/snippets/meta |
Snippets avec métadonnées parsées |
GET |
/api/snippets/ssl |
Snippets SSL uniquement |
GET |
/api/vhost/ssl-sources |
Sources SSL (snippets + certs + LE) |
POST |
/api/vhost/generate |
Générer une config vhost |
GET |
/api/git/status |
Statut dépôt + diff |
POST |
/api/git/pull |
Pull |
POST |
/api/git/test |
Test config depuis Git |
POST |
/api/git/deploy |
Pipeline complet |
POST |
/api/git/init-backup-branch |
Créer branche backup |
GET |
/api/git/test-connection |
Tester connexion Git |
GET |
/api/backups |
Liste des ZIP |
POST |
/api/backups |
Créer une sauvegarde |
POST |
/api/backups/restore |
Restaurer un ZIP |
GET |
/api/backups/download?name=… |
Télécharger un ZIP |
DELETE |
/api/backups/:name |
Supprimer |
GET |
/api/crowdsec/status |
Métriques CrowdSec (Prometheus ou LAPI) |
GET |
/api/crowdsec/decisions |
Décisions actives |
GET |
/api/crowdsec/alerts |
Alertes récentes |
GET |
/api/goaccess/sources |
Sources logs + état conteneurs |
POST |
/api/goaccess/start |
Démarrer GoAccess |
POST |
/api/goaccess/stop |
Arrêter GoAccess |
GET |
/api/goaccess/report?sourceId=… |
Rapport HTML proxy |
GET |
/api/goaccess/logs?sourceId=… |
Logs du conteneur GoAccess |
GET |
/api/auth/me |
Session courante |
GET |
/api/auth/users |
Utilisateurs (admin) |
POST |
/api/auth/hash |
Générer un hash |
GET/POST |
/api/webhooks |
Lister / créer |
DELETE |
/api/webhooks/:id |
Supprimer |
POST |
/api/webhooks/:id/test |
Tester |
Variables d'environnement
Nginx
| Variable | Défaut |
|---|---|
NGINX_TAG |
1.30.1 |
NGINX_WORKER_PROCESSES |
auto |
NGINX_WORKER_CONNECTIONS |
768 |
Dashboard
| Variable | Description | Défaut |
|---|---|---|
PORT |
Port d'écoute | 3000 |
NGINX_VTS_URL |
URL endpoint VTS | http://nginx:8080/status.json |
NGINX_CONTAINER |
Nom conteneur nginx | nginx |
NGINX_IMAGE |
Image tests éphémères | (auto-détecté) |
API_TOKEN |
Token Bearer API | changeme |
SESSION_SECRET |
Secret sessions | changeme |
SESSION_TTL_HOURS |
Durée sessions | 8 |
BACKUP_KEEP |
ZIP à conserver | 20 |
GIT_REPO_URL |
URL dépôt | (vide) |
GIT_BRANCH |
Branche source | main |
GIT_TOKEN |
Token HTTPS | (vide) |
HOST_LOGS |
Chemin hôte absolu des logs | (vide) |
HOST_GOACCESS |
Chemin hôte absolu GoAccess | (vide) |
NGINX_NETWORK |
Réseau Docker partagé | nginx-net |
GOACCESS_IMAGE |
Image GoAccess | allinurl/goaccess:latest |
CROWDSEC_PROMETHEUS_URL |
URL métriques Prometheus | (vide) |
CROWDSEC_LOCAL_ONLY |
Masquer décisions CAPI | false |
CROWDSEC_URL |
URL LAPI | (vide) |
CROWDSEC_API_KEY |
Clé API bouncer | (vide) |
Sécurité
- Sessions HMAC-SHA256, HttpOnly + SameSite=Strict
- Mots de passe SHA-256 + salt, comparaison timing-safe
- Volumes configs montés en lecture seule (
:ro) - Socket Docker monté en lecture seule
- GoAccess — aucun port exposé, WebSocket proxifié
- VTS — port 8080 restreint aux IPs privées
- Générer des secrets :
openssl rand -hex 32
Snippets de filtrage
# Bots malveillants et IA
if ($bad_bot) { return 444; }
if ($ai_bot) { return 444; }
# Filtrage géographique
if ($allow_visit_001 = 0) { return 403; } # France + Good Bots
if ($allow_visit_002 = 0) { return 403; } # France + IE + GB + Good Bots
Commandes utiles
# Test et reload nginx
docker compose exec nginx nginx -t
docker compose exec nginx nginx -s reload
# Logs en temps réel
docker compose logs -f nginx
docker compose logs -f nginx-dashboard
# Rebuild dashboard
docker compose build nginx-dashboard
docker compose up -d --force-recreate nginx-dashboard
# Conteneurs GoAccess actifs
docker ps --filter "name=ngx-goaccess-"
# Vérifier le réseau Docker
docker network ls | grep nginx
# Générer une clé CrowdSec
docker exec crowdsec cscli bouncers add nginx-dashboard