bunkerweb/docs/fr/api.md
TheophileDiot ec296adcef
Road to 1.6.10~rc3 🚀
2026-04-11 09:04:27 +02:00

27 KiB
Raw Blame History

API

Rîle de l’API

L’API BunkerWeb est le plan de contrĂŽle pour gĂ©rer instances, services, bans, plugins, jobs et configurations personnalisĂ©es. Elle tourne en FastAPI derriĂšre Gunicorn et doit rester sur un rĂ©seau de confiance. Docs interactives : /docs (ou <API_ROOT_PATH>/docs) ; schĂ©ma OpenAPI : /openapi.json.

!!! warning "Gardez-la privĂ©e" Ne l’exposez pas directement Ă  Internet. Gardez-la en rĂ©seau interne, restreignez les IP sources et imposez l’authentification.

!!! info "En bref" - Endpoints de santĂ© : GET /ping et GET /health - Chemin racine : dĂ©finissez API_ROOT_PATH en reverse proxy sur un sous-chemin pour que docs et OpenAPI fonctionnent - Auth obligatoire : tokens Biscuit, Basic admin ou Bearer de secours - Liste blanche IP par dĂ©faut sur les plages RFC1918 (API_WHITELIST_IPS) ; ne dĂ©sactivez que si l’upstream contrĂŽle l’accĂšs - Rate limiting activĂ© par dĂ©faut ; /auth a toujours son propre plafond

Checklist sécurité

  • RĂ©seau : gardez le trafic interne ; liez sur loopback ou interface interne et restreignez les IP sources avec API_WHITELIST_IPS (activĂ© par dĂ©faut).
  • Auth prĂ©sente : dĂ©finissez API_USERNAME/API_PASSWORD (admin) et, si besoin, API_ACL_BOOTSTRAP_FILE pour d’autres utilisateurs/ACL ; conservez un API_TOKEN uniquement pour le break-glass.
  • Masquage de chemin : en reverse proxy, choisissez un API_ROOT_PATH peu devinable et reflĂ©tez-le cĂŽtĂ© proxy.
  • Rate limiting : laissez activĂ© sauf si une autre couche impose des limites Ă©quivalentes ; /auth est toujours limitĂ©.
  • TLS : terminez au proxy ou activez API_SSL_ENABLED=yes avec chemins de cert/clĂ©.

Exécution

Choisissez la saveur adaptée à votre environnement.

=== "Docker"

Compose minimal avec l’API derriùre BunkerWeb. Ajustez versions et mots de passe avant usage.

