No description
  • HTML 60.7%
  • JavaScript 39%
  • Dockerfile 0.3%
Find a file
Romain 8340f63131
All checks were successful
Docker Build on Tag / build-and-push (push) Successful in 7s
9.0.5
2026-05-19 16:17:53 +02:00
.forgejo/workflows Update build-image.yaml 2026-05-17 08:12:41 +02:00
nginx-dashboard 9.0.5 2026-05-19 16:17:53 +02:00
CHANGELOG.md 5.0.0 2026-05-17 10:11:27 +02:00
docker-compose.yml 8.0.0 2026-05-19 11:07:34 +02:00
README.md 9.0.3 2026-05-19 15:06:00 +02:00
sample.env 8.0.0 2026-05-19 11:07:34 +02:00

Nginx Reverse Proxy Stack

Nginx Dashboard Node

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.conf via 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) → format combined
  • Premier token = hostname (example.com) → format combined_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-*.conf du dossier snippets/ — génère include snippets/ssl-xxx.conf
  • Certificats manuels du dossier ssl/ — pré-remplit ssl_certificate et ssl_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 crowdsec vs 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