27 KiB
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_FILEpour dâautres utilisateurs/ACL ; conservez unAPI_TOKENuniquement pour le break-glass. - Masquage de chemin : en reverse proxy, choisissez un
API_ROOT_PATHpeu devinable et reflétez-le cÎté proxy. - Rate limiting : laissez activé sauf si une autre couche impose des limites équivalentes ;
/authest toujours limité. - TLS : terminez au proxy ou activez
API_SSL_ENABLED=yesavec 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 soitadmin(true), soit des permissions finesapi_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_keyet.api_biscuit_public_key, sauf si fournies viaBISCUIT_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Ăšrentwrite. - 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_executeglobal_settings_*:global_settings_read,global_settings_updateservices:service_read,service_create,service_update,service_delete,service_convert,service_exportconfigs:configs_read,config_read,config_create,config_update,config_deleteplugins:plugin_read,plugin_create,plugin_deletecache:cache_read,cache_deletebans:ban_read,ban_update,ban_delete,ban_createdjobs:job_read,job_run
resource_idest 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_FILEou un/var/lib/bunkerweb/api_acl_bootstrap.jsonmonté. 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_AUTHAPI_RATE_LIMIT_ENABLED,API_RATE_LIMIT_HEADERS_ENABLEDAPI_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=yesplus réglagesREDIS_*(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é
- Variables dâenvironnement (y compris
environment:Docker/Compose) - Secrets dans
/run/secrets/<VAR>(Docker) - YAML sous
/etc/bunkerweb/api.yml - Fichier env sous
/etc/bunkerweb/api.env - 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 siAPI_TOKENcorrespond.
- 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 ; ajoutezfull=truepour tous les rĂ©glages,methods=truepour 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=trueinclut la provenance.POST /services: créer un service (draft ou online), définir des variables et mettre à jourSERVER_NAMEde 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Ă©fautglobal) ;with_data=trueintĂš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=truepour le contenu.PATCH /configs/{service}/{type}/{name},PATCH .../upload: mettre Ă jour ou dĂ©placer les snippets gĂ©rĂ©s par lâAPI.DELETE /configsouDELETE /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 /bansou/bans/ban: appliquer un ou plusieurs bans ; le payload peut ĂȘtre objet, tableau ou JSON sĂ©rialisĂ©.POST /bans/unbanouDELETE /bans: lever les bans globalement ou par service.
- Plugins (UI)
GET /plugins: lister les plugins ;with_data=trueinclut 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=trueintÚ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 /cacheouDELETE /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_PATHdoit correspondre au chemin reverse proxy pour que/docset 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.