```yaml
x-bw-env: &bw-env
  # On utilise une ancre pour Ă©viter de rĂ©pĂ©ter les mĂȘmes rĂ©glages
  API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" # Renseignez la plage IP correcte pour que le scheduler envoie la config à l’instance (API interne BunkerWeb)
  # Optionnel : définir un token API et le refléter dans les deux conteneurs (API interne BunkerWeb)
  API_TOKEN: ""
  DATABASE_URI: "mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db" # Mettez un mot de passe DB plus solide

services:
  bunkerweb:
    # Nom utilisĂ© par le scheduler pour identifier l’instance
    image: bunkerity/bunkerweb:1.6.10-rc3
    ports:
      - "80:8080/tcp"
      - "443:8443/tcp"
      - "443:8443/udp" # Pour QUIC / HTTP3
    environment:
      <<: *bw-env # RĂ©utilisation de l’ancre pour Ă©viter les duplications
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-services

  bw-scheduler:
    image: bunkerity/bunkerweb-scheduler:1.6.10-rc3
    environment:
      <<: *bw-env
      BUNKERWEB_INSTANCES: "bunkerweb" # Assurez-vous de mettre le bon nom d’instance
      SERVER_NAME: "api.example.com"
      MULTISITE: "yes"
      USE_REDIS: "yes"
      REDIS_HOST: "redis"
      DISABLE_DEFAULT_SERVER: "yes"
      AUTO_LETS_ENCRYPT: "yes"
      api.example.com_USE_TEMPLATE: "api"
      api.example.com_USE_REVERSE_PROXY: "yes"
      api.example.com_REVERSE_PROXY_URL: "/"
      api.example.com_REVERSE_PROXY_HOST: "http://bw-api:8888"
    volumes:
      - bw-storage:/data # Persiste le cache et les sauvegardes
    restart: "unless-stopped"
    networks:
      - bw-universe
      - bw-db

  bw-api:
    image: bunkerity/bunkerweb-api:1.6.10-rc3
    environment:
      <<: *bw-env
      API_USERNAME: "admin"
      API_PASSWORD: "Str0ng&P@ss!"
      # API_TOKEN: "admin-override-token" # optionnel
      FORWARDED_ALLOW_IPS: "127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16" # Attention : à n’utiliser que si le reverse proxy est l’unique accùs
      API_ROOT_PATH: "/"
    networks:
      - bw-universe
      - bw-db

  bw-db:
    image: mariadb:11
    # Max allowed packet plus Ă©levĂ© pour Ă©viter les problĂšmes de grosses requĂȘtes
    command: --max-allowed-packet=67108864
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
      MYSQL_DATABASE: "db"
      MYSQL_USER: "bunkerweb"
      MYSQL_PASSWORD: "changeme" # Mettez un mot de passe DB plus solide
    volumes:
      - bw-data:/var/lib/mysql
    restart: "unless-stopped"
    networks:
      - bw-db

  redis: # Redis pour persister reports/bans/stats
    image: redis:8-alpine
    command: >
      redis-server
      --maxmemory 256mb
      --maxmemory-policy allkeys-lru
      --save 60 1000
      --appendonly yes
    volumes:
      - redis-data:/data
    restart: "unless-stopped"
    networks:
      - bw-universe

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

networks:
  bw-universe:
    name: bw-universe
    ipam:
      driver: default
      config:
        - subnet: 10.20.30.0/24 # Renseignez la plage IP correcte pour que le scheduler envoie la config à l’instance
  bw-services:
    name: bw-services
  bw-db:
    name: bw-db
```

=== "All-in-One"

```bash
docker run -d \
  --name bunkerweb-aio \
  -e SERVICE_API=yes \
  -e API_WHITELIST_IPS="127.0.0.0/8" \
  -p 80:8080/tcp -p 443:8443/tcp -p 443:8443/udp \
  bunkerity/bunkerweb-all-in-one:1.6.10-rc3
```

=== "Linux"

Les paquets DEB/RPM livrent `bunkerweb-api.service`, géré via `/usr/share/bunkerweb/scripts/bunkerweb-api.sh`.

- Activer/démarrer : `sudo systemctl enable --now bunkerweb-api.service`
- Recharger : `sudo systemctl reload bunkerweb-api.service`
- Logs : journal plus `/var/log/bunkerweb/api.log`
- Écoute par dĂ©faut : `127.0.0.1:8888` avec `API_WHITELIST_IPS=127.0.0.1`
- Fichiers de config : `/etc/bunkerweb/api.env` (créé au premier démarrage avec des defaults commentés) et `/etc/bunkerweb/api.yml`
- Sources d’environnement : `api.env`, `variables.env`, `/run/secrets/<VAR>`, puis exportĂ©es dans le processus Gunicorn

Modifiez `/etc/bunkerweb/api.env` pour définir `API_USERNAME`/`API_PASSWORD`, la liste blanche, TLS, les limites ou `API_ROOT_PATH`, puis `systemctl reload bunkerweb-api`.

Authentification et autorisation

  • /auth Ă©met des Biscuit. Les identifiants peuvent venir de Basic auth, champs de formulaire, corps JSON ou d’un header Bearer Ă©gal Ă  API_TOKEN (override admin).
  • Les admins peuvent aussi appeler les routes protĂ©gĂ©es en Basic HTTP direct (sans Biscuit).
  • Si le Bearer correspond Ă  API_TOKEN, l’accĂšs est total/admin. Sinon, la garde Biscuit applique les ACL.
  • Le payload Biscuit inclut utilisateur, heure, IP cliente, host, version, un rĂŽle large role("api_user", ["read", "write"]) et soit admin(true), soit des permissions fines api_perm(resource_type, resource_id|*, permission).
  • TTL : API_BISCUIT_TTL_SECONDS (0/off dĂ©sactive l’expiration). Les clĂ©s sont sous /var/lib/bunkerweb/.api_biscuit_private_key et .api_biscuit_public_key, sauf si fournies via BISCUIT_PRIVATE_KEY/BISCUIT_PUBLIC_KEY.
  • Les endpoints d’auth ne sont exposĂ©s que lorsqu’au moins un utilisateur API existe en base.

