# Ansible managed # Stack BunkerWeb 1.6.17 : WAF + scheduler + UI + MariaDB + Redis # Mode split, applis sur 192.168.200.161 x-db-env: &db-env DATABASE_URI: "mariadb+pymysql://bunkerweb:CHANGEME@bw-db:3306/db" x-api-env: &api-env API_WHITELIST_IP: "127.0.0.0/8 10.20.30.0/24" services: bunkerweb: image: bunkerity/bunkerweb:1.6.17 container_name: bunkerweb restart: unless-stopped ports: - "80:8080/tcp" - "443:8443/tcp" - "443:8443/udp" # HTTP/3 (QUIC) labels: - "bunkerweb.INSTANCE=yes" environment: <<: [*db-env, *api-env] networks: - bw-universe - bw-services bw-scheduler: image: bunkerity/bunkerweb-scheduler:1.6.17 container_name: bw-scheduler restart: unless-stopped depends_on: - bunkerweb - bw-db - bw-redis volumes: - bw-storage:/data environment: <<: [*db-env, *api-env] BUNKERWEB_INSTANCES: "bunkerweb" SERVER_NAME: "www-bwpoc.vlab.bzh shop-bwpoc.vlab.bzh api-bwpoc.vlab.bzh bwui-bwpoc.vlab.bzh" # --- Réglages globaux --- MULTISITE: "yes" DISABLE_DEFAULT_SERVER: "yes" SERVE_FILES: "no" GENERATE_SELF_SIGNED_SSL: "yes" AUTO_LETS_ENCRYPT: "no" EMAIL_LETS_ENCRYPT: "" LETS_ENCRYPT_CHALLENGE: "http" USE_LETS_ENCRYPT_STAGING: "no" AUTO_REDIRECT_HTTP_TO_HTTPS: "yes" USE_REAL_IP: "yes" REAL_IP_FROM: "172.16.16.21" REAL_IP_HEADER: "X-Forwarded-For" REAL_IP_RECURSIVE: "yes" USE_MODSECURITY: "yes" USE_MODSECURITY_CRS: "yes" MODSECURITY_CRS_VERSION: "4" USE_BAD_BEHAVIOR: "yes" BAD_BEHAVIOR_THRESHOLD: "10" BAD_BEHAVIOR_COUNT_TIME: "1m" BAD_BEHAVIOR_BAN_TIME: "5m" USE_BLACKLIST: "yes" BLACKLIST_USER_AGENT: "PoC-EvilBot" USE_GZIP: "yes" USE_BROTLI: "yes" USE_REDIS: "yes" REDIS_HOST: "bw-redis" REDIS_PASSWORD: "CHANGEME" SEND_ANONYMOUS_REPORT: "no" # --- www-bwpoc.vlab.bzh --- www-bwpoc.vlab.bzh_USE_REVERSE_PROXY: "yes" www-bwpoc.vlab.bzh_REVERSE_PROXY_URL: "/" www-bwpoc.vlab.bzh_REVERSE_PROXY_HOST: "http://192.168.200.161:8081" www-bwpoc.vlab.bzh_SELF_SIGNED_SSL_SUBJ: "/CN=www-bwpoc.vlab.bzh/" www-bwpoc.vlab.bzh_USE_ANTIBOT: "javascript" www-bwpoc.vlab.bzh_LIMIT_REQ_RATE: "10r/s" # --- shop-bwpoc.vlab.bzh --- shop-bwpoc.vlab.bzh_USE_REVERSE_PROXY: "yes" shop-bwpoc.vlab.bzh_REVERSE_PROXY_URL: "/" shop-bwpoc.vlab.bzh_REVERSE_PROXY_HOST: "http://192.168.200.161:8082" shop-bwpoc.vlab.bzh_SELF_SIGNED_SSL_SUBJ: "/CN=shop-bwpoc.vlab.bzh/" shop-bwpoc.vlab.bzh_REVERSE_PROXY_WS: "yes" shop-bwpoc.vlab.bzh_LIMIT_REQ_RATE: "30r/s" shop-bwpoc.vlab.bzh_COOKIE_FLAGS: "* SameSite=Lax" # --- api-bwpoc.vlab.bzh --- api-bwpoc.vlab.bzh_USE_REVERSE_PROXY: "yes" api-bwpoc.vlab.bzh_REVERSE_PROXY_URL: "/" api-bwpoc.vlab.bzh_REVERSE_PROXY_HOST: "http://192.168.200.161:8083" api-bwpoc.vlab.bzh_SELF_SIGNED_SSL_SUBJ: "/CN=api-bwpoc.vlab.bzh/" api-bwpoc.vlab.bzh_ALLOWED_METHODS: "GET|POST|HEAD" api-bwpoc.vlab.bzh_MAX_CLIENT_SIZE: "1m" api-bwpoc.vlab.bzh_LIMIT_REQ_RATE: "5r/s" api-bwpoc.vlab.bzh_CUSTOM_CONF_MODSEC_poc-rule: "SecRule ARGS:poc \"@streq attack\" \"id:10001,phase:2,deny,status:403,log,msg:'PoC BunkerWeb : regle maison'\"" # --- bwui-bwpoc.vlab.bzh --- bwui-bwpoc.vlab.bzh_USE_REVERSE_PROXY: "yes" bwui-bwpoc.vlab.bzh_REVERSE_PROXY_URL: "/" bwui-bwpoc.vlab.bzh_REVERSE_PROXY_HOST: "http://bw-ui:7000" bwui-bwpoc.vlab.bzh_SELF_SIGNED_SSL_SUBJ: "/CN=bwui-bwpoc.vlab.bzh/" bwui-bwpoc.vlab.bzh_USE_TEMPLATE: "ui" # Accès réservé (poc_allowed_sources + client de test), challenge ACME toujours permis bwui-bwpoc.vlab.bzh_CUSTOM_CONF_MODSEC_poc-allowlist: "SecRule REMOTE_ADDR \"!@ipMatch 172.16.0.0/12,192.168.0.0/16,192.168.200.130\" \"id:10002,phase:1,deny,status:403,log,msg:'PoC BunkerWeb : source non autorisee',chain\"\nSecRule REQUEST_URI \"!@beginsWith /.well-known/acme-challenge/\" \"t:none\"" networks: - bw-universe - bw-db bw-ui: image: bunkerity/bunkerweb-ui:1.6.17 container_name: bw-ui restart: unless-stopped depends_on: - bw-db volumes: - bw-ui-data:/data # secrets Flask, clés TOTP et Biscuit environment: <<: *db-env ADMIN_USERNAME: "admin" ADMIN_PASSWORD: "CHANGEME" TZ: "Europe/Paris" networks: - bw-universe - bw-db bw-db: image: mariadb:11 container_name: bw-db restart: unless-stopped command: --max-allowed-packet=67108864 environment: MYSQL_RANDOM_ROOT_PASSWORD: "yes" MYSQL_DATABASE: "db" MYSQL_USER: "bunkerweb" MYSQL_PASSWORD: "CHANGEME" volumes: - bw-data:/var/lib/mysql networks: - bw-db bw-redis: image: redis:8-alpine container_name: bw-redis restart: unless-stopped command: ["redis-server", "--requirepass", "CHANGEME", "--save", "60", "1"] volumes: - bw-redis:/data networks: - bw-universe volumes: bw-data: bw-storage: bw-ui-data: bw-redis: networks: bw-universe: name: bw-universe ipam: driver: default config: - subnet: 10.20.30.0/24 # seul réseau autorisé à parler à l'API BunkerWeb bw-services: name: bw-services # réseau des applis (mode single), créé par Ansible external: true bw-db: name: bw-db