
I. Présentation
Un reverse proxy joue un rôle essentiel dans l’ouverture de vos services sur internet : placé entre les utilisateurs et vos applications, il gère la terminaison TLS et effectue le rôle de passerelle entre le réseau public et le réseau privé. Pourtant, des solutions courantes comme NGINX, HAProxy ou encore Traefik, bien qu’efficaces dans ces fonctions, restent vulnérables par défaut aux attaques. Un certificat TLS aura beau chiffrer les données transitant par le proxy, il ne bloquera en rien les menaces au niveau de la couche applicative.
C’est dans ce genre de situations que BunkerWeb répond à cette lacune en combinant reverse proxy et WAF (Web Application Firewall) dans un seul outil open-source. Développé par la société française Bunkerity, BunkerWeb intègre nativement des fonctionnalités importantes : filtrage ModSecurity avec les règles OWASP CRS, renforcement TLS, limitation de requêtes, analyse comportementale et bien d’autres ! Ici, nous découvrirons la version communautaire gratuite.
Dans cet article, nous allons déployer BunkerWeb via Docker Compose, de l’installation jusqu’à la publication d’un service. Cette approche pratique nous permettra de transformer notre passerelle web en une véritable forteresse open-source !
Cet article est le fruit d’une collaboration avec Tristan BRINGUIER. Nous tenons à le remercier pour sa participation active, incluant la fourniture de l’environnement technique et son support à la rédaction.
II. Prérequis
Pour déployer BunkerWeb, assurez-vous d’avoir les éléments suivants :
Un serveur Linux (Debian, Ubuntu, etc.) avec un environnement Docker installé dessus
Une adresse IP publique avec les ports 80/TCP, 443/TCP et 443/UDP redirigés vers BunkerWeb
Minimum 6 Go de RAM, à dimensionner en fonction du nombre de services et de la charge
Un nom de domaine
Si vous avez besoin d’aide pour installer Docker, n’hésitez pas à suivre ce tutoriel : Installation de Docker sur Debian
Dans notre cas, nous allons utiliser une machine sous Debian 12 avec 2 CPU et 8 Go de RAM.
III. Déploiement de BunkerWeb via Docker Compose
Nous allons utiliser Docker Compose pour le déploiement, car il centralise toute la configuration de l’application (services, réseaux, volumes) dans un unique fichier YAML. Cela apporte une lisibilité accrue par rapport à de multiples commandes Docker ainsi qu’une gestion des volumes et des réseaux grandement simplifiés.
A. Préparation de l’environnement
Commencez par créer un répertoire dédié pour notre projet BunkerWeb :
mkdir -p /opt/docker-compose/bunkerweb
cd /opt/docker-compose/bunkerweb
editor compose.yaml
B. Création du fichier compose.yaml
Collez dans le fichier compose.yaml le fichier Docker Compose présenté ci-dessous. Prenez le temps de bien lire les commentaires intégrés pour comprendre la configuration.
################################################################################
## BunkerWeb – Docker Compose #
## Ce fichier déploie BunkerWeb (reverse-proxy + WAF), son ordonnanceur, #
## l’interface Web d’administration et une base PostgreSQL pour le stockage. #
## #
## → AVANT DE PASSER EN PROD : #
## – Changez le mot de passe « motdepasseachanger » #
## #
## → POUR LE RÉSEAU EXTERNE ‘bw-apps’ : #
## – Créez-le avec : docker network create bw-apps #
################################################################################
################################ Variables globales ############################
## Regroupées sous une ancre YAML (&bw-env) pour pouvoir être réutilisées
## (« merge key » <<) dans les différents services.
x-bw-env: &bw-env
## Liste d’IP autorisées à appeler l’API interne de BunkerWeb.
## Indiquer le même subnet que celui du réseau « bunker »
## Format : réseaux CIDR séparés par des espaces.
API_WHITELIST_IP: “127.0.0.0/8 10.20.30.0/24”
## Chaîne de connexion à la base PostgreSQL.
## ➜ Changez le mot de passe.
DATABASE_URI: “postgresql://bunkerweb:motdepasseachanger@bw-db:5432/db”
###############################################################################
## Services ##
###############################################################################
services:
###########################################################################
## 1. Reverse-proxy / WAF ##
###########################################################################
bunkerweb:
image: bunkerity/bunkerweb:latest ## Utilise la dernière image stable
## ── Ports exposés ──────────────────────────────────────────────────────
ports:
– “80:8080/tcp” ## HTTP vers port interne 8080
– “443:8443/tcp” ## HTTPS vers port interne 8443
– “443:8443/udp” ## HTTP/3 (QUIC) sur le même port 8443 en UDP
## ── Variables d’environnement ─────────────────────────────────────────
environment:
<<: *bw-env ## Fusionne les variables communes
## ── Redémarrage automatique ───────────────────────────────────────────
restart: unless-stopped ## Relance sauf si vous l’arrêtez manuellement
## ── Réseau ────────────────────────────────────────────────────────────
networks:
– bunker # Place le conteneur sur le réseau « bunker »
– bw-apps # Place le conteneur sur le réseau externe « bw-apps »
## ── Logs ──────────────────────────────────────────────────────────────
logging:
driver: json-file
options:
max-size: “10m” ## Rotation : 10 Mo par fichier
max-file: “10” ## Garde 10 fichiers
###########################################################################
## 2. Ordonnanceur (scheduler) ##
###########################################################################
bw-scheduler:
image: bunkerity/bunkerweb-scheduler:latest
environment:
<<: *bw-env
BUNKERWEB_INSTANCES: “bunkerweb”
SERVER_NAME: “”
MULTISITE: “yes”
UI_HOST: “http://bw-ui:7000”
volumes:
– bw-data:/data ## Monte les données persistantes (policies, etc.)
restart: unless-stopped
networks:
– bunker ## Même réseau que BunkerWeb
– bunker-db ## Accès direct à la base
###########################################################################
## 3. Interface Web d’administration ##
###########################################################################
bw-ui:
image: bunkerity/bunkerweb-ui:latest
environment:
<<: *bw-env
restart: unless-stopped
networks:
– bunker ## Doit voir le proxy
– bunker-db ## Doit voir PostgreSQL
###########################################################################
## 4. Base de données PostgreSQL ##
###########################################################################
bw-db:
image: postgres:17
environment:
POSTGRES_DB: “db”
POSTGRES_USER: “bunkerweb”
## ☠️ À CHANGER ABSOLUMENT AVANT PROD !
## ➜ Pensez aussi à mettre à jour DATABASE_URI plus haut.
POSTGRES_PASSWORD: “motdepasseachanger”
volumes:
– bw-dbdata:/var/lib/postgresql/data ## Persistance des données SQL
restart: unless-stopped
networks:
– bunker-db ## Isolé du reste pour sécurité
###############################################################################
## Réseaux ##
###############################################################################
networks:
## Réseau frontal (reverse-proxy, scheduler, UI, etc.)
bunker:
name: bunker
ipam:
driver: default
config:
– subnet: 10.20.30.0/24 ## Réseau identique à celui autorisé dans BunkerWeb
## Réseau backend (UI & scheduler <-> PostgreSQL). Non exposé au proxy.
bunker-db:
name: bunker-db
## Réseau pour connecter vos applications backend à BunkerWeb.
## Doit être créé manuellement sur l’hôte Docker avant de lancer ce compose :
## → docker network create bw-apps
bw-apps:
name: bw-apps
external: true
###############################################################################
## Volumes ##
###############################################################################
volumes:
## Policies, certificats, listes IP, etc.
bw-data:
## Données SQL de PostgreSQL
bw-dbdata:
N’oubliez pas de changer le mot de passe motdepasseachanger par un autre aléatoire ! Vous pouvez également le faire avec la commande suivante (qui génère un mot de passe aléatoire de 32 caractères et remplace le contenu de compose.yaml à votre place tout en nettoyant les commentaires superflus) :
sed -i -e “s|motdepasseachanger|$(openssl rand -base64 32 | tr -dc ‘A-Za-z0-9’ | head -c32)|g” -e ‘/^\s*#/d’ -e ‘s/\s*#.*$//’ compose.yaml
Une fois ceci fait, nous devons créer une première fois le réseau docker bw-apps. C’est ce réseau qui fera la jonction entre nos applications et BunkerWeb pour connecter simplement les deux parties.
docker network create bw-apps
C. Lancement du conteneur
Une fois le fichier compose.yaml créé et le réseau docker créé, nous pouvons démarrer la stack avec la commande suivante :
docker compose up -d
Nous pouvons constater le bon déploiement du docker compose avec la commande docker ps.
Une fois les images téléchargées et les conteneurs lancés, nous pouvons consulter les logs avec :
docker compose logs -f
D. Premier démarrage via l’interface web d’administration
À cette étape de l’article, les enregistrements DNS et redirections de ports doivent être faits. C’est-à-dire que votre domaine ou sous-domaine doit bien pointer vers l’adresse IP publique de votre BunkerWeb.
Accédons à l’assistant de configuration via notre navigateur web à l’adresse suivante : https://bunkerweb.votredomaine.fr
Dans un premier temps, nous renseignons les propriétés du compte administrateur. Ce compte sera l’identifiant permettant l’accès à l’interface web d’administration.
Ensuite, nous configurons les modalités d’accès à l’interface web d’administration. “Server name” correspond à l’adresse de l’interface d’administration. Il ne faut surtout pas modifier “UI Host” et “UI URL”, qui sont les URLs internes de BunkerWeb pour effectuer le reverse proxy.
Concernant le certificat TLS, il est possible d’utiliser un certificat SSL personnalisé, mais nous allons utiliser Let’s Encrypt qui distribue gratuitement et automatiquement des certificats SSL. Nous pouvons donc cocher “Auto Let’s Encrypt”.
Si jamais nous utilisons un domaine dont l’hébergeur de zone DNS est compatible CertBot, il est possible de faire des Wildcard Certificates en cochant la case puis passant le “Challenge Type” à “dns” puis en mentionnant les clés d’API nécessaires.
Beaucoup de fournisseurs sont disponibles, vous pouvez consulter si le vôtre l’est sur la documentation de BunkerWeb !
Dans le cas d’une génération avec la méthode “dns”, nous appliquons ceci :
Dans le cas d’une génération avec la méthode “http”, ceci devrait être appliqué :
Enfin, un récapitulatif sera affiché, résumant les informations essentielles saisies lors des étapes précédentes. Nous cliquons sur “Setup”. !
Une fois l’installation démarrée, BunkerWeb génèrera les configurations et les certificats SSL adéquats. Cela peut prendre jusqu’à 5 minutes.
Lorsque l’installation est terminée, nous serons redirigés sur l’interface web.
IV. Configuration et prise en main de BunkerWeb
Nous voici dans l’interface de BunkerWeb après une reconnexion. Bravo ! Prenons le temps de la découvrir.
Sur la page d’accueil, nous retrouverons quelques statistiques essentielles liées à notre instance. Dans la barre latérale, à gauche, se trouvent les menus suivants :
Home : Page d’accueil
Instances : Uniquement utile pour un cluster, c’est dans cette rubrique que sont renseignées les différentes instances composant le cluster
Global Config : Gérer la configuration générale et commune à tous les services
Services : Gérer la configuration de chaque VirtualHost / Service
Configs : Gérer les configurations NGINX avancées
Plugins : Gérer les modules supplémentaires
Cache : Gérer les fichiers mis en cache
Reports : Consulter les alertes et blocages
Bans : Consulter les bannissements
Jobs : Gérer les tâches planifiées
Logs : Consulter les fichiers de journalisation
Les catégories principales que nous utilisons régulièrement sont : Global Config, Services et Bans / Report.
Nous allons maintenant passer en revue quelques paramètres pratiques et vers lesquels nous souhaitons attirer votre attention. Pour ce faire, rendez-vous dans la rubrique “Global Config”.
Nous vous conseillons d’activer les options suivantes :
Général
LISTEN_STREAM : false – désactive la fonctionnalité Stream de NGINX (permettant de forward les ports).
USE_TCP : false
USE_UDP : false
Brotli
USE_BROTLI : true – active la compression Brotli pour des transferts encore plus légers (vous pouvez ensuite affiner le niveau et les types MIME).
Cache client
USE_CLIENT_CACHE : true – autorise le cache côté navigateur, soulageant ainsi votre serveur.
Gzip
USE_GZIP : true – active la compression Gzip, largement reconnue ; ajustez ensuite les paramètres selon vos besoins.
Let’s Encrypt
AUTO_LETS_ENCRYPT : true – préremplit les champs Let’s Encrypt lors de la création d’un service.
EMAIL_LETS_ENCRYPT : [email protected]
Vous pouvez remplir les autres options, comme le type de challenge, et vos credentials, pour automatiser les certificats sur l’ensemble des services avec le même type de challenge.
ModSecurity
USE_MODSECURITY_GLOBAL_CRS : true – à envisager et privilégier seulement si votre machine dispose d’une capacité inférieure à 12 Go de RAM et que vous avez plusieurs services.
Miscellaneous
Disable default server : true – Vous permet d’automatiquement refuser les connexions pour des services qui n’existe pas, et les connexions sur l’adresse IP en brut.
Disable default server strict SNI : true – Bloque la possibilité de CNAME vers vos domaines. À utiliser avec précaution.
Reverse Proxy
REVERSE_PROXY_INTERCEPT_ERRORS : false – permet d’afficher l’erreur native du service (utile, par exemple, avec Guacamole).
SSL
REDIRECT_HTTP_TO_HTTPS : true – force la redirection vers HTTPS.
Real IP (Configuration pour utilisation avec proxy Cloudflare)
USE_REAL_IP : true – active la récupération des vraies adresses IPs.
Real IP from : valeur par défaut – Vous pouvez laisser les valeurs par défaut.
Real IP from URLs : cloudflare.com/ips-v4/ – Ces URLs permettront à votre BunkerWeb de récupérer les vraies adresses IPs des clients derrière votre proxy Cloudflare.
Real IP header : CF-Connecting-IP – Définis la valeur du Header qui remonte l’IP client.
Note : ces valeurs n’auront aucune incidence sur les services qui ne passeront pas dans le proxy Cloudflare.
Passons à présent au déploiement d’un service.
V. Configuration d’un hôte proxy (service)
Dans cette partie, nous allons déployer un service web interne en le plaçant derrière BunkerWeb. Pour cela, nous prendrons l’exemple d’IT-Tools, une boîte à outils web open source à destination des administrateurs système. L’application sera publiée à l’adresse suivante : it-tools-test.int.youkyi.online.
A. Déploiement du conteneur IT-Tools
Nous allons déployer le service IT-Tools dans un conteneur Docker dédié.
mkdir -p /opt/docker-compose/it-tools
cd /opt/docker-compose/it-tools
editor compose.yaml
Voici un exemple de configuration minimaliste à intégrer dans notre fichier compose.yaml :
services:
it-tools:
image: ‘corentinth/it-tools:latest’
networks:
– bw-apps
expose:
– ’80:80′
restart: unless-stopped
container_name: it-tools
networks:
bw-apps:
external: true
Quelques explications pour vous aider à interpréter ce fichier :
it-tools : nom du service, ici pour déployer l’application IT-Tools.
image : indique l’image Docker à utiliser. Ici corentinth/it-tools:latest, une image disponible sur le Docker Hub.
networks : associe le conteneur à un réseau Docker (bw-apps), ce qui permet la communication entre conteneurs sur ce réseau.
expose : ouvre le port 80 à l’intérieur du conteneur. La directive expose ne publie pas le port sur l’hôte comme ports, mais le rend accessible aux autres conteneurs sur le même réseau.
container_name : Donne un nom explicite au conteneur pour le retrouver plus facilement (docker ps, logs, etc.).
B. Configuration du service sur Bunkerweb
Ouvrez la section Services puis cliquez sur Create new service. Suivez ensuite les étapes décrites ci-après. Nous allons procéder section par section pour effectuer l’ensemble de la configuration.
Web service – Front service
“SERVER_NAME” : nom(s) de domaine à protéger. Dans notre cas : it-tools-test.int.youkyi.online
“Let’s Encrypt” : si AUTO_LETS_ENCRYPT n’est pas à true, renseignez les champs manuellement.
“Template” : choisissez un profil de sécurité (low, medium, high) adapté à la criticité de l’application.
“Security mode” : Si vous avez de trop nombreux blocages, mettez-vous en “detect”, pour pouvoir déclencher les règles, sans blocage, vous serez en capacité de voir les logs, sans que les blocages soient effectifs.
Pour configurer Let’s Encrypt, dans le cas où vous ne l’avez pas fait dans la config globale. Petit rappel pour les différents fournisseurs DNS, vous pouvez consulter la documentation de BunkerWeb !
Dans le cas d’une génération avec la méthode “dns”, cela donne :
Dans le cas d’une génération avec la méthode “http”, cela donne :
Attention, il faut bien d’abord pointer votre nom de domaine vers l’IP de votre BunkerWeb, et ne pas cocher “Wildcard Certificate”, ce n’est pas compatible avec la génération via HTTP.
Web service – Upstream server
“REVERSE_PROXY_HOST” : URL interne du service (incluant le schéma http:// ou https://).
Dans notre cas, ce sera http://it-tools:80, car nous avons nommé le container it-tools, et le port exposé est le 80.
“REVERSE_PROXY_WS” : activez-le pour la prise en charge des WebSockets (indispensable pour le bon fonctionnement de certaines applications) !
HTTP – General
Vous pouvez laisser les valeurs par défaut, sauf si besoin spécifique.
HTTP – Headers
Activez “USE_CORS” pour contrôler le partage de ressources entre sites (pratique pour limiter le vol de cookies).
Conseil : les valeurs par défaut conviennent à la plupart des cas.
Security – Bad behavior
Le module “Bad behavior” bannit les clients générant trop d’erreurs (401, 402, 403, 429, etc…). Par exemple, si un client génère beaucoup d’erreurs 404 (page introuvable), c’est suspect.
Note : les valeurs par défaut sont généralement suffisantes.
Security – Blacklisting
Activez “USE_BLACKLIST” pour bloquer immédiatement les IP ou user-agents référencés dans les listes internes ou personnelles. Par défaut, la configuration protège déjà contre les robots les plus agressifs.
Activez “USE_DNSBL” pour bloquer les IPs connues pour être agressives. DNSBL est une autre liste d’adresses IPs.
Vous pouvez laisser activer les deux listes communautaires “Community Blacklist” par défaut et activez la 3ème si vous le souhaitez. Ce sont des listes publiques qui ne sont pas alimentées directement par BunkerWeb.
Security – Limiting
Ajustez les quotas uniquement si un service légitime se voit bloqué.
“USE_LIMIT_CONN” : limite le nombre de connexions simultanées.
“USE_LIMIT_REQ” : limite le nombre de requêtes par seconde d’un client. Au-délà de la limite indiquée, le client recevra une erreur http 429.
Security – Antibot
Si jamais vous avez besoin de rajouter un captcha, choisissez JavaScript tant que possible pour préserver l’ergonomie. Si besoin de plus de sécurité, vous pouvez activer un captcha sur les pages les plus sensibles.
“USE_ANTIBOT” : active la protection contre les bots
“ANTIBOT_MODE” : captcha (résolution manuelle) ou javascript (tests invisibles).
“ANTIBOT_PROVIDER” : reCAPTCHA, hCaptcha, Turnstile, etc. (clé site et secret requis, en fonction du service sélectionné).
Security – Auth basic
Vous pouvez placer une authentification basique HTTP, avec un login et un mot de passe.
Security – Country
“BLACKLIST_COUNTRY” : bloque la liste de pays indiqués (RU KP, par exemple.)
“WHITELIST_COUNTRY” : autorise uniquement les pays listés (FR BE, etc.).
Vous pouvez consulter cette page pour voir la liste des pays sous le format de la norme ISO-3166.
Toute requête provenant d’un pays exclu reçoit un 403 Forbidden (accès refusé).
Si vous souhaitez configurer cette option, je vous conseille de le faire dans “Global Config”, afin que ce soit actif sur TOUS vos services par défaut.
Security – ModSecurity
ModSecurity analyse chaque requête / réponse à l’aide du Core Rule Set (OWASP). Conservez les réglages par défaut, puis excluez au besoin des règles via la rubrique “Custom configuration”. Pour aller plus loin, voici la documentation de Bunkerweb, qui en explique le fonctionnement.
Finaliser le déploiement
Cliquez sur Save : BunkerWeb lance immédiatement le déploiement en arrière-plan (patientez environ 1 min).
Votre service est maintenant protégé et accessible à l’extérieur !
C. Tester le déploiement
Nous pouvons nous rendre sur it-tools-test.int.youkyi.online pour tester : Jackpot, le service est fonctionnel ! D’une part, l’application est publiée grâce à la fonction de reverse proxy, et d’autre part, elle est protégée par BunkerWeb.
VI. Conclusion
Suite à la lecture de ce tutoriel, vous devriez être en mesure d’installer BunkerWeb sur votre serveur et d’effectuer la configuration de base pour sécuriser vos applications web. L’application est conçue pour être facile à prendre en main et à configurer, tout en offrant des options avancées pour renforcer la sécurité de vos services web.
Passionné par les technologies et l’administration IT, je suis un administrateur systèmes et réseaux qui expérimente au quotidien des outils sur une infrastructure hybride. Mon objectif est de démystifier des concepts tels que la sécurité, la supervision et l’administration. Je transforme ces expériences pratiques en retour d’expérience clairs et accessibles, rendant les sujets complexes accessibles pour tous.