!!! tip "Démarrage auth" 1. Définissez API_USERNAME et API_PASSWORD (et OVERRIDE_API_CREDS=yes si vous devez réamorcer). 2. Appelez POST /auth en Basic ; lisez .token dans la réponse. 3. Utilisez Authorization: Bearer <token> pour les appels suivants.

Permissions et ACL

  • RĂŽle grossier : GET/HEAD/OPTIONS requiĂšrent read ; les verbes d’écriture requiĂšrent write.
  • L’ACL fine s’applique quand les routes dĂ©clarent des permissions ; admin(true) contourne les vĂ©rifications.
  • Types de ressources : instances, global_settings, services, configs, plugins, cache, bans, jobs.
  • Noms de permissions :
    • instances_* : instances_read, instances_update, instances_delete, instances_create, instances_execute
    • global_settings_* : global_settings_read, global_settings_update
    • services : service_read, service_create, service_update, service_delete, service_convert, service_export
    • configs : configs_read, config_read, config_create, config_update, config_delete
    • plugins : plugin_read, plugin_create, plugin_delete
    • cache : cache_read, cache_delete
    • bans : ban_read, ban_update, ban_delete, ban_created
    • jobs : job_read, job_run
  • resource_id est gĂ©nĂ©ralement le deuxiĂšme composant de chemin (ex. /services/{id}) ; "*" donne un accĂšs global.
  • Bootstrap des utilisateurs non admin et des permissions via API_ACL_BOOTSTRAP_FILE ou un /var/lib/bunkerweb/api_acl_bootstrap.json montĂ©. Mots de passe en clair ou en hash bcrypt.

??? example "Bootstrap ACL minimal" json { "users": { "ci": { "admin": false, "password": "Str0ng&P@ss!", "permissions": { "services": { "*": { "service_read": true } }, "configs": { "*": { "config_read": true, "config_update": true } } } } } }

Limitation de débit

Activée par défaut avec deux chaßnes : API_RATE_LIMIT (global, défaut 100r/m) et API_RATE_LIMIT_AUTH (défaut 10r/m ou off). Formats acceptés : notation style NGINX (3r/s, 40r/m, 200r/h) ou formes verbeuses (100/minute, 200 per 30 minutes). Configurez via :

  • API_RATE_LIMIT, API_RATE_LIMIT_AUTH
  • API_RATE_LIMIT_ENABLED, API_RATE_LIMIT_HEADERS_ENABLED
  • API_RATE_LIMIT_RULES (string CSV/JSON/YAML ou chemin de fichier)
  • API_RATE_LIMIT_STRATEGY, API_RATE_LIMIT_KEY, API_RATE_LIMIT_EXEMPT_IPS
  • Stockage en mĂ©moire ou Redis/Valkey avec USE_REDIS=yes plus rĂ©glages REDIS_* (Sentinel supportĂ©).

Stratégies (propulsées par limits) :

  • fixed-window (dĂ©faut) : le bucket se rĂ©initialise Ă  chaque borne d’intervalle ; le plus lĂ©ger et suffisant pour des plafonds grossiers.
  • moving-window : vraie fenĂȘtre glissante avec horodatages prĂ©cis ; plus douce mais plus coĂ»teuse en opĂ©rations de stockage.
  • sliding-window-counter : hybride qui lisse avec des comptes pondĂ©rĂ©s de la fenĂȘtre prĂ©cĂ©dente ; plus lĂ©ger que moving et plus doux que fixed.

Plus de détails et compromis : https://limits.readthedocs.io/en/stable/strategies.html

??? example "CSV en ligne" API_RATE_LIMIT_RULES='POST /auth 10r/m, GET /instances* 200r/m, POST|PATCH /services* 40r/m'

??? example "Fichier YAML" yaml API_RATE_LIMIT: 200r/m API_RATE_LIMIT_AUTH: 15r/m API_RATE_LIMIT_RULES: - path: "/auth" methods: "POST" rate: "10r/m" - path: "/instances*" methods: "GET|POST" rate: "100r/m"

