bunkerweb/docs/fr/advanced.md
TheophileDiot 114612c84b
Road to 1.6.11~rc1 🚀
2026-05-22 23:21:55 +02:00

250 KiB
Raw Permalink Blame History

Utilisations avancées

De nombreux exemples de cas d'utilisation concrets sont disponibles dans le dossier examples du dépÎt GitHub.

Nous fournissons également de nombreux modÚles standard, tels que des fichiers YAML pour diverses intégrations et types de bases de données. Ceux-ci sont disponibles dans le dossier misc/integrations.

Cette section se concentre uniquement sur les utilisations avancées et le réglage de la sécurité, consultez la section fonctionnalités de la documentation pour voir tous les paramÚtres disponibles.

!!! tip "Tester" Pour effectuer des tests rapides lorsque le mode multisite est activĂ© (et si vous n'avez pas les bonnes entrĂ©es DNS configurĂ©es pour les domaines), vous pouvez utiliser curl avec l'en-tĂȘte HTTP Host de votre choix : shell curl -H "Host: app1.example.com" http://ip-or-fqdn-of-server

Si vous utilisez HTTPS, vous devrez configurer le SNI :
```shell
curl -H "Host: app1.example.com" --resolve example.com:443:ip-of-server https://example.com
```

DerriÚre l'équilibreur de charge ou le proxy inverse

!!! info "Real IP"

Lorsque BunkerWeb se trouve lui‑mĂȘme derriĂšre un Ă©quilibreur de charge ou un proxy inverse, vous devez le configurer afin qu'il puisse rĂ©cupĂ©rer la vĂ©ritable adresse IP des clients. **Si vous ne le faites pas, les fonctionnalitĂ©s de sĂ©curitĂ© bloqueront l'adresse IP de l'Ă©quilibreur de charge ou du proxy inverse au lieu de celle du client.**

BunkerWeb prend en fait en charge deux méthodes pour récupérer l'adresse IP réelle du client :

  • À l'aide du PROXY protocol
  • À l'aide d'un en-tĂȘte HTTP tel que X-Forwarded-For

Les paramĂštres suivants peuvent ĂȘtre utilisĂ©s :

  • USE_REAL_IP : activer/dĂ©sactiver la rĂ©cupĂ©ration d'IP rĂ©elle
  • USE_PROXY_PROTOCOL : activer/dĂ©sactiver la prise en charge du protocole PROXY.
  • REAL_IP_FROM : liste d'adresses IP/rĂ©seau de confiance autorisĂ©es pour nous envoyer la "vraie IP"
  • REAL_IP_HEADER : l'en-tĂȘte HTTP contenant l'IP rĂ©elle ou la valeur spĂ©ciale proxy_protocol lors de l'utilisation du protocole PROXY

Vous trouverez plus de paramÚtres sur l'IP réelle dans la section des fonctionnalités de la documentation.

=== "En-tĂȘte HTTP"

Nous supposerons ce qui suit concernant les équilibreurs de charge ou les proxies inverses (vous devrez mettre à jour les paramÚtres en fonction de votre configuration) :

- Ils utilisent l'en-tĂȘte `X-Forwarded-For` pour dĂ©finir l'adresse IP rĂ©elle
- Ils ont des adresses IP dans les réseaux `1.2.3.0/24` et `100.64.0.0/10`

=== "Interface utilisateur Web"

    Accédez à la page **Config Globale**, sélectionnez le plugin **Real IP** et renseignez les paramÚtres suivants :

    <figure markdown>![ParamĂštres Real IP (en-tĂȘte) via l'interface Web](assets/img/advanced-proxy1.png){ align=center }<figcaption>ParamĂštres Real IP (en-tĂȘte) via l'interface Web</figcaption></figure>

    Veuillez noter qu'il est recommandé de redémarrer BunkerWeb lorsque vous modifiez des paramÚtres liés à la récupération de la vraie adresse IP.

=== "Linux"

    Vous devrez ajouter ces paramĂštres au fichier /etc/bunkerweb/variables.env :

    ```conf
    ...
    USE_REAL_IP=yes
    REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
    REAL_IP_HEADER=X-Forwarded-For
    ...
    ```

    Veuillez noter qu'il est recommandé de redémarrer plutÎt que de recharger le service lorsque vous modifiez les paramÚtres liés à la récupération de la vraie adresse IP :

    ```shell
    sudo systemctl restart bunkerweb && \
    sudo systemctl restart bunkerweb-scheduler
    ```

=== "Tout-en-un"

    Vous devrez ajouter ces paramÚtres aux variables d'environnement lors de l'exécution du conteneur All-in-one :

    ```bash
    docker run -d \
        --name bunkerweb-aio \
        -v bw-storage:/data \
        -e USE_REAL_IP="yes" \
        -e REAL_IP_FROM="1.2.3.0/24 100.64.0.0/10" \
        -e REAL_IP_HEADER="X-Forwarded-For" \
        -p 80:8080/tcp \
        -p 443:8443/tcp \
        -p 443:8443/udp \
        bunkerity/bunkerweb-all-in-one:1.6.11-rc1
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Docker"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des conteneurs BunkerWeb et du Scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Docker autoconf"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des conteneurs BunkerWeb et du Scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Kubernetes"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des pods BunkerWeb et du Scheduler.

    Voici la partie correspondante de votre fichier `values.yaml` que vous pouvez utiliser :

    ```yaml
    bunkerweb:
      extraEnvs:
        - name: USE_REAL_IP
          value: "yes"
        - name: REAL_IP_FROM
          value: "1.2.3.0/24 100.64.0.0/10"
        - name: REAL_IP_HEADER
          value: "X-Forwarded-For"
    scheduler:
      extraEnvs:
        - name: USE_REAL_IP
          value: "yes"
        - name: REAL_IP_FROM
          value: "1.2.3.0/24 100.64.0.0/10"
        - name: REAL_IP_HEADER
          value: "X-Forwarded-For"
    ```

=== "Swarm"

    !!! warning "ObsolĂšte"
        L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

        **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des services BunkerWeb et scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "X-Forwarded-For"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Protocole proxy"

!!! warning "Lire attentivement"

  N'utilisez le protocole `PROXY protocol` que si vous ĂȘtes certain que votre Ă©quilibreur de charge ou proxy inverse l'envoie. **Si vous l'activez et qu'il n'est pas utilisĂ©, vous obtiendrez des erreurs**.

Nous supposerons ce qui suit concernant les équilibreurs de charge ou les proxies inverses (vous devrez adapter les paramÚtres en fonction de votre configuration) :

- Ils utilisent le `PROXY protocol` v1 ou v2 pour définir l'adresse IP réelle
- Ils ont des adresses IP dans les réseaux `1.2.3.0/24` et `100.64.0.0/10`

=== "Interface utilisateur Web"

    Accédez à la page **Config Globale**, sélectionnez le plugin **Real IP** et renseignez les paramÚtres suivants :

    <figure markdown>![ParamĂštres Real IP (protocole PROXY) via l'interface Web](assets/img/advanced-proxy2.png){ align=center }<figcaption>ParamĂštres Real IP (protocole PROXY) via l'interface Web</figcaption></figure>

    Veuillez noter qu'il est recommandé de redémarrer BunkerWeb lorsque vous modifiez des paramÚtres liés à la récupération de la vraie adresse IP.

=== "Linux"

    Vous devrez ajouter ces paramĂštres au fichier /etc/bunkerweb/variables.env :

    ```conf
    ...
    USE_REAL_IP=yes
    USE_PROXY_PROTOCOL=yes
    REAL_IP_FROM=1.2.3.0/24 100.64.0.0/16
    REAL_IP_HEADER=proxy_protocol
    ...
    ```

    Veuillez noter qu'il est recommandé de redémarrer plutÎt que de recharger le service lors de la configuration des paramÚtres liés au protocole PROXY :

    ```shell
    sudo systemctl restart bunkerweb && \
    sudo systemctl restart bunkerweb-scheduler
    ```

=== "Tout-en-un"

    Vous devrez ajouter ces paramÚtres aux variables d'environnement lors de l'exécution du conteneur All-in-one :

    ```bash
    docker run -d \
        --name bunkerweb-aio \
        -v bw-storage:/data \
        -e USE_REAL_IP="yes" \
        -e USE_PROXY_PROTOCOL="yes" \
        -e REAL_IP_FROM="1.2.3.0/24 100.64.0.0/10" \
        -e REAL_IP_HEADER="X-Forwarded-For" \
        -p 80:8080/tcp \
        -p 443:8443/tcp \
        -p 443:8443/udp \
        bunkerity/bunkerweb-all-in-one:1.6.11-rc1
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Docker"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des conteneurs BunkerWeb et du Scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Docker autoconf"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des conteneurs BunkerWeb et du Scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

=== "Kubernetes"

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des pods BunkerWeb et du Scheduler.

    Voici la partie correspondante de votre fichier `values.yaml` que vous pouvez utiliser :

    ```yaml
    bunkerweb:
      extraEnvs:
        - name: USE_REAL_IP
          value: "yes"
        - name: USE_PROXY_PROTOCOL
          value: "yes"
        - name: REAL_IP_FROM
          value: "1.2.3.0/24 100.64.0.0/10"
        - name: REAL_IP_HEADER
          value: "proxy_protocol"
    scheduler:
      extraEnvs:
        - name: USE_REAL_IP
          value: "yes"
        - name: USE_PROXY_PROTOCOL
          value: "yes"
        - name: REAL_IP_FROM
          value: "1.2.3.0/24 100.64.0.0/10"
        - name: REAL_IP_HEADER
          value: "proxy_protocol"
    ```

=== "Swarm"

    !!! warning "ObsolĂšte"
        L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

        **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

    Vous devrez ajouter ces paramĂštres aux variables d'environnement des services BunkerWeb et scheduler :

    ```yaml
    bunkerweb:
      image: bunkerity/bunkerweb:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ...
    bw-scheduler:
      image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
      ...
      environment:
        USE_REAL_IP: "yes"
        USE_PROXY_PROTOCOL: "yes"
        REAL_IP_FROM: "1.2.3.0/24 100.64.0.0/10"
        REAL_IP_HEADER: "proxy_protocol"
      ...
    ```

    Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

Haute disponibilité et répartition de charge

Pour garantir la disponibilitĂ© de vos applications mĂȘme si un serveur tombe, vous pouvez dĂ©ployer BunkerWeb en cluster HA. Cette architecture comporte un Manager (Scheduler) qui orchestre la configuration et plusieurs Workers (instances BunkerWeb) qui traitent le trafic.

flowchart LR

  %% ================ Styles =================
  classDef manager     fill:#eef2ff,stroke:#4c1d95,stroke-width:1px,rx:6px,ry:6px;
  classDef component     fill:#f9fafb,stroke:#6b7280,stroke-width:1px,rx:4px,ry:4px;
  classDef lb            fill:#e0f2fe,stroke:#0369a1,stroke-width:1px,rx:6px,ry:6px;
  classDef database fill:#d1fae5,stroke:#059669,stroke-width:1px,rx:4px,ry:4px;
  classDef datastore     fill:#fee2e2,stroke:#b91c1c,stroke-width:1px,rx:4px,ry:4px;
  classDef backend       fill:#ede9fe,stroke:#7c3aed,stroke-width:1px,rx:4px,ry:4px;
  classDef client        fill:#e5e7eb,stroke:#4b5563,stroke-width:1px,rx:4px,ry:4px;

  %% Container styles
  style CLUSTER fill:#f3f4f6,stroke:#d1d5db,stroke-width:1px,stroke-dasharray:6 3;
  style WORKERS fill:none,stroke:#9ca3af,stroke-width:1px,stroke-dasharray:4 2;

  %% ============== Outside left =============
  Client["Client"]:::client
  LB["Load Balancer"]:::lb

  %% ============== Cluster ==================
  subgraph CLUSTER[" "]
    direction TB

    %% ---- Top row: Manager + Redis ----
    subgraph TOP["Manager & Data Stores"]
      direction LR
      Manager["Manager<br/>(Scheduler)"]:::manager
      BDD["BDD"]:::database
      Redis["Redis/Valkey"]:::datastore
      UI["Interface Web"]:::manager
    end

    %% ---- Middle: Workers ----
    subgraph WORKERS["Workers (BunkerWeb)"]
      direction TB
      Worker1["Worker 1"]:::component
      WorkerN["Worker N"]:::component
    end

    %% ---- Bottom: App ----
    App["App"]:::backend
  end

  %% ============ Outside right ============
  Admin["Admin"]:::client

  %% ============ Traffic & control ===========
  %% Manager / control plane
  Manager -->|API 5000| Worker1
  Manager -->|API 5000| WorkerN
  Manager -->|bwcli| Redis
  Manager -->|Config| BDD

  %% User interface (UI)
  UI -->|Config| BDD
  UI -->|Reports / Bans| Redis
  BDD --- UI
  Redis --- UI
  linkStyle 6 stroke-width:0px;
  linkStyle 7 stroke-width:0px;

  %% Workers <-> Redis
  Worker1 -->|Cache partagé| Redis
  WorkerN -->|Cache partagé| Redis

  %% Workers -> App
  Worker1 -->|Trafic légitime| App
  WorkerN -->|Trafic légitime| App

  %% Client (right side) -> Load balancer -> Workers -> App
  Client -->|RequĂȘte| LB
  LB -->|HTTP/TCP| Worker1
  LB -->|HTTP/TCP| WorkerN

  %% Admin -> UI
  UI --- Admin
  Admin -->|HTTP| UI
  linkStyle 15 stroke-width:0px;

!!! info "Comprendre les API BunkerWeb" BunkerWeb s'appuie sur deux notions d'API différentes :

- Une **API interne** qui connecte automatiquement managers et workers pour l'orchestration. Elle est toujours activée et ne nécessite aucune configuration manuelle.
- Un **service API** optionnel (`bunkerweb-api`) qui expose une interface REST publique pour les outils d'automatisation (bwcli, CI/CD, etc.). Il est dĂ©sactivĂ© par dĂ©faut sur les installations Linux et est indĂ©pendant des communications internes manager↔worker.

Prérequis

Avant de mettre en place un cluster, assurez-vous de disposer de :

  • Au moins 2 hĂŽtes Linux avec accĂšs root/sudo.
  • ConnectivitĂ© rĂ©seau entre les hĂŽtes (en particulier sur le port TCP 5000 pour l'API interne).
  • L'IP ou le nom d'hĂŽte de l'application Ă  protĂ©ger.
  • (Optionnel) Équilibreur de charge (par ex. HAProxy) pour rĂ©partir le trafic entre les workers.

1. Installer le Manager

Le Manager est le cerveau du cluster. Il exécute le Scheduler, la base de données et, optionnellement, l'interface Web.

!!! warning "SĂ©curitĂ© de l'interface Web" L'interface Web Ă©coute sur un port dĂ©diĂ© (7000 par dĂ©faut) et ne doit ĂȘtre accessible qu'aux administrateurs. Si vous prĂ©voyez de l'exposer Ă  Internet, nous recommandons fortement de la protĂ©ger avec une instance BunkerWeb en frontal.

=== "Linux"

1. **Télécharger et lancer l'installateur** sur l'hÎte manager :

    ```bash
    # Télécharger le script et sa somme
    curl -fsSL -O https://github.com/bunkerity/bunkerweb/releases/download/v1.6.11-rc1/install-bunkerweb.sh
    curl -fsSL -O https://github.com/bunkerity/bunkerweb/releases/download/v1.6.11-rc1/install-bunkerweb.sh.sha256

    # Vérifier l'empreinte
    sha256sum -c install-bunkerweb.sh.sha256

    # Exécuter l'installateur
    chmod +x install-bunkerweb.sh
    sudo ./install-bunkerweb.sh
    ```

    !!! danger "Avis de sécurité"
        Vérifiez toujours l'intégrité du script avec la somme fournie avant de l'exécuter.

2. **SĂ©lectionnez Manager** au menu du type d'installation (utilisez ↑/↓ puis EntrĂ©e), puis suivez les invites :

    | Invite                       | Action                                                                                                              |
    | :--------------------------- | :------------------------------------------------------------------------------------------------------------------ |
    | **Instances BunkerWeb**      | Saisissez les IP de vos nƓuds worker sĂ©parĂ©es par des espaces (ex : `192.168.10.11 192.168.10.12`).                 |
    | **Whitelist IP**             | Acceptez l'IP détectée ou saisissez un sous-réseau (ex : `192.168.10.0/24`) pour autoriser l'accÚs à l'API.         |
    | **Résolveurs DNS**           | Choisissez **Non** pour conserver les valeurs par défaut, ou fournissez les vÎtres.                                  |
    | **HTTPS pour l'API interne** | **Recommandé :** choisissez **Oui** pour générer automatiquement des certificats et sécuriser les échanges manager-worker. |
    | **Service Web UI**           | Choisissez **Oui** pour activer l'interface Web (fortement recommandé).                                              |
    | **Service API**              | Choisissez **Non** sauf besoin d'API REST publique pour des outils externes.                                         |

    !!! note "Interface des invites"
        L'installateur utilise la TUI [gum](https://github.com/charmbracelet/gum). Au premier lancement interactif, il tĂ©lĂ©charge le binaire `gum` officiel depuis la release GitHub (SHA256 Ă©pinglĂ©), l'exĂ©cute depuis un rĂ©pertoire temporaire et supprime ce rĂ©pertoire Ă  la fin — aucun paquet systĂšme n'est installĂ©. Utilisez les flĂšches + EntrĂ©e pour rĂ©pondre aux invites. Passez `--no-tui` si vous prĂ©fĂ©rez les invites en texte brut.

#### Sécuriser et exposer l'UI

Si vous avez activĂ© l'interface Web, vous devez la sĂ©curiser. Elle peut ĂȘtre hĂ©bergĂ©e sur le Manager ou une machine dĂ©diĂ©e.

=== "Hébergée sur le Manager"

    1. Éditez `/etc/bunkerweb/ui.env` pour dĂ©finir des identifiants forts :

    ```ini
    # OVERRIDE_ADMIN_CREDS=no
    ADMIN_USERNAME=admin
    ADMIN_PASSWORD=changeme
    # FLASK_SECRET=changeme
    # TOTP_ENCRYPTION_KEYS=changeme
    LISTEN_ADDR=0.0.0.0
    # LISTEN_PORT=7000
    FORWARDED_ALLOW_IPS=127.0.0.1,::1
    # ENABLE_HEALTHCHECK=no
    ```

    !!! warning "Changer les identifiants par défaut"
        Remplacez `admin` et `changeme` par des identifiants forts avant de démarrer le service UI en production.

    2. Redémarrez l'UI :

    ```bash
    sudo systemctl restart bunkerweb-ui
    ```

=== "HĂŽte externe"

    Pour plus d'isolation, installez l'UI sur un nƓud sĂ©parĂ©.

    1. Lancez l'installateur et sélectionnez le type d'installation **Web UI Only**.
    2. Éditez `/etc/bunkerweb/ui.env` pour pointer vers la base du Manager :

        ```ini
        # Configuration base de données (doit correspondre à celle du Manager)
        DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@db-host:3306/bunkerweb
        # Pour PostgreSQL : postgresql://bunkerweb:changeme@db-host:5432/bunkerweb
        # Pour MySQL : mysql+pymysql://bunkerweb:changeme@db-host:3306/bunkerweb

        # Configuration Redis (si Redis/Valkey est utilisé pour la persistance)
        # Si non fourni, il est automatiquement pris depuis la base de données
        # REDIS_HOST=redis-host

        # Identifiants de sécurité
        ADMIN_USERNAME=admin
        ADMIN_PASSWORD=changeme

        # Réglages réseau
        LISTEN_ADDR=0.0.0.0
        # LISTEN_PORT=7000
        ```

    3. Redémarrez le service :

        ```bash
        sudo systemctl restart bunkerweb-ui
        ```

    !!! tip "Configuration du pare-feu"
        Assurez-vous que l'hĂŽte UI peut joindre la base et Redis. Vous devrez peut-ĂȘtre ajuster les rĂšgles sur l'hĂŽte UI ainsi que sur les hĂŽtes base/Redis.

=== "Docker"

Créez un fichier `docker-compose.yml` sur l'hÎte manager :

```yaml title="docker-compose.yml"
x-ui-env: &bw-ui-env
  # Nous ancrons les variables d'environnement pour éviter les duplications
  DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Pensez Ă  mettre un mot de passe plus fort

services:
  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      <<: *bw-ui-env
      BUNKERWEB_INSTANCES: "192.168.1.11 192.168.1.12" # Remplacez par les IPs de vos workers
      API_WHITELIST_IP: "127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16" # Autoriser les réseaux locaux
      # API_LISTEN_HTTPS: "yes" # Recommandé pour sécuriser l'API interne
      # API_TOKEN: "my_secure_token" # Optionnel : définir un token supplémentaire
      SERVER_NAME: ""
      MULTISITE: "yes"
      USE_REDIS: "yes"
      REDIS_HOST: "redis"
    volumes:
      - bw-storage:/data # Persistance du cache et des sauvegardes
    restart: "unless-stopped"
    networks:
      - bw-db
      - bw-redis

  bw-ui:
    image: bunkerity/bunkerweb-ui:1.6.11-rc1
    ports:
      - "7000:7000" # Exposer le port de l'UI
    environment:
      <<: *bw-ui-env
      ADMIN_USERNAME: "changeme"
      ADMIN_PASSWORD: "changeme" # Remplacez par un mot de passe plus fort
      TOTP_ENCRYPTION_KEYS: "mysecret" # Remplacez par une clé plus forte (voir la section Prérequis)
    restart: "unless-stopped"
    networks:
      - bw-db
      - bw-redis

  bw-db:
    image: mariadb:11
    # Nous fixons la taille max des paquets pour Ă©viter les soucis de grosses requĂȘtes
    command: --max-allowed-packet=67108864
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "db"
      MYSQL_USER: "bunkerweb"
      MYSQL_PASSWORD: "changeme" # Remplacez par un mot de passe plus fort
    volumes:
      - bw-data:/var/lib/mysql
    restart: "unless-stopped"
    networks:
      - bw-db

  redis: # Redis pour la persistance des rapports/bannissements/stats
    image: redis:8-alpine
    command: >
      redis-server
      --maxmemory 256mb
      --maxmemory-policy volatile-lru
      --save 60 1000
      --appendonly yes
    volumes:
      - redis-data:/data
    restart: "unless-stopped"
    networks:
      - bw-redis

volumes:
  bw-data:
  bw-storage:
  redis-data:

networks:
  bw-db:
    name: bw-db
  bw-redis:
    name: bw-redis
```

Démarrez la pile manager :

```bash
docker compose up -d
```

2. Installer les Workers

Les workers sont les nƓuds qui traitent le trafic entrant.

=== "Linux"

1. **Lancez l'installateur** sur chaque worker (mĂȘmes commandes que pour le Manager).
2. **Choisissez l'option 3) Worker** et répondez :

    | Invite                       | Action                                              |
    | :--------------------------- | :-------------------------------------------------- |
    | **IP du Manager**            | Saisissez l'IP du Manager (ex : `192.168.10.10`).   |
    | **HTTPS pour l'API interne** | Doit correspondre au choix du Manager (`Y` ou `N`). |

Le worker s'enregistrera automatiquement auprĂšs du Manager.

=== "Docker"

Créez un fichier `docker-compose.yml` sur chaque worker :

```yaml title="docker-compose.yml"
services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      - "80:8080/tcp"
      - "443:8443/tcp"
      - "443:8443/udp" # Support QUIC / HTTP3
      - "5000:5000/tcp" # Port de l'API interne
    environment:
      API_WHITELIST_IP: "127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"
      # API_LISTEN_HTTPS: "yes" # Recommandé pour sécuriser l'API interne (doit correspondre au Manager)
      # API_TOKEN: "my_secure_token" # Optionnel : token supplémentaire (doit correspondre au Manager)
    restart: "unless-stopped"
```

Démarrez le worker :

```bash
docker compose up -d
```

3. Gérer les Workers

Vous pouvez ajouter d'autres workers plus tard via l'interface Web ou la CLI.

=== "Via l'interface Web"

1. **Ouvrez l'onglet Instances**.
2. **Cliquez sur Add instance**.
3. **Renseignez l'IP/hostname du worker** puis enregistrez.

<div class="grid grid-2" markdown style="display:grid; align-items:center;">
<figure markdown style="display:flex; flex-direction:column; justify-content:center; align-items:center; height:100%;">
  ![BunkerWeb UI - Création d'instance](assets/img/ui-ha-create-instance.webp){ width="100%" }
  <figcaption>BunkerWeb UI - Création d'instance</figcaption>
</figure>
<figure markdown style="display:flex; flex-direction:column; justify-content:center; align-items:center; height:100%;">
  ![BunkerWeb UI - Formulaire de création](assets/img/ui-ha-create-instance-form.webp){ width="100%" }
  <figcaption>BunkerWeb UI - Formulaire de création</figcaption>
</figure>
</div>

=== "Via la configuration"

=== "Linux"

    1. **Modifiez** `/etc/bunkerweb/variables.env` sur le Manager :

        ```bash
        BUNKERWEB_INSTANCES=192.168.10.11 192.168.10.12 192.168.10.13
        ```

    2. **Redémarrez le Scheduler** :

        ```bash
        sudo systemctl restart bunkerweb-scheduler
        ```

=== "Docker"

    1. **Modifiez** le fichier `docker-compose.yml` sur le Manager pour mettre Ă  jour `BUNKERWEB_INSTANCES`.

    2. **Recréez le conteneur du Scheduler** :

        ```bash
        docker compose up -d bw-scheduler
        ```

4. Vérifier l'installation

=== "Linux"

1. **VĂ©rifier le statut** : connectez-vous Ă  l'UI (`http://<ip-manager>:7000`) et ouvrez l'onglet **Instances**. Tous les workers doivent ĂȘtre **Up**.
2. **Tester le basculement** : arrĂȘtez BunkerWeb sur un worker (`sudo systemctl stop bunkerweb`) et vĂ©rifiez que le trafic continue de passer.

=== "Docker"

1. **VĂ©rifier le statut** : connectez-vous Ă  l'UI (`http://<ip-manager>:7000`) et ouvrez l'onglet **Instances**. Tous les workers doivent ĂȘtre **Up**.
2. **Tester le basculement** : arrĂȘtez BunkerWeb sur un worker (`docker compose stop bunkerweb`) et vĂ©rifiez que le trafic continue de passer.

5. Répartition de charge

Pour répartir le trafic entre vos workers, utilisez un équilibreur de charge. Nous recommandons un équilibreur de couche 4 (TCP) qui supporte le PROXY protocol pour préserver l'IP client.

=== "HAProxy - Couche 4 (TCP)"

Exemple de configuration **HAProxy** qui passe le trafic (mode TCP) tout en conservant l'IP client via le **PROXY protocol**.

```cfg title="haproxy.cfg"
defaults
    timeout connect 5s
    timeout client 5s
    timeout server 5s

frontend http_front
    mode tcp
    bind *:80
    default_backend http_back

frontend https_front
    mode tcp
    bind *:443
    default_backend https_back

backend http_back
    mode tcp
    balance roundrobin
    server worker01 192.168.10.11:80 check send-proxy-v2
    server worker02 192.168.10.12:80 check send-proxy-v2

backend https_back
    mode tcp
    balance roundrobin
    server worker01 192.168.10.11:443 check send-proxy-v2
    server worker02 192.168.10.12:443 check send-proxy-v2
```

=== "HAProxy - Couche 7 (HTTP)"

Exemple de configuration **HAProxy** pour la rĂ©partition en couche 7 (HTTP). Elle ajoute l'en-tĂȘte `X-Forwarded-For` pour que BunkerWeb rĂ©cupĂšre l'IP client.

```cfg title="haproxy.cfg"
defaults
    timeout connect 5s
    timeout client 5s
    timeout server 5s

frontend http_front
    mode http
    bind *:80
    default_backend http_back

frontend https_front
    mode http
    bind *:443
    default_backend https_back

backend http_back
    mode http
    balance roundrobin
    option forwardfor
    server worker01 192.168.10.11:80 check
    server worker02 192.168.10.12:80 check

backend https_back
    mode http
    balance roundrobin
    option forwardfor
    server worker01 192.168.10.11:443 check
    server worker02 192.168.10.12:443 check
```

Rechargez HAProxy une fois la configuration enregistrée :

sudo systemctl restart haproxy

Pour plus d'informations, consultez la documentation officielle HAProxy.

!!! tip "Configurer l'IP rĂ©elle" N'oubliez pas de configurer BunkerWeb pour rĂ©cupĂ©rer la vĂ©ritable IP client (via PROXY protocol ou l'en-tĂȘte X-Forwarded-For).

Reportez-vous à la section [DerriÚre l'équilibreur de charge ou le proxy inverse](#behind-load-balancer-or-reverse-proxy) pour vérifier que vous utilisez la bonne IP client.

Consultez `/var/log/bunkerweb/access.log` sur chaque worker pour confirmer que les requĂȘtes proviennent du rĂ©seau PROXY protocol et que les deux workers se partagent la charge. Votre cluster BunkerWeb est maintenant prĂȘt pour la production avec haute disponibilitĂ©.

Utilisation de mécanismes de résolution DNS personnalisés

La configuration NGINX de BunkerWeb peut ĂȘtre personnalisĂ©e pour utiliser diffĂ©rents rĂ©solveurs DNS en fonction de vos besoins. Cela peut ĂȘtre particuliĂšrement utile dans divers scĂ©narios :

  1. Pour respecter les entrées de votre /etc/hosts fichier local
  2. Lorsque vous devez utiliser des serveurs DNS personnalisés pour certains domaines
  3. Pour s'intégrer à des solutions de mise en cache DNS locales

Utilisation de systemd-resolved

De nombreux systÚmes Linux modernes utilisent systemd-resolved la résolution DNS. Si vous souhaitez que BunkerWeb respecte le contenu de votre /etc/hosts fichier et utilise le mécanisme de résolution DNS du systÚme, vous pouvez le configurer pour utiliser le service DNS local résolu par systemd.

Pour vérifier que systemd-resolved est en cours d'exécution sur votre systÚme, vous pouvez utiliser :

systemctl status systemd-resolved

Pour activer systemd-resolved comme résolveur DNS dans BunkerWeb, définissez le DNS_RESOLVERS paramÚtre sur 127.0.0.53, qui est l'adresse d'écoute par défaut pour systemd-resolved :

=== "Interface utilisateur Web"

Accédez à la page **Config Globale** et définissez les résolveurs DNS sur `127.0.0.53`

<figure markdown>![ParamÚtres des résolveurs DNS via l'interface Web](assets/img/advanced-dns-resolvers.png){ align=center }<figcaption>ParamÚtres des résolveurs DNS via l'interface Web</figcaption></figure>

=== "Linux"

Vous devrez modifier le fichier /etc/bunkerweb/variables.env :

```conf
...
DNS_RESOLVERS=127.0.0.53
...
```

AprÚs avoir effectué cette modification, rechargez le Scheduler pour appliquer la configuration :

```shell
sudo systemctl reload bunkerweb-scheduler
```

Utilisation de dnsmasq

dnsmasq est un serveur DNS, DHCP et TFTP léger qui est couramment utilisé pour la mise en cache et la personnalisation du DNS local. C'est particuliÚrement utile lorsque vous avez besoin de plus de contrÎle sur votre résolution DNS que celui fourni par systemd-resolved.

=== "Linux"

Tout d'abord, installez et configurez dnsmasq sur votre systÚme Linux :

=== "Debian/Ubuntu"

    ```bash
    # Install dnsmasq
    sudo apt-get update && sudo apt-get install dnsmasq

    # Configure dnsmasq to listen only on localhost
    echo "listen-address=127.0.0.1" | sudo tee -a /etc/dnsmasq.conf
    echo "bind-interfaces" | sudo tee -a /etc/dnsmasq.conf

    # Add custom DNS entries if needed
    echo "address=/custom.example.com/192.168.1.10" | sudo tee -a /etc/dnsmasq.conf

    # Restart dnsmasq
    sudo systemctl restart dnsmasq
    sudo systemctl enable dnsmasq
    ```

=== "RHEL/Fedora"

    ```bash
    # Install dnsmasq
    sudo dnf install dnsmasq

    # Configure dnsmasq to listen only on localhost
    echo "listen-address=127.0.0.1" | sudo tee -a /etc/dnsmasq.conf
    echo "bind-interfaces" | sudo tee -a /etc/dnsmasq.conf

    # Add custom DNS entries if needed
    echo "address=/custom.example.com/192.168.1.10" | sudo tee -a /etc/dnsmasq.conf

    # Restart dnsmasq
    sudo systemctl restart dnsmasq
    sudo systemctl enable dnsmasq
    ```

Ensuite, configurez BunkerWeb pour utiliser dnsmasq en définissant `DNS_RESOLVERS` sur `127.0.0.1` :

=== "Web UI"

    Accédez à la page **Config Globale** et sélectionnez le plugin **NGINX**, puis définissez les résolveurs DNS sur `127.0.0.1`.

    <figure markdown>![ParamÚtres des résolveurs DNS via l'interface Web](assets/img/advanced-dns-resolvers2.png){ align=center }<figcaption>ParamÚtres des résolveurs DNS via l'interface Web</figcaption></figure>

=== "Linux"

    Vous devrez modifier le fichier `/etc/bunkerweb/variables.env` :

    ```conf
    ...
    DNS_RESOLVERS=127.0.0.1
    ...
    ```

    AprÚs avoir effectué cette modification, rechargez le Scheduler pour appliquer la configuration :

    ```shell
    sudo systemctl reload bunkerweb-scheduler
    ```

=== "Tout-en-un"

Lorsque vous utilisez l'image All-in-one, exécutez dnsmasq dans un conteneur séparé et configurez BunkerWeb pour l'utiliser :

```bash
# Create a custom network for DNS communication
docker network create bw-dns

# Run dnsmasq container using dockurr/dnsmasq with Quad9 DNS
# Quad9 provides security-focused DNS resolution with malware blocking
docker run -d \
    --name dnsmasq \
    --network bw-dns \
    -e DNS1="9.9.9.9" \
    -e DNS2="149.112.112.112" \
    -p 53:53/udp \
    -p 53:53/tcp \
    --cap-add=NET_ADMIN \
    --restart=always \
    dockurr/dnsmasq

# Run BunkerWeb All-in-one with dnsmasq DNS resolver
docker run -d \
    --name bunkerweb-aio \
    --network bw-dns \
    -v bw-storage:/data \
    -e DNS_RESOLVERS="dnsmasq" \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    -p 443:8443/udp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

=== "Docker"

Ajoutez un service dnsmasq à votre fichier docker-compose et configurez BunkerWeb pour l'utiliser :

```yaml
services:
  dnsmasq:
    image: dockurr/dnsmasq
    container_name: dnsmasq
    environment:
      # Using Quad9 DNS servers for enhanced security and privacy
      # Primary: 9.9.9.9 (Quad9 with malware blocking)
      # Secondary: 149.112.112.112 (Quad9 backup server)
      DNS1: "9.9.9.9"
      DNS2: "149.112.112.112"
    ports:
      - 53:53/udp
      - 53:53/tcp
    cap_add:
      - NET_ADMIN
    restart: always
    networks:
      - bw-dns

  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ...
    environment:
      DNS_RESOLVERS: "dnsmasq"
    ...
    networks:
      - bw-universe
      - bw-services
      - bw-dns

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    ...
    environment:
      DNS_RESOLVERS: "dnsmasq"
    ...
    networks:
      - bw-universe
      - bw-dns

networks:
  # ...existing networks...
  bw-dns:
    name: bw-dns
```

Configurations personnalisées

Pour personnaliser et ajouter des configurations personnalisĂ©es Ă  BunkerWeb, vous pouvez profiter de sa base NGINX. Des configurations NGINX personnalisĂ©es peuvent ĂȘtre ajoutĂ©es dans diffĂ©rents contextes NGINX, y compris des configurations pour le pare-feu d'applications Web (WAF) ModSecurity, qui est un composant central de BunkerWeb. Vous trouverez plus de dĂ©tails sur les configurations de ModSecurity ici.

Voici les types de configurations personnalisées disponibles :

  • http : Configurations au niveau HTTP de NGINX.
  • server-http : configurations au niveau HTTP/Server de NGINX.
  • default-server-http: configurations au niveau du serveur de NGINX, en particulier pour le "serveur par dĂ©faut" lorsque le nom de client fourni ne correspond Ă  aucun nom de serveur dans SERVER_NAME.
  • modsec-crs: Configurations appliquĂ©es avant le chargement de l'ensemble de rĂšgles de base OWASP.
  • modsec: configurations appliquĂ©es aprĂšs le chargement de l'ensemble de rĂšgles de base OWASP ou utilisĂ©es lorsque l'ensemble de rĂšgles de base n'est pas chargĂ©.
  • crs-plugins-before: Configurations pour les plugins CRS, appliquĂ©es avant le chargement des plugins CRS.
  • crs-plugins-after: Configurations pour les plugins CRS, appliquĂ©es aprĂšs le chargement des plugins CRS.
  • stream : Configurations au niveau du flux de NGINX.
  • server-stream : Configurations au niveau Stream/Server de NGINX.

Les configurations personnalisĂ©es peuvent ĂȘtre appliquĂ©es globalement ou spĂ©cifiquement pour un serveur particulier, en fonction du contexte applicable et de l'activation ou non du mode multisite .

La mĂ©thode d'application des configurations personnalisĂ©es dĂ©pend de l'intĂ©gration utilisĂ©e. Cependant, le processus sous-jacent implique l'ajout de fichiers avec le .conf suffixe Ă  des dossiers spĂ©cifiques. Pour appliquer une configuration personnalisĂ©e Ă  un serveur spĂ©cifique, le fichier doit ĂȘtre placĂ© dans un sous-dossier nommĂ© d'aprĂšs le nom du serveur principal.

Certaines intégrations offrent des moyens plus pratiques d'appliquer des configurations, par exemple à l'aide de Configs dans Docker Swarm ou de ConfigMap dans Kubernetes. Ces options offrent des approches plus simples pour la gestion et l'application des configurations.

=== "Interface utilisateur Web"

Accédez à la page **Configs**, cliquez sur **Create new custom config**, puis choisissez s'il s'agit d'une configuration globale ou spécifique à un service, le type de configuration et le nom de la configuration :

<figure markdown>![Configurations personnalisées via l'interface Web](assets/img/advanced-config.png){ align=center }<figcaption>Configurations personnalisées via l'interface Web</figcaption></figure>

N'oubliez pas de cliquer sur le bouton `đŸ’Ÿ Enregistrer`.

=== "Linux"

Lorsque vous utilisez l'intĂ©gration [Linux](integrations.md#linux), les configurations personnalisĂ©es doivent ĂȘtre Ă©crites dans le dossier `/etc/bunkerweb/configs`.

Voici un exemple pour server-http/hello-world.conf :

```nginx
location /hello {
  default_type 'text/plain';
  content_by_lua_block {
    ngx.say('world')
  }
}
```

Comme BunkerWeb s'exécute en tant qu'utilisateur non privilégié (nginx:nginx), vous devrez modifier les permissions :

```shell
chown -R root:nginx /etc/bunkerweb/configs && \
chmod -R 770 /etc/bunkerweb/configs
```

Vérifions maintenant l'état du Scheduler :

```shell
systemctl status bunkerweb-scheduler
```

S'ils sont déjà en cours d'exécution, nous pouvons le recharger :

```shell
systemctl reload bunkerweb-scheduler
```

Sinon, nous devrons le démarrer :

```shell
systemctl start bunkerweb-scheduler
```

=== "Tout-en-un"

Lorsque vous utilisez l'image [Tout-en-un](integrations.md#all-in-one-aio-image), vous avez deux options pour ajouter des configurations personnalisées :

- Utilisation de paramÚtres spécifiques `*_CUSTOM_CONF_*` comme variables d'environnement lors de l'exécution du conteneur (recommandé).
- Écriture `.conf` de fichiers dans le `/data/configs/` rĂ©pertoire du volume montĂ© sur `/data`.

**Utilisation des paramĂštres (variables d'environnement)**

Les paramÚtres à utiliser doivent suivre le schéma `<SITE>_CUSTOM_CONF_<TYPE>_<NAME>`:

- `<SITE>` : Nom du serveur primaire facultatif si le mode multisite est activĂ© et que la configuration doit ĂȘtre appliquĂ©e Ă  un service spĂ©cifique.
- `<TYPE>` : Le type de configuration, les valeurs acceptées sont `HTTP`, `DEFAULT_SERVER_HTTP`, `SERVER_HTTP` `MODSEC` `MODSEC_CRS` `CRS_PLUGINS_BEFORE`, `CRS_PLUGINS_AFTER` `STREAM` , et `SERVER_STREAM`.
- `<NAME>` : Le nom de la configuration sans le `.conf` suffixe.

Voici un exemple fictif lors de l'exécution du conteneur All-in-one :

```bash
docker run -d \
    --name bunkerweb-aio \
    -v bw-storage:/data \
    -e "CUSTOM_CONF_SERVER_HTTP_hello-world=location /hello { \
        default_type 'text/plain'; \
        content_by_lua_block { \
          ngx.say('world'); \
        } \
      }" \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

Veuillez noter que si votre conteneur est déjà créé, vous devrez le supprimer et le recréer pour que les nouvelles variables d'environnement soient appliquées.

**Utilisation de fichiers**

La premiÚre chose à faire est de créer les dossiers :

```shell
mkdir -p ./bw-data/configs/server-http
```

Vous pouvez maintenant écrire vos configurations :

```shell
echo "location /hello {
  default_type 'text/plain';
  content_by_lua_block {
    ngx.say('world')
  }
}" > ./bw-data/configs/server-http/hello-world.conf
```

Étant donnĂ© que le Scheduler s'exĂ©cute en tant qu'utilisateur non privilĂ©giĂ© avec UID et GID 101, vous devrez modifier les autorisations :

```shell
chown -R root:101 bw-data && \
chmod -R 770 bw-data
```

Au démarrage du conteneur de l'ordonnanceur, vous devrez monter le dossier sur /data :

```bash
docker run -d \
    --name bunkerweb-aio \
    -v ./bw-data:/data \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    -p 443:8443/udp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

=== "Docker"

Lorsque vous utilisez l'intégration [Docker](integrations.md#docker), vous avez deux options pour ajouter des configurations personnalisées :

- Utilisation de paramÚtres spécifiques `*_CUSTOM_CONF_*` comme variables d'environnement (recommandé)
- Écriture des fichiers .conf sur le volume montĂ© sur /data de l'ordonnanceur

**Utilisation des paramĂštres**

Les paramÚtres à utiliser doivent suivre le schéma `<SITE>_CUSTOM_CONF_<TYPE>_<NAME>` :

- `<SITE>` : nom de serveur primaire facultatif si le mode multisite est activĂ© et que la configuration doit ĂȘtre appliquĂ©e Ă  un service spĂ©cifique
- `<TYPE>` : le type de configuration, les valeurs acceptées sont `HTTP`, `DEFAULT_SERVER_HTTP` `SERVER_HTTP` `MODSEC` `MODSEC_CRS` `CRS_PLUGINS_BEFORE`, `CRS_PLUGINS_AFTER`, `STREAM` , et `SERVER_STREAM`
- `<NAME>` : le nom de config sans le suffixe .conf

Voici un exemple factice utilisant un fichier docker-compose :

```yaml
...
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  environment:
    - |
      CUSTOM_CONF_SERVER_HTTP_hello-world=
      location /hello {
        default_type 'text/plain';
        content_by_lua_block {
          ngx.say('world')
        }
      }
  ...
```

**Utilisation de fichiers**

La premiÚre chose à faire est de créer les dossiers :

```shell
mkdir -p ./bw-data/configs/server-http
```

Vous pouvez maintenant écrire vos configurations :

```nginx
echo "location /hello {
  default_type 'text/plain';
  content_by_lua_block {
    ngx.say('world')
  }
}" > ./bw-data/configs/server-http/hello-world.conf
```

Étant donnĂ© que le Scheduler s'exĂ©cute en tant qu'utilisateur non privilĂ©giĂ© avec UID et GID 101, vous devrez modifier les autorisations :

```shell
chown -R root:101 bw-data && \
chmod -R 770 bw-data
```

Au démarrage du conteneur de l'ordonnanceur, vous devrez monter le dossier sur /data :

```yaml
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  volumes:
    - ./bw-data:/data
  ...
```

=== "Docker autoconf"

Lorsque vous utilisez l'intégration [Docker autoconf](integrations.md#docker-autoconf), vous avez deux options pour ajouter des configurations personnalisées :

- Utilisation de paramÚtres spécifiques `*_CUSTOM_CONF_*` comme étiquettes (le plus simple)
- Écriture des fichiers .conf sur le volume montĂ© sur /data de l'ordonnanceur

**Utilisation des étiquettes**

!!! warning "Limitations de l'utilisation des étiquettes"
    Lorsque vous utilisez des étiquettes avec l'intégration Docker autoconf, vous ne pouvez appliquer des configurations personnalisées que pour le service web correspondant. L'application de **http**, **default-server-http**, **stream** ou de tout paramÚtre global (comme **server-http** ou **server-stream** pour tous les services) n'est pas possible : vous devrez monter des fichiers à cet effet.

Les étiquettes à utiliser doivent suivre le modÚle `bunkerweb.CUSTOM_CONF_<TYPE>_<NAME>` :

- `<TYPE>` : le type de configuration, les valeurs acceptées sont `SERVER_HTTP`, `MODSEC`, `MODSEC_CRS`, `CRS_PLUGINS_BEFORE` `CRS_PLUGINS_AFTER` et `SERVER_STREAM`
- `<NAME>` : le nom de config sans le suffixe .conf

Voici un exemple factice utilisant un fichier docker-compose :

```yaml
myapp:
  image: bunkerity/bunkerweb-hello:v1.0
  labels:
    - |
      bunkerweb.CUSTOM_CONF_SERVER_HTTP_hello-world=
      location /hello {
        default_type 'text/plain';
        content_by_lua_block {
            ngx.say('world')
        }
      }
  ...
```

**Utilisation de fichiers**

La premiÚre chose à faire est de créer les dossiers :

```shell
mkdir -p ./bw-data/configs/server-http
```

Vous pouvez maintenant écrire vos configurations :

```nginx
echo "location /hello {
  default_type 'text/plain';
  content_by_lua_block {
    ngx.say('world')
  }
}" > ./bw-data/configs/server-http/hello-world.conf
```

Étant donnĂ© que le Scheduler s'exĂ©cute en tant qu'utilisateur non privilĂ©giĂ© avec UID et GID 101, vous devrez modifier les autorisations :

```shell
chown -R root:101 bw-data && \
chmod -R 770 bw-data
```

Au démarrage du conteneur de l'ordonnanceur, vous devrez monter le dossier sur /data :

```yaml
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  volumes:
    - ./bw-data:/data
  ...
```

=== "Kubernetes"

Lors de l'utilisation de l'[intégration Kubernetes](integrations.md#kubernetes),
les configurations personnalisées sont gérées à l'aide de [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/).

Vous n'avez pas besoin de monter la ConfigMap dans un Pod (par exemple en variable d'environnement ou en volume).
Le pod autoconf surveille les événements ConfigMap et applique automatiquement la configuration dÚs qu'une modification est détectée.

Annotez chaque ConfigMap que le contrÎleur Ingress doit gérer :

- `bunkerweb.io/CONFIG_TYPE` : obligatoire. Choisissez un type pris en charge (`http`, `server-http`, `default-server-http`, `modsec`,
  `modsec-crs`, `crs-plugins-before`, `crs-plugins-after`, `stream`, `server-stream` ou `settings`).
- `bunkerweb.io/CONFIG_SITE` : optionnel. Indiquez le nom de serveur principal (tel qu'exposé via votre `Ingress`)
  pour limiter la configuration Ă  ce service ; laissez vide pour l'appliquer globalement.

Voici l'exemple :

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cfg-bunkerweb-all-server-http
  annotations:
    bunkerweb.io/CONFIG_TYPE: "server-http"
data:
  myconf: |
  location /hello {
    default_type 'text/plain';
    content_by_lua_block {
      ngx.say('world')
    }
  }
```

!!! info "Fonctionnement de la synchronisation"
    - Le contrÎleur Ingress surveille en continu les ConfigMap annotées.
    - Si la variable d'environnement `NAMESPACES` est définie, seules les ConfigMap de ces espaces de noms sont prises en compte.
    - La création ou la mise à jour d'une ConfigMap gérée déclenche immédiatement un rechargement de la configuration.
    - La suppression de la ConfigMap – ou de l'annotation `bunkerweb.io/CONFIG_TYPE` – supprime la configuration personnalisĂ©e associĂ©e.
    - Si vous définissez `bunkerweb.io/CONFIG_SITE`, le service référencé doit déjà exister ; sinon, la ConfigMap est ignorée jusqu'à son apparition.

!!! tip "Custom Extra Config"
    Depuis la version `1.6.0`, vous pouvez ajouter ou remplacer des paramĂštres en annotant une ConfigMap avec `bunkerweb.io/CONFIG_TYPE=settings`.
    Le contrÎleur Ingress d'autoconf lit chaque entrée de `data` et l'applique comme une variable d'environnement :

    - Sans `bunkerweb.io/CONFIG_SITE`, toutes les clés sont appliquées globalement.
    - Lorsque `bunkerweb.io/CONFIG_SITE` est dĂ©fini, le contrĂŽleur ajoute automatiquement le prĂ©fixe `<nom-de-serveur>_` (chaque `/` est remplacĂ© par `_`) aux clĂ©s qui ne sont pas dĂ©jĂ  spĂ©cifiques. Ajoutez ce prĂ©fixe vous-mĂȘme si vous devez mĂ©langer des clĂ©s globales et spĂ©cifiques dans la mĂȘme ConfigMap.
    - Les noms ou valeurs invalides sont ignorés et un avertissement est enregistré dans les journaux du contrÎleur autoconf.

    Exemple :

    ```yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cfg-bunkerweb-extra-settings
      annotations:
        bunkerweb.io/CONFIG_TYPE: "settings"
    data:
      USE_ANTIBOT: "captcha" # multisite setting that will be applied to all services that do not override it
      USE_REDIS: "yes" # global setting that will be applied globally
      ...
    ```

=== "Swarm"

!!! warning "ObsolĂšte"
    L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

    **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

Lorsque vous utilisez l'[Swarm integration](integrations.md#swarm), les configurations personnalisées sont gérées à l'aide des [Docker Configs](https://docs.docker.com/engine/swarm/configs/).

Pour simplifier, vous n'avez mĂȘme pas besoin d'attacher le Config Ă  un service : le service d'autoconf Ă©coute les Ă©vĂ©nements Config et mettra Ă  jour les configurations personnalisĂ©es lorsque nĂ©cessaire.

Lors de la création d'un Config, vous devrez ajouter des labels spéciaux :

* **bunkerweb.CONFIG_TYPE** : doit ĂȘtre dĂ©fini sur un type de configuration personnalisĂ© valide (http, server-http, default-server-http, modsec, modsec-crs, crs-plugins-before, crs-plugins-after, stream, server-stream ou settings)
* **bunkerweb.CONFIG_SITE** : défini sur un nom de serveur pour appliquer la configuration à ce serveur spécifique (facultatif, sera appliqué globalement s'il n'est pas défini)

Voici l'exemple :

```nginx
echo "location /hello {
  default_type 'text/plain';
  content_by_lua_block {
    ngx.say('world')
  }
}" | docker config create -l bunkerweb.CONFIG_TYPE=server-http my-config -
```

Il n'y a pas de mécanisme de mise à jour : l'alternative est de supprimer une configuration existante à l'aide puis de `docker config rm` la recréer.

Exécution de nombreux services en production

CRS mondial

!!! warning "Plugins CRS" Lorsque le SCR est chargé globalement, les plug-ins SCR ne sont pas pris en charge. Si vous avez besoin de les utiliser, vous devrez charger le SCR par service.

Si vous utilisez BunkerWeb en production avec un grand nombre de services, et que vous activez la fonctionnalité ModSecurity globalement avec des rÚgles CRS, le temps nécessaire pour charger les configurations BunkerWeb peut devenir trop long, ce qui peut entraßner un délai d'expiration.

La solution de contournement consiste Ă  charger les rĂšgles CRS globalement plutĂŽt que par service. Ce comportement n'est pas activĂ© par dĂ©faut pour des raisons de compatibilitĂ© descendante et parce qu'il prĂ©sente un inconvĂ©nient : si vous activez le chargement des rĂšgles CRS globales, il ne sera plus possible de dĂ©finir des rĂšgles modsec-crs (exĂ©cutĂ©es avant les rĂšgles CRS) par service. Cependant, cette limitation peut ĂȘtre contournĂ©e en Ă©crivant des rĂšgles d'exclusion globales modsec-crs comme suit :

SecRule REQUEST_FILENAME "@rx ^/somewhere$" "nolog,phase:4,allow,id:1010,chain"
SecRule REQUEST_HEADERS:Host "@rx ^app1\.example\.com$" "nolog"

Vous pouvez activer le chargement global du SCR en définissant USE_MODSECURITY_GLOBAL_CRS la valeur . yes

Ajuster max_allowed_packet pour MariaDB/MySQL

Il semble que la valeur par défaut du max_allowed_packet paramÚtre dans les serveurs de bases de données MariaDB et MySQL ne soit pas suffisante lors de l'utilisation de BunkerWeb avec un grand nombre de services.

Si vous rencontrez des erreurs comme celle-ci, en particulier sur le Scheduler :

[Warning] Aborted connection 5 to db: 'db' user: 'bunkerweb' host: '172.20.0.4' (Got a packet bigger than 'max_allowed_packet' bytes)

Vous devrez augmenter le max_allowed_packet sur votre serveur de base de données.

Persistance des interdictions et des signalements

Par défaut, BunkerWeb stocke les bannissements et les rapports dans un magasin de données Lua local. Bien que simple et efficace, cette configuration signifie que des données sont perdues lors du redémarrage de l'instance. Pour vous assurer que les bannissements et les rapports persistent lors des redémarrages, vous pouvez configurer BunkerWeb pour utiliser un serveur Redis ou Valkey distant .

Pourquoi utiliser Redis/Valkey ?

Redis et Valkey sont de puissants magasins de données en mémoire couramment utilisés comme bases de données, caches et courtiers de messages. Ils sont hautement évolutifs et prennent en charge une variété de structures de données, notamment :

  • ChaĂźnes: paires clĂ©-valeur de base.
  • Hachages: paires champ-valeur au sein d'une seule clĂ©.
  • Listes: collections ordonnĂ©es de chaĂźnes.
  • Ensembles: collections non ordonnĂ©es de chaĂźnes uniques.
  • Ensembles triĂ©s: Collections ordonnĂ©es avec partitions.

En tirant parti de Redis ou de Valkey, BunkerWeb peut stocker de maniÚre persistante les bannissements, les rapports et les données de cache, garantissant ainsi la durabilité et l'évolutivité.

Activation de la prise en charge Redis/Valkey

Pour activer la prise en charge de Redis ou Valkey, configurez les paramĂštres suivants dans votre fichier de configuration BunkerWeb :

# Enable Redis/Valkey support
USE_REDIS=yes

# Redis/Valkey server hostname or IP address
REDIS_HOST=<hostname>

# Redis/Valkey server port number (default: 6379)
REDIS_PORT=6379

# Redis/Valkey database number (default: 0)
REDIS_DATABASE=0
  • USE_REDIS: RĂ©glez sur yes pour activer l'intĂ©gration Redis/Valkey.
  • REDIS_HOST: SpĂ©cifiez le nom d'hĂŽte ou l'adresse IP du serveur Redis/Valkey.
  • REDIS_PORT: SpĂ©cifiez le numĂ©ro de port pour le serveur Redis/Valkey. La valeur par dĂ©faut est 6379.
  • REDIS_DATABASE: Indiquez le numĂ©ro de base de donnĂ©es Redis/Valkey Ă  utiliser. La valeur par dĂ©faut est 0.

Si vous avez besoin de paramÚtres plus avancés, tels que l'authentification, la prise en charge SSL/TLS ou le mode Sentinel, reportez-vous à la documentation sur les paramÚtres du plug-in Redis pour obtenir des conseils détaillés.

Protéger les applications UDP/TCP

!!! example "Fonctionnalité expérimentale"

  This feature is not production-ready. Feel free to test it and report us any bug using [issues](https://github.com/bunkerity/bunkerweb/issues) in the GitHub repository.

BunkerWeb offre la possibilité de fonctionner comme un proxy inverse UDP/TCP générique, ce qui vous permet de protéger toutes les applications basées sur le réseau fonctionnant au moins sur la couche 4 du modÚle OSI. Au lieu d'utiliser le module HTTP "classique", BunkerWeb exploite le module de flux de NGINX.

Il est important de noter que tous les paramÚtres et fonctionnalités de sécurité ne sont pas disponibles lors de l'utilisation du module de flux. Vous trouverez de plus amples informations à ce sujet dans les sections des fonctionnalités de la documentation.

La configuration d'un proxy inverse de base est assez similaire Ă  la configuration HTTP, car elle implique l'utilisation des mĂȘmes paramĂštres : USE_REVERSE_PROXY=yes et REVERSE_PROXY_HOST=myapp:9000. MĂȘme lorsque BunkerWeb est positionnĂ© derriĂšre un Ă©quilibreur de charge, les paramĂštres restent les mĂȘmes (le protocole PROXY Ă©tant l'option prise en charge pour des raisons Ă©videntes).

En plus de cela, les paramÚtres spécifiques suivants sont utilisés :

  • SERVER_TYPE=stream : activer le stream mode (UDP/TCP gĂ©nĂ©rique) au lieu d' http un (qui est la valeur par dĂ©faut)
  • LISTEN_STREAM_PORT=4242 : le port d'Ă©coute "simple" (sans SSL/TLS) sur lequel BunkerWeb Ă©coutera
  • LISTEN_STREAM_PORT_SSL=4343 : le port d'Ă©coute "ssl/tls" sur lequel BunkerWeb Ă©coutera
  • USE_UDP=no : Ă©couter et transfĂ©rer les paquets UDP au lieu de TCP

Pour la liste complÚte des paramÚtres concernant stream le mode, veuillez vous référer à la sections des fonctionnalités de la documentation.

!!! tip "Plusieurs ports d'écoute"

Depuis la version `1.6.0`, BunkerWeb prend en charge plusieurs ports d'écoute pour le mode `stream`. Vous pouvez les spécifier à l'aide des paramÚtres `LISTEN_STREAM_PORT` et `LISTEN_STREAM_PORT_SSL`.

Voici un exemple :

```conf
...
LISTEN_STREAM_PORT=4242
LISTEN_STREAM_PORT_SSL=4343
LISTEN_STREAM_PORT_1=4244
LISTEN_STREAM_PORT_SSL_1=4344
...
```

=== "Tout-en-un"

Vous devrez ajouter ces paramÚtres aux variables d'environnement lors de l'exécution du conteneur All-in-one. Vous devrez également exposer les ports de stream.

Cet exemple configure BunkerWeb pour agir comme proxy inverse pour deux applications basées sur le mode stream : `app1.example.com` et `app2.example.com`.

```bash
docker run -d \
    --name bunkerweb-aio \
    -v bw-storage:/data \
    -e SERVICE_UI="no" \
    -e SERVER_NAME="app1.example.com app2.example.com" \
    -e MULTISITE="yes" \
    -e USE_REVERSE_PROXY="yes" \
    -e SERVER_TYPE="stream" \
    -e app1.example.com_REVERSE_PROXY_HOST="myapp1:9000" \
    -e app1.example.com_LISTEN_STREAM_PORT="10000" \
    -e app2.example.com_REVERSE_PROXY_HOST="myapp2:9000" \
    -e app2.example.com_LISTEN_STREAM_PORT="20000" \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    -p 443:8443/udp \
    -p 10000:10000/tcp \
    -p 20000:20000/tcp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

Veuillez noter que si votre conteneur existe déjà, vous devrez le supprimer et le recréer afin que les nouvelles variables d'environnement soient prises en compte.

Vos applications (`myapp1`, `myapp2`) doivent s'exĂ©cuter dans des conteneurs sĂ©parĂ©s (ou ĂȘtre autrement accessibles) et leurs noms d'hĂŽte/adresses IP (par ex. `myapp1`, `myapp2` utilisĂ©s dans `_REVERSE_PROXY_HOST`) doivent ĂȘtre rĂ©solubles et atteignables depuis le conteneur `bunkerweb-aio`. Cela implique gĂ©nĂ©ralement de les connecter Ă  un rĂ©seau Docker partagĂ©.

!!! note "Désactiver le service UI"
    Il est recommandé de désactiver le service d'interface Web (par exemple en définissant la variable d'environnement `SERVICE_UI=no`) car l'interface Web n'est pas compatible avec `SERVER_TYPE=stream`.

=== "Docker"

Lors de l'utilisation de l'intégration Docker, la maniÚre la plus simple de protéger des applications réseau existantes est d'ajouter les services au réseau `bw-services` :

```yaml
x-bw-api-env: &bw-api-env
  # We use an anchor to avoid repeating the same settings for all services
  API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"
  # Jeton API optionnel pour les appels API authentifiés
  API_TOKEN: ""

services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      - "80:8080" # Keep it if you want to use Let's Encrypt automation when using http challenge type
      - "10000:10000" # app1
      - "20000:20000" # app2
    labels:
      - "bunkerweb.INSTANCE=yes"
    environment:
      <<: *bw-api-env
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-services

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      <<: *bw-api-env
      BUNKERWEB_INSTANCES: "bunkerweb" # This setting is mandatory to specify the BunkerWeb instance
      SERVER_NAME: "app1.example.com app2.example.com"
      MULTISITE: "yes"
      USE_REVERSE_PROXY: "yes" # Will be applied to all services
      SERVER_TYPE: "stream" # Will be applied to all services
      app1.example.com_REVERSE_PROXY_HOST: "myapp1:9000"
      app1.example.com_LISTEN_STREAM_PORT: "10000"
      app2.example.com_REVERSE_PROXY_HOST: "myapp2:9000"
      app2.example.com_LISTEN_STREAM_PORT: "20000"
    volumes:
      - bw-storage:/data # This is used to persist the cache and other data like the backups
    restart: "unless-stopped"
    networks:
      - bw-universe

  myapp1:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app1" ]
    networks:
      - bw-services

  myapp2:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app2" ]
    networks:
      - bw-services

volumes:
  bw-storage:

networks:
  bw-universe:
    name: bw-universe
    ipam:
      driver: default
      config:
        - subnet: 10.20.30.0/24
  bw-services:
    name: bw-services
```

=== "Docker autoconf"

Avant d'exécuter la pile de l'intégration [Docker autoconf](integrations.md#docker-autoconf) sur votre machine, vous devrez modifier les ports :

```yaml
services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      - "80:8080" # Keep it if you want to use Let's Encrypt automation when using http challenge type
      - "10000:10000" # app1
      - "20000:20000" # app2
...
```

Une fois la pile en cours d'exécution, vous pouvez connecter vos applications existantes au réseau `bw-services` et configurer BunkerWeb avec des `labels` :

```yaml
services:
  myapp1:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app1" ]
    networks:
      - bw-services
    labels:
      - "bunkerweb.SERVER_NAME=app1.example.com"
      - "bunkerweb.SERVER_TYPE=stream"
      - "bunkerweb.USE_REVERSE_PROXY=yes"
      - "bunkerweb.REVERSE_PROXY_HOST=myapp1:9000"
      - "bunkerweb.LISTEN_STREAM_PORT=10000"

  myapp2:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app2" ]
    networks:
      - bw-services
    labels:
      - "bunkerweb.SERVER_NAME=app2.example.com"
      - "bunkerweb.SERVER_TYPE=stream"
      - "bunkerweb.USE_REVERSE_PROXY=yes"
      - "bunkerweb.REVERSE_PROXY_HOST=myapp2:9000"
      - "bunkerweb.LISTEN_STREAM_PORT=20000"

networks:
  bw-services:
    external: true
    name: bw-services
```

=== "Kubernetes"

!!! example "Fonctionnalité expérimentale"

    Actuellement, les [Ingresses](https://kubernetes.io/docs/concepts/services-networking/ingress/) ne prennent pas en charge le mode `stream`. **Ce que nous proposons ici est une solution de contournement pour le faire fonctionner.**

    N'hésitez pas à le tester et à nous signaler tout bug en ouvrant une issue via [issues](https://github.com/bunkerity/bunkerweb/issues) du dépÎt GitHub.

Avant d'exécuter la pile de l'[intégration Kubernetes](integrations.md#kubernetes) sur votre machine, vous devrez ouvrir les ports sur votre équilibreur de charge :

```yaml
apiVersion: v1
kind: Service
metadata:
  name: lb
spec:
  type: LoadBalancer
  ports:
    - name: http # Keep it if you want to use Let's Encrypt automation when using http challenge type
      port: 80
      targetPort: 8080
    - name: app1
      port: 10000
      targetPort: 10000
    - name: app2
      port: 20000
      targetPort: 20000
  selector:
    app: bunkerweb
```

Une fois la pile en cours d'exécution, vous pouvez créer vos ressources Ingress :

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress
  namespace: services
  annotations:
    bunkerweb.io/SERVER_TYPE: "stream" # Will be applied to all services
    bunkerweb.io/app1.example.com_LISTEN_STREAM_PORT: "10000"
    bunkerweb.io/app2.example.com_LISTEN_STREAM_PORT: "20000"
spec:
  rules:
    - host: app1.example.com
      http:
        paths:
          - path: / # This isn't used in stream mode but is required
            pathType: Prefix
            backend:
              service:
                name: svc-app1
                port:
                  number: 9000
    - host: app2.example.com
      http:
        paths:
          - path: / # This isn't used in stream mode but is required
            pathType: Prefix
            backend:
              service:
                name: svc-app2
                port:
                  number: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1
  namespace: services
  labels:
    app: app1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
        - name: app1
          image: istio/tcp-echo-server:1.3
          args: ["9000", "app1"]
          ports:
            - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: svc-app1
  namespace: services
spec:
  selector:
    app: app1
  ports:
    - protocol: TCP
      port: 9000
      targetPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2
  namespace: services
  labels:
    app: app2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
        - name: app2
          image: istio/tcp-echo-server:1.3
          args: ["9000", "app2"]
          ports:
            - containerPort: 9000
---
apiVersion: v1
kind: Service
metadata:
  name: svc-app2
  namespace: services
spec:
  selector:
    app: app2
  ports:
    - protocol: TCP
      port: 9000
      targetPort: 9000
```

=== "Linux"

Vous devrez ajouter ces paramĂštres au fichier /etc/bunkerweb/variables.env :

```conf
...
SERVER_NAME=app1.example.com app2.example.com
MULTISITE=yes
USE_REVERSE_PROXY=yes
SERVER_TYPE=stream
app1.example.com_REVERSE_PROXY_HOST=myapp1.domain.or.ip:9000
app1.example.com_LISTEN_STREAM_PORT=10000
app2.example.com_REVERSE_PROXY_HOST=myapp2.domain.or.ip:9000
app2.example.com_LISTEN_STREAM_PORT=20000
...
```

Vérifions maintenant l'état du Scheduler :

```shell
systemctl status bunkerweb-scheduler
```

S'ils sont déjà en cours d'exécution, nous pouvons le recharger :

```shell
systemctl reload bunkerweb-scheduler
```

Sinon, nous devrons le démarrer :

```shell
systemctl start bunkerweb-scheduler
```

=== "Swarm"

!!! warning "ObsolĂšte"
    L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

    **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

Avant d'exécuter la pile de l'intégration [Swarm](integrations.md#swarm) sur votre machine, vous devrez modifier les ports :

```yaml
services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      # Keep it if you want to use Let's Encrypt automation when using http challenge type
      - published: 80
        target: 8080
        mode: host
        protocol: tcp
      # app1
      - published: 10000
        target: 10000
        mode: host
        protocol: tcp
      # app2
      - published: 20000
        target: 20000
        mode: host
        protocol: tcp
...
```

Une fois la pile en cours d'exécution, vous pouvez connecter vos applications existantes au réseau `bw-services` et configurer BunkerWeb à l'aide d'étiquettes :

```yaml
services:

  myapp1:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app1" ]
    networks:
      - bw-services
    deploy:
      placement:
        constraints:
          - "node.role==worker"
      labels:
        - "bunkerweb.SERVER_NAME=app1.example.com"
        - "bunkerweb.SERVER_TYPE=stream"
        - "bunkerweb.USE_REVERSE_PROXY=yes"
        - "bunkerweb.REVERSE_PROXY_HOST=myapp1:9000"
        - "bunkerweb.LISTEN_STREAM_PORT=10000"

  myapp2:
    image: istio/tcp-echo-server:1.3
    command: [ "9000", "app2" ]
    networks:
      - bw-services
    deploy:
      placement:
        constraints:
          - "node.role==worker"
      labels:
        - "bunkerweb.SERVER_NAME=app2.example.com"
        - "bunkerweb.SERVER_TYPE=stream"
        - "bunkerweb.USE_REVERSE_PROXY=yes"
        - "bunkerweb.REVERSE_PROXY_HOST=myapp2:9000"
        - "bunkerweb.LISTEN_STREAM_PORT=20000"

networks:
  bw-services:
    external: true
    name: bw-services
```

Le PHP

!!! example "FonctionnalitĂ© expĂ©rimentale" Pour le moment, le support PHP avec BunkerWeb est encore en version bĂȘta et nous vous recommandons d'utiliser une architecture de proxy inverse si vous le pouvez. D'ailleurs, PHP n'est pas du tout pris en charge pour certaines intĂ©grations comme Kubernetes.

BunkerWeb prend en charge PHP en utilisant des instances PHP-FPM externes ou distantes. Nous supposerons que vous ĂȘtes dĂ©jĂ  familiarisĂ© avec la gestion de ce type de services.

Les paramĂštres suivants peuvent ĂȘtre utilisĂ©s :

  • REMOTE_PHP : Nom d'hĂŽte de l'instance PHP-FPM distante.
  • REMOTE_PHP_PATH : Dossier racine contenant les fichiers dans l'instance PHP-FPM distante.
  • REMOTE_PHP_PORT : Port de l'instance PHP-FPM distante (9000 par dĂ©faut).
  • LOCAL_PHP : Chemin d'accĂšs au fichier socket local de l'instance PHP-FPM.
  • LOCAL_PHP_PATH : Dossier racine contenant les fichiers dans l'instance locale PHP-FPM.

=== "Tout-en-un"

Lorsque vous utilisez l'image [Tout-en-un](integrations.md#all-in-one-aio-image), pour prendre en charge les applications PHP, vous devrez :

- Montez vos fichiers PHP dans le `/var/www/html` dossier de BunkerWeb.
- Configurez un conteneur PHP-FPM pour votre application et montez le dossier contenant les fichiers PHP.
- Utilisez les paramÚtres spécifiques `REMOTE_PHP` et `REMOTE_PHP_PATH` comme variables d'environnement lors de l'exécution de BunkerWeb.

Si vous activez le [mode multisite](features.md#multisite-mode), vous devrez crĂ©er des rĂ©pertoires distincts pour chacune de vos applications. Chaque sous-rĂ©pertoire doit ĂȘtre nommĂ© Ă  l'aide de la premiĂšre valeur de `SERVER_NAME`. Voici un exemple fictif :

```
www
├── app1.example.com
│   └── index.php
└── app2.example.com
    └── index.php

2 directories, 2 files
```

Nous supposerons que vos applications PHP se trouvent dans un dossier nommé `www`. Veuillez noter que vous devrez corriger les permissions pour que BunkerWeb (UID/GID 101) puisse au moins lire les fichiers et lister les dossiers et PHP-FPM (UID/GID 33 si vous utilisez l' `php:fpm` image) soit le propriétaire des fichiers et dossiers :

```shell
chown -R 33:101 ./www && \
find ./www -type f -exec chmod 0640 {} \; && \
find ./www -type d -exec chmod 0750 {} \;
```

Vous pouvez maintenant exécuter BunkerWeb, le configurer pour votre application PHP et également exécuter les applications PHP. Vous devrez créer un réseau Docker personnalisé pour permettre à BunkerWeb de communiquer avec vos conteneurs PHP-FPM.

```bash
# Create a custom network
docker network create php-network

# Run PHP-FPM containers
docker run -d --name myapp1-php --network php-network -v ./www/app1.example.com:/app php:fpm
docker run -d --name myapp2-php --network php-network -v ./www/app2.example.com:/app php:fpm

# Run BunkerWeb All-in-one
docker run -d \
    --name bunkerweb-aio \
    --network php-network \
    -v ./www:/var/www/html \
    -v bw-storage:/data \
    -e SERVER_NAME="app1.example.com app2.example.com" \
    -e MULTISITE="yes" \
    -e REMOTE_PHP_PATH="/app" \
    -e app1.example.com_REMOTE_PHP="myapp1-php" \
    -e app2.example.com_REMOTE_PHP="myapp2-php" \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    -p 443:8443/udp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

Veuillez noter que si votre conteneur est déjà créé, vous devrez le supprimer et le recréer pour que les nouvelles variables d'environnement soient appliquées.

=== "Docker"

Lors de l'utilisation de l'intégration [Docker](integrations.md#docker), pour prendre en charge les applications PHP, vous devrez :

- Montez vos fichiers PHP dans le `/var/www/html` dossier de BunkerWeb
- Configurez un conteneur PHP-FPM pour votre application et montez le dossier contenant les fichiers PHP
- Utilisez les paramÚtres spécifiques `REMOTE_PHP` et `REMOTE_PHP_PATH` comme variables d'environnement lors du démarrage de BunkerWeb

Si vous activez le [mode multisite](features.md#multisite-mode), vous devrez crĂ©er des rĂ©pertoires distincts pour chacune de vos applications. Chaque sous-rĂ©pertoire doit ĂȘtre nommĂ© Ă  l'aide de la premiĂšre valeur de `SERVER_NAME`. Voici un exemple fictif :

```
www
├── app1.example.com
│   └── index.php
├── app2.example.com
│   └── index.php
└── app3.example.com
    └── index.php

3 directories, 3 files
```

Nous supposerons que vos applications PHP se trouvent dans un dossier nommé `www`. Veuillez noter que vous devrez corriger les permissions pour que BunkerWeb (UID/GID 101) puisse au moins lire les fichiers et lister les dossiers et PHP-FPM (UID/GID 33 si vous utilisez l' `php:fpm` image) soit le propriétaire des fichiers et dossiers :

```shell
chown -R 33:101 ./www && \
find ./www -type f -exec chmod 0640 {} \; && \
find ./www -type d -exec chmod 0750 {} \;
```

Vous pouvez maintenant exécuter BunkerWeb, le configurer pour votre application PHP et également exécuter les applications PHP :

```yaml
x-bw-api-env: &bw-api-env
  # We use an anchor to avoid repeating the same settings for all services
  API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"

services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      - "80:8080/tcp"
      - "443:8443/tcp"
      - "443:8443/udp" # QUIC
    environment:
      <<: *bw-api-env
    volumes:
      - ./www:/var/www/html
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-services

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      <<: *bw-api-env
      BUNKERWEB_INSTANCES: "bunkerweb" # This setting is mandatory to specify the BunkerWeb instance
      SERVER_NAME: "app1.example.com app2.example.com"
      MULTISITE: "yes"
      REMOTE_PHP_PATH: "/app" # Will be applied to all services thanks to the MULTISITE setting
      app1.example.com_REMOTE_PHP: "myapp1"
      app2.example.com_REMOTE_PHP: "myapp2"
      app3.example.com_REMOTE_PHP: "myapp3"
    volumes:
      - bw-storage:/data # This is used to persist the cache and other data like the backups
    restart: "unless-stopped"
    networks:
      - bw-universe

  myapp1:
    image: php:fpm
    volumes:
      - ./www/app1.example.com:/app
    networks:
      - bw-services

  myapp2:
    image: php:fpm
    volumes:
      - ./www/app2.example.com:/app
    networks:
      - bw-services

  myapp3:
    image: php:fpm
    volumes:
      - ./www/app3.example.com:/app
    networks:
      - bw-services

volumes:
  bw-storage:

networks:
  bw-universe:
    name: bw-universe
    ipam:
      driver: default
      config:
        - subnet: 10.20.30.0/24
  bw-services:
    name: bw-services
```

=== "Docker autoconf"

!!! info "Mode multisite activé"
    L'intégration [Docker autoconf](integrations.md#docker-autoconf) implique l'utilisation du mode multisite : protéger une application PHP équivaut à protéger plusieurs.

Lors de l'utilisation de l'intégration [Docker autoconf](integrations.md#docker-autoconf), pour prendre en charge les applications PHP, vous devrez :

- Montez vos fichiers PHP dans le `/var/www/html` dossier de BunkerWeb
- Configurez un conteneur PHP-FPM pour vos applications et montez le dossier contenant les applications PHP
- Utilisez les paramÚtres spécifiques `REMOTE_PHP` et `REMOTE_PHP_PATH` comme étiquettes pour votre conteneur PHP-FPM

Comme l'autoconf de Docker implique d'utiliser le [mode multisite](features.md#multisite-mode), vous devrez crĂ©er des rĂ©pertoires distincts pour chacune de vos applications. Chaque sous-rĂ©pertoire doit ĂȘtre nommĂ© Ă  l'aide de la premiĂšre valeur de `SERVER_NAME`. Voici un exemple fictif :

```
www
├── app1.example.com
│   └── index.php
├── app2.example.com
│   └── index.php
└── app3.example.com
    └── index.php

3 directories, 3 files
```

Une fois les dossiers créés, copiez vos fichiers et corrigez les permissions afin que BunkerWeb (UID/GID 101) puisse au moins lire les fichiers et lister les dossiers et PHP-FPM (UID/GID 33 si vous utilisez l' `php:fpm` image) soit le propriétaire des fichiers et dossiers :

```shell
chown -R 33:101 ./www && \
find ./www -type f -exec chmod 0640 {} \; && \
find ./www -type d -exec chmod 0750 {} \;
```

Lorsque vous démarrez la pile autoconf de BunkerWeb, montez le `www` dossier dans `/var/www/html` le  conteneur **Scheduler** :

```yaml
x-bw-api-env: &bw-api-env
  # We use an anchor to avoid repeating the same settings for all services
  AUTOCONF_MODE: "yes"
  API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24"

services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    labels:
      - "bunkerweb.INSTANCE=yes"
    environment:
      <<: *bw-api-env
    volumes:
      - ./www:/var/www/html
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-services

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      <<: *bw-api-env
      BUNKERWEB_INSTANCES: "" # We don't need to specify the BunkerWeb instance here as they are automatically detected by the autoconf service
      SERVER_NAME: "" # The server name will be filled with services labels
      MULTISITE: "yes" # Mandatory setting for autoconf
      DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Remember to set a stronger password for the database
    volumes:
      - bw-storage:/data # This is used to persist the cache and other data like the backups
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-db

  bw-autoconf:
    image: bunkerity/bunkerweb-autoconf:1.6.11-rc1
    depends_on:
      - bunkerweb
      - bw-docker
    environment:
      AUTOCONF_MODE: "yes"
      DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Remember to set a stronger password for the database
      DOCKER_HOST: "tcp://bw-docker:2375" # The Docker socket
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-docker
      - bw-db

  bw-docker:
    image: tecnativa/docker-socket-proxy:nightly
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: "1"
      LOG_LEVEL: "warning"
    networks:
      - bw-docker

  bw-db:
    image: mariadb:11
    # We set the max allowed packet size to avoid issues with large queries
    command: --max-allowed-packet=67108864
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "db"
      MYSQL_USER: "bunkerweb"
      MYSQL_PASSWORD: "changeme" # Remember to set a stronger password for the database
    volumes:
      - bw-data:/var/lib/mysql
    networks:
      - bw-docker

volumes:
  bw-data:
  bw-storage:

networks:
  bw-universe:
    name: bw-universe
    ipam:
      driver: default
      config:
        - subnet: 10.20.30.0/24
  bw-services:
    name: bw-services
  bw-docker:
    name: bw-docker
```

Vous pouvez maintenant créer vos conteneurs PHP-FPM, monter les bons sous-dossiers et utiliser des libellés pour configurer BunkerWeb :

```yaml
services:
  myapp1:
      image: php:fpm
      volumes:
        - ./www/app1.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp1
      labels:
        - "bunkerweb.SERVER_NAME=app1.example.com"
        - "bunkerweb.REMOTE_PHP=myapp1"
        - "bunkerweb.REMOTE_PHP_PATH=/app"

  myapp2:
      image: php:fpm
      volumes:
        - ./www/app2.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp2
      labels:
        - "bunkerweb.SERVER_NAME=app2.example.com"
        - "bunkerweb.REMOTE_PHP=myapp2"
        - "bunkerweb.REMOTE_PHP_PATH=/app"

  myapp3:
      image: php:fpm
      volumes:
        - ./www/app3.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp3
      labels:
        - "bunkerweb.SERVER_NAME=app3.example.com"
        - "bunkerweb.REMOTE_PHP=myapp3"
        - "bunkerweb.REMOTE_PHP_PATH=/app"

networks:
  bw-services:
    external: true
    name: bw-services
```

=== "Kubernetes"

!!! warning "PHP n'est pas pris en charge pour Kubernetes"
  L'intégration Kubernetes permet la configuration via [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) et le contrÎleur BunkerWeb ne prend actuellement en charge que les applications HTTP.

=== "Linux"

Nous supposerons que vous avez déjà la pile d'intégration [Linux integration](integrations.md#linux) en cours d'exécution sur votre machine.

Par défaut, BunkerWeb recherchera les fichiers web dans le dossier /var/www/html. Vous pouvez l'utiliser pour stocker vos applications PHP. Veuillez noter que vous devrez configurer votre service PHP-FPM pour définir l'utilisateur/groupe des processus en cours et le fichier de socket UNIX utilisé pour communiquer avec BunkerWeb.

Tout d'abord, assurez-vous que votre instance PHP-FPM peut accéder aux fichiers situés dans /var/www/html et que BunkerWeb peut accéder au fichier de socket UNIX afin de communiquer avec PHP-FPM. Il est recommandé d'utiliser un utilisateur distinct tel que www-data pour le service PHP-FPM et d'autoriser le groupe nginx à accéder au fichier de socket UNIX. Voici la configuration PHP-FPM correspondante :

```ini
...
[www]
user = www-data
group = www-data
listen = /run/php/php-fpm.sock
listen.owner = www-data
listen.group = nginx
listen.mode = 0660
...
```

N'oubliez pas de redémarrer votre service PHP-FPM :

```shell
systemctl restart php-fpm
```

Si vous activez le [mode multisite](features.md#multisite-mode), vous devrez crĂ©er des rĂ©pertoires distincts pour chacune de vos applications. Chaque sous-rĂ©pertoire doit ĂȘtre nommĂ© en utilisant la premiĂšre valeur de `SERVER_NAME`. Voici un exemple fictif :

```
/var/www/html
├── app1.example.com
│   └── index.php
├── app2.example.com
│   └── index.php
└── app3.example.com
    └── index.php

3 directories, 3 files
```

Veuillez noter que vous devrez corriger les permissions afin que BunkerWeb (groupe `nginx`) puisse au moins lire les fichiers et lister les dossiers, et que PHP-FPM (utilisateur `www-data`, qui peut varier selon votre systÚme) soit le propriétaire des fichiers et dossiers :

```shell
chown -R www-data:nginx /var/www/html && \
find /var/www/html -type f -exec chmod 0640 {} \; && \
find /var/www/html -type d -exec chmod 0750 {} \;
```

Vous pouvez maintenant éditer le fichier `/etc/bunkerweb/variable.env` :

```conf
HTTP_PORT=80
HTTPS_PORT=443
DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4
API_LISTEN_IP=127.0.0.1
MULTISITE=yes
SERVER_NAME=app1.example.com app2.example.com app3.example.com
app1.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app1.example.com_LOCAL_PHP_PATH=/var/www/html/app1.example.com
app2.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app2.example.com_LOCAL_PHP_PATH=/var/www/html/app2.example.com
app3.example.com_LOCAL_PHP=/run/php/php-fpm.sock
app3.example.com_LOCAL_PHP_PATH=/var/www/html/app3.example.com
```

Vérifions maintenant l'état du Scheduler :

```shell
systemctl status bunkerweb-scheduler
```

S'il est déjà en cours d'exécution, nous pouvons le recharger :

```shell
systemctl reload bunkerweb-scheduler
```

Sinon, nous devrons le démarrer :

```shell
systemctl start bunkerweb-scheduler
```

=== "Swarm"

!!! warning "ObsolĂšte"
    L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

    **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

!!! info "Mode multisite activé"
    L'intégration [Swarm](integrations.md#docker-autoconf) implique l'utilisation du mode multisite : protéger une application PHP équivaut à protéger plusieurs applications.

!!! info "Volume partagé"
    L'utilisation de PHP avec l'intégration Docker Swarm nécessite un volume partagé entre toutes les instances BunkerWeb et PHP-FPM, ce qui n'est pas couvert dans cette documentation.

Lors de l'utilisation de l'intégration [Swarm](integrations.md#swarm), pour prendre en charge les applications PHP, vous devrez :

- Montez vos fichiers PHP dans le `/var/www/html` dossier de BunkerWeb
- Configurez un conteneur PHP-FPM pour vos applications et montez le dossier contenant les applications PHP
- Utilisez les paramÚtres spécifiques `REMOTE_PHP` et `REMOTE_PHP_PATH` comme étiquettes pour votre conteneur PHP-FPM

Étant donnĂ© que l'intĂ©gration de Swarm implique l'utilisation du [mode multisite](features.md#multisite-mode), vous devrez crĂ©er des rĂ©pertoires distincts pour chacune de vos applications. Chaque sous-rĂ©pertoire doit ĂȘtre nommĂ© Ă  l'aide de la premiĂšre valeur de `SERVER_NAME`. Voici un exemple fictif :

```
www
├── app1.example.com
│   └── index.php
├── app2.example.com
│   └── index.php
└── app3.example.com
    └── index.php

3 directories, 3 files
```

À titre d'exemple, nous considĂ©rerons que vous avez un dossier partagĂ© montĂ© sur vos nƓuds de travail sur le point de `/shared` terminaison.

Une fois les dossiers créés, copiez vos fichiers et corrigez les permissions afin que BunkerWeb (UID/GID 101) puisse au moins lire les fichiers et lister les dossiers et PHP-FPM (UID/GID 33 si vous utilisez l' `php:fpm` image) soit le propriétaire des fichiers et dossiers :

```shell
chown -R 33:101 /shared/www && \
find /shared/www -type f -exec chmod 0640 {} \; && \
find /shared/www -type d -exec chmod 0750 {} \;
```

Lorsque vous démarrez la pile BunkerWeb, montez le dossier /shared/www sur /var/www/html dans le conteneur **Scheduler** :

```yaml
services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    volumes:
      - /shared/www:/var/www/html
...
```

Vous pouvez maintenant créer vos services PHP-FPM, monter les sous-dossiers appropriés et utiliser des labels pour configurer BunkerWeb :

```yaml
services:
  myapp1:
      image: php:fpm
      volumes:
        - ./www/app1.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp1
      deploy:
        placement:
          constraints:
            - "node.role==worker"
        labels:
          - "bunkerweb.SERVER_NAME=app1.example.com"
          - "bunkerweb.REMOTE_PHP=myapp1"
          - "bunkerweb.REMOTE_PHP_PATH=/app"

  myapp2:
      image: php:fpm
      volumes:
        - ./www/app2.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp2
      deploy:
        placement:
          constraints:
            - "node.role==worker"
        labels:
          - "bunkerweb.SERVER_NAME=app2.example.com"
          - "bunkerweb.REMOTE_PHP=myapp2"
          - "bunkerweb.REMOTE_PHP_PATH=/app"

  myapp3:
      image: php:fpm
      volumes:
        - ./www/app3.example.com:/app
      networks:
        bw-services:
            aliases:
              - myapp3
      deploy:
        placement:
          constraints:
            - "node.role==worker"
        labels:
          - "bunkerweb.SERVER_NAME=app3.example.com"
          - "bunkerweb.REMOTE_PHP=myapp3"
          - "bunkerweb.REMOTE_PHP_PATH=/app"

networks:
  bw-services:
    external: true
    name: bw-services
```

IPv6

!!! example "Fonctionnalité expérimentale"

Cette fonctionnalitĂ© n'est pas prĂȘte pour la production. N'hĂ©sitez pas Ă  la tester et Ă  nous signaler tout bug via les [issues](https://github.com/bunkerity/bunkerweb/issues) du dĂ©pĂŽt GitHub.

Par défaut, BunkerWeb n'écoutera que les adresses IPv4 et n'utilisera pas IPv6 pour les communications réseau. Si vous souhaitez activer la prise en charge d'IPv6, vous devez définir USE_IPV6=yes. Veuillez noter que la configuration IPv6 de votre réseau et de votre environnement n'entre pas dans le champ d'application de cette documentation.

=== "Docker / Autoconf / Swarm"

Tout d'abord, vous devrez configurer le démon Docker pour activer la prise en charge d'IPv6 pour les conteneurs et utiliser ip6tables si nécessaire. Voici une configuration d'exemple pour votre fichier /etc/docker/daemon.json :

```json
{
  "experimental": true,
  "ipv6": true,
  "ip6tables": true,
  "fixed-cidr-v6": "fd00:dead:beef::/48"
}
```

Vous pouvez maintenant redémarrer le service Docker pour appliquer les modifications :

```shell
systemctl restart docker
```

Une fois Docker configuré pour prendre en charge IPv6, vous pouvez ajouter le paramÚtre `USE_IPV6` et configurer le réseau bw-services pour IPv6 :

```yaml
services:
  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      USE_IPv6: "yes"

...

networks:
  bw-services:
    name: bw-services
    enable_ipv6: true
    ipam:
      config:
        - subnet: fd00:13:37::/48
          gateway: fd00:13:37::1

...
```

=== "Linux"

Vous devrez ajouter ces paramĂštres au fichier /etc/bunkerweb/variables.env :

```conf
...
USE_IPV6=yes
...
```

Vérifions maintenant l'état de BunkerWeb :

```shell
systemctl status bunkerweb
```

S'il est déjà en cours d'exécution, nous pouvons redémarrer le scheduler pour qu'il régénÚre la configuration NGINX avec IPv6 activé :

```shell
systemctl restart bunkerweb-scheduler
```

Sinon, nous devrons le démarrer :

```shell
systemctl start bunkerweb
```

Options de configuration de journalisation

BunkerWeb offre une configuration de journalisation flexible, vous permettant d'envoyer les journaux vers plusieurs destinations (comme des fichiers, stdout/stderr ou syslog) simultanément. Cela est particuliÚrement utile pour l'intégration avec des collecteurs de journaux externes tout en conservant des journaux locaux pour l'interface Web.

Il y a deux catégories principales de journaux à configurer :

  1. Journaux de service : Journaux générés par les composants BunkerWeb (Scheduler, UI, Autoconf, etc.). ContrÎlés par service via LOG_TYPES (et optionnellement LOG_FILE_PATH, LOG_SYSLOG_ADDRESS, LOG_SYSLOG_TAG).
  2. Journaux d'accÚs et d'erreur : Journaux d'accÚs et d'erreur HTTP générés par NGINX. Seuls le service bunkerweb les utilise (ACCESS_LOG / ERROR_LOG / LOG_LEVEL).

Journaux de service

Les journaux de service sont contrÎlés par le paramÚtre LOG_TYPES, qui peut accepter plusieurs valeurs séparées par des espaces (par exemple, LOG_TYPES="stderr syslog").

Valeur Description
file Écrit les journaux dans un fichier plat. La rotation externe est assurĂ©e par logrotate sur les installations Linux ou par votre pilote de journalisation de conteneur sous Docker. Requis pour le visualiseur de journaux de l'interface Web.
stderr Écrit les journaux vers l'erreur standard. Standard pour les environnements conteneurisĂ©s (docker logs).
syslog Envoie les journaux vers un serveur syslog. Nécessite que LOG_SYSLOG_ADDRESS soit défini.

Lors de l'utilisation de file, vous devriez également configurer :

  • LOG_FILE_PATH : Chemin oĂč les fichiers de logs sont Ă©crits lorsque LOG_TYPES inclut file.

Lors de l'utilisation de syslog, vous devriez également configurer :

  • LOG_SYSLOG_ADDRESS : L'adresse du serveur syslog (par exemple, udp://bw-syslog:514 ou /dev/log).
  • LOG_SYSLOG_TAG : Une Ă©tiquette unique pour le service (par exemple, bw-scheduler) pour distinguer ses entrĂ©es.

Journaux d'accĂšs et d'erreur

Ce sont des journaux NGINX standard, configurés via le service bunkerweb uniquement. Ils prennent en charge plusieurs destinations en suffixant le nom du paramÚtre (par exemple, ACCESS_LOG, ACCESS_LOG_1 et le LOG_FORMAT correspondant, LOG_FORMAT_1 ou ERROR_LOG, ERROR_LOG_1 et leur LOG_LEVEL respectif, LOG_LEVEL_1).

  • ACCESS_LOG : Destination pour les journaux d'accĂšs (par dĂ©faut : /var/log/bunkerweb/access.log). Accepte un chemin de fichier, syslog:server=host[:port][,param=value], tampon partagĂ© memory:name:size, ou off pour dĂ©sactiver. Voir la documentation NGINX access_log pour plus de dĂ©tails.
  • ERROR_LOG : Destination pour les journaux d'erreur (par dĂ©faut : /var/log/bunkerweb/error.log). Accepte un chemin de fichier, stderr, syslog:server=host[:port][,param=value], ou tampon partagĂ© memory:size. Voir la documentation NGINX error_log pour plus de dĂ©tails.
  • LOG_LEVEL : Niveau de verbositĂ© des journaux d'erreur (par dĂ©faut : notice).

Ces paramÚtres acceptent des valeurs NGINX standard, y compris des chemins de fichiers, stderr, syslog:server=... (voir la documentation NGINX syslog), ou des tampons de mémoire partagée. Ils prennent en charge plusieurs destinations via des suffixes numérotés (voir la convention des paramÚtres multiples). Les autres services (Scheduler, UI, Autoconf, etc.) reposent uniquement sur LOG_TYPES/LOG_FILE_PATH/LOG_SYSLOG_*.

Exemple avec plusieurs journaux d'accÚs/erreur (bunkerweb uniquement, suffixes numérotés) :

ACCESS_LOG=/var/log/bunkerweb/access.log
ACCESS_LOG_1=syslog:server=unix:/dev/log,tag=bunkerweb
LOG_FORMAT=$host $remote_addr - $request_id $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
LOG_FORMAT_1=$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent
ERROR_LOG=/var/log/bunkerweb/error.log
ERROR_LOG_1=syslog:server=unix:/dev/log,tag=bunkerweb
LOG_LEVEL=notice
LOG_LEVEL_1=error

Valeurs par défaut et exemples d'intégration

=== "Linux"

**Comportement par défaut** : `LOG_TYPES="file"`. Les journaux sont écrits dans `/var/log/bunkerweb/*.log`. La rotation est gérée par la configuration systÚme `logrotate` installée dans `/etc/logrotate.d/bunkerweb` (quotidienne, rétention de 7 jours, compression via `copytruncate`).

**Exemple** : Conserver les fichiers locaux (pour l'interface Web) et les reproduire également vers le syslog systÚme.

```conf
  # Logs de service (à définir dans /etc/bunkerweb/variables.env ou les fichiers d'environnement spécifiques aux services)
  LOG_TYPES="file syslog"
  LOG_SYSLOG_ADDRESS=/dev/log
  SCHEDULER_LOG_FILE_PATH=/var/log/bunkerweb/scheduler.log
  UI_LOG_FILE_PATH=/var/log/bunkerweb/ui.log
  # ...
  # LOG_SYSLOG_TAG est défini automatiquement par service (remplacez-le par service si nécessaire)

  # Logs NGINX (service bunkerweb uniquement ; à définir dans /etc/bunkerweb/variables.env)
  ACCESS_LOG_1=syslog:server=unix:/dev/log,tag=bunkerweb_access
  ERROR_LOG_1=syslog:server=unix:/dev/log,tag=bunkerweb
```

=== "Docker / Autoconf / Swarm"

**Comportement par défaut** : `LOG_TYPES="stderr"`. Les journaux sont visibles via `docker logs`.

**Exemple (Adapté du guide de démarrage rapide)** : Conserver `docker logs` (stderr) ET envoyer vers un conteneur syslog central (nécessaire pour l'interface Web et CrowdSec).

```yaml
x-bw-env:
  &bw-env # On utilise une ancre pour Ă©viter de rĂ©pĂ©ter les mĂȘmes paramĂštres pour les deux services
  API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" # Assurez-vous de définir la plage IP correcte pour que le Scheduler puisse envoyer la configuration à l'instance
  # Optionnel : définissez un token API et répliquez-le dans les deux conteneurs
  API_TOKEN: ""
  DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # N'oubliez pas de définir un mot de passe plus fort pour la base de données
  # Logs des services
  LOG_TYPES: "stderr syslog"
  LOG_SYSLOG_ADDRESS: "udp://bw-syslog:514"
  # LOG_SYSLOG_TAG sera défini automatiquement par service (remplacez-le par service si nécessaire)
  # Logs NGINX : envoyer au syslog (bunkerweb uniquement)
  ACCESS_LOG_1: "syslog:server=bw-syslog:514,tag=bunkerweb_access"
  ERROR_LOG_1: "syslog:server=bw-syslog:514,tag=bunkerweb"

services:
  bunkerweb:
    # Ceci est le nom qui sera utilisé pour identifier l'instance dans le Scheduler
    image: bunkerity/bunkerweb:1.6.11-rc1
    ports:
      - "80:8080/tcp"
      - "443:8443/tcp"
      - "443:8443/udp" # Pour la prise en charge de QUIC / HTTP3
    environment:
      <<: *bw-env # Nous utilisons l'ancre pour Ă©viter de rĂ©pĂ©ter les mĂȘmes paramĂštres pour tous les services
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-services

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
    environment:
      <<: *bw-env
      BUNKERWEB_INSTANCES: "bunkerweb" # Assurez-vous de définir le nom d'instance correct
      SERVER_NAME: ""
      MULTISITE: "yes"
      UI_HOST: "http://bw-ui:7000" # Modifiez si nécessaire
      USE_REDIS: "yes"
      REDIS_HOST: "redis"
    volumes:
      - bw-storage:/data # Utilisé pour persister le cache et d'autres données (sauvegardes, etc.)
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-db

  bw-ui:
    image: bunkerity/bunkerweb-ui:1.6.11-rc1
    environment:
      <<: *bw-env
    volumes:
      - bw-logs:/var/log/bunkerweb # Permet Ă  l'UI de lire les logs syslog
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-db

  bw-db:
    image: mariadb:11
    # Nous dĂ©finissons max_allowed_packet pour Ă©viter les problĂšmes avec de grandes requĂȘtes
    command: --max-allowed-packet=67108864
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "db"
      MYSQL_USER: "bunkerweb"
      MYSQL_PASSWORD: "changeme" # N'oubliez pas de définir un mot de passe plus fort pour la base de données
    volumes:
      - bw-data:/var/lib/mysql
    restart: "unless-stopped"
    networks:
      - bw-db

  redis: # Service Redis pour la persistance des rapports/bans/statistiques
    image: redis:8-alpine
    command: >
      redis-server
      --maxmemory 256mb
      --maxmemory-policy volatile-lru
      --save 60 1000
      --appendonly yes
    volumes:
      - redis-data:/data
    restart: "unless-stopped"
    networks:
      - bw-universe

  bw-syslog:
    image: balabit/syslog-ng:4.10.2
    cap_add:
      - NET_BIND_SERVICE # Lier aux ports bas
      - NET_BROADCAST # Envoyer des broadcasts
      - NET_RAW # Utiliser des sockets bruts
      - DAC_READ_SEARCH # Lire des fichiers en contournant les permissions
      - DAC_OVERRIDE # Outrepasser les permissions de fichiers
      - CHOWN # Changer les propriétaires
      - SYSLOG # Écrire dans les journaux systùme
    volumes:
      - bw-logs:/var/log/bunkerweb # Volume utilisé pour stocker les logs
      - ./syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf # Fichier de configuration syslog-ng
    restart: "unless-stopped"
    networks:
      - bw-universe

volumes:
  bw-data:
  bw-storage:
  redis-data:
  bw-logs:

networks:
  bw-universe:
    name: bw-universe
  ipam:
    driver: default
    config:
      - subnet: 10.20.30.0/24 # Assurez-vous de définir la plage IP correcte pour que le Scheduler puisse envoyer la configuration à l'instance
  bw-services:
    name: bw-services
  bw-db:
    name: bw-db
```

=== "Kubernetes"

**Comportement par défaut** : Les journaux sont écrits sur `stderr` et visibles via `kubectl logs`.

**Exemple** : Activer le sidecar syslog intégré dans le chart Helm pour collecter les journaux pour l'interface Web (nécessite BunkerWeb 1.6.7+).

```yaml
ui:
  logs:
    # Activer le sidecar de collecte de journaux
    enabled: true

    # Adresse syslog pour le transfert des journaux
    # Automatiquement défini sur le service Sidecar si vide
    syslogAddress: ""

    # Conteneur syslog-ng pour la collecte de journaux
    repository: docker.io/balabit/syslog-ng
    pullPolicy: Always
    tag: 4.8.0

    # Stockage persistant pour les journaux
    persistence:
      size: 5Gi
      storageClass: ""
```

Consultez l'[exemple complet logging.yaml](https://github.com/bunkerity/bunkerweb-helm/blob/dev/examples/logging.yaml) dans le [dépÎt bunkerity/bunkerweb-helm](https://github.com/bunkerity/bunkerweb-helm).

Configuration de syslog-ng

Voici un exemple de fichier syslog-ng.conf que vous pouvez utiliser pour rediriger les journaux vers un fichier :

@version: 4.10

# Configuration de la source pour recevoir les journaux envoyés par les services BunkerWeb (ACCESS_LOG / ERROR_LOG et LOG_TYPES=syslog)
source s_net {
  udp(
    ip("0.0.0.0")
  );
};

# ModĂšle pour formater les messages de journalisation
template t_imp {
  template("$MSG\n");
  template_escape(no);
};

# Destination : écrire les journaux dans des fichiers nommés dynamiquement
destination d_dyna_file {
  file(
    "/var/log/bunkerweb/${PROGRAM}.log"
    template(t_imp)
    owner("101")
    group("101")
    dir_owner("root")
    dir_group("101")
    perm(0440)
    dir_perm(0770)
    create_dirs(yes)
    logrotate(
      enable(yes),
      size(100MB),
      rotations(7)
    )
  );
};

# Chemin de journalisation pour diriger les logs vers des fichiers nommés dynamiquement
log {
  source(s_net);
  destination(d_dyna_file);
};

Meilleures pratiques de journalisation Docker

Lors de l'utilisation de Docker, il est important de gérer les journaux des conteneurs pour éviter qu'ils ne consomment un espace disque excessif. Par défaut, Docker utilise le pilote de journalisation json-file, ce qui peut entraßner des fichiers journaux trÚs volumineux s'il n'est pas configuré.

Pour Ă©viter cela, vous pouvez configurer la rotation des journaux. Cela peut ĂȘtre fait pour des services spĂ©cifiques dans votre fichier docker-compose.yml, ou globalement pour le dĂ©mon Docker.

Configuration par service

Vous pouvez configurer le pilote de journalisation pour vos services dans votre fichier docker-compose.yml afin de faire pivoter automatiquement les journaux. Voici un exemple qui conserve jusqu'Ă  10 fichiers journaux de 20 Mo chacun :

services:
  bunkerweb:
    image: bunkerity/bunkerweb:1.6.11-rc1
    logging:
      driver: "json-file"
      options:
        max-size: "20m"
        max-file: "10"
    ...

Cette configuration garantit la rotation des journaux, les empĂȘchant de remplir votre disque. Vous pouvez l'appliquer Ă  n'importe quel service de votre configuration Docker Compose.

ParamĂštres globaux (daemon.json)

Si vous souhaitez appliquer ces paramÚtres de journalisation à tous les conteneurs de l'hÎte par défaut, vous pouvez configurer le démon Docker en modifiant (ou en créant) le fichier /etc/docker/daemon.json :

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "20m",
    "max-file": "10"
  }
}

AprÚs avoir modifié daemon.json, vous devez redémarrer le démon Docker pour que les modifications prennent effet :

sudo systemctl restart docker

Ces paramÚtres globaux seront hérités par tous les conteneurs. Cependant, toute configuration de journalisation définie par service dans un fichier docker-compose.yml remplacera les paramÚtres globaux dans daemon.json.

Réglage de la sécurité

BunkerWeb offre de nombreuses fonctionnalitĂ©s de sĂ©curitĂ© que vous pouvez configurer avec les fonctionnalitĂ©s. MĂȘme si les valeurs par dĂ©faut des paramĂštres assurent une "sĂ©curitĂ© par dĂ©faut" minimale, nous vous recommandons vivement de les rĂ©gler. Ce faisant, vous serez en mesure de vous assurer du niveau de sĂ©curitĂ© de votre choix, mais aussi de gĂ©rer les faux positifs.

!!! tip "Autres fonctionnalités" Cette section se concentre uniquement sur le réglage de la sécurité, voir la section fonctionnalités de la documentation pour d'autres paramÚtres.

![Vue d'ensemble](assets/img/core-order.svg){ align=center }
Vue d'ensemble et ordre des plugins de sécurité de base

Intégration de la console CrowdSec

Si vous n'ĂȘtes pas dĂ©jĂ  familier avec l'intĂ©gration de la console CrowdSec, CrowdSec exploite l'intelligence participative pour lutter contre les cybermenaces. ConsidĂ©rez-le comme le "Waze de la cybersĂ©curitĂ©" : lorsqu'un serveur est attaquĂ©, les autres systĂšmes du monde entier sont alertĂ©s et protĂ©gĂ©s contre les mĂȘmes attaquants. Vous pouvez en savoir plus Ă  ce sujet ici.

Félicitations, votre instance BunkerWeb est maintenant inscrite dans votre console CrowdSec !

Conseil professionnel : Lorsque vous consultez vos alertes, cliquez sur l'option "colonnes" et cochez la case "contexte" pour accéder aux données spécifiques à BunkerWeb.

![Vue d'ensemble](assets/img/crowdity4.png){ align=center }
Données BunkerWeb affichées dans la colonne de contexte

Proxy direct pour le trafic sortant

Si votre environnement doit faire passer le trafic HTTP(S) sortant par un proxy direct (par exemple un proxy d'entreprise ou Squid), vous pouvez utiliser les variables d'environnement de proxy standard. Il n'existe pas de réglage BunkerWeb dédié.

NGINX lui-mĂȘme n'utilise pas ces variables pour le trafic upstream, donc la configuration du proxy direct ne concerne que les composants qui initient des requĂȘtes sortantes. En pratique, configurez-les sur le Scheduler, car il gĂšre des tĂąches pĂ©riodiques comme les renouvellements de certificats Let's Encrypt, les appels d'API externes et les webhooks.

Les variables couramment utilisées sont :

  • HTTP_PROXY / HTTPS_PROXY : URL du proxy, Ă©ventuellement avec identifiants.
  • NO_PROXY : liste sĂ©parĂ©e par des virgules des hĂŽtes, domaines ou CIDR Ă  exclure du proxy (adaptez selon l'intĂ©gration : noms de services en Docker/Swarm, domaines de cluster en Kubernetes, ou simplement localhost sous Linux).
  • REQUESTS_CA_BUNDLE / SSL_CERT_FILE : optionnel, requis si le proxy utilise une AC personnalisĂ©e. Montez le bundle CA dans le conteneur et pointez ces variables vers celui-ci afin que les requĂȘtes Python puissent valider TLS (adaptez le chemin Ă  votre image de base).

!!! warning "NO_PROXY est requis pour le trafic interne" Si vous omettez les plages internes ou les noms de services, le trafic interne peut ĂȘtre envoyĂ© au proxy et Ă©chouer. Adaptez la liste Ă  votre intĂ©gration (par exemple noms de services Docker, domaines de cluster Kubernetes ou simplement localhost sous Linux).

=== "Linux"

Ajoutez les variables dans `/etc/bunkerweb/variables.env`. Ce fichier est chargé par les deux services, mais seul le Scheduler les utilisera :

```conf
HTTP_PROXY=http://proxy.example.local:3128
HTTPS_PROXY=http://proxy.example.local:3128
NO_PROXY=localhost,127.0.0.1
REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
```

Redémarrez les services pour recharger l'environnement :

```shell
sudo systemctl restart bunkerweb && \
sudo systemctl restart bunkerweb-scheduler
```

=== "All-in-one"

Fournissez les variables lors de la création du conteneur (et montez le bundle CA si nécessaire). L'image All-in-one inclut le Scheduler, ce qui couvre les tùches sortantes :

```bash
docker run -d \
    --name bunkerweb-aio \
    -v bw-storage:/data \
    -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro \
    -e HTTP_PROXY="http://proxy.example.local:3128" \
    -e HTTPS_PROXY="http://proxy.example.local:3128" \
    -e NO_PROXY="localhost,127.0.0.1" \
    -e REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" \
    -e SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt" \
    -p 80:8080/tcp \
    -p 443:8443/tcp \
    -p 443:8443/udp \
    bunkerity/bunkerweb-all-in-one:1.6.11-rc1
```

Si le conteneur existe déjà, recréez-le pour appliquer le nouvel environnement.

=== "Docker"

Ajoutez les variables au conteneur scheduler :

```yaml
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  ...
  environment:
    HTTP_PROXY: "http://proxy.example.local:3128"
    HTTPS_PROXY: "http://proxy.example.local:3128"
    NO_PROXY: "localhost,127.0.0.1,bunkerweb,bw-scheduler,redis,db"
    REQUESTS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt"
    SSL_CERT_FILE: "/etc/ssl/certs/ca-certificates.crt"
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
  ...
```

=== "Docker autoconf"

Appliquez les variables au conteneur scheduler :

```yaml
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  ...
  environment:
    HTTP_PROXY: "http://proxy.example.local:3128"
    HTTPS_PROXY: "http://proxy.example.local:3128"
    NO_PROXY: "localhost,127.0.0.1,bunkerweb,bw-scheduler,redis,db"
    REQUESTS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt"
    SSL_CERT_FILE: "/etc/ssl/certs/ca-certificates.crt"
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
  ...
```

=== "Kubernetes"

Ajoutez les variables au pod Scheduler via `extraEnvs`. Si vous avez besoin d'une AC personnalisée, montez-la via `extraVolumes`/`extraVolumeMounts` et pointez les variables vers le chemin monté :

```yaml
scheduler:
  extraEnvs:
    - name: HTTP_PROXY
      value: "http://proxy.example.local:3128"
    - name: HTTPS_PROXY
      value: "http://proxy.example.local:3128"
    - name: NO_PROXY
      value: "localhost,127.0.0.1,.svc,.cluster.local"
    - name: REQUESTS_CA_BUNDLE
      value: "/etc/ssl/certs/ca-certificates.crt"
    - name: SSL_CERT_FILE
      value: "/etc/ssl/certs/ca-certificates.crt"
```

=== "Swarm"

!!! warning "ObsolĂšte"
    L'intégration Swarm est obsolÚte et sera supprimée dans une future version. Veuillez envisager d'utiliser l'[intégration Kubernetes](integrations.md#kubernetes) à la place.

    **Plus d'informations sont disponibles dans la [documentation de l'intégration Swarm](integrations.md#swarm).**

Ajoutez les variables au service scheduler :

```yaml
bw-scheduler:
  image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
  ...
  environment:
    HTTP_PROXY: "http://proxy.example.local:3128"
    HTTPS_PROXY: "http://proxy.example.local:3128"
    NO_PROXY: "localhost,127.0.0.1,bunkerweb,bw-scheduler,redis,db"
    REQUESTS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt"
    SSL_CERT_FILE: "/etc/ssl/certs/ca-certificates.crt"
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
  ...
```

Surveillance et rapports

Monitoring crown pro icon (PRO)

Prise en charge de STREAM ❌

Le plugin de surveillance vous permet de collecter et de rĂ©cupĂ©rer des mĂ©triques sur BunkerWeb. En l'activant, votre ou vos instances commenceront Ă  collecter diverses donnĂ©es liĂ©es aux attaques, aux requĂȘtes et aux performances. Vous pouvez ensuite les rĂ©cupĂ©rer en appelant rĂ©guliĂšrement le point de terminaison de l' /monitoring API ou en utilisant d'autres plugins comme celui de l'exportateur Prometheus.

Liste des fonctionnalités

  • Permettre la collecte de diverses mĂ©triques BunkerWeb
  • RĂ©cupĂ©rer des mĂ©triques Ă  partir de l'API
  • Utilisation en combinaison avec d'autres plugins (par exemple Prometheus exporter)
  • DĂ©diĂ©e Ă  la page d'interface utilisateur pour surveiller vos instances

Liste des paramĂštres

Réglage Défaut Contexte Multiple Description
USE_MONITORING yes global Non Activez la surveillance de BunkerWeb.
MONITORING_METRICS_DICT_SIZE 10M global Non Taille du dictionnaire pour stocker les métriques de surveillance.
MONITORING_IGNORE_URLS global Non Liste de chemins d'URL séparés par des espaces à exclure de la surveillance (ex. /health /ready).

Prometheus exporter crown pro icon (PRO)

Prise en charge de STREAM ❌

Le plugin d'exportation Prometheus ajoute un exportateur Prometheus sur votre ou vos instances BunkerWeb. Lorsqu'elle est activée, vous pouvez configurer votre ou vos instances Prometheus pour récupérer un point de terminaison spécifique sur Bunkerweb et collecter des métriques internes.

Nous fournissons également un tableau de bord Grafana que vous pouvez importer dans votre propre instance et connecter à votre propre source de données Prometheus.

Veuillez noter que l'utilisation du plugin d'exportation Prometheus nécessite d'activer le plugin de surveillance (USE_MONITORING=yes)

Liste des fonctionnalités

  • L'exportateur Prometheus fournit des mĂ©triques internes Ă  BunkerWeb
  • Port dĂ©diĂ© et configurable, IP et URL d'Ă©coute
  • Liste blanche IP/rĂ©seau pour une sĂ©curitĂ© maximale

Liste des paramĂštres

Réglage Ddéfaut Contexte Multiple Description
USE_PROMETHEUS_EXPORTER no global Non Activez l'exportation Prometheus.
PROMETHEUS_EXPORTER_IP 0.0.0.0 global Non IP d'écoute de l'exportateur Prometheus.
PROMETHEUS_EXPORTER_PORT 9113 global Non Port d'écoute de l'exportateur Prometheus.
PROMETHEUS_EXPORTER_URL /metrics global Non URL HTTP de l'exportateur Prometheus.
PROMETHEUS_EXPORTER_ALLOW_IP 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 global Non Liste des adresses IP/réseaux autorisés à contacter le point de terminaison de l'exportateur Prometheus.

Reporting crown pro icon (PRO)

Prise en charge de STREAM ❌

!!! warning "Plugin de surveillance nécessaire" Ce plug-in nécessite l'installation et l'activation du plug-in Monitoring Pro avec le USE_MONITORING paramÚtre défini sur yes.

Le plugin Reporting fournit une solution complÚte pour la communication réguliÚre de données importantes de BunkerWeb, y compris les statistiques mondiales, les attaques, les bannissements, les demandes, les raisons et les informations AS. Il offre un large éventail de fonctionnalités, notamment la création automatique de rapports, des options de personnalisation et une intégration transparente avec le plugin monitoring pro. Avec le plugin Reporting, vous pouvez facilement générer et gérer des rapports pour surveiller les performances et la sécurité de votre application.

Liste des fonctionnalités

  • Rapports rĂ©guliers sur les donnĂ©es importantes de BunkerWeb, y compris les statistiques mondiales, les attaques, les bannissements, les demandes, les raisons et les informations sur les SA.
  • IntĂ©gration avec le plug-in Monitoring Pro pour une intĂ©gration transparente et des capacitĂ©s de reporting amĂ©liorĂ©es.
  • Prise en charge des webhooks (classique, Discord et Slack) pour les notifications en temps rĂ©el.
  • Prise en charge de SMTP pour les notifications par e-mail.
  • Options de configuration pour plus de personnalisation et de flexibilitĂ©.

Liste des paramĂštres

Réglage Par défaut Contexte Description
USE_REPORTING_SMTP no global Activer l'envoi du rapport par e-mail (HTML).
USE_REPORTING_WEBHOOK no global Activer l'envoi du rapport via webhook (Markdown).
REPORTING_SCHEDULE weekly global Cadence du rapport : daily, weekly ou monthly.
REPORTING_WEBHOOK_URLS global URLs de webhook séparées par des espaces ; Discord et Slack sont détectés automatiquement.
REPORTING_SMTP_EMAILS global Destinataires e-mail séparés par des espaces.
REPORTING_SMTP_HOST global Nom d'hĂŽte ou IP du serveur SMTP.
REPORTING_SMTP_PORT 465 global Port SMTP. Utilisez 465 pour SSL, 587 pour TLS.
REPORTING_SMTP_FROM_EMAIL global Adresse de l'expéditeur (désactivez la 2FA si nécessaire).
REPORTING_SMTP_FROM_USER global Nom d'utilisateur SMTP (utilise l'adresse d'envoi si seul le mot de passe est fourni).
REPORTING_SMTP_FROM_PASSWORD global Mot de passe SMTP.
REPORTING_SMTP_SSL SSL global Sécurité de connexion : no, SSL ou TLS.
REPORTING_SMTP_SUBJECT BunkerWeb Report global Objet des envois e-mail.

!!! info "Information et comportement" - REPORTING_SMTP_EMAILS est requis quand l'envoi SMTP est activé ; REPORTING_WEBHOOK_URLS est requis quand les webhooks sont activés. - Si les webhooks et SMTP échouent tous, une nouvelle tentative est effectuée lors de la prochaine exécution planifiée. - Les modÚles HTML et Markdown se trouvent dans reporting/files/ ; personnalisez-les prudemment pour conserver les variables.

Sauvegarde et restauration

Backup S3 crown pro icon (PRO)

Prise en charge STREAM ✅

L'outil Backup S3 automatise de maniÚre transparente la protection des données, à l'instar du plug-in de sauvegarde communautaire. Cependant, il se distingue par le stockage sécurisé des sauvegardes directement dans un compartiment S3.

En activant cette fonctionnalité, vous protégez de maniÚre proactive l'intégrité de vos données. Le stockage à distance des sauvegardes protÚge les informations cruciales contre les menaces telles que ** les pannes matérielles**, les cyberattaques ou les catastrophes naturelles. Cela garantit à la fois la sécurité et la disponibilité, ce qui permet une récupération rapide en cas ** d'événements inattendus**, préservant la continuité opérationnelle et garantissant la tranquillité d'esprit.

??? warning "Informations pour les utilisateurs de Red Hat Enterprise Linux (RHEL) 8.9" Si vous utilisez RHEL 8.9 et que vous prévoyez d'utiliser une base de données externe, vous devez installer le mysql-community-client package pour vous assurer que la mysqldump commande est disponible. Vous pouvez installer le package en exécutant les commandes suivantes :

=== "MySQL/MariaDB"

    1. **Installez le paquet de configuration du dépÎt MySQL**

      ```bash
      sudo dnf install https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm
      ```

    2. **Activez le dépÎt MySQL**

      ```bash
      sudo dnf config-manager --enable mysql80-community
      ```

    3. **Installez le client MySQL**

      ```bash
      sudo dnf install mysql-community-client
      ```

=== "PostgreSQL"

    1. **Installez le paquet de configuration du dépÎt PostgreSQL**

      ```bash
      dnf install "https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm"
      ```

    2. **Installez le client PostgreSQL**

      ```bash
      dnf install postgresql<version>
      ```

Liste des fonctionnalités

  • Sauvegarde automatique des donnĂ©es dans un compartiment S3
  • Options de planification flexibles : quotidienne, hebdomadaire ou mensuelle
  • Gestion de la rotation pour contrĂŽler le nombre de sauvegardes Ă  conserver
  • Niveau de compression personnalisable pour les fichiers de sauvegarde

Liste des paramĂštres

Réglage Faire défaut Contexte Description
USE_BACKUP_S3 no global Activer ou désactiver la fonction de sauvegarde S3
BACKUP_S3_SCHEDULE daily global La fréquence de la sauvegarde
BACKUP_S3_ROTATION 7 global Le nombre de sauvegardes Ă  conserver
BACKUP_S3_ENDPOINT global Le point de terminaison S3
BACKUP_S3_BUCKET global Le godet S3
BACKUP_S3_DIR global L'annuaire S3
BACKUP_S3_REGION global La région S3
BACKUP_S3_ACCESS_KEY_ID global L'ID de la clé d'accÚs S3
BACKUP_S3_ACCESS_KEY_SECRET global Le secret de la clé d'accÚs S3
BACKUP_S3_COMP_LEVEL 6 global Le niveau de compression du fichier zip de sauvegarde

Sauvegarde manuelle

Pour lancer manuellement une sauvegarde, exécutez la commande suivante :

=== "Linux"

```bash
bwcli plugin backup_s3 save
```

=== "Docker"

```bash
docker exec -it <scheduler_container> bwcli plugin backup_s3 save
```

Cette commande crée une sauvegarde de votre base de données et la stocke dans le compartiment S3 spécifié dans le BACKUP_S3_BUCKET paramÚtre.

Vous pouvez également spécifier un compartiment S3 personnalisé pour la sauvegarde en fournissant la variable d' BACKUP_S3_BUCKET environnement lors de l'exécution de la commande :

=== "Linux"

```bash
BACKUP_S3_BUCKET=your-bucket-name bwcli plugin backup_s3 save
```

=== "Docker"

```bash
docker exec -it -e BACKUP_S3_BUCKET=your-bucket-name <scheduler_container> bwcli plugin backup_s3 save
```

!!! note "Spécifications pour MariaDB/MySQL"

Si vous utilisez MariaDB/MySQL, vous pouvez rencontrer l'erreur suivante lors de la sauvegarde de votre base de données :

```bash
caching_sha2_password could not be loaded: Error loading shared library /usr/lib/mariadb/plugin/caching_sha2_password.so
```

Pour résoudre ce problÚme, vous pouvez exécuter la commande suivante pour changer le plugin d'authentification en `mysql_native_password` :

```sql
ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
```

Si vous utilisez l'intégration Docker, vous pouvez ajouter la commande suivante au fichier `docker-compose.yml` pour changer automatiquement le plugin d'authentification :

=== "MariaDB"

    ```yaml
    bw-db:
        image: mariadb:<version>
        command: --default-authentication-plugin=mysql_native_password
        ...
    ```

=== "MySQL"

    ```yaml
    bw-db:
        image: mysql:<version>
        command: --default-authentication-plugin=mysql_native_password
        ...
    ```

Restauration manuelle

Pour lancer manuellement une restauration, exécutez la commande suivante :

=== "Linux"

```bash
bwcli plugin backup_s3 restore
```

=== "Docker"

```bash
docker exec -it <scheduler_container> bwcli plugin backup_s3 restore
```

Cette commande crée une sauvegarde temporaire de votre base de données dans le compartiment S3 spécifié dans le BACKUP_S3_BUCKET paramÚtre et restaure votre base de données à la derniÚre sauvegarde disponible dans le compartiment.

Vous pouvez également spécifier un fichier de sauvegarde personnalisé pour la restauration en fournissant le chemin d'accÚs à celui-ci en tant qu'argument lors de l'exécution de la commande :

=== "Linux"

```bash
bwcli plugin backup_s3 restore s3_backup_file.zip
```

=== "Docker"

```bash
docker exec -it <scheduler_container> bwcli plugin backup restore s3_backup_file.zip
```

!!! example "En cas de panne"

Don't worry if the restore fails, you can always restore your database to the previous state by executing the command again as a backup is created before the restore:

=== "Linux"

    ```bash
    bwcli plugin backup_s3 restore
    ```

=== "Docker"

    ```bash
    docker exec -it <scheduler_container> bwcli plugin backup_s3 restore
    ```

Serveur MCP

Le serveur MCP BunkerWeb permet aux assistants IA comme Claude Code et Claude Desktop de gérer votre installation BunkerWeb via le Model Context Protocol (MCP).

!!! warning "Prérequis" Le serveur MCP nécessite le déploiement de l'API externe BunkerWeb (bunkerity/bunkerweb-api). Il communique avec BunkerWeb exclusivement via cette API.

Fonctionnalités

  • 37 outils pour gĂ©rer les instances, services, configurations, bans, plugins, jobs et cache
  • Ressources MCP pour un accĂšs en lecture seule (@config://global, @bans://active, etc.)
  • Plusieurs transports : Stdio, HTTP, WebSocket

Exemple Docker Compose

Un exemple complet est disponible dans examples/mcp-stack/ :

services:
  bw-api:
    image: bunkerity/bunkerweb-api:1.6.11-rc1
    environment:
      API_TOKEN: "my-bearer-token-for-mcp"
      DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"
      FORWARDED_ALLOW_IPS: "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
    networks:
      - bw-universe
      - bw-db
      - bw-mcp

  bw-mcp:
    image: bunkerity/bunkerweb-mcp:v0.1.0
    ports:
      - "127.0.0.1:8080:8080"
    environment:
      BUNKERWEB_BASE_URL: "http://bw-api:8888"
      BUNKERWEB_API_TOKEN: "my-bearer-token-for-mcp"
      BUNKERWEB_LOG_LEVEL: INFO
    networks:
      - bw-mcp

Utilisation avec Claude Code

=== "Configuration projet"

Ajoutez un fichier `.mcp.json` Ă  la racine de votre projet (ou dans `~/.claude/.mcp.json` pour une configuration globale) :

```json
{
  "mcpServers": {
    "bunkerweb": {
      "type": "http",
      "url": "http://127.0.0.1:8080/mcp/"
    }
  }
}
```

=== "CLI"

```bash
# Ajouter le serveur MCP via HTTP
claude mcp add --transport http bunkerweb --scope local http://localhost:8080/mcp

# Ou via stdio (installation locale)
pip install mcp-bunkerweb
claude mcp add --transport stdio bunkerweb --scope local -- mcp-bunkerweb
```

Exemples de requĂȘtes :

> Liste toutes les instances BunkerWeb
> Montre-moi les bans actuels
> Analyse @config://global et suggÚre des améliorations de sécurité

Intégration Kubernetes

Le serveur MCP peut ĂȘtre dĂ©ployĂ© aux cĂŽtĂ©s de BunkerWeb en utilisant le chart Helm officiel. Un exemple complet est disponible dans examples/mcp-integration.yaml.

Valeurs Helm

mcp:
  # Activer le serveur MCP
  enabled: true

  # Configuration de l'image
  repository: docker.io/bunkerity/bunkerweb-mcp
  tag: v0.1.0

  # ParamĂštres du serveur MCP
  config:
    logLevel: "INFO"
    enableDnsRebindingProtection: true
    allowedHosts: "localhost,127.0.0.1,mcp.example.com"
    cacheEnabled: true

  # Identifiants pour l'authentification MCP vers l'API BunkerWeb
  secrets:
    bunkerwebApiToken: "votre-token-api-securise"

  # Configuration Ingress (optionnel)
  ingress:
    enabled: false
    ingressClassName: "bunkerweb"
    serverName: "mcp.example.com"
    annotations:
      bunkerweb.io/AUTO_LETS_ENCRYPT: "yes"
      bunkerweb.io/USE_REVERSE_PROXY: "yes"
      bunkerweb.io/REVERSE_PROXY_URL: "/"
      bunkerweb.io/REVERSE_PROXY_HOST: "http://mcp-bunkerweb.bunkerweb.svc.cluster.local:8080"
      # SÉCURITÉ : Restreindre l'accùs aux IPs de confiance uniquement
      bunkerweb.io/USE_WHITELIST: "yes"
      bunkerweb.io/WHITELIST_IP: "10.0.0.0/8 192.168.0.0/16"

Déploiement

# Déployer BunkerWeb avec MCP activé
helm install bunkerweb bunkerweb/bunkerweb -f mcp-integration.yaml

# Accéder au MCP localement via port-forward (recommandé pour la sécurité)
kubectl port-forward svc/mcp-bunkerweb 8080:8080

# Configurer Claude Code avec http://localhost:8080/mcp

!!! warning "Sécurité" Le serveur MCP n'a pas d'authentification intégrée pour le endpoint /mcp. Sécurisez l'accÚs en utilisant :

- **Liste blanche d'IPs** via les annotations BunkerWeb (`USE_WHITELIST`, `WHITELIST_IP`)
- **Politiques réseau** pour restreindre la communication entre pods
- **Port-forward** au lieu d'exposer externellement (recommandé pour le développement)

Pour la documentation complÚte, visitez le dépÎt BunkerWeb MCP.

Migration crown pro icon (PRO)

Prise en charge STREAM ✅

Le plug-in de migration révolutionne les transferts de configuration BunkerWeb entre les instances grùce à son interface Web conviviale, simplifiant ainsi l'ensemble du parcours de migration. Que vous mettiez à niveau des systÚmes, que vous fassiez évoluer une infrastructure ou que vous transformiez d'environnement, cet outil vous permet de transférer sans effort les paramÚtres, les préférences et les données avec une facilité et une confiance inégalées. Dites adieu aux processus manuels fastidieux et bonjour à une expérience de migration transparente et sans tracas.

Liste des fonctionnalités

  • Migration sans effort : TransfĂ©rez facilement les configurations BunkerWeb entre les instances sans les complexitĂ©s des procĂ©dures manuelles.

  • Interface Web intuitive : Naviguez sans effort dans le processus de migration grĂące Ă  une interface Web conviviale conçue pour un fonctionnement intuitif.

  • CompatibilitĂ© entre bases de donnĂ©es : profitez d'une migration transparente sur diverses plates-formes de bases de donnĂ©es, notamment SQLite, MySQL, MariaDB et PostgreSQL, garantissant la compatibilitĂ© avec votre environnement de base de donnĂ©es prĂ©fĂ©rĂ©.

Créer un fichier de migration

Pour créer manuellement un fichier de migration, exécutez la commande suivante :

=== "Linux"

```bash
bwcli plugin migration create /path/to/migration/file
```

=== "Docker"

1. Créez un fichier de migration :

    ```bash
    docker exec -it <scheduler_container> bwcli plugin migration create /path/to/migration/file
    ```

2. Copiez le fichier de migration sur votre ordinateur local :

    ```bash
    docker cp <scheduler_container>:/path/to/migration/file /path/to/migration/file
    ```

Cette commande créera une sauvegarde de votre base de données et la stockera dans le répertoire de sauvegarde spécifié dans la commande.

!!! note "Spécifications pour MariaDB/MySQL"

Si vous utilisez MariaDB/MySQL, vous pouvez rencontrer l'erreur suivante lors de la sauvegarde de votre base de données :

```bash
caching_sha2_password could not be loaded: Error loading shared library /usr/lib/mariadb/plugin/caching_sha2_password.so
```

Pour résoudre ce problÚme, vous pouvez exécuter la commande suivante pour changer le plugin d'authentification en `mysql_native_password` :

```sql
ALTER USER 'yourusername'@'localhost' IDENTIFIED WITH mysql_native_password BY 'youpassword';
```

Si vous utilisez l'intégration Docker, vous pouvez ajouter la commande suivante au fichier `docker-compose.yml` pour changer automatiquement le plugin d'authentification :

=== "MariaDB"

    ```yaml
    bw-db:
        image: mariadb:<version>
        command: --default-authentication-plugin=mysql_native_password
        ...
    ```

=== "MySQL"

    ```yaml
    bw-db:
        image: mysql:<version>
        command: --default-authentication-plugin=mysql_native_password
        ...
    ```

Initialiser une migration

Pour initialiser manuellement une migration, exécutez la commande suivante :

=== "Linux"

```bash
bwcli plugin migration migrate /path/to/migration/file
```

=== "Docker"

1. Copiez le fichier de migration dans le conteneur :

    ```bash
    docker cp /path/to/migration/file <scheduler_container>:/path/to/migration/file
    ```

2. Initialisez la migration :

    ```bash
    docker exec -it <scheduler_container> bwcli plugin migration migrate /path/to/migration/file
    ```

=== "Tout-en-un"

1. Copiez le fichier de migration dans le conteneur :

    ```bash
    docker cp /path/to/migration/file bunkerweb-aio:/path/to/migration/file
    ```

2. Initialisez la migration :

    ```bash
    docker exec -it bunkerweb-aio bwcli plugin migration migrate /path/to/migration/file
    ```

Cette commande migre de maniÚre transparente vos données BunkerWeb pour qu'elles correspondent précisément à la configuration décrite dans le fichier de migration.

Anti DDoS crown pro icon (PRO)

Prise en charge de STREAM ❌

Le plug-in anti-DDoS offre une protection avancée contre les attaques par déni de service distribué (DDoS) en surveillant, analysant et filtrant le trafic suspect en temps réel.

En utilisant un mĂ©canisme de fenĂȘtre glissante, le plugin maintient un dictionnaire en mĂ©moire des horodatages des requĂȘtes pour dĂ©tecter les pics de trafic anormaux Ă  partir d'adresses IP individuelles. En fonction du mode de sĂ©curitĂ© configurĂ©, il peut soit bloquer les connexions incriminĂ©es, soit consigner l'activitĂ© suspecte pour un examen plus approfondi.

Fonctionnalités

  • Analyse du trafic en temps rĂ©el : surveille en permanence les demandes entrantes pour dĂ©tecter les attaques DDoS potentielles.
  • MĂ©canisme de fenĂȘtre glissante : suit l'activitĂ© rĂ©cente des demandes dans une fenĂȘtre de temps configurable.
  • Seuils configurables : vous permet de dĂ©finir le nombre maximum de requĂȘtes suspectes par IP.
  • Logique de blocage avancĂ©e : Ă©value Ă  la fois le nombre de requĂȘtes par IP et le nombre d'adresses IP distinctes dĂ©passant le seuil.
  • Modes de sĂ©curitĂ© flexibles : choisissez entre le blocage immĂ©diat de la connexion ou le mode de dĂ©tection uniquement (journalisation).
  • Magasin de donnĂ©es en mĂ©moire optimisĂ© : Garantit des recherches Ă  grande vitesse et un suivi efficace des mĂ©triques.
  • Entretien mĂ©nager automatique : efface pĂ©riodiquement les donnĂ©es obsolĂštes pour maintenir des performances optimales.

Configuration

Personnalisez le comportement du plug-in Ă  l'aide des paramĂštres suivants :

Réglage Faire défaut Contexte Multiple Description
USE_ANTIDDOS no global Non Activez ou désactivez la protection anti-DDoS. Réglez sur "yes" pour activer le plugin.
ANTIDDOS_METRICS_DICT_SIZE 10M global Non Taille de la banque de données en mémoire pour le suivi des métriques DDoS (par exemple, 10M, 500k).
ANTIDDOS_THRESHOLD 100 global Non Nombre maximum de requĂȘtes suspectes autorisĂ©es par IP dans la fenĂȘtre de temps dĂ©finie.
ANTIDDOS_WINDOW_TIME 10 global Non FenĂȘtre de temps en secondes pendant laquelle les demandes suspectes sont comptabilisĂ©es.
ANTIDDOS_STATUS_CODES 429 403 444 global Non Codes d'état HTTP considérés comme suspects et utilisés pour déclencher des actions anti-DDoS.
ANTIDDOS_DISTINCT_IP 5 global Non Nombre minimum d'adresses IP distinctes qui doivent dépasser le seuil avant d'appliquer le mode de blocage.

Bonnes pratiques

  • RĂ©glage du seuil : ajustez ANTIDDOS_THRESHOLD et ANTIDDOS_WINDOW_TIME en fonction de vos modĂšles de trafic typiques.
  • RĂ©vision du code d'Ă©tat : mettez rĂ©guliĂšrement Ă  jour ANTIDDOS_STATUS_CODES pour capturer les comportements suspects nouveaux ou en Ă©volution.
  • Surveillance : analysez rĂ©guliĂšrement les journaux et les mĂ©triques pour affiner les paramĂštres et amĂ©liorer la protection globale.

User Manager crown pro icon (PRO)

STREAM support ❌

Le plugin User Manager offre une interface robuste pour l'administration des comptes utilisateurs au sein de votre systĂšme.

Avec ce plugin, les administrateurs peuvent aisément créer, mettre à jour et désactiver des comptes utilisateurs, gérer les rÎles, basculer l'authentification à deux facteurs (2FA) et consulter des informations détaillées sur les utilisateurs telles que les horodatages de la derniÚre connexion et les statuts des comptes (actif ou inactif). Conçu dans un souci de sécurité et de facilité d'utilisation, ce plugin simplifie les tùches courantes de gestion des utilisateurs tout en garantissant la conformité et l'auditabilité.

Fonctionnalités

  • OpĂ©rations de compte utilisateur : importez au format CSV/XLSX, crĂ©ez, modifiez et supprimez des comptes utilisateur en toute simplicitĂ©.
  • ContrĂŽle d'accĂšs basĂ© sur les rĂŽles : attribuez et modifiez les rĂŽles d'utilisateur pour gĂ©rer les autorisations et les niveaux d'accĂšs.
  • Gestion 2FA : dĂ©sactivez l'authentification Ă  deux facteurs en fonction des dĂ©cisions administratives.
  • Informations complĂštes sur les utilisateurs : surveillez les donnĂ©es clĂ©s des utilisateurs, notamment les heures de derniĂšre connexion, les dates de crĂ©ation de compte et le statut actif/inactif.
  • Journalisation des audits : conservez une piste d'audit pour toutes les actions de gestion des utilisateurs afin d'amĂ©liorer la sĂ©curitĂ© et la conformitĂ©.

Configuration

ParamÚtre Défaut Contexte Multiple Description
USERS_REQUIRE_2FA no global non Exiger l'authentification Ă  deux facteurs pour tous les utilisateurs.
![Vue d'ensemble](assets/img/user-manager.png){ align=center }
Page User Manager
![Créer un formulaire utilisateur](assets/img/user-manager-create.png){ align=center }
User Manager - Formulaire de création d'utilisateur
![Page d'activités](assets/img/user-manager-activities.png){ align=center }
User Manager - Page Activités

UI Single Sign-On crown pro icon (PRO)

STREAM support ❌

Le plugin UI Single Sign-On permet l'authentification SSO pour l'interface web de BunkerWeb en lisant les en-tĂȘtes dĂ©finis par un proxy d'authentification externe (tel qu'Authentik, Authelia, Keycloak ou Traefik Forward Auth) placĂ© devant l'interface web.

Au lieu de gĂ©rer des identifiants distincts pour BunkerWeb, les administrateurs peuvent dĂ©lĂ©guer l'authentification Ă  un fournisseur d'identitĂ© existant. Le proxy d'authentification gĂšre la connexion des utilisateurs et injecte des en-tĂȘtes d'identitĂ© avant de transmettre les requĂȘtes Ă  l'interface web de BunkerWeb.

!!! danger "Risque d'usurpation d'en-tĂȘtes" Les en-tĂȘtes SSO peuvent ĂȘtre facilement falsifiĂ©s par n'importe quel client. Vous devez restreindre UI_SSO_TRUSTED_IPS aux adresses IP de votre proxy d'authentification. Si ce paramĂštre est mal configurĂ©, n'importe quel client peut envoyer de faux en-tĂȘtes et obtenir un accĂšs non autorisĂ©, y compris un accĂšs administrateur.

La valeur par défaut `127.0.0.1,::1` ne fait confiance qu'au localhost. Dans les déploiements **Docker, Swarm ou Kubernetes**, le proxy d'authentification s'exécute dans un conteneur séparé avec sa propre adresse IP. Définissez `UI_SSO_TRUSTED_IPS` sur l'adresse IP ou le CIDR réel du conteneur du proxy d'authentification (par ex. `10.20.30.5` ou `172.18.0.0/16`). Ne le définissez jamais à `0.0.0.0/0`.

Fonctionnalités

  • Authentification par en-tĂȘtes : lit le nom d'utilisateur, l'e-mail, le nom d'affichage et les groupes depuis les en-tĂȘtes du proxy d'authentification.
  • Correspondance groupe-rĂŽle : associez les groupes de l'IdP aux rĂŽles BunkerWeb (admin, writer, reader).
  • Provisionnement automatique des utilisateurs : crĂ©e des comptes locaux lors de la premiĂšre connexion SSO avec un rĂŽle par dĂ©faut configurable.
  • Liaison de comptes : associe les utilisateurs SSO entrants aux comptes locaux existants par nom d'utilisateur ou e-mail.
  • Restriction par IP de confiance : n'accepte les en-tĂȘtes SSO que depuis les adresses IP ou plages CIDR configurĂ©es.
  • Repli vers la connexion classique : permet optionnellement la connexion par mot de passe lorsque les en-tĂȘtes SSO sont absents.
  • Redirection de dĂ©connexion : redirige les utilisateurs vers l'endpoint de dĂ©connexion du fournisseur SSO aprĂšs la dĂ©connexion locale.

Configuration

ParamÚtre Défaut Contexte Multiple Description
USE_UI_SSO no global non Activer ou désactiver l'authentification UI Single Sign-On pour l'interface web.
UI_SSO_HEADER_USERNAME X-User global non En-tĂȘte HTTP contenant le nom d'utilisateur authentifiĂ©.
UI_SSO_HEADER_EMAIL X-Email global non En-tĂȘte HTTP contenant l'adresse e-mail de l'utilisateur.
UI_SSO_HEADER_GROUPS X-Groups global non En-tĂȘte HTTP contenant les groupes de l'utilisateur (sĂ©parĂ©s par des virgules ou des espaces).
UI_SSO_HEADER_NAME X-Name global non En-tĂȘte HTTP contenant le nom d'affichage de l'utilisateur.
UI_SSO_TRUSTED_IPS 127.0.0.1,::1 global non Liste d'adresses IP ou de plages CIDR de confiance autorisĂ©es Ă  envoyer les en-tĂȘtes SSO, sĂ©parĂ©es par des virgules.
UI_SSO_AUTO_CREATE_USERS yes global non Créer automatiquement de nouveaux utilisateurs lors de leur premiÚre authentification SSO.
UI_SSO_DEFAULT_ROLE reader global non RÎle par défaut attribué aux nouveaux utilisateurs SSO lorsqu'aucune correspondance de groupe n'est trouvée.
UI_SSO_GROUP_ADMIN global non Nom du groupe accordant le rÎle admin (priorité la plus haute).
UI_SSO_GROUP_WRITER global non Nom du groupe accordant le rĂŽle writer.
UI_SSO_GROUP_READER global non Nom du groupe accordant le rĂŽle reader.
UI_SSO_FALLBACK_TO_LOGIN yes global non Permettre aux utilisateurs de se rabattre sur la connexion classique lorsque les en-tĂȘtes SSO sont absents.
UI_SSO_UPDATE_USER_ON_LOGIN yes global non Mettre Ă  jour les informations utilisateur (e-mail, rĂŽle) depuis les en-tĂȘtes SSO Ă  chaque connexion.
UI_SSO_ACCOUNT_LINKING username_or_email global non Mode de correspondance des utilisateurs SSO entrants avec les comptes locaux (username_only ou username_or_email).
UI_SSO_LOGOUT_REDIRECT_URL global non URL de redirection aprÚs déconnexion (par ex. endpoint de déconnexion du fournisseur SSO).

Démarrage rapide

  1. Placez un proxy d'authentification (Authentik, Authelia, Keycloak, etc.) devant l'interface web de BunkerWeb.
  2. Activez le plugin : USE_UI_SSO=yes.
  3. VĂ©rifiez que le proxy dĂ©finit les en-tĂȘtes attendus (X-User, X-Email, X-Groups, X-Name) -- ou ajustez les noms d'en-tĂȘtes via les paramĂštres UI_SSO_HEADER_*.
  4. Restreignez les sources de confiance : définissez UI_SSO_TRUSTED_IPS sur les adresses IP du proxy d'authentification.
  5. Associez les groupes aux rÎles : définissez UI_SSO_GROUP_ADMIN, UI_SSO_GROUP_WRITER et UI_SSO_GROUP_READER pour correspondre aux noms de groupes de votre IdP.

Conseils d'utilisation

  • DĂ©finissez UI_SSO_FALLBACK_TO_LOGIN=no en production pour imposer un accĂšs exclusivement SSO. Lorsque la valeur est laissĂ©e Ă  yes (par dĂ©faut), les utilisateurs peuvent contourner le SSO et se connecter avec des identifiants locaux, ignorant ainsi les politiques MFA ou de session imposĂ©es par votre fournisseur d'identitĂ©.
  • Conservez UI_SSO_UPDATE_USER_ON_LOGIN Ă  sa valeur par dĂ©faut (yes) pour garantir la synchronisation des rĂŽles avec les modifications de groupes de l'IdP.
  • Avec UI_SSO_ACCOUNT_LINKING=username_or_email, les comptes locaux existants sont automatiquement liĂ©s lors de la premiĂšre connexion SSO si le nom d'utilisateur ou l'e-mail correspond. Utilisez username_only si votre IdP permet aux utilisateurs de dĂ©finir des adresses e-mail arbitraires, afin de prĂ©venir la prise de contrĂŽle de comptes par usurpation d'e-mail.

Easy Resolve crown pro icon (PRO)

Le plugin Easy Resolve vous permet de remĂ©dier rapidement aux faux positifs et aux problĂšmes rĂ©currents directement depuis la page Rapports. Il transforme les actions guidĂ©es "RĂ©soudre" en mises Ă  jour de configuration sĂ»res et Ă©tendues—sans Ă©dition manuelle.

Fonctionnalités

  • Actions en un clic depuis les Rapports et les dĂ©tails des rapports.
  • Suggestions contextuelles pour ModSecurity, blacklist, DNSBL, limitation de dĂ©bit, mĂ©thodes HTTP autorisĂ©es et pays en liste blanche/noire.
  • GĂ©nĂšre des exclusions ModSecurity sĂ»res ou met Ă  jour les listes d'ignorance.
  • Applique les changements au niveau du service ou global avec vĂ©rifications des permissions.
  • Ouverture automatique optionnelle de la page de configuration liĂ©e aprĂšs application.
![Vue d'ensemble](assets/img/easy-resolve.png){ align=center }
Page Rapports - avec Easy Resolve

Load Balancer crown pro icon (PRO)

Le plugin Load Balancer transforme BunkerWeb en un directeur de trafic avec garde-fous. DĂ©clarez des pools upstream une fois, pointez votre proxy inverse vers eux, et laissez le Ă©quilibrage conscient de la santĂ© garder les utilisateurs sur des backends rĂ©actifs. Le mode sticky cookie Ă©met automatiquement un cookie BWLBID pour que les sessions restent ancrĂ©es oĂč vous le souhaitez.

Fonctionnalités

  • Blocs par upstream : nommez les pools et rĂ©utilisez-les sur les hĂŽtes proxy inverse.
  • Équilibrage flexible : round-robin par dĂ©faut, ou sticky via IP ou cookie signĂ©.
  • Cibles intelligentes : rĂ©solution DNS optionnelle pour les backends hostname plus rĂ©glage keepalive.
  • SantĂ© intĂ©grĂ©e : sondes HTTP/HTTPS avec chemins personnalisĂ©s, intervalles, codes de statut et vĂ©rifications SSL.
  • ContinuitĂ© de session : cookie BWLBID automatique lorsque le mode sticky-cookie est activĂ©.

Configuration

Définition upstream

ParamÚtre Défaut Contexte Multiple Description
LOADBALANCER_UPSTREAM_NAME global oui Identifiant upstream (référencé par REVERSE_PROXY_HOST).
LOADBALANCER_UPSTREAM_SERVERS global oui Liste séparée par espaces d'adresses backend (ex. 10.0.0.1:8080 10.0.0.2:8080).
LOADBALANCER_UPSTREAM_MODE round-robin global oui Stratégie d'équilibrage (round-robin ou sticky).
LOADBALANCER_UPSTREAM_STICKY_METHOD ip global oui Méthode sticky (ip ou cookie). Mode cookie émet BWLBID.
LOADBALANCER_UPSTREAM_RESOLVE no global oui Résoudre les hostnames upstream via DNS.
LOADBALANCER_UPSTREAM_KEEPALIVE global oui Connexions keepalive par worker.
LOADBALANCER_UPSTREAM_KEEPALIVE_TIMEOUT 60s global oui Timeout inactif pour les connexions keepalive.
LOADBALANCER_UPSTREAM_KEEPALIVE_TIME 1h global oui Durée de vie maximale pour les connexions keepalive.

Vérifications de santé

ParamÚtre Défaut Contexte Multiple Description
LOADBALANCER_HEALTHCHECK_DICT_SIZE 10m global non Taille du dictionnaire partagé pour l'état des vérifications de santé.
LOADBALANCER_HEALTHCHECK_URL /status global oui Chemin Ă  sonder sur chaque backend.
LOADBALANCER_HEALTHCHECK_INTERVAL 2000 global oui Intervalle entre vérifications (ms).
LOADBALANCER_HEALTHCHECK_TIMEOUT 1000 global oui Timeout par vérification (ms).
LOADBALANCER_HEALTHCHECK_FALL 3 global oui Échecs consĂ©cutifs avant de marquer comme down.
LOADBALANCER_HEALTHCHECK_RISE 1 global oui SuccÚs consécutifs avant de marquer comme up.
LOADBALANCER_HEALTHCHECK_VALID_STATUSES 200 global oui Liste séparée par espaces de codes de statut HTTP valides.
LOADBALANCER_HEALTHCHECK_CONCURRENCY 10 global oui Maximum de sondes concurrentes.
LOADBALANCER_HEALTHCHECK_TYPE http global oui Protocole pour les vérifications de santé (http ou https).
LOADBALANCER_HEALTHCHECK_SSL_VERIFY yes global oui Vérifier les certificats TLS lors des vérifications HTTPS.
LOADBALANCER_HEALTHCHECK_HOST global oui Remplacer l'en-tĂȘte Host pendant les vĂ©rifications (utile pour SNI).

Démarrage rapide

  1. Définissez votre pool : définissez LOADBALANCER_UPSTREAM_NAME=my-app et listez les cibles dans LOADBALANCER_UPSTREAM_SERVERS (ex. 10.0.0.1:8080 10.0.0.2:8080).
  2. Dirigez le trafic : définissez REVERSE_PROXY_HOST=http://my-app pour que le proxy inverse utilise l'upstream nommé.
  3. Choisissez un mode : gardez round-robin par défaut ou définissez LOADBALANCER_UPSTREAM_MODE=sticky avec LOADBALANCER_UPSTREAM_STICKY_METHOD=cookie ou ip.
  4. Ajoutez de la santé : gardez /status ou ajustez les URLs, intervalles et statuts valides pour refléter le comportement de votre app.
  5. Réglez les connexions : configurez les valeurs keepalive pour réutiliser les connexions backend et réduire la surcharge de handshake.

Conseils d'utilisation

  • Faites correspondre REVERSE_PROXY_HOST Ă  LOADBALANCER_UPSTREAM_NAME lors de l'utilisation de cookies sticky pour que les clients s'Ă©pinglent au bon pool.
  • Gardez les intervalles et timeouts des vĂ©rifications de santĂ© Ă©quilibrĂ©s pour Ă©viter les oscillations sur les liens lents.
  • Activez LOADBALANCER_UPSTREAM_RESOLVE lorsque vous pointez vers des hostnames qui peuvent changer via DNS.
  • RĂ©glez les valeurs keepalive pour reflĂ©ter la capacitĂ© backend et les objectifs de rĂ©utilisation des connexions.

Custom Pages crown pro icon (PRO)

Le plugin Custom Pages vous permet de remplacer les pages intégrées de BunkerWeb (pages d'erreur, page du serveur par défaut et pages de défi antibot) par vos propres modÚles HTML ou Lua personnalisés. Cela vous permet de maintenir une image de marque cohérente sur toutes les pages destinées aux utilisateurs servies par BunkerWeb.

Fonctionnalités

  • Pages d'erreur personnalisĂ©es par service et pages de dĂ©fi antibot (captcha, vĂ©rification JavaScript, reCAPTCHA, hCaptcha, Turnstile, mCaptcha, Cap.js).
  • Page du serveur par dĂ©faut personnalisĂ©e globale pour le vhost de repli/par dĂ©faut.
  • Analyse HTML et vĂ©rifications d'Ă©quilibre des balises de modĂšle Lua avant qu'un modĂšle soit acceptĂ©.
  • Mise en cache automatique vers /var/cache/bunkerweb/custom_pages avec dĂ©tection des modifications pour dĂ©clencher les rechargements.
  • Configuration par site ou globale via les paramĂštres/UI ou les variables d'environnement.

Comment ça fonctionne

  1. Au démarrage (ou lorsque les paramÚtres changent), le job custom-pages.py lit les chemins de modÚles configurés.
  2. Chaque fichier doit exister et ĂȘtre lisible par le scheduler ; le job valide la structure HTML et l'Ă©quilibre des balises de modĂšle Lua ({% %}, {{ }}, {* *}).
  3. Les fichiers acceptés sont mis en cache sous /var/cache/bunkerweb/custom_pages/<type>.html ; les paramÚtres manquants/vides suppriment le fichier mis en cache.
  4. NGINX est dirigé vers le répertoire de cache via $template_root lorsqu'au moins une page mise en cache existe, de sorte que vos modÚles sont servis à la place des pages par défaut.

ParamĂštres de configuration

ParamÚtre Défaut Contexte Description
CUSTOM_ERROR_PAGE multisite Chemin absolu vers le modÚle de page d'erreur personnalisé.
CUSTOM_DEFAULT_SERVER_PAGE global Chemin absolu vers le modÚle de page du serveur par défaut personnalisé.
CUSTOM_ANTIBOT_CAPTCHA_PAGE multisite Chemin absolu vers la page de défi CAPTCHA antibot personnalisée.
CUSTOM_ANTIBOT_JAVASCRIPT_PAGE multisite Chemin absolu vers la page de vérification JavaScript antibot personnalisée.
CUSTOM_ANTIBOT_RECAPTCHA_PAGE multisite Chemin absolu vers la page reCAPTCHA antibot personnalisée.
CUSTOM_ANTIBOT_HCAPTCHA_PAGE multisite Chemin absolu vers la page hCaptcha antibot personnalisée.
CUSTOM_ANTIBOT_TURNSTILE_PAGE multisite Chemin absolu vers la page Turnstile antibot personnalisée.
CUSTOM_ANTIBOT_MCAPTCHA_PAGE multisite Chemin absolu vers la page mCaptcha antibot personnalisée.
CUSTOM_ANTIBOT_CAPJS_PAGE multisite Chemin absolu vers la page Cap.js antibot personnalisée.

Référence des variables de modÚle

Les modĂšles BunkerWeb utilisent le moteur lua-resty-template. Les variables suivantes sont disponibles selon le type de page :

Variables de page d'erreur

Ces variables sont disponibles dans les modÚles de page d'erreur personnalisés (CUSTOM_ERROR_PAGE) :

Variable Type Description
title string Titre complet de la page (ex. 403 - Forbidden)
error_title string Texte du titre d'erreur (ex. Forbidden)
error_code string Code de statut HTTP (ex. 403, 404, 500)
error_text string Message d'erreur descriptif
error_type string Catégorie d'erreur : client (4xx) ou server (5xx)
error_solution string Texte de solution suggérée
nonce_script string Valeur nonce pour les balises <script> inline (conformité CSP)
nonce_style string Valeur nonce pour les balises <style> inline (conformité CSP)
request_id string Identifiant de requĂȘte unique pour le dĂ©bogage
client_ip string Adresse IP du client
request_time string Horodatage de la requĂȘte (format : YYYY-MM-DD HH:MM:SS UTC)

Variables de page du serveur par défaut

Ces variables sont disponibles dans les modÚles de page du serveur par défaut personnalisés (CUSTOM_DEFAULT_SERVER_PAGE) :

Variable Type Description
nonce_style string Valeur nonce pour les balises <style> inline (conformité CSP)

Variables de page de défi antibot

Ces variables sont disponibles dans les modÚles de page de défi antibot :

Variables communes (toutes les pages antibot) :

Variable Type Description
antibot_uri string URI d'action de formulaire pour soumettre le défi
nonce_script string Valeur nonce pour les balises <script> inline (conformité CSP)
nonce_style string Valeur nonce pour les balises <style> inline (conformité CSP)

Défi JavaScript (CUSTOM_ANTIBOT_JAVASCRIPT_PAGE) :

Variable Type Description
random string Chaßne aléatoire utilisée pour la preuve de travail

Captcha (CUSTOM_ANTIBOT_CAPTCHA_PAGE) :

Variable Type Description
captcha string Image captcha encodée en Base64 (format JPEG)

reCAPTCHA (CUSTOM_ANTIBOT_RECAPTCHA_PAGE) :

Variable Type Description
recaptcha_sitekey string Votre clé de site reCAPTCHA
recaptcha_classic boolean true si utilisant reCAPTCHA classique, false pour v3

hCaptcha (CUSTOM_ANTIBOT_HCAPTCHA_PAGE) :

Variable Type Description
hcaptcha_sitekey string Votre clé de site hCaptcha

Turnstile (CUSTOM_ANTIBOT_TURNSTILE_PAGE) :

Variable Type Description
turnstile_sitekey string Votre clé de site Cloudflare Turnstile

mCaptcha (CUSTOM_ANTIBOT_MCAPTCHA_PAGE) :

Variable Type Description
mcaptcha_sitekey string Votre clé de site mCaptcha
mcaptcha_url string Votre URL mCaptcha

Cap.js (CUSTOM_ANTIBOT_CAPJS_PAGE) :

Variable Type Description
capjs_sitekey string Votre clé de site Cap.js
capjs_url string URL de base du frontend Cap.js

Syntaxe de modĂšle

Les modÚles utilisent la syntaxe de modÚle Lua avec les délimiteurs suivants :

  • {{ variable }} – Afficher une variable (Ă©chappĂ©e HTML)
  • {* variable *} – Afficher une variable (brut, non Ă©chappĂ©)
  • {% lua_code %} – ExĂ©cuter du code Lua (conditions, boucles, etc.)
  • {-raw-} ... {-raw-} – Bloc brut (pas de traitement)

Important : Utilisez toujours les attributs nonce pour les scripts et styles inline pour respecter la Content Security Policy (CSP) :

<style nonce="{*nonce_style*}">
  /* Votre CSS ici */
</style>
<script nonce="{*nonce_script*}">
  // Votre JavaScript ici
</script>

Exemples

=== "Page d'erreur personnalisée"

Créez un modÚle de page d'erreur personnalisé dans `/etc/bunkerweb/templates/error.html` :

```html
{-raw-}<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8" />
    <title>{{ title }}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    {-raw-}
    <style nonce="{*nonce_style*}">
      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background: #f5f5f5;
        color: #333;
      }
      .container {
        text-align: center;
        padding: 2rem;
      }
      .error-code {
        font-size: 6rem;
        font-weight: bold;
        color: {% if error_type == "server" %}#dc3545{% else %}#ffc107{% end %};
        margin: 0;
      }
      .error-title {
        font-size: 1.5rem;
        margin: 1rem 0;
      }
      .error-text {
        color: #666;
        margin-bottom: 1rem;
      }
      .request-info {
        font-size: 0.8rem;
        color: #999;
        margin-top: 2rem;
      }
    </style>
    {-raw-}
  </head>
  <body>
    <div class="container">
      <p class="error-code">{{ error_code }}</p>
      <h1 class="error-title">{{ error_title }}</h1>
      <p class="error-text">{{ error_text }}</p>
      <p class="error-text">{{ error_solution }}</p>
      <div class="request-info">
        {% if request_id %}
        <p>ID de requĂȘte : <code>{{ request_id }}</code></p>
        {% end %}
        {% if request_time %}
        <p>Heure : {{ request_time }}</p>
        {% end %}
      </div>
    </div>
  </body>
</html>
{-raw-}
```

=== "Page captcha personnalisée"

Créez une page de défi captcha personnalisée dans `/etc/bunkerweb/templates/captcha.html` :

```html
{-raw-}<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8" />
    <title>Vérification de sécurité</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    {-raw-}
    <style nonce="{*nonce_style*}">
      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      }
      .card {
        background: white;
        padding: 2rem;
        border-radius: 1rem;
        box-shadow: 0 10px 40px rgba(0,0,0,0.2);
        text-align: center;
        max-width: 400px;
      }
      h1 {
        color: #333;
        margin-bottom: 1rem;
      }
      .captcha-img {
        margin: 1rem 0;
        border-radius: 0.5rem;
      }
      input[type="text"] {
        width: 100%;
        padding: 0.75rem;
        font-size: 1.2rem;
        border: 2px solid #ddd;
        border-radius: 0.5rem;
        text-align: center;
        box-sizing: border-box;
      }
      button {
        margin-top: 1rem;
        padding: 0.75rem 2rem;
        font-size: 1rem;
        background: #667eea;
        color: white;
        border: none;
        border-radius: 0.5rem;
        cursor: pointer;
      }
      button:hover {
        background: #5a6fd6;
      }
    </style>
    {-raw-}
  </head>
  <body>
    <div class="card">
      <h1>🔒 VĂ©rification de sĂ©curitĂ©</h1>
      <p>Veuillez entrer le texte que vous voyez ci-dessous pour continuer.</p>
      {-raw-}
      <form method="POST" action="{*antibot_uri*}">
        <img class="captcha-img" src="data:image/jpeg;base64,{*captcha*}" alt="Captcha" />
        {-raw-}
        <input type="text" name="captcha" placeholder="Entrez le code" required autocomplete="off" />
        <button type="submit">Vérifier</button>
      </form>
    </div>
  </body>
</html>
{-raw-}
```

=== "Page du serveur par défaut personnalisée"

Créez une page du serveur par défaut personnalisée dans `/etc/bunkerweb/templates/default.html` :

```html
{-raw-}<!doctype html>
<html lang="fr">
  <head>
    <meta charset="utf-8" />
    <title>Bienvenue</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    {-raw-}
    <style nonce="{*nonce_style*}">
      body {
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        margin: 0;
        background: #1a1a2e;
        color: #eee;
      }
      .container {
        text-align: center;
      }
      h1 {
        font-size: 3rem;
        margin-bottom: 0.5rem;
      }
      p {
        color: #888;
      }
    </style>
    {-raw-}
  </head>
  <body>
    <div class="container">
      <h1>đŸ›Ąïž ProtĂ©gĂ© par BunkerWeb</h1>
      <p>Ce serveur est sĂ©curisĂ© et prĂȘt.</p>
    </div>
  </body>
</html>
{-raw-}
```

Exemples de déploiement

=== "Linux"

1. Créez vos fichiers de modÚle dans un répertoire de votre choix (ex. `/opt/bunkerweb/templates/`) :

    ```bash
    sudo mkdir -p /opt/bunkerweb/templates
    sudo nano /opt/bunkerweb/templates/error.html
    # Collez votre modÚle de page d'erreur personnalisé
    ```

2. Configurez BunkerWeb en éditant `/etc/bunkerweb/variables.env` :

    ```conf
    # Page d'erreur personnalisée pour tous les services (ou utilisez par service avec préfixe)
    CUSTOM_ERROR_PAGE=/opt/bunkerweb/templates/error.html

    # Page du serveur par défaut personnalisée (global uniquement)
    CUSTOM_DEFAULT_SERVER_PAGE=/opt/bunkerweb/templates/default.html

    # Page captcha personnalisée (par service ou globale)
    CUSTOM_ANTIBOT_CAPTCHA_PAGE=/opt/bunkerweb/templates/captcha.html
    ```

3. Rechargez le scheduler BunkerWeb pour qu'il prenne en compte les nouveaux modĂšles :

    ```bash
    sudo systemctl reload bunkerweb-scheduler
    ```

=== "Docker"

Le **scheduler** est responsable de la lecture, de la validation et de la mise en cache de vos modĂšles personnalisĂ©s. Seul le scheduler a besoin d'accĂ©der aux fichiers de modĂšle—BunkerWeb reçoit automatiquement la configuration validĂ©e.

1. Créez vos fichiers de modÚle dans un répertoire local (ex. `./templates/`) et définissez les bonnes permissions :

    ```bash
    mkdir templates && \
    chown root:101 templates && \
    chmod 770 templates
    ```

    !!! info "Pourquoi UID/GID 101 ?"
        Le conteneur scheduler s'exĂ©cute en tant qu'**utilisateur non privilĂ©giĂ© avec UID 101 et GID 101**. Le rĂ©pertoire doit ĂȘtre lisible par cet utilisateur pour que le scheduler puisse accĂ©der Ă  vos modĂšles.

    Si le dossier existe déjà :

    ```bash
    chown -R root:101 templates && \
    chmod -R 770 templates
    ```

    Lors de l'utilisation de [Docker en mode rootless](https://docs.docker.com/engine/security/rootless) ou [Podman](https://podman.io/), les UID/GID des conteneurs sont remappés. Vérifiez vos plages subuid/subgid :

    ```bash
    grep ^$(whoami): /etc/subuid && \
    grep ^$(whoami): /etc/subgid
    ```

    Par exemple, si la plage commence Ă  **100000**, le GID effectif devient **100100** (100000 + 100) :

    ```bash
    mkdir templates && \
    sudo chgrp 100100 templates && \
    chmod 770 templates
    ```

2. Montez le répertoire de modÚles vers le **scheduler** et configurez les paramÚtres sur le scheduler (le scheduler agit comme manager et distribue la configuration aux workers BunkerWeb). Vous pouvez monter les modÚles vers n'importe quel chemin dans le conteneur :

    ```yaml
    services:
      bunkerweb:
        image: bunkerity/bunkerweb:1.6.11-rc1
        # ... autres paramÚtres (pas de variables d'environnement nécessaires ici pour les pages personnalisées)

      bw-scheduler:
        image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
        volumes:
          - ./templates:/custom_templates:ro
        environment:
          - CUSTOM_ERROR_PAGE=/custom_templates/error.html
          - CUSTOM_DEFAULT_SERVER_PAGE=/custom_templates/default.html
          - CUSTOM_ANTIBOT_CAPTCHA_PAGE=/custom_templates/captcha.html
          # ... autres paramĂštres
    ```

!!! warning "AccĂšs au scheduler requis"
    Si le scheduler ne peut pas lire les fichiers de modÚle (à cause d'un montage manquant ou de permissions incorrectes), les modÚles seront silencieusement ignorés et les pages par défaut seront utilisées à la place. Vérifiez les logs du scheduler pour les erreurs de validation.

=== "Kubernetes"

Le **scheduler** est responsable de la lecture, de la validation et de la mise en cache de vos modÚles personnalisés. Vous devez monter les modÚles vers le pod du scheduler.

1. Créez une ConfigMap avec vos modÚles :

    ```yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: bunkerweb-custom-templates
    data:
      error.html: |
        {-raw-}<!doctype html>
        <html lang="fr">
          <head>
            <meta charset="utf-8" />
            <title>{{ title }}</title>
            {-raw-}
            <style nonce="{*nonce_style*}">
              body { font-family: sans-serif; text-align: center; padding: 2rem; }
              .error-code { font-size: 4rem; color: #dc3545; }
            </style>
            {-raw-}
          </head>
          <body>
            <p class="error-code">{{ error_code }}</p>
            <h1>{{ error_title }}</h1>
            <p>{{ error_text }}</p>
          </body>
        </html>
        {-raw-}
      captcha.html: |
        {-raw-}<!doctype html>
        <html lang="fr">
          <head>
            <meta charset="utf-8" />
            <title>Vérification de sécurité</title>
            {-raw-}
            <style nonce="{*nonce_style*}">
              body { font-family: sans-serif; text-align: center; padding: 2rem; }
            </style>
            {-raw-}
          </head>
          <body>
            <h1>Veuillez vĂ©rifier que vous ĂȘtes humain</h1>
            {-raw-}
            <form method="POST" action="{*antibot_uri*}">
              <img src="data:image/jpeg;base64,{*captcha*}" alt="Captcha" />
              {-raw-}
              <input type="text" name="captcha" placeholder="Entrez le code" required />
              <button type="submit">Vérifier</button>
            </form>
          </body>
        </html>
        {-raw-}
    ```

2. Montez la ConfigMap de modĂšles vers le pod du **scheduler** et configurez les paramĂštres comme variables d'environnement :

    ```yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: bunkerweb-scheduler
    spec:
      template:
        spec:
          containers:
            - name: bunkerweb-scheduler
              image: bunkerity/bunkerweb-scheduler:1.6.11-rc1
              env:
                - name: CUSTOM_ERROR_PAGE
                  value: "/custom_templates/error.html"
                - name: CUSTOM_ANTIBOT_CAPTCHA_PAGE
                  value: "/custom_templates/captcha.html"
                # ... autres paramĂštres
              volumeMounts:
                - name: custom-templates
                  mountPath: /custom_templates
                  readOnly: true
              # ... autres paramĂštres du conteneur
          volumes:
            - name: custom-templates
              configMap:
                name: bunkerweb-custom-templates
          # ... autres paramĂštres du pod
    ```

!!! tip "Utilisation du contrĂŽleur Ingress BunkerWeb"
    Si vous utilisez le contrÎleur Ingress BunkerWeb, le scheduler est intégré au contrÎleur. Montez la ConfigMap vers le pod du contrÎleur à la place.

Notes et dépannage

  • Les chemins doivent ĂȘtre absolus et se terminer par un nom de fichier ; les valeurs vides dĂ©sactivent la page personnalisĂ©e correspondante et suppriment son cache.
  • Si la validation Ă©choue (HTML incorrect ou balises Lua dĂ©sĂ©quilibrĂ©es), le modĂšle est ignorĂ© et la page par dĂ©faut reste active. VĂ©rifiez les logs du scheduler pour les dĂ©tails.
  • Les fichiers mis en cache se trouvent dans /var/cache/bunkerweb/custom_pages ; la mise Ă  jour du fichier source suffit—le job dĂ©tecte le nouveau hash et recharge NGINX automatiquement.
  • ConformitĂ© CSP : Utilisez toujours les variables nonce_script et nonce_style pour les scripts et styles inline afin d'assurer une bonne gestion de la Content Security Policy.
  • Test des modĂšles : Vous pouvez tester vos modĂšles localement en les rendant avec un moteur de modĂšle Lua avant de les dĂ©ployer sur BunkerWeb.

OpenID Connect crown pro icon (PRO)

Le plugin OpenID Connect (PRO) ajoute le Single Sign-On (SSO) devant votre application en utilisant le flux OAuth 2.0 / OIDC Authorization Code.

Il s'exĂ©cute dans BunkerWeb (NGINX/Lua) et impose l'authentification pendant la phase access, ce qui bloque les requĂȘtes non authentifiĂ©es avant qu'elles n'atteignent votre upstream.

Comment fonctionne le flux de requĂȘte

Lorsqu'un navigateur demande une URL protégée :

  1. S'il n'y a pas de session valide, BunkerWeb redirige l'utilisateur vers le fournisseur d'identité (IdP).
  2. L'IdP authentifie l'utilisateur et redirige vers BunkerWeb sur OPENIDC_REDIRECT_URI (par défaut : /callback) avec un code d'autorisation.
  3. BunkerWeb échange le code contre des jetons sur l'endpoint token de l'IdP.
  4. Les jetons sont validés (issuer, audience, expiration, iat avec tolérance, signature via JWKS).
  5. Une session est créée et le navigateur est redirigé vers l'URL initiale.
sequenceDiagram
  participant B as Navigateur
  participant BW as BunkerWeb (OpenIDC)
  participant IdP as Fournisseur d'identité
  participant Up as Upstream

  B->>BW: GET /protected
  alt Non authentifié
  BW-->>B: 302 Redirection vers l'endpoint authorize de l'IdP
  B->>IdP: RequĂȘte d'autorisation (nonce/PKCE optionnel)
  IdP-->>B: 302 Redirection vers /callback?code=...
  B->>BW: GET /callback?code=...
  BW->>IdP: RequĂȘte token (Ă©change du code)
  IdP-->>BW: ID token + access token (+ refresh token)
  BW-->>B: 302 Redirection vers l'URL d'origine
  end
  B->>BW: GET /protected (authentifié)
  BW->>Up: Transmettre la requĂȘte (+ header d'identitĂ© optionnel)
  Up-->>BW: Réponse
  BW-->>B: Réponse

!!! warning "L'URL de callback doit correspondre à la configuration du client IdP" Enregistrez l'URL de callback complÚte cÎté IdP (schéma + hÎte + chemin). Par exemple avec les valeurs par défaut : https://app.example.com/callback.

ParamÚtres (expliqués)

!!! info "ParamĂštres requis" Au minimum, OPENIDC_DISCOVERY et OPENIDC_CLIENT_ID doivent ĂȘtre dĂ©finis pour que le plugin fonctionne.

Activation

  • USE_OPENIDC (dĂ©faut : no) : activer ou dĂ©sactiver l'authentification OpenID Connect pour le site.

Fournisseur d'identité (IdP) + enregistrement du client

  • OPENIDC_DISCOVERY : URL de discovery (ex. https://idp.example.com/.well-known/openid-configuration).
  • OPENIDC_CLIENT_ID : identifiant du client OAuth 2.0 enregistrĂ© auprĂšs de l'IdP.
  • OPENIDC_CLIENT_SECRET : secret du client OAuth 2.0 (utilisĂ© par basic, post et secret_jwt).

Callback / redirection

  • OPENIDC_REDIRECT_URI (dĂ©faut : /callback) : chemin de callback utilisĂ© par l'IdP aprĂšs authentification (doit ĂȘtre enregistrĂ© cĂŽtĂ© IdP).

Scopes et paramĂštres d'autorisation

  • OPENIDC_SCOPE (dĂ©faut : openid email profile) : liste d'espaces des scopes Ă  demander.
  • OPENIDC_AUTHORIZATION_PARAMS : paramĂštres d'autorisation supplĂ©mentaires sous forme key=value sĂ©parĂ©s par des virgules.

Renforcement de sécurité

  • OPENIDC_USE_NONCE (dĂ©faut : yes) : ajouter un nonce aux requĂȘtes d'autorisation.
  • OPENIDC_USE_PKCE (dĂ©faut : no) : activer PKCE pour le flux Authorization Code.
  • OPENIDC_IAT_SLACK (dĂ©faut : 120) : tolĂ©rance de dĂ©rive d'horloge (secondes) pour la validation des jetons.
  • OPENIDC_ACCEPT_UNSUPPORTED_ALG (dĂ©faut : no) : accepter des jetons signĂ©s avec des algorithmes non supportĂ©s (non recommandĂ©).
  • OPENIDC_FORCE_REAUTHORIZE (dĂ©faut : no) : forcer la rĂ©-autorisation Ă  chaque requĂȘte (debug uniquement).

ContrĂŽle d'accĂšs par claims (ACL)

Les claims sont des paires clé-valeur du jeton OIDC qui décrivent l'utilisateur (par ex. email, groups, sub). La fonctionnalité ACL vous permet de restreindre l'accÚs en fonction de valeurs spécifiques de claims.

ParamÚtre Défaut Contexte Multiple Description
OPENIDC_USE_ACL no multisite non Activer le contrÎle d'accÚs par claims aprÚs l'authentification OIDC. Seuls les utilisateurs dont les claims correspondent aux rÚgles configurées se voient accorder l'accÚs.
OPENIDC_ACL_MATCH_MODE all multisite non Mode d'évaluation des rÚgles ACL multiples. all = toutes les rÚgles doivent passer (ET). any = au moins une rÚgle doit passer (OU).
OPENIDC_ACL_DENIED_URL multisite non URL de redirection en cas de refus par l'ACL. Si vide, renvoie une réponse 403 Forbidden.
OPENIDC_ACL_CLAIM multisite oui Nom du claim OIDC à vérifier (par ex. groups, email, sub). Associé à OPENIDC_ACL_CLAIM_VALUE.
OPENIDC_ACL_CLAIM_VALUE multisite oui Valeur attendue pour le claim. Pour les claims de type tableau (par ex. groups), vérifie l'appartenance. Pour les claims de type chaßne, vérifie l'égalité stricte.

!!! tip "RÚgles ACL multiples" Utilisez des suffixes numériques pour définir plusieurs rÚgles. Chaque paire OPENIDC_ACL_CLAIM / OPENIDC_ACL_CLAIM_VALUE constitue une rÚgle :

```yaml
OPENIDC_USE_ACL: "yes"
OPENIDC_ACL_MATCH_MODE: "any"
OPENIDC_ACL_CLAIM: "groups"
OPENIDC_ACL_CLAIM_VALUE: "engineering"
OPENIDC_ACL_CLAIM_1: "email"
OPENIDC_ACL_CLAIM_VALUE_1: "admin@example.com"
```

Avec `OPENIDC_ACL_MATCH_MODE=any`, l'accĂšs est accordĂ© si l'utilisateur fait partie du groupe `engineering` **ou** possĂšde l'e-mail `admin@example.com`. Avec `all`, les deux conditions doivent ĂȘtre remplies.

Cycle de vie session/jetons

  • OPENIDC_REFRESH_SESSION_INTERVAL : intervalle (secondes) pour rĂ©-authentifier/rafraĂźchir silencieusement la session (vide = dĂ©sactivĂ©).
  • OPENIDC_ACCESS_TOKEN_EXPIRES_IN (dĂ©faut : 3600) : durĂ©e par dĂ©faut du jeton d'accĂšs si l'IdP ne la fournit pas.
  • OPENIDC_RENEW_ACCESS_TOKEN_ON_EXPIRY (dĂ©faut : yes) : renouveler automatiquement le jeton d'accĂšs via le refresh token.

ParamĂštres d'authentification sur l'endpoint token

  • OPENIDC_TOKEN_ENDPOINT_AUTH_METHOD (dĂ©faut : basic) : basic, post, secret_jwt, private_key_jwt.
  • OPENIDC_CLIENT_RSA_PRIVATE_KEY : requis avec private_key_jwt.
  • OPENIDC_CLIENT_RSA_PRIVATE_KEY_ID : kid optionnel pour private_key_jwt.
  • OPENIDC_CLIENT_JWT_ASSERTION_EXPIRES_IN : durĂ©e de vie (secondes) de l'assertion JWT.

Comportement de logout

  • OPENIDC_LOGOUT_PATH (dĂ©faut : /logout) : chemin de logout local gĂ©rĂ© par BunkerWeb.
  • OPENIDC_REVOKE_TOKENS_ON_LOGOUT (dĂ©faut : no) : rĂ©voquer les jetons cĂŽtĂ© IdP lors du logout.
  • OPENIDC_REDIRECT_AFTER_LOGOUT_URI : redirection aprĂšs logout local (vide = comportement par dĂ©faut de l'IdP).
  • OPENIDC_POST_LOGOUT_REDIRECT_URI : redirection aprĂšs fin du logout IdP (si supportĂ©).

Connectivité et TLS vers l'IdP

  • OPENIDC_TIMEOUT_CONNECT|SEND|READ (dĂ©faut : 10000 ms chacun) : timeouts pour les appels HTTP vers l'IdP.
  • OPENIDC_SSL_VERIFY (dĂ©faut : yes) : vĂ©rifier les certificats TLS de l'IdP.
  • OPENIDC_KEEPALIVE (dĂ©faut : yes) : keepalive pour les connexions IdP.
  • OPENIDC_HTTP_PROXY / OPENIDC_HTTPS_PROXY : proxys pour les appels IdP.

Transmission de l'identité à l'upstream

  • OPENIDC_USER_HEADER (dĂ©faut : X-User) : header transmis Ă  l'upstream (vide = dĂ©sactivĂ©).
  • OPENIDC_USER_HEADER_CLAIM (dĂ©faut : sub) : claim Ă  extraire pour la valeur du header.
  • OPENIDC_DISPLAY_CLAIM (dĂ©faut : preferred_username) : claim utilisĂ© pour l'affichage dans les logs/mĂ©triques.

Cache

  • OPENIDC_DISCOVERY_DICT_SIZE (dĂ©faut : 1m) : taille du shared dict pour le cache discovery.
  • OPENIDC_JWKS_DICT_SIZE (dĂ©faut : 1m) : taille du shared dict pour le cache JWKS.

!!! tip "Stockage de session Redis" Lorsque USE_REDIS=yes est configuré globalement dans BunkerWeb, le plugin OpenIDC stocke les sessions dans Redis au lieu des cookies (avec fallback automatique vers les cookies si Redis devient indisponible). C'est le mode recommandé pour les déploiements multi-instance / HA.

Cache discovery + JWKS

Le plugin utilise OPENIDC_DISCOVERY (l'URL .well-known/openid-configuration de l'IdP) pour découvrir les endpoints, puis récupÚre et met en cache les clés JWKS pour valider les signatures.

Les données discovery/JWKS sont mises en cache dans des shared dictionaries NGINX. Si vous avez beaucoup de tenants/IdP ou de gros ensembles de clés, augmentez :

  • OPENIDC_DISCOVERY_DICT_SIZE (global)
  • OPENIDC_JWKS_DICT_SIZE (global)

Sessions (cookies vs Redis)

Par défaut, les sessions sont stockées dans des cookies sécurisés gérés par la bibliothÚque OpenID Connect.

Si USE_REDIS=yes est activé globalement et que Redis est configuré, le plugin bascule automatiquement vers des sessions Redis (avec fallback automatique vers les cookies si Redis est temporairement indisponible). Recommandé en load-balancing / HA et évite les limites de taille des cookies lorsque les jetons sont volumineux.

Transmission de l'identité utilisateur à l'upstream

Si OPENIDC_USER_HEADER est défini (défaut : X-User), le plugin injecte un header extrait d'un claim (défaut : OPENIDC_USER_HEADER_CLAIM=sub).

Comportement de sécurité important :

  • Le plugin supprime tout header entrant portant le mĂȘme nom que OPENIDC_USER_HEADER pour Ă©viter le spoofing cĂŽtĂ© client.
  • Si le claim configurĂ© est absent, le header n'est pas dĂ©fini.
  • DĂ©finissez OPENIDC_USER_HEADER Ă  une valeur vide pour dĂ©sactiver la transmission de l'identitĂ©.

!!! tip "Choisir un claim" Privilégiez des identifiants stables présents dans les jetons (ex. sub, email, preferred_username). Les claims sont lus d'abord depuis l'ID token, puis depuis userinfo si présent.

Logout

Les requĂȘtes de logout sont gĂ©rĂ©es sur OPENIDC_LOGOUT_PATH (dĂ©faut : /logout).

  • Pour rĂ©voquer les jetons cĂŽtĂ© IdP lors du logout, dĂ©finissez OPENIDC_REVOKE_TOKENS_ON_LOGOUT=yes.
  • Utilisez OPENIDC_REDIRECT_AFTER_LOGOUT_URI et OPENIDC_POST_LOGOUT_REDIRECT_URI pour contrĂŽler les redirections aprĂšs logout.

Authentification Ă  l'endpoint token

La plupart des IdP fonctionnent avec la valeur par défaut OPENIDC_TOKEN_ENDPOINT_AUTH_METHOD=basic (client secret via HTTP Basic). Sont aussi supportés :

  • post
  • secret_jwt
  • private_key_jwt (requiert OPENIDC_CLIENT_RSA_PRIVATE_KEY, optionnel OPENIDC_CLIENT_RSA_PRIVATE_KEY_ID)

Exemples de configuration minimale

ParamÚtres minimum requis par service protégé :

  • USE_OPENIDC=yes
  • OPENIDC_DISCOVERY=...
  • OPENIDC_CLIENT_ID=...
  • OPENIDC_CLIENT_SECRET=... (ou configuration de clĂ© JWT pour private_key_jwt)

Options fréquentes de durcissement / tuning :

  • OPENIDC_USE_NONCE=yes (dĂ©faut)
  • OPENIDC_USE_PKCE=yes
  • OPENIDC_IAT_SLACK=... en cas de dĂ©rive d'horloge
  • OPENIDC_TIMEOUT_CONNECT|SEND|READ adaptĂ© Ă  la latence de l'IdP
  • OPENIDC_SSL_VERIFY=yes (dĂ©faut)

Dépannage

  • 403 avec "Authentication failed" : le plus souvent une URL discovery incorrecte, un mismatch d'URL de callback cĂŽtĂ© IdP, ou un IdP injoignable.
  • DĂ©rive d'horloge / "token not yet valid" : activez NTP ; ajustez OPENIDC_IAT_SLACK si nĂ©cessaire.
  • Header utilisateur absent : vĂ©rifiez que le claim de OPENIDC_USER_HEADER_CLAIM existe dans l'ID token/userinfo.
  • DĂ©ploiements multi-instance : activez USE_REDIS=yes et configurez REDIS_HOST (ou Sentinel) pour partager les sessions.

LDAP SSO crown pro icon (PRO)

STREAM support ❌

Le plugin LDAP SSO ajoute le Single Sign-On basĂ© sur LDAP Ă  vos services BunkerWeb. Il fournit un formulaire de connexion, authentifie les utilisateurs auprĂšs d'un annuaire LDAP, crĂ©e une session et transmet optionnellement le nom d'utilisateur authentifiĂ© Ă  votre upstream via un en-tĂȘte configurable.

Le plugin prend en charge deux modes d'authentification :

  • Mode recherche puis liaison (search-then-bind) (recommandĂ©, aussi appelĂ© "mode recherche enterprise") : un compte de service recherche l'utilisateur dans l'annuaire, puis se lie au DN trouvĂ© pour vĂ©rifier le mot de passe. ActivĂ© lorsque LDAP_USER_SEARCH_BASE_DN est dĂ©fini.
  • Mode liaison directe (direct bind) : construit le DN de l'utilisateur Ă  partir d'un modĂšle (LDAP_USER_DN_TEMPLATE) et effectue une liaison directe. UtilisĂ© en repli lorsque le mode recherche n'est pas configurĂ©.

Fonctionnalités

  • LDAP/LDAPS/STARTTLS : connexion en LDAP non chiffrĂ©, LDAPS (TLS dĂšs le dĂ©part) ou montĂ©e en STARTTLS.
  • Mode recherche puis liaison : un compte de service effectue la dĂ©couverte d'utilisateurs avec base de recherche, filtre, portĂ©e et limites de taille/temps configurables.
  • Repli en liaison directe : authentification basĂ©e sur un modĂšle de DN lorsque le mode recherche n'est pas nĂ©cessaire.
  • Filtre d'autorisation : filtre LDAP supplĂ©mentaire optionnel pour restreindre l'accĂšs au-delĂ  de l'authentification de base.
  • Pool de connexions : keepalive avec taille de pool et timeout configurables pour rĂ©duire les allers-retours LDAP.
  • Gestion des sessions : TTL configurable avec nettoyage automatique des sessions.
  • Transmission du header utilisateur : transmet le nom d'utilisateur authentifiĂ© aux upstreams via un en-tĂȘte configurable (dĂ©faut : X-User).
  • Chemins de connexion/dĂ©connexion : endpoints dĂ©diĂ©s pour l'authentification et la terminaison de session.

!!! danger "Les identifiants sont transmis en clair par défaut" Avec les paramÚtres par défaut (LDAP_LDAPS=no, LDAP_STARTTLS=no), les mots de passe des utilisateurs sont transmis en clair au serveur LDAP. Activez toujours LDAP_LDAPS=yes (avec LDAP_PORT=636) ou LDAP_STARTTLS=yes en production. Conservez LDAP_SSL_VERIFY=yes pour prévenir les attaques par dégradation TLS.

Configuration

ParamĂštres principaux

ParamÚtre Défaut Contexte Multiple Description
USE_LDAP no multisite non Activer ou désactiver l'authentification LDAP SSO.
LDAP_HOST multisite non Nom d'hĂŽte ou adresse IP du serveur LDAP.
LDAP_PORT 389 multisite non Port du serveur LDAP (389 pour LDAP/STARTTLS, 636 pour LDAPS).
LDAP_LDAPS no multisite non Utiliser LDAPS (TLS dÚs le début de la connexion).
LDAP_STARTTLS no multisite non Utiliser la montée en STARTTLS sur la connexion LDAP.
LDAP_SSL_VERIFY yes multisite non Vérifier le certificat TLS du serveur.
LDAP_TIMEOUT 10000 multisite non Timeout du socket LDAP en millisecondes.

Pool de connexions

ParamÚtre Défaut Contexte Multiple Description
LDAP_KEEPALIVE_TIMEOUT 60000 multisite non Timeout du keepalive LDAP en millisecondes.
LDAP_KEEPALIVE_POOL_SIZE 10 multisite non Taille du pool de connexions keepalive LDAP.
LDAP_KEEPALIVE_POOL_NAME multisite non Nom personnalisé optionnel du pool keepalive LDAP.

Mode recherche enterprise

ParamÚtre Défaut Contexte Multiple Description
LDAP_BIND_DN multisite non DN du compte de service utilisé pour effectuer les recherches d'utilisateurs LDAP.
LDAP_BIND_PASSWORD multisite non Mot de passe du compte de service LDAP (bind DN).
LDAP_USER_SEARCH_BASE_DN multisite non DN de base pour la recherche d'utilisateurs (active le mode recherche enterprise lorsque défini).
LDAP_USER_SEARCH_FILTER (&(objectClass=person)(|(uid={username})(mail={username})(sAMAccountName={username})(userPrincipalName={username}))) multisite non ModĂšle de filtre de recherche LDAP. Utilisez le placeholder {username}.
LDAP_AUTHZ_FILTER multisite non Filtre d'autorisation LDAP supplémentaire optionnel (combiné en ET avec le filtre de recherche).
LDAP_USER_SEARCH_SCOPE subtree multisite non Portée de la recherche LDAP : base, onelevel ou subtree.
LDAP_USER_SEARCH_DEREF_ALIASES always multisite non Mode de déréférencement des alias LDAP : always, never, in_searching ou finding_base.
LDAP_USER_SEARCH_SIZE_LIMIT 10 multisite non Nombre maximum d'entrées LDAP retournées par la recherche d'utilisateurs.
LDAP_USER_SEARCH_TIME_LIMIT 10 multisite non Durée maximale de la recherche d'utilisateurs LDAP en secondes.
LDAP_USER_SEARCH_ATTRIBUTES dn multisite non Attributs demandés lors de la recherche d'utilisateurs (séparés par des espaces).
LDAP_USER_SEARCH_DN_FIELD object_name multisite non Nom du champ dans la réponse de recherche pour extraire le DN de l'utilisateur. La valeur par défaut object_name est le champ DN retourné par la bibliothÚque LDAP sous-jacente ; en général, il n'est pas nécessaire de le modifier.
LDAP_USER_SEARCH_REQUIRE_UNIQUE yes multisite non Exiger exactement un seul résultat de recherche avant d'authentifier l'utilisateur.

Mode liaison directe

ParamÚtre Défaut Contexte Multiple Description
LDAP_USER_DN_TEMPLATE uid={username},ou=people,dc=example,dc=com multisite non ModÚle de DN utilisateur pour la liaison directe. Doit inclure {username} lorsque défini.

Session et chemins

ParamÚtre Défaut Contexte Multiple Description
LDAP_USERNAME_REGEX ^[A-Za-z0-9@._-]+$ multisite non Regex PCRE utilisée pour valider les noms d'utilisateur soumis.
LDAP_LOGIN_PATH /ldap/login multisite non Chemin de la page de connexion exposé par le plugin LDAP.
LDAP_LOGOUT_PATH /ldap/logout multisite non Chemin de déconnexion exposé par le plugin LDAP.
LDAP_SESSION_TTL 3600 multisite non Durée de validité de la session LDAP en secondes.
LDAP_REALM LDAP SSO multisite non Realm d'authentification affiché sur le formulaire de connexion LDAP.
LDAP_USER_HEADER X-User multisite non En-tĂȘte pour transmettre le nom d'utilisateur authentifiĂ© Ă  l'upstream (vide pour dĂ©sactiver).
LDAP_REDIRECT_AFTER_LOGIN / multisite non Chemin relatif de repli aprÚs une connexion réussie lorsqu'aucune cible de redirection n'est fournie.
LDAP_REDIRECT_AFTER_LOGOUT / multisite non Chemin relatif vers lequel rediriger les utilisateurs aprÚs la déconnexion.

Démarrage rapide

  1. Définissez les valeurs minimales par service protégé :
    • USE_LDAP=yes
    • LDAP_HOST=ldap.example.com
  2. Pour le mode recherche enterprise (recommandé), définissez également :
    • LDAP_BIND_DN=cn=readonly,dc=example,dc=com
    • LDAP_BIND_PASSWORD=secret (utilisez les secrets Docker en production)
    • LDAP_USER_SEARCH_BASE_DN=ou=people,dc=example,dc=com
  3. Pour le mode liaison directe, ajustez LDAP_USER_DN_TEMPLATE pour correspondre Ă  la structure de votre annuaire.
  4. Optionnellement, restreignez l'accĂšs avec LDAP_AUTHZ_FILTER (par ex. (memberOf=cn=allowed,ou=groups,dc=example,dc=com)).

Conseils d'utilisation

  • PrivilĂ©giez le mode recherche puis liaison par rapport Ă  la liaison directe : il prend en charge des recherches flexibles sur plusieurs attributs (uid, mail, sAMAccountName, UPN).
  • Utilisez LDAPS (LDAP_LDAPS=yes) ou STARTTLS (LDAP_STARTTLS=yes) en production pour chiffrer les identifiants en transit.
  • Lorsque vous activez LDAPS (LDAP_LDAPS=yes), pensez Ă©galement Ă  dĂ©finir LDAP_PORT=636. Le port ne change pas automatiquement.
  • Conservez LDAP_SSL_VERIFY=yes sauf pour des tests avec des certificats auto-signĂ©s.
  • Ajustez LDAP_KEEPALIVE_POOL_SIZE en fonction du volume d'utilisateurs simultanĂ©s attendu afin de rĂ©duire la surcharge de connexions LDAP.
  • DĂ©finissez LDAP_USER_HEADER sur une valeur vide pour dĂ©sactiver la transmission de l'identitĂ© aux upstreams.

OpenAPI Validator crown pro icon (PRO)

Le plugin OpenAPI Validator applique votre contrat d'API en validant les requĂȘtes entrantes par rapport Ă  une spĂ©cification OpenAPI / Swagger. Il s'assure que le chemin demandĂ© existe, que la mĂ©thode HTTP est autorisĂ©e et valide Ă©ventuellement les paramĂštres de requĂȘte, d'en-tĂȘte, de cookie et de chemin par rapport Ă  leurs dĂ©finitions de schĂ©ma.

Fonctionnement

  1. Un job planifié (openapi-download.py) récupÚre le document OpenAPI à partir d'une URL ou d'un fichier et le met en cache sur le disque (toutes les heures par défaut).
  2. Au moment de l'initialisation de NGINX, le plugin compile les routes à partir de la spécification mise en cache et les stocke dans un espace de stockage interne partagé.
  3. Pendant le traitement de la requĂȘte, le plugin fait correspondre la requĂȘte aux routes compilĂ©es et applique la validation.

Fonctionnalités

  • Validation du chemin et de la mĂ©thode avec une rĂ©ponse 405 lorsque la mĂ©thode n'est pas autorisĂ©e.
  • Validation optionnelle des paramĂštres pour les requĂȘtes, les en-tĂȘtes, les cookies et les paramĂštres de chemin.
  • Surcharge du chemin de base via OPENAPI_BASE_PATH ou dĂ©duction automatique Ă  partir de la spĂ©cification.
  • Autoriser ou refuser les requĂȘtes vers des chemins non listĂ©s dans la spĂ©cification.
  • Liste d'ignorĂ©s configurable pour les points de terminaison tels que la documentation ou les fichiers de spĂ©cification.
  • La spĂ©cification mise en cache est actualisĂ©e toutes les heures sans bloquer les requĂȘtes.

Configuration

ParamÚtre Défaut Contexte Multiple Description
USE_OPENAPI_VALIDATOR no multisite non Activer la validation des routes OpenAPI pour ce site.
OPENAPI_SPEC multisite non Chemin absolu ou URL HTTP(S) vers le document OpenAPI au format JSON/YAML.
OPENAPI_BASE_PATH multisite non Préfixe de chemin de base optionnel à ajouter à chaque chemin de la spécification.
OPENAPI_ALLOW_UNSPECIFIED no multisite non Autoriser les requĂȘtes vers des chemins non listĂ©s dans la spĂ©cification.
OPENAPI_ALLOW_INSECURE_URL no multisite non Autoriser la récupération de la spécification OpenAPI via HTTP simple (non recommandé).
OPENAPI_IGNORE_URLS ^/docs$ ^/redoc$ ^/openapi\\.json$ multisite non Liste d'expressions réguliÚres d'URL séparées par des espaces pour contourner la validation OpenAPI.
OPENAPI_MAX_SPEC_SIZE 2M global non Taille maximale autorisée du document OpenAPI (accepte les suffixes k/M/G).
OPENAPI_VALIDATE_PARAMS yes multisite non Valider les paramĂštres de requĂȘte, d'en-tĂȘte, de cookie et de chemin par rapport Ă  la spĂ©cification.

Notes de comportement

  • OPENAPI_SPEC peut ĂȘtre un fichier local ou une URL HTTPS. Les URL HTTP sont bloquĂ©es sauf si OPENAPI_ALLOW_INSECURE_URL=yes.
  • Si OPENAPI_BASE_PATH est vide, le plugin dĂ©duit le chemin de base Ă  partir de servers[*].url (OpenAPI 3) ou basePath (Swagger 2) lorsqu'il est prĂ©sent.
  • Les requĂȘtes HEAD sont acceptĂ©es lorsque GET est dĂ©fini pour le mĂȘme chemin, et la correspondance de chemin tolĂšre un slash final.
  • Lorsqu'un chemin est absent de la spĂ©cification et que OPENAPI_ALLOW_UNSPECIFIED=no, la requĂȘte est refusĂ©e avec le statut de refus configurĂ©.
  • Les Ă©checs de validation de paramĂštres sont refusĂ©s et seule la premiĂšre erreur est enregistrĂ©e pour garder les logs concis.

Démarrage rapide

Définissez les valeurs minimales par service protégé :

  • USE_OPENAPI_VALIDATOR=yes
  • OPENAPI_SPEC=/path/to/openapi.yaml (ou https://...)

Autorisez éventuellement les chemins inconnus pendant le déploiement :

  • OPENAPI_ALLOW_UNSPECIFIED=yes

Cache crown pro icon (PRO)

Prise en charge de STREAM ❌

Le plugin Cache PRO active la mise en cache des réponses au niveau du reverse proxy à l'aide des directives NGINX proxy_cache*. Il est utile pour absorber les lectures répétées sur du contenu cacheable, soulager les upstreams lors des pics de charge et servir du contenu périmé pendant de courtes indisponibilités du backend.

Fonctionnement

  1. Chaque valeur globale CACHE_PATH* crée une directive proxy_cache_path dans le contexte HTTP.
  2. Un service n'utilise le cache que lorsque CACHE_ZONE correspond à l'une des zones déclarées dans CACHE_PATH*.
  3. Les paramÚtres au niveau du service contrÎlent ensuite la clé de cache, les conditions de bypass/no-cache, le verrouillage, l'utilisation de contenu périmé et les rÚgles de validité.
  4. Si CACHE_HEADER est dĂ©fini, BunkerWeb ajoute un en-tĂȘte de rĂ©ponse exposant $upstream_cache_status comme HIT, MISS, BYPASS, EXPIRED ou STALE.

Liste des fonctionnalités

  • Mise en cache des rĂ©ponses du reverse proxy avec chemins et zones configurables.
  • Activation du cache par service via CACHE_ZONE.
  • En-tĂȘte facultatif exposant l'Ă©tat du cache avec $upstream_cache_status.
  • ContrĂŽles fins pour le bypass, le no-cache, la clĂ©, les mĂ©thodes, le verrouillage, le stale et la revalidation.
  • Plusieurs rĂšgles de validitĂ© via des paramĂštres CACHE_VALID*.

Liste des paramĂštres

Réglage Défaut Contexte Multiple Description
CACHE_PATH global oui Chemin et paramĂštres d'un cache.
CACHE_ZONE multisite non Nom de la zone de cache à utiliser (définie dans un réglage CACHE_PATH).
CACHE_HEADER X-Cache multisite non Ajoute un en-tĂȘte exposant l'Ă©tat du cache.
CACHE_BACKGROUND_UPDATE no multisite non Active ou désactive la mise à jour du cache en arriÚre-plan.
CACHE_BYPASS multisite non Liste de variables dĂ©terminant si le cache doit ĂȘtre contournĂ©.
CACHE_NO_CACHE $http_pragma$http_authorization multisite non Désactive le stockage en cache si des variables sont définies.
CACHE_KEY $scheme$proxy_host$request_uri multisite non Clé utilisée pour identifier les éléments mis en cache.
CACHE_CONVERT_HEAD_TO_GET yes multisite non Convertit les requĂȘtes HEAD en GET lors de la mise en cache.
CACHE_LOCK no multisite non Verrouille les requĂȘtes concurrentes lors du remplissage du cache.
CACHE_LOCK_AGE 5s multisite non Envoie la requĂȘte Ă  l'upstream si le cache est verrouillĂ© depuis ce dĂ©lai.
CACHE_LOCK_TIMEOUT 5s multisite non Envoie la requĂȘte Ă  l'upstream si le verrou persiste pendant ce dĂ©lai.
CACHE_METHODS GET HEAD multisite non Met en cache uniquement les réponses pour ces méthodes HTTP.
CACHE_MIN_USES 1 multisite non Nombre de requĂȘtes avant de stocker la rĂ©ponse en cache.
CACHE_REVALIDATE no multisite non Revalide les Ă©lĂ©ments expirĂ©s via des requĂȘtes conditionnelles.
CACHE_USE_STALE off multisite non Définit dans quels cas servir un contenu périmé.
CACHE_VALID 10m multisite oui Définit la durée de cache avec code(s) HTTP optionnel(s).

Exemple d'utilisation

  1. Définissez un chemin global et une zone de cache :

    CACHE_PATH: "/var/cache/bunkerweb/proxy levels=1:2 keys_zone=htmlcache:10m max_size=1g inactive=60m use_temp_path=off"
    
  2. Activez le reverse proxy et attachez la zone Ă  un service :

    www.example.com_USE_REVERSE_PROXY: "yes"
    www.example.com_REVERSE_PROXY_HOST: "http://app:8080"
    www.example.com_CACHE_ZONE: "htmlcache"
    www.example.com_CACHE_HEADER: "X-Cache"
    www.example.com_CACHE_VALID: "200 301 302 10m"
    www.example.com_CACHE_VALID_1: "404 1m"
    
  3. Ajoutez des contrÎles optionnels si nécessaire :

    www.example.com_CACHE_BYPASS: "$cookie_nocache $arg_nocache"
    www.example.com_CACHE_NO_CACHE: "$http_pragma $http_authorization"
    www.example.com_CACHE_LOCK: "yes"
    www.example.com_CACHE_BACKGROUND_UPDATE: "yes"
    www.example.com_CACHE_USE_STALE: "error timeout updating http_500 http_502 http_503 http_504"
    

!!! info "Comportement important" - Ce plugin s'applique uniquement au trafic reverse proxy. Il ne met pas en cache le contenu servi directement depuis des fichiers statiques locaux ni les services stream/TCP. - CACHE_ZONE doit correspondre Ă  une zone dĂ©finie dans une valeur CACHE_PATH* via keys_zone=<nom>:<taille>. - Si CACHE_ZONE est vide pour un service, les directives de cache ne sont pas appliquĂ©es Ă  ce service. - Utilisez des suffixes numĂ©riques pour les valeurs rĂ©pĂ©tĂ©es, par exemple CACHE_PATH_1, CACHE_PATH_2, CACHE_VALID_1 et CACHE_VALID_2. - Gardez le trafic authentifiĂ© ou spĂ©cifique Ă  un utilisateur hors cache, sauf si votre CACHE_KEY varie explicitement selon cet Ă©tat. - CACHE_LOCK=yes et CACHE_BACKGROUND_UPDATE=yes permettent de rĂ©duire les rafales de requĂȘtes vers l'origine.

ACME crown pro icon (PRO)

STREAM support ✅

Le plugin ACME fournit une gestion avancée des certificats via le protocole ACME avec prise en charge d'autorités de certification personnalisées (Step CA, Vault PKI, Sectigo, Google Trust Services, etc.). Il complÚte le plugin Let's Encrypt intégré en ajoutant la prise en charge de CA personnalisées, les challenges DNS-01 et TLS-ALPN-01, les certificats wildcard, la surveillance des certificats avec alertes d'expiration, la surveillance des logs Certificate Transparency et un OCSP stapling amélioré.

!!! tip "Quand utiliser ACME ou le plugin Let's Encrypt intégré" Si vous avez uniquement besoin de certificats Let's Encrypt avec des challenges HTTP-01, le plugin Let's Encrypt intégré (AUTO_LETS_ENCRYPT=yes) est suffisant. Utilisez le plugin ACME lorsque vous avez besoin de CA personnalisées, de challenges DNS-01 ou TLS-ALPN-01, de certificats wildcard, ou de surveillance des certificats avec alertes.

Fonctionnalités

  • Prise en charge de CA personnalisĂ©es : utilisez n'importe quelle autoritĂ© de certification compatible ACME, pas uniquement Let's Encrypt.
  • Plusieurs types de challenges : HTTP-01, DNS-01 (requis pour les wildcards) et TLS-ALPN-01.
  • IntĂ©gration de fournisseurs DNS : prise en charge intĂ©grĂ©e de Cloudflare, Route53, DigitalOcean, OVH et d'autres.
  • External Account Binding (EAB) : pour les CA nĂ©cessitant des clĂ©s prĂ©-enregistrĂ©es (Sectigo, Google Trust Services).
  • Certificats wildcard : via le challenge DNS-01.
  • Surveillance des certificats : suit l'expiration de tous les certificats gĂ©rĂ©s (y compris le Let's Encrypt OSS) avec des seuils d'alerte configurables.
  • Alertes d'expiration : envoi d'alertes par webhook ou e-mail lorsque les certificats approchent de leur expiration.
  • Surveillance Certificate Transparency : interroge crt.sh pour dĂ©tecter l'Ă©mission non autorisĂ©e de certificats pour vos domaines.
  • OCSP stapling amĂ©liorĂ© : rĂ©cupĂ©ration et mise en cache proactives des rĂ©ponses OCSP.
  • Types de clĂ©s configurables : ECDSA (256/384) ou RSA (2048/4096).

Prérequis

Le challenge HTTP-01 nécessite LETS_ENCRYPT_PASSTHROUGH=yes

Lorsque vous utilisez ACME_CHALLENGE=http (la valeur par dĂ©faut), vous devez dĂ©finir LETS_ENCRYPT_PASSTHROUGH=yes sur le mĂȘme service.

Le plugin Let's Encrypt intĂ©grĂ© de BunkerWeb inclut Ă  la fois un bloc location NGINX et un gestionnaire d'accĂšs Lua pour /.well-known/acme-challenge/. Comme le bloc location NGINX correspond avant que le code des plugins Lua ne s'exĂ©cute, il intercepte les requĂȘtes de challenge avant que le plugin ACME PRO ne puisse les servir. DĂ©finir LETS_ENCRYPT_PASSTHROUGH=yes dĂ©sactive les deux mĂ©canismes afin que le plugin ACME PRO puisse gĂ©rer correctement les tokens du challenge HTTP-01.

Cela n'est nécessaire que pour HTTP-01. Les challenges DNS-01 et TLS-ALPN-01 ne sont pas concernés.

Passthrough ACME vers l'amont (ACME_PASSTHROUGH)

Si le serveur amont derriĂšre BunkerWeb exĂ©cute dĂ©jĂ  son propre client ACME et doit gĂ©rer lui-mĂȘme la validation HTTP-01, dĂ©finissez ACME_PASSTHROUGH=yes sur le service. Le plugin ACME PRO cessera alors de rendre son bloc location /.well-known/acme-challenge/ et n'ajoutera plus les chemins de challenge Ă  la liste blanche en phase access, afin que les fichiers de validation servis par l'amont parviennent Ă  la CA sans ĂȘtre interceptĂ©s.

Laissez ACME_PASSTHROUGH=no (la valeur par dĂ©faut) lorsque vous voulez que le plugin ACME PRO obtienne et renouvelle lui-mĂȘme les certificats. La combinaison standard HTTP-01 pour les services gĂ©rĂ©s par ACME PRO est LETS_ENCRYPT_PASSTHROUGH=yes (pour que le plugin OSS Let's Encrypt cĂšde son bloc location de challenge) associĂ© Ă  ACME_PASSTHROUGH=no. Ne passez ACME_PASSTHROUGH Ă  yes que lorsque l'amont possĂšde le cycle de vie complet du certificat — dans ce mode, BunkerWeb n'essaiera pas d'Ă©mettre de certificat pour ce service.

Ce paramĂštre reproduit le comportement du LETS_ENCRYPT_PASSTHROUGH du cƓur OSS et n'affecte que HTTP-01 ; les challenges DNS-01 et TLS-ALPN-01 ne sont pas concernĂ©s.

Ordre d'exécution des plugins

Le plugin ACME se réordonne automatiquement pour s'exécuter en premier dans la phase NGINX ssl_certificate, garantissant que les certificats de challenge TLS-ALPN-01 sont servis avant que d'autres plugins fournisseurs de certificats (selfsigned, letsencrypt, customcert) ne court-circuitent la boucle.

Lorsque vous utilisez ACME aux cÎtés d'autres plugins PRO nécessitant un TLS valide (par ex. OpenID Connect, UI SSO), il est recommandé d'ajouter explicitement acme juste aprÚs customcert dans les paramÚtres d'ordre des phases concernées :

PLUGINS_ORDER_SSL_CERTIFICATE=customcert acme letsencrypt selfsigned
PLUGINS_ORDER_INIT=sessions whitelist blacklist greylist bunkernet limit authbasic securitytxt robotstxt crowdsec dnsbl headers customcert acme letsencrypt selfsigned

Les plugins externes/PRO non listés dans les paramÚtres PLUGINS_ORDER_* sont ajoutés par ordre alphabétique aprÚs les plugins principaux explicitement ordonnés.

!!! warning "N'activez pas USE_ACME et AUTO_LETS_ENCRYPT sur le mĂȘme service" Le plugin ACME et le plugin Let's Encrypt intĂ©grĂ© utilisent des stockages et des chemins de challenge sĂ©parĂ©s, mais les activer tous les deux sur le mĂȘme service provoquera des conflits. Utilisez l'un ou l'autre par service. En mode multisite, diffĂ©rents services peuvent utiliser diffĂ©rents plugins -- par exemple, app1.example.com_USE_ACME=yes et app2.example.com_AUTO_LETS_ENCRYPT=yes.

Configuration

ParamĂštres principaux ACME

ParamÚtre Défaut Contexte Multiple Description
USE_ACME no multisite non Activer la gestion des certificats ACME pour ce service.
ACME_PASSTHROUGH no multisite non Laisser passer les requĂȘtes du challenge HTTP-01 vers le serveur amont (l'amont gĂšre son propre client ACME).
ACME_DIRECTORY_URL multisite non URL du répertoire ACME de l'autorité de certification.
ACME_EMAIL multisite non Adresse e-mail pour l'enregistrement du compte ACME et les notifications.
ACME_CHALLENGE http multisite non Type de challenge ACME : http, dns ou alpn.
ACME_KEY_TYPE ecdsa multisite non Type de clé pour le certificat : ecdsa ou rsa.
ACME_KEY_SIZE 256 multisite non Taille de la clé en bits. ECDSA : 256 ou 384. RSA : 2048 ou 4096.
ACME_RENEWAL_DAYS 30 multisite non Renouveler le certificat lorsqu'il reste moins de ce nombre de jours avant l'expiration.
ACME_SSL_VERIFY yes multisite non Vérifier les certificats SSL lors de la communication avec le serveur ACME.
ACME_WILDCARD no multisite non Demander un certificat wildcard (nécessite le challenge DNS-01).
ACME_MUST_STAPLE no multisite non Demander l'extension OCSP Must-Staple dans le certificat.
ACME_MAX_RETRIES 3 multisite non Nombre de tentatives de génération du certificat en cas d'échec (0 désactive les tentatives).
ACME_PREFERRED_CHAIN multisite non CN de l'émetteur de la chaßne de certificats préférée lorsque la CA fournit plusieurs chaßnes.
ACME_CA_CERT_PATH multisite non Chemin du fichier du certificat racine CA pour les serveurs ACME privés.

External Account Binding (EAB)

ParamÚtre Défaut Contexte Multiple Description
ACME_EAB_KID multisite non Key ID de l'External Account Binding (requis par certaines CA).
ACME_EAB_HMAC_KEY multisite non Clé HMAC de l'External Account Binding (encodée en base64).

Challenge DNS-01

ParamÚtre Défaut Contexte Multiple Description
ACME_DNS_PROVIDER multisite non Fournisseur DNS pour les challenges DNS-01.
ACME_DNS_CREDENTIAL_ITEM multisite oui Identifiant du fournisseur DNS au format key value (par ex. cloudflare_api_token YOUR_TOKEN). Utilisez des suffixes numĂ©riques pour plusieurs Ă©lĂ©ments (par ex. ACME_DNS_CREDENTIAL_ITEM_1). Les valeurs peuvent ĂȘtre encodĂ©es en base64.
ACME_DNS_CREDENTIAL_DECODE_BASE64 yes multisite oui DĂ©coder automatiquement les identifiants DNS encodĂ©s en base64. DĂ©sactivez si vos identifiants sont du texte brut qui se trouve ĂȘtre du base64 valide.
ACME_DNS_PROPAGATION default multisite non Temps d'attente pour la propagation DNS en secondes (default ou un nombre).

Surveillance des certificats

ParamÚtre Défaut Contexte Multiple Description
USE_ACME_MONITORING yes global non Activer la surveillance de l'expiration des certificats pour tous les certificats gérés (y compris le Let's Encrypt OSS).
ACME_ALERT_DAYS 30 14 7 1 global non Liste de seuils en jours séparés par des espaces déclenchant des alertes d'expiration.

Alertes (webhook)

ParamÚtre Défaut Contexte Multiple Description
USE_ACME_ALERT_WEBHOOK no global non Envoyer les alertes de certificat par webhook.
ACME_ALERT_WEBHOOK_URLS global non Liste d'URL de webhook séparées par des espaces pour les alertes.

Alertes (e-mail)

ParamÚtre Défaut Contexte Multiple Description
USE_ACME_ALERT_EMAIL no global non Envoyer les alertes de certificat par e-mail.
ACME_ALERT_SMTP_EMAILS global non Liste de destinataires e-mail séparés par des espaces.
ACME_ALERT_SMTP_HOST global non HĂŽte SMTP pour les e-mails d'alerte de certificat.
ACME_ALERT_SMTP_PORT 465 global non Port SMTP (SSL=465, TLS=587).
ACME_ALERT_SMTP_FROM_EMAIL global non Adresse e-mail de l'expéditeur pour les alertes de certificat.
ACME_ALERT_SMTP_FROM_USER global non Utilisateur d'authentification SMTP.
ACME_ALERT_SMTP_FROM_PASSWORD global non Mot de passe d'authentification SMTP.
ACME_ALERT_SMTP_SSL SSL global non Type de connexion : no, SSL ou TLS.

Surveillance Certificate Transparency

ParamÚtre Défaut Contexte Multiple Description
USE_ACME_CT_MONITORING no global non Activer la surveillance des logs CT via crt.sh pour détecter l'émission non autorisée de certificats.
ACME_CT_MONITORED_DOMAINS global non Liste de domaines à surveiller séparés par des espaces. Laisser vide pour la détection automatique.

OCSP stapling

ParamÚtre Défaut Contexte Multiple Description
USE_ACME_OCSP_STAPLING no multisite non Activer l'OCSP stapling amélioré avec récupération et mise en cache proactives des réponses.
ACME_OCSP_CACHE_SIZE 1m global non Taille du dictionnaire partagé pour la mise en cache des réponses OCSP.

Démarrage rapide

  1. Définissez les valeurs minimales par service protégé :
    • USE_ACME=yes
    • ACME_DIRECTORY_URL=https://ca.example.com/acme/directory
    • ACME_EMAIL=admin@example.com
  2. Pour les certificats wildcard, passez au challenge DNS-01 :
    • ACME_CHALLENGE=dns
    • ACME_DNS_PROVIDER=cloudflare
    • ACME_DNS_CREDENTIAL_ITEM=cloudflare_api_token YOUR_TOKEN (utilisez les secrets Docker en production)
    • ACME_WILDCARD=yes
  3. Pour les CA nécessitant l'External Account Binding :
    • ACME_EAB_KID=your-key-id
    • ACME_EAB_HMAC_KEY=your-base64-hmac-key (utilisez les secrets Docker en production)
  4. Pour les CA privées avec des certificats racines auto-signés :
    • ACME_CA_CERT_PATH=/path/to/ca-root.pem
    • ACME_SSL_VERIFY=yes (fournir ACME_CA_CERT_PATH permet Ă  la vĂ©rification de fonctionner avec des CA privĂ©es sans dĂ©sactiver la vĂ©rification SSL)

Conseils d'utilisation

  • La surveillance des certificats (USE_ACME_MONITORING) est activĂ©e par dĂ©faut et suit Ă©galement les certificats Let's Encrypt OSS. Configurez les seuils ACME_ALERT_DAYS et au moins un canal d'alerte (webhook ou e-mail) pour recevoir les avertissements d'expiration.
  • Activez la surveillance CT (USE_ACME_CT_MONITORING=yes) pour dĂ©tecter les certificats non autorisĂ©s Ă©mis pour vos domaines via les logs Certificate Transparency.
  • Utilisez les clĂ©s ECDSA (par dĂ©faut) pour des certificats plus compacts et plus rapides. Passez Ă  RSA uniquement lorsque la compatibilitĂ© avec des clients anciens est requise.
  • Lors de l'utilisation des challenges DNS-01, ajustez ACME_DNS_PROPAGATION si votre fournisseur DNS est lent Ă  propager les enregistrements.
  • DĂ©finissez ACME_MAX_RETRIES=0 pour dĂ©sactiver les tentatives automatiques si vous prĂ©fĂ©rez investiguer les Ă©checs manuellement.

Coexistence avec le Let's Encrypt intégré

Le plugin ACME PRO et le plugin Let's Encrypt OSS utilisent des stockages, des endpoints API et des clĂ©s de cache entiĂšrement sĂ©parĂ©s. Les deux peuvent ĂȘtre actifs simultanĂ©ment sur diffĂ©rents services en mode multisite :

MULTISITE: "yes"
SERVER_NAME: "app1.example.com app2.example.com"

# ACME PRO pour app1 (CA privée)
app1.example.com_USE_ACME: "yes"
app1.example.com_ACME_DIRECTORY_URL: "https://ca.internal:9000/acme/acme/directory"
app1.example.com_ACME_CA_CERT_PATH: "/certs/step-ca-root.pem"
app1.example.com_LETS_ENCRYPT_PASSTHROUGH: "yes"  # nécessaire pour HTTP-01

# Let's Encrypt intégré pour app2
app2.example.com_AUTO_LETS_ENCRYPT: "yes"

Dépannage

  • Échec du challenge HTTP-01 : vĂ©rifiez que LETS_ENCRYPT_PASSTHROUGH=yes est dĂ©fini -- sans cela, le bloc location intĂ©grĂ© de BunkerWeb intercepte les requĂȘtes de challenge avant que le plugin ACME PRO ne puisse les servir. VĂ©rifiez Ă©galement que le port 80 est accessible depuis le serveur ACME et que AUTO_LETS_ENCRYPT n'est pas Ă©galement activĂ© pour le mĂȘme service.
  • Échec du challenge TLS-ALPN-01 : vĂ©rifiez que le port 443 est accessible depuis le serveur ACME et qu'aucun autre plugin ne sert de certificat avant ACME dans la phase ssl_certificate. VĂ©rifiez PLUGINS_ORDER_SSL_CERTIFICATE en cas de doute.
  • Échec du challenge DNS-01 : vĂ©rifiez les identifiants du fournisseur DNS dans ACME_DNS_CREDENTIAL_ITEM et ajustez ACME_DNS_PROPAGATION si votre fournisseur est lent Ă  propager les enregistrements.
  • Certificat non renouvelĂ© : vĂ©rifiez ACME_RENEWAL_DAYS et les logs du scheduler. Le job acme-renew s'exĂ©cute quotidiennement et renouvelle les certificats qui se trouvent dans le seuil configurĂ©.

Wildcard crown pro icon (PRO)

Prise en charge STREAM ❌

Le plugin Wildcard permet à un service BunkerWeb unique de répondre à :

  • son nom d'hĂŽte exact
  • tout sous-domaine direct de ce nom d'hĂŽte

Lorsqu'il est activé, le plugin prend la premiÚre entrée de SERVER_NAME et ajoute un server_name wildcard à la configuration NGINX générée.

Par exemple, si la premiÚre entrée est example.com, le plugin ajoute :

server_name *.example.com;

Le service répond alors à :

  • example.com
  • www.example.com
  • api.example.com

Il s'agit d'un plugin minimal, uniquement basé sur la configuration :

  • aucun job
  • aucun Lua
  • aucune UI

Fonctionnement

Le plugin dérive le nom d'hÎte wildcard à partir de la premiÚre valeur de SERVER_NAME et injecte un nom de serveur wildcard NGINX standard lors de la génération de la configuration.

Il ne modifie pas la logique de traitement des requĂȘtes au-delĂ  de la correspondance des noms d'hĂŽte.

!!! info "Les hĂŽtes wildcard ne sont pas des certificats wildcard" Ce plugin agit uniquement sur le routage HTTP. Il indique Ă  NGINX quels noms d'hĂŽte le service doit accepter.

Il ne provisionne **pas** de certificat TLS wildcard.

Pour servir `*.example.com` en HTTPS, vous avez toujours besoin d'un certificat wildcard correspondant, généralement avec l'une de ces options :

- `USE_LETS_ENCRYPT_WILDCARD=yes` avec le plugin Let's Encrypt intégré
- `ACME_WILDCARD=yes` avec le plugin [ACME PRO](#acme) en utilisant un challenge DNS-01

Fonctionnalités

  • Activation simple : activez le routage wildcard avec USE_WILDCARD=yes
  • DĂ©rivation automatique : l'hĂŽte wildcard est construit Ă  partir de la premiĂšre entrĂ©e de SERVER_NAME
  • SĂ©mantique native NGINX : la correspondance suit le comportement standard de server_name
  • Compatible multisite : chaque service peut activer ou dĂ©sactiver le routage wildcard indĂ©pendamment

Configuration

ParamÚtre Valeur par défaut Contexte Multiple Description
USE_WILDCARD no multisite non Active un server_name wildcard pour le service en ajoutant *.domain pour la premiÚre entrée de SERVER_NAME.

Démarrage rapide

  1. Placez en premier dans SERVER_NAME le domaine que vous souhaitez utiliser en wildcard
  2. Définissez USE_WILDCARD=yes
  3. Faites pointer l'enregistrement DNS wildcard vers BunkerWeb, généralement avec un enregistrement wildcard A ou AAAA
  4. Si vous avez besoin de HTTPS, provisionnez séparément un certificat wildcard
  5. Rechargez ou redémarrez BunkerWeb

Exemples

Single-site

SERVER_NAME: "example.com"
USE_WILDCARD: "yes"

Ce service répondra à :

  • example.com
  • www.example.com
  • api.example.com
  • tout autre nom d'hĂŽte *.example.com qui rĂ©sout vers BunkerWeb

Multisite

MULTISITE: "yes"
SERVER_NAME: "app.example.com docs.example.org"

# Seul app.example.com obtient le routage wildcard
app.example.com_USE_WILDCARD: "yes"

Dans cette configuration :

  • app.example.com et *.app.example.com vont vers le premier service
  • docs.example.org conserve uniquement la correspondance exacte

Comportement important

!!! warning "Seul le premier domaine devient wildcard" Si SERVER_NAME vaut :

```yaml
SERVER_NAME: "example.com example.org"
```

seul `*.example.com` est ajouté.

Placez en premier le domaine que vous souhaitez utiliser en wildcard.

!!! note "Les entrées wildcard existantes sont conservées" Si le premier domaine commence déjà par *., par exemple :

```yaml
SERVER_NAME: "*.example.com"
```

le plugin n'émet rien.

!!! note "La correspondance wildcard ne couvre qu'un seul label" *.example.com correspond Ă  foo.example.com, mais pas Ă  a.b.example.com.

Pour des sous-domaines plus profonds, utilisez une entrée `SERVER_NAME` explicite ou un service séparé.

!!! note "Les correspondances exactes sont prioritaires" Si un autre service définit explicitement foo.example.com, NGINX route d'abord ce nom d'hÎte vers la correspondance exacte.


Recommandé avec les certificats wildcard Let's Encrypt

Si vous utilisez ce plugin avec USE_LETS_ENCRYPT_WILDCARD=yes, utilisez ce modĂšle :

SERVER_NAME: "<root_domain> <any_app>.<root_domain>"

Le domaine racine doit venir en premier.

Exemple :

SERVER_NAME: "example.com app.example.com"
USE_WILDCARD: "yes"
AUTO_LETS_ENCRYPT: "yes"
EMAIL_LETS_ENCRYPT: "admin@example.com"
LETS_ENCRYPT_CHALLENGE: "dns"
LETS_ENCRYPT_DNS_PROVIDER: "cloudflare"
LETS_ENCRYPT_DNS_CREDENTIAL_ITEM: "api_token YOUR_API_TOKEN"
USE_LETS_ENCRYPT_WILDCARD: "yes"

!!! tip "Pourquoi ce modÚle est important" - Seule la premiÚre entrée de SERVER_NAME devient wildcard

Si `example.com` vient en premier, le plugin émet `*.example.com`.

Si `app.example.com` vient en premier, il émet `*.app.example.com`, ce qui correspond généralement au mauvais niveau de wildcard.

- **La deuxiÚme entrée aide Let's Encrypt à détecter le bon domaine de base**
  Avec seulement un domaine apex nu, la détection de certificat wildcard peut échouer sur certains domaines à suffixe public comme `example.co.uk`.

- **Le deuxiÚme nom d'hÎte n'a pas besoin de backend réel**
  Utilisez n'importe quelle valeur stable comme `app.example.com` ou `www.example.com`.

Multisite avec Let's Encrypt wildcard

MULTISITE: "yes"
SERVER_NAME: "example.com app.example.com"
example.com_USE_WILDCARD: "yes"
example.com_USE_LETS_ENCRYPT_WILDCARD: "yes"
example.com_LETS_ENCRYPT_CHALLENGE: "dns"
example.com_LETS_ENCRYPT_DNS_PROVIDER: "cloudflare"
example.com_LETS_ENCRYPT_DNS_CREDENTIAL_ITEM: "api_token YOUR_API_TOKEN"

Conseils d'utilisation

  • Planifiez le TLS sĂ©parĂ©ment Le routage wildcard ne suffit pas pour HTTPS. Vous avez toujours besoin d'une couverture de certificat pour les sous-domaines.

  • Gardez l'ordre de SERVER_NAME stable RĂ©ordonner les entrĂ©es change quel domaine devient la cible du wildcard.

  • Fonctionne bien avec REVERSE_PROXY_HOST C'est utile lorsque de nombreux sous-domaines sont routĂ©s via un upstream partagĂ©, comme un routeur de tenants.

  • Soyez prudent avec les services qui se chevauchent NGINX privilĂ©gie toujours la correspondance server_name la plus spĂ©cifique.