Sources de configuration et priorité

  1. Variables d’environnement (y compris environment: Docker/Compose)
  2. Secrets dans /run/secrets/<VAR> (Docker)
  3. YAML sous /etc/bunkerweb/api.yml
  4. Fichier env sous /etc/bunkerweb/api.env
  5. Valeurs par défaut intégrées

Runtime et fuseau horaire

Setting Description Valeurs acceptées Défaut
TZ Fuseau horaire pour les logs API et les claims basés sur le temps (ex. TTL Biscuit et horodatages de logs) Nom de la base TZ (ex. UTC, Europe/Paris) unset (défaut conteneur, généralement UTC)

DĂ©sactivez docs ou schĂ©ma en mettant leurs URLs Ă  off|disabled|none|false|0. Activez API_SSL_ENABLED=yes avec API_SSL_CERTFILE et API_SSL_KEYFILE pour terminer TLS dans l’API. En reverse proxy, fixez API_FORWARDED_ALLOW_IPS aux IPs du proxy pour que Gunicorn fasse confiance aux X-Forwarded-*.

Référence de configuration (power users)

Surface & docs

Setting Description Valeurs acceptées Défaut
API_DOCS_URL, API_REDOC_URL, API_OPENAPI_URL Chemins Swagger, ReDoc et schéma OpenAPI ; mettre off/disabled/none/false/0 pour désactiver Chemin ou off /docs, /redoc, /openapi.json
API_ROOT_PATH Préfixe de montage en reverse proxy Chemin (ex. /api) vide
API_FORWARDED_ALLOW_IPS IPs proxy de confiance pour X-Forwarded-* IPs/CIDR séparées par virgule 127.0.0.1,::1 (défaut paquet)
API_PROXY_ALLOW_IPS IPs proxy de confiance pour le protocole PROXY IPs/CIDR séparées par virgule FORWARDED_ALLOW_IPS

Auth, ACL, Biscuit

Setting Description Valeurs acceptées Défaut
API_USERNAME, API_PASSWORD Utilisateur admin initial ChaĂźnes ; mot de passe fort requis hors debug unset
OVERRIDE_API_CREDS Réappliquer les creds admin au démarrage yes/no/on/off/true/false/0/1 no
API_TOKEN Bearer d’override admin Chaüne opaque unset
API_ACL_BOOTSTRAP_FILE Chemin JSON pour utilisateurs/permissions Chemin ou /var/lib/bunkerweb/api_acl_bootstrap.json monté unset
BISCUIT_PRIVATE_KEY, BISCUIT_PUBLIC_KEY Clés Biscuit (hex) si pas de fichiers Chaßnes hex auto-générées/persistées
API_BISCUIT_TTL_SECONDS Durée de vie du token ; 0/off désactive Secondes entiÚres ou off/disabled 3600
CHECK_PRIVATE_IP Lier le Biscuit Ă  l’IP cliente (hors privĂ©es) yes/no/on/off/true/false/0/1 yes

Liste blanche

Setting Description Valeurs acceptées Défaut
API_WHITELIST_ENABLED Activer/dĂ©sactiver le middleware d’IP yes/no/on/off/true/false/0/1 yes
API_WHITELIST_IPS IPs/CIDR séparées par espace/virgule IPs/CIDR Plages RFC1918 en code

Limitation

Setting Description Valeurs acceptées Défaut
API_RATE_LIMIT Limite globale (chaĂźne style NGINX) 3r/s, 100/minute, 500 per 30 minutes 100r/m
API_RATE_LIMIT_AUTH Limite de /auth (ou off) idem ou off/disabled/none/false/0 10r/m
API_RATE_LIMIT_ENABLED Activer le limiteur yes/no/on/off/true/false/0/1 yes
API_RATE_LIMIT_HEADERS_ENABLED Injecter les headers de limite idem yes
API_RATE_LIMIT_RULES RĂšgles par chemin (CSV/JSON/YAML ou fichier) ChaĂźne ou chemin unset
API_RATE_LIMIT_STRATEGY Algorithme fixed-window, moving-window, sliding-window-counter fixed-window
API_RATE_LIMIT_KEY Sélectionneur de clé ip, header:<Name> ip
API_RATE_LIMIT_EXEMPT_IPS Exempter ces IPs/CIDR des limites Séparées par espace/virgule unset
API_RATE_LIMIT_STORAGE_OPTIONS JSON fusionné dans la config de stockage Chaßne JSON unset

Redis/Valkey (pour les limites)

Setting Description Valeurs acceptées Défaut
USE_REDIS Activer le backend Redis yes/no/on/off/true/false/0/1 no
REDIS_HOST, REDIS_PORT, REDIS_DATABASE Détails de connexion Host, int, int unset, 6379, 0
REDIS_USERNAME, REDIS_PASSWORD Auth ChaĂźnes unset
REDIS_SSL, REDIS_SSL_VERIFY TLS et vérification yes/no/on/off/true/false/0/1 no, yes
REDIS_TIMEOUT Timeout (ms) Entier 1000
REDIS_KEEPALIVE_POOL Keepalive du pool Entier 10
REDIS_SENTINEL_HOSTS HÎtes Sentinel host:port séparés par espace unset
REDIS_SENTINEL_MASTER Nom du master Sentinel ChaĂźne unset
REDIS_SENTINEL_USERNAME, REDIS_SENTINEL_PASSWORD Auth Sentinel ChaĂźnes unset

!!! info "Redis fourni par la BD" Si la configuration BunkerWeb en base contient Redis/Valkey, l’API la rĂ©utilise automatiquement pour le rate limiting mĂȘme sans USE_REDIS dans l’environnement. Surcharger via variables d’environnement si nĂ©cessaire.

Listener & TLS

Setting Description Valeurs acceptées Défaut
API_LISTEN_ADDR, API_LISTEN_PORT Adresse/port de bind pour Gunicorn IP ou hostname, int 127.0.0.1, 8888 (script paquet)
API_SSL_ENABLED Activer TLS dans l’API yes/no/on/off/true/false/0/1 no
API_SSL_CERTFILE, API_SSL_KEYFILE Certificat et clé PEM Chemins de fichier unset
API_SSL_CA_CERTS CA/chaĂźne optionnelle Chemin de fichier unset

Logging & runtime (défauts paquet)

Setting Description Valeurs acceptées Défaut
LOG_LEVEL, CUSTOM_LOG_LEVEL Niveau de base / override debug, info, warning, error, critical info
LOG_TYPES Destinations stderr/file/syslog séparés par espaces stderr
LOG_FILE_PATH Chemin du log (utilisé si LOG_TYPES contient file ou CAPTURE_OUTPUT=yes) Chemin de fichier /var/log/bunkerweb/api.log si file/capture, sinon unset
LOG_SYSLOG_ADDRESS Cible syslog (udp://host:514, tcp://host:514, socket) Host:port, host préfixé protocole ou socket unset
LOG_SYSLOG_TAG Tag syslog ChaĂźne bw-api
MAX_WORKERS, MAX_THREADS Workers/threads Gunicorn Entier ou unset pour auto unset
MAX_REQUESTS RequĂȘtes avant recyclage du worker Gunicorn (Ă©vite la fuite mĂ©moire) Entier 1000
CAPTURE_OUTPUT Rediriger stdout/stderr Gunicorn vers les handlers configurés yes ou no no

Surface API (carte des capacités)

  • Core
    • GET /ping, GET /health : vĂ©rifications de vivacitĂ© de l’API.
  • Auth
    • POST /auth : Ă©mettre des Biscuit ; accepte Basic, formulaire, JSON ou Bearer override si API_TOKEN correspond.
  • Instances
    • GET /instances : lister les instances avec metadata de crĂ©ation/derniĂšre vue.
    • POST /instances : enregistrer une instance (hostname/port/server_name/method).
    • GET/PATCH/DELETE /instances/{hostname} : inspecter, mettre Ă  jour les champs mutables ou supprimer les instances gĂ©rĂ©es par l’API.
    • DELETE /instances : suppression en masse des instances gĂ©rĂ©es par l’API ; celles hors API sont ignorĂ©es.
    • SantĂ©/actions : GET /instances/ping, GET /instances/{hostname}/ping, POST /instances/reload?test=yes|no, POST /instances/{hostname}/reload, POST /instances/stop, POST /instances/{hostname}/stop.
  • Global settings
    • GET /global_settings : par dĂ©faut uniquement les non-defaults ; ajoutez full=true pour tous les rĂ©glages, methods=true pour la provenance.
    • PATCH /global_settings : upsert des globals dĂ©tenus par l’API ; les clĂ©s read-only sont rejetĂ©es.
  • Services
    • GET /services : lister les services (brouillons inclus par dĂ©faut).
    • GET /services/{service} : rĂ©cupĂ©rer les non-defaults ou la config complĂšte (full=true) ; methods=true inclut la provenance.
    • POST /services : crĂ©er un service (draft ou online), dĂ©finir des variables et mettre Ă  jour SERVER_NAME de façon atomique.
    • PATCH /services/{service} : renommer, mettre Ă  jour les variables, basculer le draft.
    • DELETE /services/{service} : supprimer le service et les clĂ©s dĂ©rivĂ©es de config.
    • POST /services/{service}/convert?convert_to=online|draft : bascule rapide draft/online.
  • Custom configs
    • GET /configs : lister les snippets (service par dĂ©faut global) ; with_data=true intĂšgre le contenu imprimable.
    • POST /configs, POST /configs/upload : crĂ©er des snippets via JSON ou upload de fichier.
    • GET /configs/{service}/{type}/{name} : rĂ©cupĂ©rer un snippet ; with_data=true pour le contenu.
    • PATCH /configs/{service}/{type}/{name}, PATCH .../upload : mettre Ă  jour ou dĂ©placer les snippets gĂ©rĂ©s par l’API.
    • DELETE /configs ou DELETE /configs/{service}/{type}/{name} : supprimer les snippets gĂ©rĂ©s par l’API ; ceux gĂ©rĂ©s par template sont ignorĂ©s.
    • Types supportĂ©s : http, server_http, default_server_http, modsec, modsec_crs, stream, server_stream, hooks CRS/plugin.
  • Bans
    • GET /bans : agrĂ©ger les bans actifs depuis les instances.
    • POST /bans ou /bans/ban : appliquer un ou plusieurs bans ; le payload peut ĂȘtre objet, tableau ou JSON sĂ©rialisĂ©.
    • POST /bans/unban ou DELETE /bans : lever les bans globalement ou par service.
  • Plugins (UI)
    • GET /plugins : lister les plugins ; with_data=true inclut les bytes packagĂ©s quand dispo.
    • POST /plugins/upload : installer des plugins UI depuis .zip, .tar.gz, .tar.xz.
    • DELETE /plugins/{id} : supprimer un plugin par ID.
  • Cache (artefacts de jobs)
    • GET /cache : lister les fichiers de cache avec filtres (service, plugin, job_name) ; with_data=true intĂšgre le contenu imprimable.
    • GET /cache/{service}/{plugin}/{job}/{file} : rĂ©cupĂ©rer/tĂ©lĂ©charger un fichier de cache spĂ©cifique (download=true).
    • DELETE /cache ou DELETE /cache/{service}/{plugin}/{job}/{file} : supprimer des fichiers de cache et notifier le scheduler.
  • Jobs
    • GET /jobs : lister jobs, plannings et rĂ©sumĂ©s de cache.
    • POST /jobs/run : marquer des plugins comme modifiĂ©s pour dĂ©clencher les jobs associĂ©s.

Comportement opérationnel

  • RĂ©ponses d’erreur normalisĂ©es en {"status": "error", "message": "..."} avec les codes HTTP adĂ©quats.
  • Les Ă©critures sont persistĂ©es en base partagĂ©e ; les instances consomment les changements via sync scheduler ou aprĂšs un reload.
  • API_ROOT_PATH doit correspondre au chemin reverse proxy pour que /docs et les liens fonctionnent.
  • Le dĂ©marrage Ă©choue s’il n’existe aucun chemin d’auth (pas de clĂ©s Biscuit, pas d’admin, pas de API_TOKEN) ; les erreurs sont loggĂ©es dans /var/tmp/bunkerweb/api.error.