Muchos ejemplos de casos de uso del mundo real están disponibles en la carpeta examples del repositorio de GitHub.
También proporcionamos numerosos boilerplates, como archivos YAML para diversas integraciones y tipos de bases de datos. Estos están disponibles en la carpeta misc/integrations.
Esta sección solo se enfoca en usos avanzados y ajustes de seguridad, consulta la sección de características de la documentación para ver todas las configuraciones disponibles.
Pruebas
Para realizar pruebas rápidas cuando el modo multisitio está habilitado (y si no tienes las entradas DNS adecuadas configuradas para los dominios) puedes usar curl con la cabecera HTTP Host de tu elección:
Detrás de un balanceador de carga o proxy inverso¶
IP real
Cuando BunkerWeb está a su vez detrás de un balanceador de carga o un proxy inverso, necesitas configurarlo para que pueda obtener la dirección IP real de los clientes. Si no lo haces, las características de seguridad bloquearán la dirección IP del balanceador de carga o del proxy inverso en lugar de la del cliente.
BunkerWeb admite dos métodos para recuperar la dirección IP real del cliente:
Usando el protocolo PROXY
Usando una cabecera HTTP como X-Forwarded-For
Se pueden usar las siguientes configuraciones:
USE_REAL_IP: habilitar/deshabilitar la recuperación de la IP real
USE_PROXY_PROTOCOL: habilitar/deshabilitar el soporte del protocolo PROXY.
REAL_IP_FROM: lista de direcciones IP/red de confianza permitidas para enviarnos la "IP real"
REAL_IP_HEADER: la cabecera HTTP que contiene la IP real o el valor especial proxy_protocol cuando se usa el protocolo PROXY
Asumiremos lo siguiente con respecto a los balanceadores de carga o proxies inversos (necesitarás actualizar la configuración dependiendo de tu configuración):
Usan la cabecera X-Forwarded-For para establecer la IP real
Tienen IPs en las redes 1.2.3.0/24 y 100.64.0.0/10
Navega a la página de Configuración Global, selecciona el plugin Real IP y completa las siguientes configuraciones:
Configuración de IP real (cabecera) usando la interfaz de usuario web
Ten en cuenta que se recomienda reiniciar BunkerWeb cuando cambies la configuración relacionada con la IP real.
Necesitarás agregar la configuración al archivo /etc/bunkerweb/variables.env:
Ten en cuenta que si tu servicio ya está creado, necesitarás eliminarlo y recrearlo para que se actualicen las nuevas variables de entorno.
Lee con atención
Solo usa el protocolo PROXY si estás seguro de que tu balanceador de carga o proxy inverso lo está enviando. Si lo habilitas y no se está usando, obtendrás errores.
Asumiremos lo siguiente con respecto a los balanceadores de carga o proxies inversos (necesitarás actualizar la configuración dependiendo de tu configuración):
Usan el protocolo PROXY v1 o v2 para establecer la IP real
Tienen IPs en las redes 1.2.3.0/24 y 100.64.0.0/10
Navega a la página de Configuración Global, selecciona el plugin Real IP y completa las siguientes configuraciones:
Configuración de IP real (protocolo PROXY) usando la interfaz de usuario web
Ten en cuenta que se recomienda reiniciar BunkerWeb cuando cambies la configuración relacionada con la IP real.
Necesitarás agregar la configuración al archivo /etc/bunkerweb/variables.env:
Para que tus aplicaciones sigan disponibles incluso si un servidor falla, puedes desplegar BunkerWeb en un clúster de Alta Disponibilidad (HA). Esta arquitectura incluye un Manager (Scheduler) que orquesta la configuración y varios Workers (instancias BunkerWeb) que manejan el tráfico.
Una API interna que conecta automáticamente managers y workers para la orquestación. Siempre está habilitada y no requiere configuración manual.
Un servicio API opcional (bunkerweb-api) que expone una interfaz REST pública para herramientas de automatización (bwcli, CI/CD, etc.). Está deshabilitada por defecto en instalaciones Linux y es independiente de las comunicaciones internas manager↔worker.
El Manager es el cerebro del clúster. Ejecuta el Scheduler, la base de datos y, opcionalmente, la interfaz web.
Seguridad de la interfaz web
La interfaz web escucha en un puerto dedicado (7000 por defecto) y solo debería ser accesible por administradores. Si piensas exponerla a internet, recomendamos encarecidamente protegerla con una instancia de BunkerWeb delante.
Descarga y ejecuta el instalador en el host del manager:
Comprueba siempre la integridad del script con el checksum proporcionado antes de ejecutarlo.
Selecciona Manager en el menú de tipo de instalación (usa ↑/↓ y luego Enter), y sigue las indicaciones:
Pregunta
Acción
Instancias BunkerWeb
Introduce las IP de tus nodos worker separadas por espacios (ej.: 192.168.10.11 192.168.10.12).
Whitelist IP
Acepta la IP detectada o introduce un subnet (ej.: 192.168.10.0/24) para permitir el acceso a la API.
Resolutores DNS
Elige No para mantener los valores predeterminados, o indica los tuyos.
HTTPS para la API interna
Recomendado: elige Sí para generar certificados y asegurar la comunicación manager-worker.
Servicio Web UI
Elige Sí para activar la interfaz web (muy recomendado).
Servicio API
Elige No salvo que necesites la API REST pública para herramientas externas.
Interfaz de indicaciones
El instalador usa la TUI gum. En la primera ejecución interactiva descarga el binario gum oficial desde la release de GitHub (SHA256 fijado), lo ejecuta desde un directorio temporal y elimina ese directorio al salir — no se instala ningún paquete del sistema. Usa las flechas + Enter para responder. Pasa --no-tui si prefieres indicaciones de texto plano.
Sustituye admin y changeme por credenciales robustas antes de arrancar el servicio UI en producción.
Reinicia la UI:
sudosystemctlrestartbunkerweb-ui
Para más aislamiento, instala la UI en un nodo independiente.
Ejecuta el instalador y selecciona el tipo de instalación Web UI Only.
Edita /etc/bunkerweb/ui.env para apuntar a la base de datos del Manager:
# Configuración de base de datos (debe coincidir con la del Manager)DATABASE_URI=mariadb+pymysql://bunkerweb:changeme@db-host:3306/bunkerweb# Para PostgreSQL: postgresql://bunkerweb:changeme@db-host:5432/bunkerweb# Para MySQL: mysql+pymysql://bunkerweb:changeme@db-host:3306/bunkerweb# Configuración de Redis (si usas Redis/Valkey para persistencia)# Si no se proporciona, se toma automáticamente de la base de datos# REDIS_HOST=redis-host# Credenciales de seguridadADMIN_USERNAME=adminADMIN_PASSWORD=changeme# Ajustes de redLISTEN_ADDR=0.0.0.0# LISTEN_PORT=7000
Reinicia el servicio:
sudosystemctlrestartbunkerweb-ui
Configuración de firewall
Asegúrate de que el host de la UI pueda llegar a los puertos de base de datos y Redis. Puede que debas ajustar las reglas de firewall tanto en el host de la UI como en los hosts de la base/Redis.
Crea un archivo docker-compose.yml en el host del manager:
docker-compose.yml
x-ui-env:&bw-ui-env# Anclamos las variables de entorno para evitar duplicacionesDATABASE_URI:\"mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db\"# Usa una contraseña más fuerteservices:bw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1environment:<<:*bw-ui-envBUNKERWEB_INSTANCES:\"192.168.1.11 192.168.1.12\"# Sustituye por las IP de tus workersAPI_WHITELIST_IP:\"127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16\"# Permitir redes locales# API_LISTEN_HTTPS: \"yes\" # Recomendado para asegurar la API interna# API_TOKEN: \"my_secure_token\" # Opcional: token adicionalSERVER_NAME:\"\"MULTISITE:\"yes\"USE_REDIS:\"yes\"REDIS_HOST:\"redis\"volumes:-bw-storage:/data# Persistencia del caché y backupsrestart:\"unless-stopped\"networks:-bw-db-bw-redisbw-ui:image:bunkerity/bunkerweb-ui:1.6.18-rc1ports:-\"7000:7000\"# Exponer el puerto de la UIenvironment:<<:*bw-ui-envADMIN_USERNAME:\"changeme\"ADMIN_PASSWORD:\"changeme\"# Usa una contraseña más fuerte# TOTP_ENCRYPTION_KEYS: \"changeme\" # Opcional: se genera en el volumen bw-ui-data si no se define; una clave tiene 43 caracteresvolumes:-bw-ui-data:/data# Se usa para conservar los secretos de la interfaz web (secreto Flask, claves de cifrado TOTP, claves Biscuit)restart:\"unless-stopped\"networks:-bw-db-bw-redisbw-db:image:mariadb:11# Establecemos el tamaño máximo de paquete para evitar problemas con consultas grandescommand:--max-allowed-packet=67108864environment:MYSQL_RANDOM_ROOT_PASSWORD:\"yes\"MYSQL_DATABASE:\"db\"MYSQL_USER:\"bunkerweb\"MYSQL_PASSWORD:\"changeme\"# Usa una contraseña más fuertevolumes:-bw-data:/var/lib/mysqlrestart:\"unless-stopped\"networks:-bw-dbredis:# Redis para la persistencia de informes/prohibiciones/estadísticasimage:redis:8-alpinecommand:>redis-server--maxmemory 256mb--maxmemory-policy volatile-lru--save 60 1000--appendonly yesvolumes:-redis-data:/datarestart:\"unless-stopped\"networks:-bw-redisvolumes:bw-data:bw-storage:redis-data:bw-ui-data:networks:bw-db:name:bw-dbbw-redis:name:bw-redis
Los workers son los nodos que procesan el tráfico entrante.
Ejecuta el instalador en cada nodo worker (mismos comandos que para el Manager).
Selecciona la opción 3) Worker y configura:
Pregunta
Acción
IP del Manager
Introduce la IP de tu Manager (ej.: 192.168.10.10).
HTTPS para la API interna
Debe coincidir con el ajuste del Manager (Y o N).
El worker se registrará automáticamente en el Manager.
Crea un archivo docker-compose.yml en cada worker:
docker-compose.yml
services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1ports:-\"80:8080/tcp\"-\"443:8443/tcp\"-\"443:8443/udp\"# Compatibilidad QUIC / HTTP3-\"5000:5000/tcp\"# Puerto de la API internaenvironment: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\" # Recomendado para asegurar la API interna (debe coincidir con el Manager)# API_TOKEN: \"my_secure_token\" # Opcional: token adicional (debe coincidir con el Manager)restart:\"unless-stopped\"
=== \"Linux\"
1. **Edita** `/etc/bunkerweb/variables.env` en el Manager:
```bash
BUNKERWEB_INSTANCES=192.168.10.11 192.168.10.12 192.168.10.13
```
2. **Reinicia el Scheduler**:
```bash
sudo systemctl restart bunkerweb-scheduler
```
=== \"Docker\"
1. **Edita** el archivo `docker-compose.yml` en el Manager para actualizar `BUNKERWEB_INSTANCES`.
2. **Recrea el contenedor del Scheduler**:
```bash
docker compose up -d bw-scheduler
```
Para repartir el tráfico entre tus workers, utiliza un Load Balancer. Recomendamos uno de capa 4 (TCP) que soporte PROXY protocol para preservar la IP del cliente.
Ejemplo de configuración HAProxy que pasa el tráfico (modo TCP) manteniendo la IP cliente mediante PROXY protocol.
Revisa /var/log/bunkerweb/access.log en cada worker para confirmar que las solicitudes llegan desde la red del PROXY protocol y que los dos workers comparten la carga. Tu clúster BunkerWeb ya está listo para proteger cargas de producción con alta disponibilidad.
6. IP flotante con keepalived (sin Load Balancer)¶
Si no tienes un Load Balancer, puedes ejecutar los workers en modo activo/pasivo con keepalived. Una IP virtual (VIP) se desplaza entre los workers mediante VRRP, el DNS apunta a la VIP y solo el worker que la posee atiende el tráfico. Es una alternativa a la sección 5: el tráfico no se reparte entre los workers, pero un worker que falla es sustituido en unos segundos.
Los ejemplos usan la VIP 192.168.10.100, worker01 (192.168.10.11, master) y worker02 (192.168.10.12, backup).
El script de comprobación de salud de BunkerWeb, llamado con el argumento ok, sale con código 0 cuando la instancia responde ok en http://127.0.0.1:6000/healthz. ok significa que NGINX está en ejecución y la instancia ha recibido su configuración, incluso mientras aplica una nueva y sigue sirviendo la anterior (desde la versión 1.6.16). El script sale con código 1 mientras la instancia siga en estado loading o NGINX esté detenido. Si se llama sin argumentos, el script también acepta loading; no uses esa forma aquí, porque un worker recién iniciado tomaría la VIP y mostraría la página «Generating...».
Configura keepalived. Crea /etc/keepalived/keepalived.conf en cada worker. Ajusta interface a la interfaz de red (consulta ip addr) y usa los mismos valores de virtual_router_id y auth_pass en ambos workers. En la pestaña Docker, sustituye la línea script por el comando docker compose anterior (keepalived avisa si el binario no se indica con su ruta completa).
La comprobación no tiene weight, así que dos fallos consecutivos (unos 4 segundos) ponen el nodo en estado FAULT y liberan la VIP. script_user root es necesario para ejecutar docker compose exec. enable_script_security acepta el script porque otros usuarios no pueden modificar los archivos de BunkerWeb. La contraseña auth_pass de VRRP se transmite en texto claro y solo protege frente a errores de configuración; mantén los workers en una red de confianza.
BunkerWeb 1.6.15
En la versión 1.6.15, /healthz responde loading en todos los workers durante unos 5 segundos con cada recarga. Usa fall 4 y interval 2 en lugar de fall 2 para que una recarga no ponga ambos workers en estado FAULT.
Inicia keepalived en ambos workers:
sudosystemctlenable--nowkeepalived
Cortafuegos
VRRP usa el protocolo IP 112 (no es un puerto TCP ni UDP). Permítelo entre los workers, junto con los puertos 80 y 443 hacia los clientes.
IP real
Los clientes se conectan directamente a la VIP, por lo que no hace falta configurar PROXY protocol ni X-Forwarded-For. BunkerWeb ve la IP real del cliente de forma predeterminada.
Verifica la conmutación por error:
En worker01, ejecuta ip addr show eth0. Debe aparecer la VIP 192.168.10.100.
Detén BunkerWeb en worker01: sudo systemctl stop bunkerweb (Linux) o docker compose stop bunkerweb (Docker).
Tras unos segundos, la VIP desaparece de worker01 y aparece en worker02. En nuestras pruebas, los clientes recuperaron el servicio en unos 4 segundos al detener el contenedor y en unos 7 segundos cuando solo falló la comprobación de salud.
Inicia BunkerWeb de nuevo. worker01 solo recupera la VIP cuando la comprobación pasa, por lo que nunca atiende tráfico mientras está cargando.
Sigue los cambios de estado con sudo journalctl -u keepalived -f.
Sidecar de Docker. Si keepalived se ejecuta en un contenedor con network_mode: "service:bunkerweb", pierde su interfaz de red cuando se reinicia el contenedor de BunkerWeb y no vuelve a obtener la VIP. Añadir depends_on: { bunkerweb: { condition: service_started, restart: true } } al servicio keepalived solo cubre los reinicios hechos mediante Compose (docker compose restart o up). No cubre un reinicio automático por la política de reinicio de Docker (fallo, falta de memoria) ni un docker restart normal. En esos casos, reinicia juntos los contenedores de keepalived y BunkerWeb, o ejecuta keepalived en el host como en la pestaña Docker anterior.
Manager no disponible. Los workers que ya tienen su configuración siguen respondiendo ok y conservan la VIP. Un worker que se reinicia mientras el manager está caído permanece en estado loading y no obtiene la VIP. Si ambos se reinician, ningún worker puede asumirla y el servicio queda inactivo hasta que vuelva el manager.
Configuración. El manager envía la configuración a ambos workers sin importar el estado de la VIP, así que el worker de reserva ya tiene los últimos ajustes cuando toma el relevo.
Estado compartido. Los bloqueos, los contadores y las sesiones residen en cada worker. Un cliente bloqueado en worker01 no queda bloqueado en worker02 tras un fallo. Activa Redis (USE_REDIS=yes, consulta los ajustes de Redis/Valkey) y usa la misma instancia Redis en ambos workers para compartir bloqueos y contadores. Redis por sí solo no mantiene las sesiones válidas entre workers: SESSIONS_SECRET y SESSIONS_NAME tienen el valor random de forma predeterminada y se generan por instancia. Define valores fijos e idénticos para ambos en el manager (son ajustes globales que se envían a los dos workers).
Let's Encrypt. El token del desafío HTTP se envía a todas las instancias registradas en el manager, por lo que ambos workers pueden responder.
Usando mecanismos de resolución DNS personalizados¶
La configuración de NGINX de BunkerWeb se puede personalizar para usar diferentes resolutores de DNS según tus necesidades. Esto puede ser particularmente útil en varios escenarios:
Para respetar las entradas en tu archivo local /etc/hosts
Cuando necesitas usar servidores DNS personalizados para ciertos dominios
Para integrarse con soluciones locales de caché de DNS
Muchos sistemas Linux modernos usan systemd-resolved para la resolución de DNS. Si quieres que BunkerWeb respete el contenido de tu archivo /etc/hosts y use el mecanismo de resolución de DNS del sistema, puedes configurarlo para que use el servicio DNS local de systemd-resolved.
Para verificar que systemd-resolved se está ejecutando en tu sistema, puedes usar:
systemctlstatussystemd-resolved
Para habilitar systemd-resolved como tu resolutor de DNS en BunkerWeb, establece la configuración DNS_RESOLVERS a 127.0.0.53, que es la dirección de escucha predeterminada para systemd-resolved:
Navega a la página de Configuración Global y establece los resolutores de DNS en 127.0.0.53
Configuración de resolutores de DNS usando la interfaz de usuario web
Necesitarás modificar el archivo /etc/bunkerweb/variables.env:
...
DNS_RESOLVERS=127.0.0.53
...
Después de hacer este cambio, recarga el Programador para aplicar la configuración:
dnsmasq es un servidor ligero de DNS, DHCP y TFTP que se usa comúnmente para el almacenamiento en caché y la personalización de DNS local. Es particularmente útil cuando necesitas más control sobre tu resolución de DNS del que proporciona systemd-resolved.
Primero, instala y configura dnsmasq en tu sistema Linux:
# Instalar dnsmasq
sudoapt-getupdate&&sudoapt-getinstalldnsmasq
# Configurar dnsmasq para escuchar solo en localhostecho"listen-address=127.0.0.1"|sudotee-a/etc/dnsmasq.conf
echo"bind-interfaces"|sudotee-a/etc/dnsmasq.conf
# Agregar entradas DNS personalizadas si es necesarioecho"address=/custom.example.com/192.168.1.10"|sudotee-a/etc/dnsmasq.conf
# Reiniciar dnsmasq
sudosystemctlrestartdnsmasq
sudosystemctlenablednsmasq
# Instalar dnsmasq
sudodnfinstalldnsmasq
# Configurar dnsmasq para escuchar solo en localhostecho"listen-address=127.0.0.1"|sudotee-a/etc/dnsmasq.conf
echo"bind-interfaces"|sudotee-a/etc/dnsmasq.conf
# Agregar entradas DNS personalizadas si es necesarioecho"address=/custom.example.com/192.168.1.10"|sudotee-a/etc/dnsmasq.conf
# Reiniciar dnsmasq
sudosystemctlrestartdnsmasq
sudosystemctlenablednsmasq
Luego configura BunkerWeb para que use dnsmasq estableciendo DNS_RESOLVERS en 127.0.0.1:
Navega a la página de Configuración Global, selecciona el plugin NGINX y establece los resolutores de DNS en 127.0.0.1.
Configuración de resolutores de DNS usando la interfaz de usuario web
Necesitarás modificar el archivo /etc/bunkerweb/variables.env:
...
DNS_RESOLVERS=127.0.0.1
...
Después de hacer este cambio, recarga el Programador:
sudosystemctlreloadbunkerweb-scheduler
Cuando uses el contenedor Todo en uno, ejecuta dnsmasq en un contenedor separado y configura BunkerWeb para usarlo:
# Crear una red personalizada para la comunicación DNS
dockernetworkcreatebw-dns
# Ejecutar el contenedor dnsmasq usando dockurr/dnsmasq con Quad9 DNS# Quad9 proporciona resolución de DNS centrada en la seguridad con bloqueo de malware
dockerrun-d\--namednsmasq\--networkbw-dns\-eDNS1="9.9.9.9"\-eDNS2="149.112.112.112"\-p53:53/udp\-p53:53/tcp\--cap-add=NET_ADMIN\--restart=always\dockurr/dnsmasq
# Ejecutar BunkerWeb Todo en uno con el resolutor de DNS dnsmasq
dockerrun-d\--namebunkerweb-aio\--networkbw-dns\-vbw-storage:/data\-eDNS_RESOLVERS="dnsmasq"\-p80:8080/tcp\-p443:8443/tcp\-p443:8443/udp\bunkerity/bunkerweb-all-in-one:1.6.18-rc1
Agrega un servicio dnsmasq a tu archivo docker-compose y configura BunkerWeb para usarlo:
services:dnsmasq:image:dockurr/dnsmasqcontainer_name:dnsmasqenvironment:# Usando los servidores DNS de Quad9 para mayor seguridad y privacidad# Primario: 9.9.9.9 (Quad9 con bloqueo de malware)# Secundario: 149.112.112.112 (Servidor de respaldo de Quad9)DNS1:"9.9.9.9"DNS2:"149.112.112.112"ports:-53:53/udp-53:53/tcpcap_add:-NET_ADMINrestart:alwaysnetworks:-bw-dnsbunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1...environment:DNS_RESOLVERS:"dnsmasq"...networks:-bw-universe-bw-services-bw-dnsbw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1...environment:DNS_RESOLVERS:"dnsmasq"...networks:-bw-universe-bw-dnsnetworks:# ...redes existentes...bw-dns:name:bw-dns
Para personalizar y añadir configuraciones personalizadas a BunkerWeb, puedes aprovechar su base NGINX. Las configuraciones personalizadas de NGINX se pueden añadir en diferentes contextos de NGINX, incluidas las configuraciones para el Firewall de Aplicaciones Web (WAF) ModSecurity, que es un componente central de BunkerWeb. Se pueden encontrar más detalles sobre las configuraciones de ModSecurity aquí.
Estos son los tipos de configuraciones personalizadas disponibles:
http: Configuraciones a nivel HTTP de NGINX.
server-http: Configuraciones a nivel HTTP/Servidor de NGINX.
default-server-http: Configuraciones a nivel de Servidor de NGINX, específicamente para el "servidor predeterminado" cuando el nombre del cliente proporcionado no coincide con ningún nombre de servidor en SERVER_NAME.
modsec-crs: Configuraciones aplicadas antes de que se cargue el Core Rule Set de OWASP.
modsec: Configuraciones aplicadas después de que se cargue el Core Rule Set de OWASP, o se utilizan cuando el Core Rule Set no está cargado.
crs-plugins-before: Configuraciones para los plugins CRS, aplicadas antes de que se carguen los plugins CRS.
crs-plugins-after: Configuraciones para los plugins CRS, aplicadas después de que se carguen los plugins CRS.
stream: Configuraciones a nivel de Stream de NGINX.
server-stream: Configuraciones a nivel de Stream/Servidor de NGINX.
Las configuraciones personalizadas se pueden aplicar globalmente o específicamente para un servidor en particular, dependiendo del contexto aplicable y de si el modo multisitio está habilitado.
El método para aplicar configuraciones personalizadas depende de la integración que se esté utilizando. Sin embargo, el proceso subyacente implica añadir archivos con el sufijo .conf a carpetas específicas. Para aplicar una configuración personalizada para un servidor específico, el archivo debe colocarse en una subcarpeta con el nombre del servidor principal.
Algunas integraciones proporcionan formas más convenientes de aplicar configuraciones, como el uso de Configs en Docker Swarm o ConfigMap en Kubernetes. Estas opciones ofrecen enfoques más sencillos para gestionar y aplicar configuraciones.
Navega a la página de Configuraciones, haz clic en Crear nueva configuración personalizada, luego puedes elegir si es global o específica para un servicio, el tipo de configuración y el nombre de la configuración:
Configuraciones personalizadas usando la interfaz de usuario web
No olvides hacer clic en el botón 💾 Guardar.
Cuando se utiliza la integración de Linux, las configuraciones personalizadas deben escribirse en la carpeta /etc/bunkerweb/configs.
Aquí hay un ejemplo para server-http/hello-world.conf:
Una recarga vuelve a leer /etc/bunkerweb/configs: los archivos creados, modificados o eliminados allí se aplican y se guardan en la base de datos. Una configuración que pertenece a la interfaz web o a la API conserva su propietario, solo su contenido se actualiza desde el archivo.
Cuando se utiliza la imagen Todo en uno, tienes dos opciones para añadir configuraciones personalizadas:
Usar configuraciones específicas *_CUSTOM_CONF_* como variables de entorno al ejecutar el contenedor (recomendado).
Escribir archivos .conf en el directorio /data/configs/ dentro del volumen montado en /data.
Usando configuraciones (Variables de Entorno)
Las configuraciones a usar deben seguir el patrón <SITE>_CUSTOM_CONF_<TYPE>_<NAME>:
<SITE> : Nombre del servidor principal opcional si el modo multisitio está habilitado y la configuración debe aplicarse a un servicio específico.
<TYPE> : El tipo de configuración, los valores aceptados son HTTP, DEFAULT_SERVER_HTTP, SERVER_HTTP, MODSEC, MODSEC_CRS, CRS_PLUGINS_BEFORE, CRS_PLUGINS_AFTER, STREAM y SERVER_STREAM.
<NAME> : El nombre de la configuración sin el sufijo .conf.
Aquí hay un ejemplo de prueba al ejecutar el contenedor Todo en uno:
Cuando se utiliza la integración de Docker, tienes dos opciones para añadir configuraciones personalizadas:
Usar configuraciones específicas *_CUSTOM_CONF_* como variables de entorno (recomendado)
Escribir archivos .conf en el volumen montado en /data del programador
Usando configuraciones
Las configuraciones a usar deben seguir el patrón <SITE>_CUSTOM_CONF_<TYPE>_<NAME>:
<SITE>: nombre del servidor principal opcional si el modo multisitio está habilitado y la configuración debe aplicarse a un servicio específico
<TYPE>: el tipo de configuración, los valores aceptados son HTTP, DEFAULT_SERVER_HTTP, SERVER_HTTP, MODSEC, MODSEC_CRS, CRS_PLUGINS_BEFORE, CRS_PLUGINS_AFTER, STREAM y SERVER_STREAM
<NAME>: el nombre de la configuración sin el sufijo .conf
Aquí hay un ejemplo de prueba usando un archivo docker-compose:
Usar configuraciones específicas *_CUSTOM_CONF_* como etiquetas (más fácil)
Escribir archivos .conf en el volumen montado en /data del programador
Usando etiquetas
Limitaciones al usar etiquetas
Cuando usas etiquetas con la integración de autoconfiguración de Docker, solo puedes aplicar configuraciones personalizadas para el servicio web correspondiente. No es posible aplicar configuraciones http, default-server-http, stream o cualquier ajuste global (como server-http o server-stream para todos los servicios): necesitarás montar archivos para ese propósito.
Las etiquetas a usar deben seguir el patrón bunkerweb.CUSTOM_CONF_<TYPE>_<NAME>:
<TYPE>: el tipo de configuración, los valores aceptados son SERVER_HTTP, MODSEC, MODSEC_CRS, CRS_PLUGINS_BEFORE, CRS_PLUGINS_AFTER y SERVER_STREAM
<NAME>: el nombre de la configuración sin el sufijo .conf
Aquí hay un ejemplo de prueba usando un archivo docker-compose:
No es necesario montar la ConfigMap en un Pod (por ejemplo, como variable de entorno o volumen).
El pod de autoconfiguración escucha los eventos de ConfigMap y aplica los cambios en cuanto se detectan.
Anota cada ConfigMap que deba gestionar el controlador de Ingress:
bunkerweb.io/CONFIG_TYPE: obligatorio. Elige uno de los tipos compatibles (http, server-http, default-server-http, modsec,
modsec-crs, crs-plugins-before, crs-plugins-after, stream, server-stream o settings).
bunkerweb.io/CONFIG_SITE: opcional. Establece el nombre del servidor principal (tal como se publica a través del Ingress)
para limitar la configuración a ese servicio; déjalo vacío para aplicarla globalmente.
El controlador de Ingress vigila continuamente las ConfigMap anotadas.
Si la variable de entorno NAMESPACES está definida, solo se tienen en cuenta las ConfigMap de esos espacios de nombres.
Crear o actualizar una ConfigMap gestionada provoca la recarga inmediata de la configuración.
Eliminar la ConfigMap, o quitar la anotación bunkerweb.io/CONFIG_TYPE, elimina la configuración personalizada asociada.
Si defines bunkerweb.io/CONFIG_SITE, el servicio referenciado debe existir previamente;
de lo contrario, la ConfigMap se ignora hasta que aparezca el servicio.
Configuración extra personalizada
Desde la versión 1.6.0, puedes añadir o sobrescribir parámetros anotando una ConfigMap con bunkerweb.io/CONFIG_TYPE=settings.
El controlador de Ingress de autoconf lee cada entrada de data y la aplica como si fuera una variable de entorno:
Sin bunkerweb.io/CONFIG_SITE, todas las claves se aplican globalmente.
Cuando bunkerweb.io/CONFIG_SITE está definido, el controlador añade automáticamente el prefijo <nombre-del-servidor>_ (cada / se sustituye por _) a las claves que aún no están acotadas. Añade el prefijo manualmente si necesitas mezclar claves globales y específicas en la misma ConfigMap.
Los nombres o valores no válidos se omiten y el controlador autoconf registra una advertencia.
Aquí hay un ejemplo:
apiVersion:v1kind:ConfigMapmetadata:name:cfg-bunkerweb-extra-settingsannotations:bunkerweb.io/CONFIG_TYPE:"settings"data:USE_ANTIBOT:"captcha"# configuración multisitio que se aplicará a todos los servicios que no la sobrescribanUSE_REDIS:"yes"# ajuste global que se aplicará globalmente...
Obsoleto
La integración de Swarm está obsoleta y se eliminará en una futura versión. Por favor, considera usar la integración de Kubernetes en su lugar.
Para mantenerlo simple, ni siquiera necesitas adjuntar la Configuración a un servicio: el servicio de autoconfiguración está escuchando los eventos de Configuración y actualizará las configuraciones personalizadas cuando sea necesario.
Al crear una Configuración, necesitarás añadir etiquetas especiales:
bunkerweb.CONFIG_TYPE: debe establecerse a un tipo de configuración personalizada válido (http, server-http, default-server-http, modsec, modsec-crs, crs-plugins-before, crs-plugins-after, stream, server-stream o settings)
bunkerweb.CONFIG_SITE: establece un nombre de servidor para aplicar la configuración a ese servidor específico (opcional, se aplicará globalmente si no se establece)
Cuando el CRS se carga globalmente, los plugins CRS no son compatibles. Si necesitas usarlos, tendrás que cargar el CRS por servicio.
Si usas BunkerWeb en producción con un gran número de servicios y habilitas la característica de ModSecurity globalmente con las reglas CRS, el tiempo requerido para cargar las configuraciones de BunkerWeb puede volverse demasiado largo, resultando potencialmente en un tiempo de espera agotado.
La solución es cargar las reglas CRS globalmente en lugar de por servicio. Este comportamiento no está habilitado por defecto por razones de compatibilidad con versiones anteriores y porque tiene un inconveniente: si habilitas la carga global de reglas CRS, ya no será posible definir reglas modsec-crs (ejecutadas antes de las reglas CRS) por servicio. Sin embargo, esta limitación puede ser superada escribiendo reglas de exclusión globales modsec-crs como esta:
Parece que el valor predeterminado para el parámetro max_allowed_packet en los servidores de bases de datos MariaDB y MySQL no es suficiente cuando se utiliza BunkerWeb con un gran número de servicios.
Si encuentras errores como este, especialmente en el programador:
[Warning] Aborted connection 5 to db: 'db' user: 'bunkerweb' host: '172.20.0.4' (Got a packet bigger than 'max_allowed_packet' bytes)
Necesitarás aumentar el max_allowed_packet en tu servidor de base de datos.
El valor recomendado es 67108864 bytes (64 MiB). Cuando la base de datos se ejecuta en un contenedor, configúralo mediante la directiva command::
Para una base de datos instalada localmente o externa, añade en su lugar el parámetro a la configuración del servidor (por ejemplo, un archivo dedicado en /etc/mysql/mariadb.conf.d/ o /etc/my.cnf.d/):
Por defecto, BunkerWeb almacena los bloqueos e informes en un almacén de datos Lua local. Aunque es simple y eficiente, esta configuración significa que los datos se pierden cuando se reinicia la instancia. Para asegurar que los bloqueos e informes persistan a través de los reinicios, puedes configurar BunkerWeb para que utilice un servidor remoto Redis o Valkey.
¿Por qué usar Redis/Valkey?
Redis y Valkey son potentes almacenes de datos en memoria comúnmente utilizados como bases de datos, cachés y agentes de mensajes. Son altamente escalables y soportan una variedad de estructuras de datos, incluyendo:
Strings: Pares básicos de clave-valor.
Hashes: Pares de campo-valor dentro de una sola clave.
Lists: Colecciones ordenadas de cadenas.
Sets: Colecciones no ordenadas de cadenas únicas.
Sorted Sets: Colecciones ordenadas con puntuaciones.
Al aprovechar Redis o Valkey, BunkerWeb puede almacenar persistentemente bloqueos, informes y datos de caché, asegurando durabilidad y escalabilidad.
Habilitando el soporte de Redis/Valkey
Para habilitar el soporte de Redis o Valkey, configura los siguientes ajustes en tu archivo de configuración de BunkerWeb:
# Habilitar el soporte de Redis/Valkey
USE_REDIS=yes
# Nombre de host o dirección IP del servidor Redis/Valkey
REDIS_HOST=<hostname>
# Número de puerto del servidor Redis/Valkey (predeterminado: 6379)
REDIS_PORT=6379
# Número de base de datos de Redis/Valkey (predeterminado: 0)
REDIS_DATABASE=0
USE_REDIS: Establécelo en yes para habilitar la integración con Redis/Valkey.
REDIS_HOST: Especifica el nombre de host o la dirección IP del servidor Redis/Valkey.
REDIS_PORT: Especifica el número de puerto para el servidor Redis/Valkey. El valor predeterminado es 6379.
REDIS_DATABASE: Especifica el número de la base de datos de Redis/Valkey a utilizar. El valor predeterminado es 0.
Esta característica no está lista para producción. Siéntete libre de probarla y reportarnos cualquier error usando los issues en el repositorio de GitHub.
BunkerWeb ofrece la capacidad de funcionar como un proxy inverso genérico UDP/TCP, permitiéndote proteger cualquier aplicación basada en red que opere al menos en la capa 4 del modelo OSI. En lugar de utilizar el módulo HTTP "clásico", BunkerWeb aprovecha el módulo stream de NGINX.
Es importante tener en cuenta que no todas las configuraciones y características de seguridad están disponibles cuando se utiliza el módulo stream. Puedes encontrar información adicional sobre esto en las secciones de características de la documentación.
Configurar un proxy inverso básico es bastante similar a la configuración HTTP, ya que implica usar las mismas configuraciones: USE_REVERSE_PROXY=yes y REVERSE_PROXY_HOST=myapp:9000. Incluso cuando BunkerWeb está posicionado detrás de un Balanceador de Carga, las configuraciones siguen siendo las mismas (siendo el protocolo PROXY la opción soportada por razones evidentes).
Además de eso, se utilizan las siguientes configuraciones específicas:
SERVER_TYPE=stream: activa el modo stream (UDP/TCP genérico) en lugar del http (que es el predeterminado)
LISTEN_STREAM_PORT=4242: el puerto de escucha "plano" (sin SSL/TLS) en el que BunkerWeb escuchará
LISTEN_STREAM_PORT_SSL=4343: el puerto de escucha "ssl/tls" en el que BunkerWeb escuchará
USE_UDP=no: escucha y reenvía paquetes UDP en lugar de TCP
Para obtener una lista completa de las configuraciones relacionadas con el modo stream, consulta la sección de características de la documentación.
múltiples puertos de escucha
Desde la versión 1.6.0, BunkerWeb soporta múltiples puertos de escucha para el modo stream. Puedes especificarlos usando las configuraciones LISTEN_STREAM_PORT y LISTEN_STREAM_PORT_SSL.
Necesitarás agregar la configuración a las variables de entorno al ejecutar el contenedor Todo en uno. También necesitarás exponer los puertos de stream.
Este ejemplo configura BunkerWeb para hacer proxy de dos aplicaciones basadas en stream, app1.example.com y app2.example.com.
Ten en cuenta que si tu contenedor ya está creado, necesitarás eliminarlo y recrearlo para que se apliquen las nuevas variables de entorno.
Tus aplicaciones (myapp1, myapp2) deberían estar ejecutándose en contenedores separados (o ser accesibles de otra manera) y sus nombres de host/IPs (p. ej., myapp1, myapp2 usados en _REVERSE_PROXY_HOST) deben ser resolvibles y alcanzables desde el contenedor bunkerweb-aio. Esto típicamente implica conectarlos a una red Docker compartida.
Desactivar el servicio de la interfaz de usuario
Se recomienda desactivar el servicio de la interfaz de usuario (p. ej., estableciendo SERVICE_UI=no como una variable de entorno) ya que la interfaz de usuario web no es compatible con SERVER_TYPE=stream.
Cuando se utiliza la integración con Docker, la forma más fácil de proteger las aplicaciones de red existentes es agregar los servicios a la red bw-services:
x-bw-api-env:&bw-api-env# Usamos un ancla para evitar repetir la misma configuración para todos los serviciosAPI_WHITELIST_IP:"127.0.0.0/810.20.30.0/24"# Token de API opcional para llamadas de API autenticadasAPI_TOKEN:""services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1ports:-"80:8080"# Mantenlo si quieres usar la automatización de Let's Encrypt al usar el tipo de desafío http-"10000:10000"# app1-"20000:20000"# app2labels:-"bunkerweb.INSTANCE=yes"environment:<<:*bw-api-envrestart:"unless-stopped"networks:-bw-universe-bw-servicesbw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1environment:<<:*bw-api-envBUNKERWEB_INSTANCES:"bunkerweb"# Esta configuración es obligatoria para especificar la instancia de BunkerWebSERVER_NAME:"app1.example.comapp2.example.com"MULTISITE:"yes"USE_REVERSE_PROXY:"yes"# Se aplicará a todos los serviciosSERVER_TYPE:"stream"# Se aplicará a todos los serviciosapp1.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# Esto se usa para persistir la caché y otros datos como las copias de seguridadrestart:"unless-stopped"networks:-bw-universemyapp1:image:istio/tcp-echo-server:1.3command:["9000","app1"]networks:-bw-servicesmyapp2:image:istio/tcp-echo-server:1.3command:["9000","app2"]networks:-bw-servicesvolumes:bw-storage:networks:bw-universe:name:bw-universeipam:driver:defaultconfig:-subnet:10.20.30.0/24bw-services:name:bw-services
services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1ports:-"80:8080"# Mantenlo si quieres usar la automatización de Let's Encrypt cuando usas el tipo de desafío http-"10000:10000"# app1-"20000:20000"# app2...
Una vez que el stack esté en ejecución, puedes conectar tus aplicaciones existentes a la red bw-services y configurar BunkerWeb con etiquetas:
Por el momento, los Ingresses no soportan el modo stream. Lo que estamos haciendo aquí es una solución alternativa para que funcione.
Siéntete libre de probarlo y reportarnos cualquier error usando los issues en el repositorio de GitHub.
Antes de ejecutar el stack de la integración de Kubernetes en tu máquina, necesitarás abrir los puertos en tu balanceador de carga:
apiVersion:v1kind:Servicemetadata:name:lbspec:type:LoadBalancerports:-name:http# Mantenlo si quieres usar la automatización de Let's Encrypt cuando usas el tipo de desafío httpport:80targetPort:8080-name:app1port:10000targetPort:10000-name:app2port:20000targetPort:20000selector:app:bunkerweb
Una vez que el stack esté en ejecución, puedes crear tus recursos de ingress:
apiVersion:networking.k8s.io/v1kind:Ingressmetadata:name:ingressnamespace:servicesannotations:bunkerweb.io/SERVER_TYPE:"stream"# Se aplicará a todos los serviciosbunkerweb.io/app1.example.com_LISTEN_STREAM_PORT:"10000"bunkerweb.io/app2.example.com_LISTEN_STREAM_PORT:"20000"spec:rules:-host:app1.example.comhttp:paths:-path:/# Esto no se usa en modo stream pero es obligatoriopathType:Prefixbackend:service:name:svc-app1port:number:9000-host:app2.example.comhttp:paths:-path:/# Esto no se usa en modo stream pero es obligatoriopathType:Prefixbackend:service:name:svc-app2port:number:9000---apiVersion:apps/v1kind:Deploymentmetadata:name:app1namespace:serviceslabels:app:app1spec:replicas:1selector:matchLabels:app:app1template:metadata:labels:app:app1spec:containers:-name:app1image:istio/tcp-echo-server:1.3args:["9000","app1"]ports:-containerPort:9000---apiVersion:v1kind:Servicemetadata:name:svc-app1namespace:servicesspec:selector:app:app1ports:-protocol:TCPport:9000targetPort:9000---apiVersion:apps/v1kind:Deploymentmetadata:name:app2namespace:serviceslabels:app:app2spec:replicas:1selector:matchLabels:app:app2template:metadata:labels:app:app2spec:containers:-name:app2image:istio/tcp-echo-server:1.3args:["9000","app2"]ports:-containerPort:9000---apiVersion:v1kind:Servicemetadata:name:svc-app2namespace:servicesspec:selector:app:app2ports:-protocol:TCPport:9000targetPort:9000
Necesitarás agregar la configuración al archivo /etc/bunkerweb/variables.env:
Antes de ejecutar el stack de integración de Swarm en tu máquina, necesitarás editar los puertos:
services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1ports:# Mantenlo si quieres usar la automatización de Let's Encrypt cuando usas el tipo de desafío http-published:80target:8080mode:hostprotocol:tcp# app1-published:10000target:10000mode:hostprotocol:tcp# app2-published:20000target:20000mode:hostprotocol:tcp...
Una vez que el stack esté en ejecución, puedes conectar tus aplicaciones existentes a la red bw-services y configurar BunkerWeb con etiquetas:
Por el momento, el soporte de PHP con BunkerWeb todavía está en beta y te recomendamos que utilices una arquitectura de proxy inverso si puedes. Por cierto, PHP no es compatible en absoluto con algunas integraciones como Kubernetes.
BunkerWeb soporta PHP usando instancias externas o remotas de PHP-FPM. Asumiremos que ya estás familiarizado con la gestión de este tipo de servicios.
Se pueden usar las siguientes configuraciones:
REMOTE_PHP: Nombre de host de la instancia remota de PHP-FPM.
REMOTE_PHP_PATH: Carpeta raíz que contiene los archivos en la instancia remota de PHP-FPM.
REMOTE_PHP_PORT: Puerto de la instancia remota de PHP-FPM (el predeterminado es 9000).
LOCAL_PHP: Ruta al archivo de socket local de la instancia de PHP-FPM.
LOCAL_PHP_PATH: Carpeta raíz que contiene los archivos en la instancia local de PHP-FPM.
Cuando se utiliza la imagen Todo en uno, para soportar aplicaciones PHP, necesitarás:
Montar tus archivos PHP en la carpeta /var/www/html de BunkerWeb.
Configurar un contenedor PHP-FPM para tu aplicación y montar la carpeta que contiene los archivos PHP.
Usar las configuraciones específicas REMOTE_PHP y REMOTE_PHP_PATH como variables de entorno al ejecutar BunkerWeb.
Si habilitas el modo multisitio, necesitarás crear directorios separados para cada una de tus aplicaciones. Cada subdirectorio debe nombrarse usando el primer valor de SERVER_NAME. Aquí hay un ejemplo de prueba:
Asumiremos que tus aplicaciones PHP están ubicadas en una carpeta llamada www. Ten en cuenta que necesitarás corregir los permisos para que BunkerWeb (UID/GID 101) pueda al menos leer archivos y listar carpetas, y que PHP-FPM (UID/GID 33 si usas la imagen php:fpm) sea el propietario de los archivos y carpetas:
Ahora puedes ejecutar BunkerWeb, configurarlo para tu aplicación PHP y también ejecutar las aplicaciones PHP. Necesitarás crear una red Docker personalizada para permitir que BunkerWeb se comunique con tus contenedores PHP-FPM.
# Crear una red personalizada
dockernetworkcreatephp-network
# Ejecutar contenedores PHP-FPM
dockerrun-d--namemyapp1-php--networkphp-network-v./www/app1.example.com:/appphp:fpm
dockerrun-d--namemyapp2-php--networkphp-network-v./www/app2.example.com:/appphp:fpm
# Ejecutar BunkerWeb Todo en uno
dockerrun-d\--namebunkerweb-aio\--networkphp-network\-v./www:/var/www/html\-vbw-storage:/data\-eSERVER_NAME="app1.example.com app2.example.com"\-eMULTISITE="yes"\-eREMOTE_PHP_PATH="/app"\-eapp1.example.com_REMOTE_PHP="myapp1-php"\-eapp2.example.com_REMOTE_PHP="myapp2-php"\-p80:8080/tcp\-p443:8443/tcp\-p443:8443/udp\bunkerity/bunkerweb-all-in-one:1.6.18-rc1
Ten en cuenta que si tu contenedor ya está creado, necesitarás eliminarlo y recrearlo para que se apliquen las nuevas variables de entorno.
Cuando se utiliza la integración de Docker, para admitir aplicaciones PHP, necesitarás:
Montar tus archivos PHP en la carpeta /var/www/html de BunkerWeb
Configurar un contenedor PHP-FPM para tu aplicación y montar la carpeta que contiene los archivos PHP
Usar las configuraciones específicas REMOTE_PHP y REMOTE_PHP_PATH como variables de entorno al iniciar BunkerWeb
Si habilitas el modo multisitio, necesitarás crear directorios separados para cada una de tus aplicaciones. Cada subdirectorio debe nombrarse utilizando el primer valor de SERVER_NAME. Aquí hay un ejemplo de prueba:
Asumiremos que tus aplicaciones PHP están ubicadas en una carpeta llamada www. Ten en cuenta que necesitarás arreglar los permisos para que BunkerWeb (UID/GID 101) pueda al menos leer archivos y listar carpetas y PHP-FPM (UID/GID 33 si usas la imagen php:fpm) sea el propietario de los archivos y carpetas:
Ahora puedes ejecutar BunkerWeb, configurarlo para tu aplicación PHP y también ejecutar las aplicaciones PHP:
x-bw-api-env:&bw-api-env# Usamos un ancla para evitar repetir la misma configuración para todos los serviciosAPI_WHITELIST_IP:"127.0.0.0/810.20.30.0/24"services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1ports:-"80:8080/tcp"-"443:8443/tcp"-"443:8443/udp"# QUICenvironment:<<:*bw-api-envvolumes:-./www:/var/www/htmlrestart:"unless-stopped"networks:-bw-universe-bw-servicesbw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1environment:<<:*bw-api-envBUNKERWEB_INSTANCES:"bunkerweb"# Esta configuración es obligatoria para especificar la instancia de BunkerWebSERVER_NAME:"app1.example.comapp2.example.com"MULTISITE:"yes"REMOTE_PHP_PATH:"/app"# Se aplicará a todos los servicios gracias a la configuración MULTISITEapp1.example.com_REMOTE_PHP:"myapp1"app2.example.com_REMOTE_PHP:"myapp2"app3.example.com_REMOTE_PHP:"myapp3"volumes:-bw-storage:/data# Esto se usa para persistir la caché y otros datos como las copias de seguridadrestart:"unless-stopped"networks:-bw-universemyapp1:image:php:fpmvolumes:-./www/app1.example.com:/appnetworks:-bw-servicesmyapp2:image:php:fpmvolumes:-./www/app2.example.com:/appnetworks:-bw-servicesmyapp3:image:php:fpmvolumes:-./www/app3.example.com:/appnetworks:-bw-servicesvolumes:bw-storage:networks:bw-universe:name:bw-universeipam:driver:defaultconfig:-subnet:10.20.30.0/24bw-services:name:bw-services
Modo multisitio habilitado
La integración de Docker autoconf implica el uso del modo multisitio: proteger una aplicación PHP es lo mismo que proteger varias.
Montar tus archivos PHP en la carpeta /var/www/html de BunkerWeb
Configurar contenedores PHP-FPM para tus aplicaciones y montar la carpeta que contiene las aplicaciones PHP
Usar las configuraciones específicas REMOTE_PHP y REMOTE_PHP_PATH como etiquetas para tu contenedor PHP-FPM
Dado que la autoconfiguración de Docker implica el uso del modo multisitio, necesitarás crear directorios separados para cada una de tus aplicaciones. Cada subdirectorio debe tener el nombre del primer valor de SERVER_NAME. Aquí hay un ejemplo de prueba:
Una vez creadas las carpetas, copia tus archivos y corrige los permisos para que BunkerWeb (UID/GID 101) pueda al menos leer archivos y listar carpetas, y PHP-FPM (UID/GID 33 si usas la imagen php:fpm) sea el propietario de los archivos y carpetas:
Cuando inicies el stack de autoconfiguración de BunkerWeb, monta la carpeta www en /var/www/html para el contenedor del Scheduler:
x-bw-api-env:&bw-api-env# Usamos un ancla para evitar repetir la misma configuración para todos los serviciosAUTOCONF_MODE:"yes"API_WHITELIST_IP:"127.0.0.0/810.20.30.0/24"services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1labels:-"bunkerweb.INSTANCE=yes"environment:<<:*bw-api-envvolumes:-./www:/var/www/htmlrestart:"unless-stopped"networks:-bw-universe-bw-servicesbw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1environment:<<:*bw-api-envBUNKERWEB_INSTANCES:""# No necesitamos especificar la instancia de BunkerWeb aquí, ya que son detectadas automáticamente por el servicio de autoconfiguraciónSERVER_NAME:""# El nombre del servidor se llenará con las etiquetas de los serviciosMULTISITE:"yes"# Configuración obligatoria para la autoconfiguraciónDATABASE_URI:"mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"# Recuerda establecer una contraseña más segura para la base de datosvolumes:-bw-storage:/data# Se utiliza para persistir la caché y otros datos como las copias de seguridadrestart:"unless-stopped"networks:-bw-universe-bw-dbbw-autoconf:image:bunkerity/bunkerweb-autoconf:1.6.18-rc1depends_on:-bunkerweb-bw-dockerenvironment:AUTOCONF_MODE:"yes"DATABASE_URI:"mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"# Recuerda establecer una contraseña más segura para la base de datosDOCKER_HOST:"tcp://bw-docker:2375"# El socket de Dockerrestart:"unless-stopped"networks:-bw-universe-bw-docker-bw-dbbw-docker:image:tecnativa/docker-socket-proxy:nightlyvolumes:-/var/run/docker.sock:/var/run/docker.sock:roenvironment:CONTAINERS:"1"LOG_LEVEL:"warning"networks:-bw-dockerbw-db:image:mariadb:11# Establecemos el tamaño máximo de paquete permitido para evitar problemas con consultas grandescommand:--max-allowed-packet=67108864environment:MYSQL_RANDOM_ROOT_PASSWORD:"yes"MYSQL_DATABASE:"db"MYSQL_USER:"bunkerweb"MYSQL_PASSWORD:"changeme"# Recuerda establecer una contraseña más segura para la base de datosvolumes:-bw-data:/var/lib/mysqlnetworks:-bw-dockervolumes:bw-data:bw-storage:networks:bw-universe:name:bw-universeipam:driver:defaultconfig:-subnet:10.20.30.0/24bw-services:name:bw-servicesbw-docker:name:bw-docker
Ahora puedes crear tus contenedores PHP-FPM, montar las subcarpetas correctas y usar etiquetas para configurar BunkerWeb:
La integración de Kubernetes permite la configuración a través de Ingress y el controlador de BunkerWeb solo admite aplicaciones HTTP por el momento.
Asumiremos que ya tienes el stack de integración de Linux funcionando en tu máquina.
Por defecto, BunkerWeb buscará archivos web dentro de la carpeta /var/www/html. Puedes usarla para almacenar tus aplicaciones PHP. Ten en cuenta que necesitarás configurar tu servicio PHP-FPM para obtener o establecer el usuario/grupo de los procesos en ejecución y el archivo de socket UNIX utilizado para comunicarse con BunkerWeb.
En primer lugar, deberás asegurarte de que tu instancia de PHP-FPM pueda acceder a los archivos dentro de la carpeta /var/www/html y también de que BunkerWeb pueda acceder al archivo de socket UNIX para comunicarse con PHP-FPM. Recomendamos establecer un usuario diferente como www-data para el servicio PHP-FPM y dar al grupo nginx acceso al archivo de socket UNIX. Aquí está la configuración correspondiente de PHP-FPM:
Si habilitas el modo multisitio, necesitarás crear directorios separados para cada una de tus aplicaciones. Cada subdirectorio debe nombrarse utilizando el primer valor de SERVER_NAME. Aquí hay un ejemplo de prueba:
Ten en cuenta que necesitarás arreglar los permisos para que BunkerWeb (grupo nginx) pueda al menos leer archivos y listar carpetas, y PHP-FPM (usuario www-data, pero podría ser diferente dependiendo de tu sistema) sea el propietario de los archivos y carpetas:
La integración Swarm implica el uso del modo multisitio: proteger una aplicación PHP es lo mismo que proteger varias.
Volumen compartido
Usar PHP con la integración de Docker Swarm necesita un volumen compartido entre todas las instancias de BunkerWeb y PHP-FPM, lo cual no se cubre en esta documentación.
Cuando se usa la integración Swarm, para admitir aplicaciones PHP, necesitarás:
Montar tus archivos PHP en la carpeta /var/www/html de BunkerWeb
Configurar contenedores PHP-FPM para tus aplicaciones y montar la carpeta que contiene las aplicaciones PHP
Usar las configuraciones específicas REMOTE_PHP y REMOTE_PHP_PATH como etiquetas para tu contenedor PHP-FPM
Dado que la integración de Swarm implica el uso del modo multisitio, necesitarás crear directorios separados para cada una de tus aplicaciones. Cada subdirectorio debe tener el nombre del primer valor de SERVER_NAME. Aquí hay un ejemplo de prueba:
Como ejemplo, consideraremos que tienes una carpeta compartida montada en tus nodos de trabajo en el punto final /shared.
Una vez creadas las carpetas, copia tus archivos y corrige los permisos para que BunkerWeb (UID/GID 101) pueda al menos leer archivos y listar carpetas, y PHP-FPM (UID/GID 33 si usas la imagen php:fpm) sea el propietario de los archivos y carpetas:
Esta característica no está lista para producción. Siéntete libre de probarla y reportarnos cualquier error usando los issues en el repositorio de GitHub.
Por defecto, BunkerWeb solo escuchará en direcciones IPv4 y no usará IPv6 para las comunicaciones de red. Si quieres habilitar el soporte de IPv6, necesitas establecer USE_IPV6=yes. Ten en cuenta que la configuración de IPv6 de tu red y entorno está fuera del alcance de esta documentación.
En primer lugar, necesitarás configurar tu demonio de Docker para habilitar el soporte de IPv6 para los contenedores y usar ip6tables si es necesario. Aquí hay una configuración de ejemplo para tu archivo /etc/docker/daemon.json:
BunkerWeb ofrece una configuración de registros flexible que permite enviar registros a múltiples destinos (por ejemplo, archivos, stdout/stderr o syslog) simultáneamente. Esto es especialmente útil para integrarse con recopiladores externos de registros mientras se mantienen registros locales para la interfaz web.
Hay dos categorías principales de registros para configurar:
Registros de servicio: Logs generados por los componentes de BunkerWeb (Scheduler, UI, Autoconf, etc.). Se controlan por servicio mediante LOG_TYPES (y opcionalmente LOG_FILE_PATH, LOG_SYSLOG_ADDRESS, LOG_SYSLOG_TAG).
Registros de acceso y error: Registros HTTP de acceso y errores generados por NGINX. Solo el servicio bunkerweb usa estos (ACCESS_LOG / ERROR_LOG / LOG_LEVEL).
Los registros de servicio se controlan con la configuración LOG_TYPES, que puede aceptar múltiples valores separados por espacios (por ejemplo, LOG_TYPES="stderr syslog").
Valor
Descripción
file
Escribe los registros en un archivo plano. En instalaciones Linux, la rotación externa la gestiona logrotate. En un contenedor, nada rota un archivo que un servicio escribe por sí mismo: la retención es responsabilidad del operador, así que monta el archivo en un volumen y rótalo tú mismo, o prefiere stderr/syslog ahí. Requerido para el visor de registros de la interfaz UI.
stderr
Escribe los registros en la salida de error estándar. Estándar en entornos con contenedores (docker logs).
syslog
Envía los registros a un servidor syslog. Requiere definir LOG_SYSLOG_ADDRESS.
Al usar file, también debes configurar:
LOG_FILE_PATH: Ruta donde se escriben los archivos de log cuando LOG_TYPES incluye file.
Al usar syslog, también debes configurar:
LOG_SYSLOG_ADDRESS: La dirección del servidor syslog (por ejemplo, udp://bw-syslog:514 o /dev/log).
LOG_SYSLOG_TAG: Una etiqueta única para el servicio (por ejemplo, bw-scheduler) para distinguir sus entradas.
Estos son registros estándar de NGINX, configurados únicamente mediante el servicio bunkerweb. Soportan múltiples destinos añadiendo sufijos numerados a la configuración (por ejemplo, ACCESS_LOG, ACCESS_LOG_1 junto con LOG_FORMAT, LOG_FORMAT_1, o ERROR_LOG, ERROR_LOG_1 con sus respectivos LOG_LEVEL, LOG_LEVEL_1).
ACCESS_LOG: Destino para los registros de acceso (por defecto: /var/log/bunkerweb/access.log). Acepta ruta de archivo, syslog:server=host[:port][,param=value], buffer compartido memory:name:size, o off para desactivar. Consulta la documentación de NGINX sobre access_log para más detalles.
ERROR_LOG: Destino para los registros de error (por defecto: /var/log/bunkerweb/error.log). Acepta ruta de archivo, stderr, syslog:server=host[:port][,param=value], o buffer compartido memory:size. Consulta la documentación de NGINX sobre error_log para más detalles.
LOG_LEVEL: Nivel de verbosidad de los registros de error (por defecto: notice).
Estas configuraciones aceptan valores estándar de NGINX, incluyendo rutas de archivo, stderr, syslog:server=... (ver documentación de syslog en NGINX), o buffers en memoria compartida. Soportan múltiples destinos mediante sufijos numerados (consulta la convención de múltiples ajustes). Los demás servicios (Scheduler, UI, Autoconf, etc.) dependen únicamente de LOG_TYPES/LOG_FILE_PATH/LOG_SYSLOG_*.
Ejemplo con múltiples registros de acceso/errores (solo bunkerweb, sufijos numerados):
Solo las integraciones que mantienen archivos de registro reales necesitan retención, y ambas usan el mismo mecanismo: logrotate, con la política que BunkerWeb instala en /etc/logrotate.d/bunkerweb. Rota cada archivo que coincida con /var/log/bunkerweb/*.log a diario, o antes si el archivo supera los 100 MB, conserva catorce generaciones numeradas (modsec_audit.log.1, .2.gz, etc.) y usa copytruncate.
Linux: los paquetes dependen de logrotate y el sistema lo ejecuta con su propio temporizador. No hay nada más que hacer.
All-in-one: la imagen incluye logrotate y lo ejecuta cada hora bajo supervisor, usando ese mismo archivo de política.
Docker, Autoconf, Swarm y Kubernetes: no hay nada que rotar. src/bw/Dockerfile sustituye access.log, error.log y modsec_audit.log por enlaces simbólicos a la salida estándar y al error estándar del propio contenedor al construir la imagen, de modo que la retención corresponde al driver de logging de tu entorno de ejecución de contenedores (consulta las buenas prácticas de logging de Docker más abajo).
copytruncate es lo que hace que una sola política funcione para todas ellas. Copia el archivo aparte y vacía el original en el mismo sitio en lugar de renombrarlo, de modo que un proceso que nunca reabre su registro sigue escribiendo en el archivo correcto. ModSecurity es exactamente ese proceso: abre el registro de auditoría una vez, cuando se carga la configuración, y mantiene el descriptor abierto. Rotar mediante renombrado lo dejaría escribiendo en el archivo archivado para siempre, con el archivo activo vacío.
Edita /etc/logrotate.d/bunkerweb para cambiar el umbral, el número de generaciones, o para añadir un maxage. En el All-in-one, monta tu propio archivo sobre esa ruta.
Dos directivas son decisivas ahí. maxsize es lo que mantiene vivo a daily: la directiva size, muy parecida, es excluyente con las directivas de intervalo y rotaría solo por tamaño. Y añadir dateext nombraría cada archivo comprimido según la fecha, de modo que una segunda rotación en la misma fecha falla con destination ... already exists, skipping rotation y deja el archivo activo sin rotar hasta que cambie la fecha.
La ubicación del registro de auditoría se establece mediante MODSECURITY_SEC_AUDIT_LOG (multisite, por defecto /var/log/bunkerweb/modsec_audit.log); consulta los ajustes de ModSecurity. Si lo apuntas fuera de /var/log/bunkerweb, queda fuera de la política anterior, y en una integración de contenedores sustituye el enlace simbólico por un archivo real que nada rota. Si lo mueves, móntalo en un volumen y rótalo tú mismo. El ajuste solo acepta una ruta bajo /var/log/bunkerweb, así que no puede apuntar a /data: para conservar el historial de auditoría tras recrear el contenedor, monta un volumen sobre /var/log/bunkerweb, lo que preserva todo el conjunto de registros y no solo el de auditoría.
Con el valor por defecto BCFH de MODSECURITY_SEC_AUDIT_LOG_PARTS, la parte C coloca el cuerpo de la petición en el registro de auditoría. Trata el archivo como sensible antes de copiarlo a ningún sitio.
Comportamiento predeterminado: LOG_TYPES="file". Los registros se escriben en /var/log/bunkerweb/*.log. La rotación la gestiona la configuración del sistema logrotate instalada en /etc/logrotate.d/bunkerweb (diaria o al superar 100 MB, catorce generaciones, comprimida con copytruncate).
Ejemplo: Mantener archivos locales (para la interfaz web) y también enviar una copia al syslog del sistema.
# Registros de servicio (establecidos en /etc/bunkerweb/variables.env o en archivos env específicos del servicio)
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 se asigna automáticamente por servicio (anular por servicio si es necesario)
# Registros de NGINX (solo servicio bunkerweb; establecer en /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
Comportamiento predeterminado: LOG_TYPES="stderr". Los registros son visibles mediante docker logs.
Estas imágenes no tienen, de entrada, ningún archivo de registro gestionado por BunkerWeb que limitar: src/bw/Dockerfile elimina access.log, error.log y modsec_audit.log al construir la imagen y sustituye los tres por enlaces simbólicos a la salida estándar y al error estándar del propio contenedor, de modo que ACCESS_LOG, ERROR_LOG y MODSECURITY_SEC_AUDIT_LOG van directamente al flujo de registro del contenedor por defecto. La retención ahí es responsabilidad de tu entorno de ejecución, a través del driver de logging (consulta las buenas prácticas de logging de Docker más abajo) o de un colector externo; BunkerWeb no incluye logrotate en sus imágenes.
Ejemplo (adaptado de la guía de inicio rápido): Mantener docker logs (stderr) Y enviar también a un contenedor syslog central (necesario para la interfaz web y CrowdSec).
x-bw-env:&bw-env# Usamos un ancla para evitar repetir la misma configuración para ambos serviciosAPI_WHITELIST_IP:"127.0.0.0/810.20.30.0/24"# Asegúrate de establecer el rango de IP correcto para que el Scheduler pueda enviar la configuración a la instancia# Opcional: establece un token de API y refléjalo en ambos contenedoresAPI_TOKEN:""DATABASE_URI:"mariadb+pymysql://bunkerweb:changeme@bw-db:3306/db"# Recuerda establecer una contraseña más segura para la base de datos# Registros de servicioLOG_TYPES:"stderrsyslog"LOG_SYSLOG_ADDRESS:"udp://bw-syslog:514"# LOG_SYSLOG_TAG se asigna automáticamente por servicio (anular por servicio si es necesario)# Registros NGINX: enviar a Syslog (solo bunkerweb)ACCESS_LOG_1:"syslog:server=bw-syslog:514,tag=bunkerweb_access"ERROR_LOG_1:"syslog:server=bw-syslog:514,tag=bunkerweb"services:bunkerweb:# Este es el nombre que se usará para identificar la instancia en el Schedulerimage:bunkerity/bunkerweb:1.6.18-rc1ports:-"80:8080/tcp"-"443:8443/tcp"-"443:8443/udp"# Para soporte QUIC / HTTP3environment:<<:*bw-env# Usamos el ancla para evitar repetir la misma configuración para todos los serviciosrestart:"unless-stopped"networks:-bw-universe-bw-servicesbw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1environment:<<:*bw-envBUNKERWEB_INSTANCES:"bunkerweb"# Asegúrate de establecer el nombre correcto de la instanciaSERVER_NAME:""MULTISITE:"yes"UI_HOST:"http://bw-ui:7000"# Cambia si es necesarioUSE_REDIS:"yes"REDIS_HOST:"redis"volumes:-bw-storage:/data# Esto se usa para persistir la caché y otros datos como las copias de seguridadrestart:"unless-stopped"networks:-bw-universe-bw-dbbw-ui:image:bunkerity/bunkerweb-ui:1.6.18-rc1environment:<<:*bw-envvolumes:-bw-logs:/var/log/bunkerweb# Esto se usa para leer los registros syslog desde la interfaz web-bw-ui-data:/data# Se usa para conservar los secretos de la interfaz web (secreto Flask, claves de cifrado TOTP, claves Biscuit)restart:"unless-stopped"networks:-bw-universe-bw-dbbw-db:image:mariadb:11# Establecemos el tamaño máximo de paquete permitido para evitar problemas con consultas grandescommand:--max-allowed-packet=67108864environment:MYSQL_RANDOM_ROOT_PASSWORD:"yes"MYSQL_DATABASE:"db"MYSQL_USER:"bunkerweb"MYSQL_PASSWORD:"changeme"# Recuerda establecer una contraseña más segura para la base de datosvolumes:-bw-data:/var/lib/mysqlrestart:"unless-stopped"networks:-bw-dbredis:# Servicio Redis para la persistencia de reportes/bloqueos/estadísticasimage:redis:8-alpinecommand:>redis-server--maxmemory 256mb--maxmemory-policy volatile-lru--save 60 1000--appendonly yesvolumes:-redis-data:/datarestart:"unless-stopped"networks:-bw-universebw-syslog:image:balabit/syslog-ng:4.10.2cap_add:-NET_BIND_SERVICE# Enlazar a puertos bajos-NET_BROADCAST# Enviar broadcasts-NET_RAW# Usar sockets raw-DAC_READ_SEARCH# Leer archivos saltando permisos-DAC_OVERRIDE# Anular permisos de archivos-CHOWN# Cambiar propiedad de archivos-SYSLOG# Escribir en logs del sistemavolumes:-bw-logs:/var/log/bunkerweb# Este es el volumen usado para almacenar los registros-./syslog-ng.conf:/etc/syslog-ng/syslog-ng.conf# Este es el archivo de configuración de syslog-ngrestart:"unless-stopped"networks:-bw-universevolumes:bw-data:bw-storage:redis-data:bw-logs:bw-ui-data:networks:bw-universe:name:bw-universeipam:driver:defaultconfig:-subnet:10.20.30.0/24# Asegúrate de establecer el rango de IP correcto para que el Scheduler pueda enviar la configuración a la instanciabw-services:name:bw-servicesbw-db:name:bw-db
Comportamiento predeterminado: igual que Docker (LOG_TYPES="stderr"), pero la imagen All-in-one conserva ACCESS_LOG, ERROR_LOG y MODSECURITY_SEC_AUDIT_LOG como archivos reales bajo /var/log/bunkerweb/ (los mismos valores por defecto que en Linux), porque tanto el CrowdSec incluido como el visor de registros de la interfaz web los leen desde disco.
BunkerWeb los limita por ti ahí: la imagen incluye logrotate y lo ejecuta cada hora bajo supervisor, con la misma política que instalan los paquetes de Linux (consulta Retención de los archivos de registro más arriba). Como la rotación se hace con copytruncate, los archivos conservan su inodo, de modo que el analizador de CrowdSec y el visor de registros los siguen a través de una rotación sin necesidad de reiniciar.
Comportamiento predeterminado: Los registros se escriben en stderr y son visibles mediante kubectl logs.
Ejemplo: Habilitar el sidecar syslog integrado en el chart de Helm para recopilar registros para la interfaz web (requiere BunkerWeb 1.6.7+).
ui:logs:# Habilitar sidecar de recopilación de registrosenabled:true# Dirección syslog para reenvío de registros# Se configura automáticamente al servicio Sidecar si está vacíosyslogAddress:""# Contenedor syslog-ng para recopilación de registrosrepository:docker.io/balabit/syslog-ngpullPolicy:Alwaystag:4.8.0# Almacenamiento persistente para registrospersistence:size:5GistorageClass:""
Aquí tienes un ejemplo de un archivo syslog-ng.conf que puedes usar para reenviar los registros a un archivo:
@version: 4.10
# Configuración de la fuente para recibir registros enviados por los servicios de BunkerWeb (ACCESS_LOG / ERROR_LOG y LOG_TYPES=syslog)
source s_net {
udp(
ip("0.0.0.0")
);
};
# Plantilla para formatear los mensajes de registro
template t_imp {
template("$MSG\n");
template_escape(no);
};
# Configuración de destino para escribir registros en archivos con nombre dinámico
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)
)
);
};
# Ruta de registro para dirigir los registros a archivos con nombre dinámico
log {
source(s_net);
destination(d_dyna_file);
};
Cuando se utiliza Docker, es importante gestionar los registros de los contenedores para evitar que consuman un espacio excesivo en el disco. Por defecto, Docker utiliza el controlador de registro json-file, lo que puede dar lugar a archivos de registro muy grandes si no se configura.
Para evitar esto, puede configurar la rotación de registros. Esto se puede hacer para servicios específicos en su archivo docker-compose.yml, o globalmente para el demonio de Docker.
Configuración por servicio
Puede configurar el controlador de registro para sus servicios en su archivo docker-compose.yml para rotar automáticamente los registros. Aquí hay un ejemplo que mantiene hasta 10 archivos de registro de 20 MB cada uno:
Esta configuración asegura que los registros se roten, evitando que llenen su disco. Puede aplicar esto a cualquier servicio en su configuración de Docker Compose.
Ajustes globales (daemon.json)
Si desea aplicar esta configuración de registro a todos los contenedores en el host por defecto, puede configurar el demonio de Docker editando (o creando) el archivo /etc/docker/daemon.json:
Después de modificar daemon.json, debe reiniciar el demonio de Docker para que los cambios surtan efecto:
sudosystemctlrestartdocker
Estos ajustes globales serán heredados por todos los contenedores. Sin embargo, cualquier configuración de registro definida por servicio en un archivo docker-compose.yml anulará los ajustes globales en daemon.json.
BunkerWeb ofrece muchas características de seguridad que puedes configurar con características. Aunque los valores predeterminados de las configuraciones aseguran una "seguridad por defecto" mínima, te recomendamos encarecidamente que los ajustes. Al hacerlo, podrás asegurar el nivel de seguridad de tu elección y también gestionar los falsos positivos.
Otras características
Esta sección solo se enfoca en el ajuste de seguridad, consulta la sección de características de la documentación para otras configuraciones.
Descripción general y orden de los plugins de seguridad principales
Si aún no estás familiarizado con la integración de la Consola de CrowdSec, CrowdSec aprovecha la inteligencia de la comunidad para combatir las amenazas cibernéticas. Piénsalo como el "Waze de la ciberseguridad"—cuando un servidor es atacado, otros sistemas en todo el mundo son alertados y protegidos de los mismos atacantes. Puedes aprender más sobre ello aquí.
¡Felicidades, tu instancia de BunkerWeb ahora está inscrita en tu Consola de CrowdSec!
Consejo profesional: Al ver tus alertas, haz clic en la opción "columnas" y marca la casilla "contexto" para acceder a los datos específicos de BunkerWeb.
Datos de BunkerWeb mostrados en la columna de contexto
Si tu entorno requiere que el tráfico HTTP(S) saliente pase por un proxy directo (por ejemplo un proxy corporativo o Squid), puedes usar las variables de entorno estándar del proxy. No hay una configuración específica de BunkerWeb para esto.
NGINX no utiliza estas variables para el tráfico upstream, por lo que la configuración del proxy directo solo afecta a los componentes que inician solicitudes salientes. En la práctica, configúralas en el Scheduler, porque gestiona tareas periódicas como las renovaciones de certificados de Let's Encrypt, llamadas a API externas y webhooks.
Las variables habituales son:
HTTP_PROXY / HTTPS_PROXY: URL del proxy, opcionalmente con credenciales.
NO_PROXY: lista separada por comas de hosts, dominios o CIDR que deben excluir el proxy (ajusta según la integración: nombres de servicios en Docker/Swarm, dominios del clúster en Kubernetes, o solo localhost en Linux).
REQUESTS_CA_BUNDLE / SSL_CERT_FILE: opcional, necesario si el proxy usa una CA personalizada. Monta el bundle de CA en el contenedor y apunta las variables a él para que las solicitudes de Python validen TLS (ajusta la ruta a tu imagen base).
NO_PROXY es obligatorio para el tráfico interno
Si omites rangos internos o nombres de servicios, el tráfico interno puede ir al proxy y fallar. Ajusta la lista a tu integración (por ejemplo nombres de servicios Docker, dominios del clúster de Kubernetes o solo localhost en Linux).
Añade las variables a /etc/bunkerweb/variables.env. Este archivo se carga para ambos servicios, pero solo el Scheduler las utilizará:
Proporciona las variables al crear el contenedor (y monta el bundle de CA si es necesario). La imagen All-in-one incluye el Scheduler, así que esto cubre las tareas salientes:
Añade las variables al pod del Scheduler usando extraEnvs. Si necesitas una CA personalizada, móntala mediante extraVolumes/extraVolumeMounts y apunta las variables a la ruta montada:
El plugin de monitoreo te permite recolectar y recuperar métricas sobre BunkerWeb. Al habilitarlo, tu(s) instancia(s) comenzará(n) a recolectar varios datos relacionados con ataques, solicitudes y rendimiento. Luego puedes recuperarlos llamando al punto final de la API /monitoring de forma regular o usando otros plugins como el exportador de Prometheus.
Lista de características
Habilitar la recolección de varias métricas de BunkerWeb
Recuperar métricas de la API
Usar en combinación con otros plugins (p. ej. exportador de Prometheus)
Página de interfaz de usuario dedicada para monitorear tu(s) instancia(s)
Lista de configuraciones
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_MONITORING
yes
global
no
Habilitar el monitoreo de BunkerWeb.
MONITORING_METRICS_DICT_SIZE
10M
global
no
Tamaño del diccionario para almacenar métricas de monitoreo.
MONITORING_IGNORE_URLS
global
no
Lista de rutas URL separadas por espacios que se excluirán del monitoreo (p. ej. /health /ready).
El plugin exportador de Prometheus agrega un exportador de Prometheus en tu(s) instancia(s) de BunkerWeb. Cuando está habilitado, puedes configurar tu(s) instancia(s) de Prometheus para que extraigan datos de un punto final específico en BunkerWeb y recopilen métricas internas.
También proporcionamos un panel de control de Grafana que puedes importar en tu propia instancia y conectar a tu propia fuente de datos de Prometheus.
Ten en cuenta que el uso del plugin exportador de Prometheus requiere habilitar el plugin de Monitoreo (USE_MONITORING=yes)
Lista de características
Exportador de Prometheus que proporciona métricas internas de BunkerWeb
Puerto, IP de escucha y URL dedicados y configurables
Este plugin requiere que el plugin de monitoreo Pro esté instalado y habilitado con la configuración USE_MONITORING establecida en yes.
El plugin de Reportes proporciona una solución integral para reportes regulares de datos importantes de BunkerWeb, incluyendo estadísticas globales, ataques, bloqueos, solicitudes, razones e información de AS. Ofrece una amplia gama de características, incluyendo creación automática de reportes, opciones de personalización e integración perfecta con el plugin de monitoreo pro. Con el plugin de Reportes, puedes generar y gestionar fácilmente reportes para monitorear el rendimiento y la seguridad de tu aplicación.
Lista de características
Reportes regulares de datos importantes de BunkerWeb, incluyendo estadísticas globales, ataques, bloqueos, solicitudes, razones e información de AS.
Integración con el plugin de monitoreo Pro para una integración perfecta y capacidades de reporte mejoradas.
Soporte para webhooks (clásicos, Discord y Slack) para notificaciones en tiempo real.
Soporte para SMTP para notificaciones por correo electrónico.
Opciones de configuración para personalización y flexibilidad.
Lista de configuraciones
Configuración
Predeterminado
Contexto
Descripción
USE_REPORTING_SMTP
no
global
Habilitar el envío del reporte por correo electrónico (HTML).
USE_REPORTING_WEBHOOK
no
global
Habilitar el envío del reporte por webhook (Markdown).
REPORTING_SCHEDULE
weekly
global
Cadencia del reporte: daily, weekly o monthly.
REPORTING_WEBHOOK_URLS
global
URLs de webhook separadas por espacios; Discord y Slack se detectan automáticamente.
REPORTING_SMTP_EMAILS
global
Destinatarios de correo electrónico separados por espacios.
REPORTING_SMTP_HOST
global
Nombre de host o IP del servidor SMTP.
REPORTING_SMTP_PORT
465
global
Puerto SMTP. Usa 465 para SSL, 587 para TLS.
REPORTING_SMTP_FROM_EMAIL
global
Dirección del remitente (desactiva 2FA si es requerido por tu proveedor).
REPORTING_SMTP_FROM_USER
global
Nombre de usuario SMTP (recurre al correo del remitente cuando se omite y se establece una contraseña).
REPORTING_SMTP_FROM_PASSWORD
global
Contraseña SMTP.
REPORTING_SMTP_SSL
SSL
global
Seguridad de conexión: no, SSL o TLS.
REPORTING_SMTP_SUBJECT
BunkerWeb Report
global
Línea de asunto para entregas por correo electrónico.
Notas de comportamiento
REPORTING_SMTP_EMAILS es requerido cuando la entrega SMTP está habilitada; REPORTING_WEBHOOK_URLS es requerido cuando la entrega por webhook está habilitada.
Si tanto los webhooks como SMTP fallan, la entrega se reintenta en la próxima ejecución programada.
Las plantillas HTML y Markdown se encuentran en reporting/files/; personalízalas con precaución para mantener los marcadores de posición intactos.
La herramienta de Copia de seguridad S3 automatiza sin problemas la protección de datos, de forma similar al plugin de copia de seguridad de la comunidad. Sin embargo, se destaca por almacenar de forma segura las copias de seguridad directamente en un bucket S3.
Al activar esta función, estás salvaguardando proactivamente la integridad de tus datos. Almacenar las copias de seguridad de forma remota protege la información crucial de amenazas como fallos de hardware, ciberataques o desastres naturales. Esto garantiza tanto la seguridad como la disponibilidad, permitiendo una rápida recuperación durante eventos inesperados, preservando la continuidad operativa y asegurando la tranquilidad.
Información para usuarios de Red Hat Enterprise Linux (RHEL) 8.9
Si estás utilizando RHEL 8.9 y planeas usar una base de datos externa, necesitarás instalar el paquete mysql-community-client para asegurar que el comando mysqldump esté disponible. Puedes instalar el paquete ejecutando los siguientes comandos:
Instalar el paquete de configuración del repositorio de MySQL
Este comando creará una copia de seguridad de tu base de datos y la almacenará en el bucket S3 especificado en la configuración BACKUP_S3_BUCKET.
También puedes especificar un bucket S3 personalizado para la copia de seguridad proporcionando la variable de entorno BACKUP_S3_BUCKET al ejecutar el comando:
Las imágenes Docker de BunkerWeb incluyen los plugins de autenticación de MariaDB Connector/C que requiere caching_sha2_password de MySQL. En Linux, si el cliente indica que no se pudo cargar caching_sha2_password, instala los plugins de autenticación de MariaDB Connector/C de tu distribución o un cliente MySQL compatible. No cambies la cuenta de la base de datos a mysql_native_password, ya que no está disponible en MySQL v9.
Este comando creará una copia de seguridad temporal de tu base de datos en el bucket S3 especificado en la configuración BACKUP_S3_BUCKET y restaurará tu base de datos a la última copia de seguridad disponible en el bucket.
También puedes especificar un archivo de copia de seguridad personalizado para la restauración proporcionando la ruta al mismo como argumento al ejecutar el comando:
No te preocupes si la restauración falla, siempre puedes restaurar tu base de datos al estado anterior ejecutando el comando de nuevo, ya que se crea una copia de seguridad antes de la restauración:
El servidor MCP de BunkerWeb permite que asistentes de IA como Claude Code y Claude Desktop gestionen tu instalación de BunkerWeb a través del Model Context Protocol (MCP).
Requisito
El servidor MCP requiere que la API externa de BunkerWeb (bunkerity/bunkerweb-api) esté desplegada. Se comunica con BunkerWeb exclusivamente a través de esta API.
El servidor MCP se puede desplegar junto con BunkerWeb utilizando el chart Helm oficial. Un ejemplo completo está disponible en examples/mcp-integration.yaml.
mcp:# Habilitar el servidor MCPenabled:true# Configuración de la imagen del contenedorrepository:docker.io/bunkerity/bunkerweb-mcptag:0.2.0# Configuración del servidor MCPconfig:logLevel:"INFO"enableDnsRebindingProtection:trueallowedHosts:"localhost,127.0.0.1,mcp.example.com"cacheEnabled:true# Credenciales para la autenticación del MCP con la API de BunkerWebsecrets:bunkerwebApiToken:"tu-token-api-seguro"# Configuración de Ingress (opcional)ingress:enabled:falseingressClassName:"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"# SEGURIDAD: Restringir el acceso solo a IPs de confianzabunkerweb.io/USE_WHITELIST:"yes"bunkerweb.io/WHITELIST_IP:"10.0.0.0/8192.168.0.0/16"
# Desplegar BunkerWeb con MCP habilitado
helminstallbunkerwebbunkerweb/bunkerweb-fmcp-integration.yaml
# Acceder al MCP localmente via port-forward (recomendado para seguridad)
kubectlport-forwardsvc/mcp-bunkerweb8080:8080
# Configurar Claude Code con http://localhost:8080/mcp
Seguridad
El servidor MCP no tiene autenticación integrada para el endpoint /mcp. Asegura el acceso usando:
Lista blanca de IPs mediante anotaciones de BunkerWeb (USE_WHITELIST, WHITELIST_IP)
Políticas de red para restringir la comunicación entre pods
Port-forward en lugar de exponer externamente (recomendado para desarrollo)
El plugin de Migración revoluciona las transferencias de configuración de BunkerWeb entre instancias con su interfaz web fácil de usar, simplificando todo el proceso de migración. Ya sea que estés actualizando sistemas, escalando la infraestructura o haciendo la transición de entornos, esta herramienta te permite transferir sin esfuerzo configuraciones, preferencias y datos con una facilidad y confianza inigualables. Di adiós a los engorrosos procesos manuales y hola a una experiencia de migración fluida y sin complicaciones.
Lista de características
Migración sin esfuerzo: Transfiere fácilmente las configuraciones de BunkerWeb entre instancias sin las complejidades de los procedimientos manuales.
Interfaz web intuitiva: Navega por el proceso de migración sin esfuerzo con una interfaz web fácil de usar diseñada para una operación intuitiva.
Compatibilidad entre bases de datos: Disfruta de una migración fluida a través de varias plataformas de bases de datos, incluidas SQLite, MySQL, MariaDB y PostgreSQL, lo que garantiza la compatibilidad con tu entorno de base de datos preferido.
Este comando creará una copia de seguridad de tu base de datos y la almacenará en el directorio de copia de seguridad especificado en el comando.
Compatibilidad del cliente MariaDB/MySQL
Las imágenes Docker de BunkerWeb incluyen los plugins de autenticación de MariaDB Connector/C que requiere caching_sha2_password de MySQL. En Linux, si el cliente indica que no se pudo cargar caching_sha2_password, instala los plugins de autenticación de MariaDB Connector/C de tu distribución o un cliente MySQL compatible. No cambies la cuenta de la base de datos a mysql_native_password, ya que no está disponible en MySQL v9.
El plugin Anti DDoS proporciona protección avanzada contra ataques de denegación de servicio distribuido (DDoS) mediante el monitoreo, análisis y filtrado de tráfico sospechoso en tiempo real.
Mediante el empleo de un mecanismo de ventana deslizante, el plugin mantiene un diccionario en memoria de las marcas de tiempo de las solicitudes para detectar picos de tráfico anormales de direcciones IP individuales. Según el modo de seguridad configurado, puede bloquear las conexiones ofensivas o registrar la actividad sospechosa para una revisión posterior.
El plugin User Manager ofrece una interfaz robusta para administrar cuentas de usuario dentro de su sistema.
Con este plugin, los administradores pueden crear, actualizar y deshabilitar cuentas de usuario sin esfuerzo, gestionar roles de usuario, activar o desactivar la autenticación de dos factores (2FA) y ver información detallada del usuario, como las marcas de tiempo del último inicio de sesión y los estados de la cuenta (activa o inactiva). Diseñado teniendo en cuenta la seguridad y la facilidad de uso, este plugin simplifica las tareas rutinarias de gestión de usuarios al tiempo que garantiza el cumplimiento y la auditabilidad.
Operaciones de cuenta de usuario: Importar en formato CSV/XLSX, crear, editar y eliminar cuentas de usuario con facilidad.
Control de acceso basado en roles: Asignar y modificar roles de usuario para gestionar permisos y niveles de acceso.
Gestión de 2FA: Desactivar la autenticación de dos factores según las decisiones administrativas.
Información completa del usuario: Supervisar los datos clave del usuario, incluidos los últimos tiempos de inicio de sesión, las fechas de creación de la cuenta y el estado activo/inactivo.
Registro de auditoría: Mantener un registro de auditoría de todas las acciones de gestión de usuarios para mejorar la seguridad y el cumplimiento.
El plugin UI Single Sign-On habilita la autenticación SSO para la interfaz web de BunkerWeb leyendo cabeceras establecidas por un proxy de autenticación externo (como Authentik, Authelia, Keycloak o Traefik Forward Auth) ubicado delante de la interfaz web.
En lugar de gestionar credenciales separadas para BunkerWeb, los administradores pueden delegar la autenticación a un proveedor de identidad existente. El proxy de autenticación gestiona el inicio de sesión del usuario e inyecta cabeceras de identidad antes de reenviar las solicitudes a la interfaz web de BunkerWeb.
Riesgo de suplantación de cabeceras
Las cabeceras SSO pueden ser falsificadas fácilmente por cualquier cliente. Debe restringir UI_SSO_TRUSTED_IPS a la(s) dirección(es) IP de su proxy de autenticación. Si este ajuste está mal configurado, cualquier cliente puede enviar cabeceras falsas y obtener acceso no autorizado, incluido acceso de administrador.
El valor predeterminado 127.0.0.1,::1 solo confía en localhost. En despliegues Docker, Swarm o Kubernetes, el proxy de autenticación se ejecuta en un contenedor independiente con su propia IP. Establezca UI_SSO_TRUSTED_IPS con la IP real o CIDR del contenedor del proxy de autenticación (p. ej. 10.20.30.5 o 172.18.0.0/16). Nunca lo establezca como 0.0.0.0/0.
Autenticación basada en cabeceras: lee nombre de usuario, correo electrónico, nombre para mostrar y grupos desde las cabeceras del proxy de autenticación.
Asignación de grupo a rol: mapea grupos del IdP a roles de BunkerWeb (admin, writer, reader).
Aprovisionamiento automático de usuarios: crea cuentas locales en el primer inicio de sesión SSO con rol predeterminado configurable.
Vinculación de cuentas: asocia usuarios SSO entrantes con cuentas locales existentes por nombre de usuario o correo electrónico.
Aplicación de IP de confianza: solo acepta cabeceras SSO desde direcciones IP o rangos CIDR configurados.
Respaldo al inicio de sesión normal: permite opcionalmente el inicio de sesión con contraseña cuando las cabeceras SSO no están presentes.
Redirección de cierre de sesión: redirige a los usuarios al endpoint de cierre de sesión del proveedor SSO tras el cierre de sesión local.
Coloque un proxy de autenticación (Authentik, Authelia, Keycloak, etc.) delante de la interfaz web de BunkerWeb.
Habilite el plugin: USE_UI_SSO=yes.
Asegúrese de que el proxy establece las cabeceras esperadas (X-User, X-Email, X-Groups, X-Name) -- o ajuste los nombres de las cabeceras mediante los ajustes UI_SSO_HEADER_*.
Restrinja las fuentes de confianza: establezca UI_SSO_TRUSTED_IPS con la(s) dirección(es) IP del proxy de autenticación.
Mapee grupos a roles: establezca UI_SSO_GROUP_ADMIN, UI_SSO_GROUP_WRITER y UI_SSO_GROUP_READER para que coincidan con los nombres de grupo de su IdP.
Establezca UI_SSO_FALLBACK_TO_LOGIN=no en producción para imponer acceso exclusivo por SSO. Cuando se deja en yes (valor predeterminado), los usuarios pueden eludir el SSO e iniciar sesión con credenciales locales, omitiendo cualquier MFA o política de sesión aplicada por su proveedor de identidad.
Mantenga UI_SSO_UPDATE_USER_ON_LOGIN en su valor predeterminado (yes) para garantizar que los roles permanezcan sincronizados con los cambios de grupo en el IdP.
Al usar UI_SSO_ACCOUNT_LINKING=username_or_email, las cuentas locales existentes se vinculan automáticamente en el primer inicio de sesión SSO si el nombre de usuario o correo electrónico coincide. Use username_only si su IdP permite a los usuarios establecer direcciones de correo electrónico arbitrarias, para prevenir la toma de cuentas mediante suplantación de correo electrónico.
El plugin Easy Resolve te permite remediar rápidamente falsos positivos y problemas recurrentes directamente desde la página de Informes. Convierte las acciones guiadas de "Resolver" en actualizaciones de configuración seguras y acotadas, sin edición manual.
El Plugin de Load Balancer convierte BunkerWeb en un director de tráfico con guardarraíles. Declare pools upstream una vez, apunte su proxy inverso a ellos, y deje que el balanceo consciente de salud mantenga a los usuarios en backends responsivos. El modo sticky cookie emite automáticamente una cookie BWLBID para que las sesiones se mantengan ancladas donde quiera.
El plugin Custom Pages le permite reemplazar las páginas integradas de BunkerWeb (páginas de error, página del servidor por defecto y páginas de desafío antibot) con sus propias plantillas HTML o Lua personalizadas. Esto le permite mantener una marca consistente en todas las páginas orientadas al usuario servidas por BunkerWeb.
Para obtener información sobre el comportamiento y la personalización de Maintenance, consulte la guía avanzada de Maintenance.
Páginas de error personalizadas por servicio y páginas de desafío antibot (captcha, verificación JavaScript, reCAPTCHA, hCaptcha, Turnstile, mCaptcha, Cap.js).
Página del servidor por defecto personalizada global para el vhost de respaldo/por defecto.
Análisis HTML y verificaciones de balance de etiquetas de plantilla Lua antes de que una plantilla sea aceptada.
Caché automático a /var/cache/bunkerweb/custom_pages con detección de cambios para activar recargas.
Configuración por sitio o global a través de configuraciones/UI o variables de entorno.
Al iniciar (o cuando cambian las configuraciones), el job custom-pages.py lee las rutas de plantilla configuradas.
Cada archivo debe existir y ser legible por el scheduler; el job valida la estructura HTML y el balance de etiquetas de plantilla Lua ({% %}, {{ }}, {* *}).
Los archivos aceptados se almacenan en caché bajo /var/cache/bunkerweb/custom_pages/<type>.html; configuraciones faltantes/vacías eliminan el archivo en caché.
NGINX apunta al directorio de caché vía $template_root cuando existe al menos una página en caché, de modo que sus plantillas se sirven en lugar de las predeterminadas.
Cree una plantilla de página de error personalizada en /etc/bunkerweb/templates/error.html:
{-raw-}<!doctype html><htmllang="es"><head><metacharset="utf-8"/><title>{{ title }}</title><metaname="viewport"content="width=device-width, initial-scale=1"/>
{-raw-}
<stylenonce="{*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:{%iferror_type=="server"%}#dc3545{%else%}#ffc107{%end%};margin:0;}.error-title{font-size:1.5rem;margin:1rem0;}.error-text{color:#666;margin-bottom:1rem;}.request-info{font-size:0.8rem;color:#999;margin-top:2rem;}</style>
{-raw-}
</head><body><divclass="container"><pclass="error-code">{{ error_code }}</p><h1class="error-title">{{ error_title }}</h1><pclass="error-text">{{ error_text }}</p><pclass="error-text">{{ error_solution }}</p><divclass="request-info">
{% if request_id %}
<p>ID de solicitud: <code>{{ request_id }}</code></p>
{% end %}
{% if request_time %}
<p>Hora: {{ request_time }}</p>
{% end %}
</div></div></body></html>
{-raw-}
Cree una página de desafío captcha personalizada en /etc/bunkerweb/templates/captcha.html:
{-raw-}<!doctype html><htmllang="es"><head><metacharset="utf-8"/><title>Verificación de seguridad</title><metaname="viewport"content="width=device-width, initial-scale=1"/>
{-raw-}
<stylenonce="{*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,#667eea0%,#764ba2100%);}.card{background:white;padding:2rem;border-radius:1rem;box-shadow:010px40pxrgba(0,0,0,0.2);text-align:center;max-width:400px;}h1{color:#333;margin-bottom:1rem;}.captcha-img{margin:1rem0;border-radius:0.5rem;}input[type="text"]{width:100%;padding:0.75rem;font-size:1.2rem;border:2pxsolid#ddd;border-radius:0.5rem;text-align:center;box-sizing:border-box;}button{margin-top:1rem;padding:0.75rem2rem;font-size:1rem;background:#667eea;color:white;border:none;border-radius:0.5rem;cursor:pointer;}button:hover{background:#5a6fd6;}</style>
{-raw-}
</head><body><divclass="card"><h1>🔒 Verificación de seguridad</h1><p>Por favor ingrese el texto que ve abajo para continuar.</p>
{-raw-}
<formmethod="POST"action="{*antibot_uri*}"><imgclass="captcha-img"src="data:image/jpeg;base64,{*captcha*}"alt="Captcha"/>
{-raw-}
<inputtype="text"name="captcha"placeholder="Ingrese el código"requiredautocomplete="off"/><buttontype="submit">Verificar</button></form></div></body></html>
{-raw-}
Cree una página del servidor por defecto personalizada en /etc/bunkerweb/templates/default.html:
{-raw-}<!doctype html><htmllang="es"><head><metacharset="utf-8"/><title>Bienvenido</title><metaname="viewport"content="width=device-width, initial-scale=1"/>
{-raw-}
<stylenonce="{*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><divclass="container"><h1>🛡️ Protegido por BunkerWeb</h1><p>Este servidor está seguro y listo.</p></div></body></html>
{-raw-}
# Página de error personalizada para todos los servicios (o use por servicio con prefijo)
CUSTOM_ERROR_PAGE=/opt/bunkerweb/templates/error.html
# Página del servidor por defecto personalizada (solo global)
CUSTOM_DEFAULT_SERVER_PAGE=/opt/bunkerweb/templates/default.html
# Página captcha personalizada (por servicio o global)
CUSTOM_ANTIBOT_CAPTCHA_PAGE=/opt/bunkerweb/templates/captcha.html
Recargue el scheduler de BunkerWeb para que tome las nuevas plantillas:
sudosystemctlreloadbunkerweb-scheduler
El scheduler es responsable de leer, validar y almacenar en caché sus plantillas personalizadas. Solo el scheduler necesita acceso a los archivos de plantilla—BunkerWeb recibe la configuración validada automáticamente.
Cree sus archivos de plantilla en un directorio local (ej. ./templates/) y establezca los permisos correctos:
El contenedor scheduler se ejecuta como un usuario sin privilegios con UID 101 y GID 101. El directorio debe ser legible por este usuario para que el scheduler pueda acceder a sus plantillas.
Si la carpeta ya existe:
chown-Rroot:101templates&&\
chmod-R770templates
Al usar Docker en modo rootless o Podman, los UID/GID de contenedor se remapean. Verifique sus rangos subuid/subgid:
Monte el directorio de plantillas al scheduler y configure los ajustes en el scheduler (el scheduler actúa como gestor y distribuye la configuración a los workers de BunkerWeb). Puede montar las plantillas en cualquier ruta dentro del contenedor:
services:bunkerweb:image:bunkerity/bunkerweb:1.6.18-rc1# ... otras configuraciones (no se necesitan variables de entorno aquí para páginas personalizadas)bw-scheduler:image:bunkerity/bunkerweb-scheduler:1.6.18-rc1volumes:-./templates:/custom_templates:roenvironment:-CUSTOM_ERROR_PAGE=/custom_templates/error.html-CUSTOM_DEFAULT_SERVER_PAGE=/custom_templates/default.html-CUSTOM_ANTIBOT_CAPTCHA_PAGE=/custom_templates/captcha.html# ... otras configuraciones
Acceso al scheduler requerido
Si el scheduler no puede leer los archivos de plantilla (debido a montaje faltante o permisos incorrectos), las plantillas serán silenciosamente ignoradas y se usarán las páginas por defecto. Verifique los logs del scheduler para errores de validación.
El scheduler es responsable de leer, validar y almacenar en caché sus plantillas personalizadas. Necesita montar las plantillas al pod del scheduler.
Monte el ConfigMap de plantillas al pod del scheduler y configure los ajustes como variables de entorno:
apiVersion:apps/v1kind:Deploymentmetadata:name:bunkerweb-schedulerspec:template:spec:containers:-name:bunkerweb-schedulerimage:bunkerity/bunkerweb-scheduler:1.6.18-rc1env:-name:CUSTOM_ERROR_PAGEvalue:"/custom_templates/error.html"-name:CUSTOM_ANTIBOT_CAPTCHA_PAGEvalue:"/custom_templates/captcha.html"# ... otras configuracionesvolumeMounts:-name:custom-templatesmountPath:/custom_templatesreadOnly:true# ... otras configuraciones del contenedorvolumes:-name:custom-templatesconfigMap:name:bunkerweb-custom-templates# ... otras configuraciones del pod
Usando el controlador Ingress de BunkerWeb
Si está usando el controlador Ingress de BunkerWeb, el scheduler está integrado en el controlador. Monte el ConfigMap al pod del controlador en su lugar.
Las rutas deben ser absolutas y terminar con un nombre de archivo; valores vacíos desactivan la página personalizada correspondiente y eliminan su caché.
Si la validación falla (HTML incorrecto o etiquetas Lua desbalanceadas), la plantilla se omite y la página por defecto permanece activa. Verifique los logs del scheduler para detalles.
Los archivos en caché están en /var/cache/bunkerweb/custom_pages; actualizar el archivo fuente es suficiente—el job detecta el nuevo hash y recarga NGINX automáticamente.
Cumplimiento CSP: Siempre use las variables nonce_script y nonce_style para scripts y estilos inline para asegurar el manejo adecuado de la Content Security Policy.
Probando plantillas: Puede probar sus plantillas localmente renderizándolas con un motor de plantillas Lua antes de desplegarlas en BunkerWeb.
Mantenimiento reemplaza las respuestas de las ubicaciones estándar de proxy inverso por una página de mantenimiento mientras la aplicación no está disponible. Se activa de forma opcional por servicio, devuelve 503 Service Unavailable y nunca llega al upstream. La configuración multisite tiene no como valor predeterminado.
Establezca USE_MAINTENANCE en yes en un servicio multisite existente que utilice el proxy inverso estándar. Este fragmento muestra las claves de entorno relevantes; intégrelo en la configuración del scheduler en lugar de tratarlo como un archivo Compose completo:
# Fragmento: entorno del scheduler para un servicio con proxy inversoenvironment:app.example.com_USE_REVERSE_PROXY:"yes"app.example.com_REVERSE_PROXY_HOST:"http://app:8080"app.example.com_USE_MAINTENANCE:"yes"
Aplíquelo mediante su integración habitual de BunkerWeb. El scheduler genera la configuración del servicio y recarga los workers. Establezca app.example.com_USE_MAINTENANCE en no y vuelva a aplicar para restaurar el proxy. Si la configuración del proxy inverso ya existe, solo necesita este ajuste.
La interfaz web proporciona dos interruptores rápidos: el botón con el icono de llave inglesa en la columna Maintenance en la página de servicios y el botón de llave inglesa flotante en la página de edición de un servicio. Ambos actualizan el ajuste del servicio y lo aplican sin recargar la página. El formulario de edición permanece sincronizado, incluidos los modos Easy/Advanced y el editor sin formato, mientras los cambios no guardados que no están relacionados permanecen en su lugar.
Los interruptores requieren una base de datos con permisos de escritura y acceso de escritura al servicio. Se desactivan para usuarios de solo lectura, bases de datos de solo lectura y servicios USE_UI=yes para que la interfaz integrada siga disponible. Rechazan sobrescribir un valor de USE_MAINTENANCE administrado externamente; cámbielo a través de su propietario. Un interruptor se rechaza mientras una aplicación está en curso.
Mantenimiento se aplica únicamente a las ubicaciones generadas a partir de la configuración de proxy inverso estándar de BunkerWeb, incluidas REVERSE_PROXY_HOST y sus variantes numeradas. No añade ubicaciones de proxy, modifica ubicaciones personalizadas ni se apropia de los controladores de reescritura manuales. Si la configuración personalizada reemplaza esos controladores o las variables del backend, integre usted mismo la respuesta de mantenimiento.
Mantenimiento conserva la política HTTPS existente, por lo que una redirección de HTTP a HTTPS habilitada ocurre primero. En el origen HTTPS efectivo devuelve 503 con Cache-Control: no-store, una Content Security Policy restrictiva y X-Content-Type-Options: nosniff.
Las solicitudes GET, POST, OPTIONS y los handshakes de WebSocket reciben la página de mantenimiento. BunkerWeb descarta el cuerpo de la solicitud, por lo que el cuerpo de un POST nunca se reenvía ni se reproduce. HEAD recibe el mismo estado y las mismas cabeceras sin cuerpo. Los WebSockets existentes no se cierran explícitamente; se aplica el apagado normal de los workers durante la recarga.
Mantenimiento se ejecuta antes de la autenticación, antibot y otras comprobaciones de acceso, por lo que los clientes incluidos en la lista blanca y los servicios en modo de detección también la reciben. Las ubicaciones locales de NGINX, la API interna y los endpoints de estado conservan su comportamiento normal. Lo mismo se aplica a /.well-known/acme-challenge/ y al passthrough de Let's Encrypt configurado. Mantenimiento conserva esta excepción; no emite certificados ni crea un controlador ACME.
La página incluida funciona sin Custom Pages. Para personalizarla con Custom Pages, abra el editor de Custom Pages y elija Maintenance. Easy Mode edita el título y el mensaje de mantenimiento, el favicon, el logotipo/texto del pie de página y la ilustración SVG. El título actualiza el título del navegador y el encabezado; un título o una ilustración vacíos conservan el valor predeterminado. Conserve las clases SVG maintenance-top y maintenance-tool para la animación de la ilustración.
En Advanced Mode, edite la plantilla HTML/Lua completa. Las variables disponibles son:
Variable
Propósito
title
Site under maintenance, el título de página proporcionado por el plugin.
nonce_style
Nonce CSP por respuesta para elementos <style> inline.
nonce_script
Nonce CSP por respuesta para elementos <script> inline.
Use los valores nonce en cada estilo y script inline, por ejemplo nonce="{* nonce_style *}". La respuesta permite imágenes incrustadas, SVG y fuentes mediante URL data: y bloquea otros orígenes. Incruste los recursos inline o como URL de datos; las URL de recursos de la aplicación también reciben mantenimiento y no pueden cargar dependencias.
Para una página administrada mediante archivo, establezca CUSTOM_MAINTENANCE_PAGE en una ruta absoluta que el scheduler pueda leer. Tiene prioridad sobre una plantilla de la UI y bloquea ese ámbito en el editor. Sin ella, un servicio utiliza su propia plantilla de la UI o hereda la plantilla global. Delete elimina una anulación del servicio y restaura la herencia. Reset elimina la plantilla de la UI y fuerza la página incluida, incluso cuando existe una personalización global. Guardar una nueva anulación de servicio borra su marcador de restablecimiento. Active o desactive el mantenimiento por separado con USE_MAINTENANCE.
El job de Custom Pages valida el HTML y protege contra peligros conocidos de compilación de plantillas Lua antes de almacenar en caché. Una fuente no válida conserva la última caché aceptada. Una página activa no disponible o que falla recurre a la página incluida y después a una página de emergencia mínima. Un error de renderizado nunca restaura el tráfico del proxy.
El interruptor está desactivado o se rechaza: compruebe los permisos de escritura, USE_UI y la propiedad externa de USE_MAINTENANCE; cambie los valores administrados externamente a través de su propietario.
La aplicación sigue respondiendo: confirme que una ubicación de proxy inverso estándar tiene USE_REVERSE_PROXY=yes y USE_MAINTENANCE=yes. Las rutas locales y ACME son excepciones.
Recibe una redirección en lugar de 503: la política HTTPS existente redirige primero; siga la URL HTTPS.
Se muestra la página incluida: compruebe el archivo legible por el scheduler, la validación de la plantilla y el log del scheduler; un ajuste de archivo bloquea la plantilla de la UI.
Faltan recursos o scripts inline: incrústelos y use nonce_style o nonce_script; las URL de la aplicación no están disponibles.
El plugin OpenID Connect (PRO) agrega Single Sign-On (SSO) delante de su aplicación utilizando el flujo estándar OAuth 2.0 / OIDC Authorization Code.
Se ejecuta dentro de BunkerWeb (NGINX/Lua) y aplica la autenticación durante la fase access, por lo que las solicitudes no autenticadas se bloquean antes de llegar a su upstream.
Si no hay una sesión válida, BunkerWeb redirige al usuario al proveedor de identidad (IdP).
El IdP autentica al usuario y redirige de vuelta a BunkerWeb en OPENIDC_REDIRECT_URI (por defecto: /callback) con un código de autorización.
BunkerWeb intercambia el código por tokens en el endpoint token del IdP.
Los tokens se validan (issuer, audience, expiración, iat con tolerancia y firma mediante JWKS).
Se crea una sesión y el navegador es redirigido a la URL original.
sequenceDiagram
participant B as Navegador
participant BW as BunkerWeb (OpenIDC)
participant IdP as Proveedor de identidad
participant Up as Upstream
B->>BW: GET /protected
alt No autenticado
BW-->>B: 302 Redirección al endpoint authorize del IdP
B->>IdP: Solicitud de autorización (nonce/PKCE opcional)
IdP-->>B: 302 Redirección a /callback?code=...
B->>BW: GET /callback?code=...
BW->>IdP: Solicitud de token (intercambio del código)
IdP-->>BW: ID token + access token (+ refresh token)
BW-->>B: 302 Redirección a la URL original
end
B->>BW: GET /protected (autenticado)
BW->>Up: Reenviar solicitud (+ header de identidad opcional)
Up-->>BW: Respuesta
BW-->>B: Respuesta
La URL de callback debe coincidir con la configuración del cliente en el IdP
Registre la URL completa de callback en el IdP (esquema + host + ruta). Por ejemplo con valores por defecto: https://app.example.com/callback.
Los claims son pares clave-valor en el token OIDC que describen al usuario (p. ej. email, groups, sub). La funcionalidad ACL permite restringir el acceso en base a valores de claims específicos.
Configuración
Predeterminado
Contexto
Múltiple
Descripción
OPENIDC_USE_ACL
no
multisite
no
Habilitar el control de acceso basado en claims tras la autenticación OIDC. Solo se concederá acceso a los usuarios cuyos claims coincidan con las reglas configuradas.
OPENIDC_ACL_MATCH_MODE
all
multisite
no
Cómo se evalúan múltiples reglas ACL. all = todas deben cumplirse (AND). any = al menos una debe cumplirse (OR).
OPENIDC_ACL_DENIED_URL
multisite
no
URL de redirección cuando el ACL deniega el acceso. Si está vacío, devuelve una respuesta 403 Forbidden.
OPENIDC_ACL_CLAIM
multisite
sí
Nombre del claim OIDC a verificar (p. ej. groups, email, sub). Se empareja con OPENIDC_ACL_CLAIM_VALUE.
OPENIDC_ACL_CLAIM_VALUE
multisite
sí
Valor esperado del claim. Para claims de tipo array (p. ej. groups), verifica pertenencia. Para claims de tipo string, verifica igualdad estricta.
Múltiples reglas ACL
Use sufijos numéricos para definir múltiples reglas. Cada par OPENIDC_ACL_CLAIM / OPENIDC_ACL_CLAIM_VALUE forma una regla:
Con OPENIDC_ACL_MATCH_MODE=any, se concede acceso si el usuario pertenece al grupo engineeringo tiene el correo admin@example.com. Con all, ambas condiciones deben cumplirse.
OPENIDC_DISCOVERY_DICT_SIZE (por defecto: 1m): tamaño del shared dict para caché de discovery.
OPENIDC_JWKS_DICT_SIZE (por defecto: 1m): tamaño del shared dict para caché de JWKS.
Almacenamiento de sesión en Redis
Cuando USE_REDIS=yes está configurado globalmente en BunkerWeb, el plugin OpenIDC almacena las sesiones en Redis en lugar de cookies (con fallback automático a cookies si Redis no está disponible). Es el modo recomendado para despliegues multi-instancia / HA.
El plugin usa OPENIDC_DISCOVERY (la URL .well-known/openid-configuration del IdP) para descubrir endpoints y luego obtiene y cachea claves JWKS para validar firmas.
Los datos de discovery/JWKS se cachean en shared dictionaries de NGINX. Si tiene muchos tenants/IdPs o conjuntos grandes de claves, incremente:
Por defecto, las sesiones se almacenan como cookies seguras gestionadas por la librería de OpenID Connect.
Si USE_REDIS=yes está habilitado globalmente y Redis está configurado, el plugin cambia automáticamente a sesiones en Redis (con fallback automático a cookies si Redis no está disponible temporalmente). Recomendado en load balancing / HA y evita límites de tamaño de cookies cuando los tokens son grandes.
Si OPENIDC_USER_HEADER está configurado (por defecto: X-User), el plugin inyecta un valor de header extraído de un claim (por defecto: OPENIDC_USER_HEADER_CLAIM=sub).
Comportamiento de seguridad importante:
El plugin borra cualquier header entrante que coincida con OPENIDC_USER_HEADER para evitar spoofing del cliente.
Si el claim configurado falta, el header no se establece.
Configure OPENIDC_USER_HEADER como vacío para desactivar el envío de identidad.
Elegir un claim
Prefiera identificadores estables presentes en los tokens (p. ej. sub, email, preferred_username). Los claims se leen primero del ID token, luego de userinfo si existe.
El plugin SAML (PRO) convierte BunkerWeb en un proveedor de servicios (SP) SAML 2.0 para el SSO del navegador. Acepta una respuesta del IdP cuya aserción esté cubierta por una firma de confianza, crea una sesión y puede exponer atributos seleccionados al upstream protegido como cabeceras. Es compatible con BunkerWeb 1.6.14 y versiones posteriores de la serie 1.6.x.
Utilice un origen HTTPS público para cada servicio protegido, como https://app.example.com, sin barra final, ruta ni cadena de consulta. Se permite un puerto HTTPS no estándar. SAML necesita tres piezas de material PEM:
una clave privada RSA sin cifrar para el SP;
el certificado SP correspondiente en formato PEM; y
el certificado de firma PEM del IdP, en el que BunkerWeb confía al verificar las aserciones.
La clave y el certificado del SP deben coincidir y deben ser claves RSA de al menos 2048 bits. La URL SSO del IdP y, cuando se proporcione, la URL SLO del IdP deben usar HTTPS. Mantenga secreta la clave privada; BunkerWeb la utiliza para firmar las solicitudes de autenticación y cierre de sesión.
Abra SAML para el servicio de destino y elija su ámbito. El formulario agrupa los ajustes en secciones de IdP, SP, sesión, cabeceras de identidad y ACL. Utilice este orden:
Habilite USE_SAML para el servicio.
Introduzca el origen público del SP, el ID de entidad del SP, el certificado SP y la clave privada RSA sin cifrar.
Introduzca el ID de entidad del IdP, la URL SSO HTTPS, el certificado de firma PEM de confianza y la URL SLO HTTPS opcional. Una URL SLO vacía utiliza la URL SSO.
Mantenga las rutas locales predeterminadas salvo que entren en conflicto con una ruta existente. Guarde y aplique la configuración.
Use Export metadata para descargar o mostrar los metadatos SP de BunkerWeb y, a continuación, registre esos metadatos y las URL ACS/SLO exactas en el IdP.
Configure los atributos de identidad y las reglas ACL, y vuelva a guardar y aplicar.
BunkerWeb exporta los metadatos SP; no importa ni actualiza automáticamente los metadatos del IdP. Configure primero los campos y certificados del IdP y después exporte los metadatos para evitar una configuración circular.
Un inicio de sesión iniciado por el SP firma la AuthnRequest con la clave privada del SP y la envía al IdP mediante HTTP-Redirect. El IdP devuelve a la ACS mediante HTTP-POST una respuesta cuya aserción está cubierta por su firma. BunkerWeb valida la correlación, el destino, el emisor, las marcas de tiempo de la aserción, la firma y el estado de repetición antes de crear una sesión. El cuerpo de la solicitud original no se reproduce.
sequenceDiagram
participant B as Navegador
participant BW as BunkerWeb (SP SAML)
participant IdP as Proveedor de identidad
participant Up as Upstream
B->>BW: GET /protected
BW-->>B: 302 AuthnRequest HTTP-Redirect firmada
B->>IdP: GET URL SSO con SAMLRequest
IdP-->>B: 200/POST SAMLResponse con aserción protegida por firma
B->>BW: POST ACS con SAMLResponse
BW->>BW: Validar firma, emisor, destino, expiración y repetición
BW-->>B: 302 /protected con cookie de sesión
B->>BW: GET /protected
BW->>Up: Solicitud más cabeceras de identidad configuradas
Up-->>BW: Respuesta
BW-->>B: Respuesta
Todas las rutas de endpoint son rutas locales en el origen SP público. Las predeterminadas son ajustes multisite y pueden cambiarse cuando estén disponibles para el servicio.
Endpoint
Configuración
Predeterminado
Método y propósito
Metadatos SP
SAML_METADATA_PATH
/saml/metadata
GET o HEAD; publica los metadatos de entidad SP, ACS, SLO y certificado de firma.
Servicio consumidor de aserciones (ACS)
SAML_ACS_PATH
/saml/acs
POST; recibe la respuesta del IdP cuya aserción está cubierta por su firma.
Cierre de sesión local
SAML_LOGOUT_PATH
/saml/logout
Inicia el cierre de sesión local; una sesión autenticada activa una solicitud de cierre de sesión firmada al IdP.
Servicio de cierre de sesión único (SLS)
SAML_SLS_PATH
/saml/sls
GET o POST; recibe una solicitud o respuesta de cierre de sesión del IdP.
SAML_LOGOUT_REDIRECT (predeterminado /) es la ruta local utilizada después del cierre de sesión. Mantenga las cuatro rutas de endpoint distintas y sin cadenas de consulta, fragmentos, barras invertidas, espacios en blanco ni segmentos de recorrido.
La guía del cliente SAML de Keycloak 26.5.2 utiliza las pestañas de cliente Settings, Keys y Advanced. Utilice los siguientes valores para la disposición de endpoints predeterminada de BunkerWeb. Reemplace https://app.example.com con el SAML_SP_BASE_URL exacto.
Cree un cliente SAML habilitado con estos valores de registro. En la UI de Keycloak, Enabled y Front channel logout están activados (true); el protocolo del cliente es SAML.
Configuración del cliente
Valor
ID del cliente
https://app.example.com/saml/metadata
Protocolo
SAML
Habilitado
true
Cierre de sesión del canal frontal
true
URI de redirección válidas
https://app.example.com/saml/acs y https://app.example.com/saml/sls
En la configuración del cliente, exija aserciones y documentos firmados, exija firmas del cliente, seleccione RSA_SHA256 y active Force POST Binding. Deje Encrypt Assertions desactivado: BunkerWeb requiere que la aserción esté cubierta por una firma de IdP de confianza, ya sea en la aserción o en la respuesta completa, y no acepta aserciones cifradas. En Keys, active Client Signature Required. Establezca Use metadata descriptor URL en OFF y proporcione manualmente el certificado SP, para que Keycloak pueda verificar las solicitudes firmadas de BunkerWeb sin un ciclo de importación de metadatos del IdP. En Advanced, establezca Assertion Consumer Service POST Binding URL en /saml/acs y tanto Logout Service POST Binding URL como Logout Service Redirect Binding URL en /saml/sls en el origen público. Establezca el formato Name ID en username y fuerce ese formato.
Añada mapeadores de protocolo para email, groups y name. Para cada mapeador, utilice protocol: "saml", protocolMapper: "saml-user-attribute-mapper" y consentRequired: false; establezca config.user.attribute y config.attribute.name en el mismo atributo, y config.attribute.nameformat en Basic. Asegúrese de que el usuario del IdP tenga realmente estos atributos; un claim ausente no produce la cabecera correspondiente en el upstream.
Desfase de reloj permitido para la aserción en segundos; el rango válido es 0–300.
SAML_SESSION_IDLE_TIMEOUT
900
Duración de la sesión inactiva en segundos; el rango válido es 1–86400.
SAML_SESSION_ABSOLUTE_TIMEOUT
3600
Duración máxima de la sesión en segundos; el rango válido es 1–86400.
SAML_USER_HEADER
X-User
Cabecera del upstream para el valor de usuario; vacío la desactiva.
SAML_USER_ATTRIBUTE
NameID
Atributo para el valor de usuario; NameID significa el identificador del sujeto.
SAML_EMAIL_HEADER
empty
Cabecera del upstream para el correo electrónico; vacío la desactiva.
SAML_EMAIL_ATTRIBUTE
email
Atributo para el correo electrónico; NameID significa el identificador del sujeto.
SAML_GROUPS_HEADER
empty
Cabecera del upstream para los grupos; vacío la desactiva.
SAML_GROUPS_ATTRIBUTE
groups
Atributo para los grupos; NameID significa el identificador del sujeto.
SAML_NAME_HEADER
empty
Cabecera del upstream para el nombre mostrado; vacío la desactiva.
SAML_NAME_ATTRIBUTE
name
Atributo para el nombre mostrado; NameID significa el identificador del sujeto.
SAML_GROUPS_SEPARATOR
,
Une varios valores en una cabecera.
Antes de la autenticación, BunkerWeb elimina cada cabecera de identidad SAML configurada de la solicitud entrante. Solo añade una cabecera después de una respuesta válida y cuando existe el atributo asignado. Los nombres de cabecera deben ser únicos y sintácticamente válidos, y no pueden utilizar prefijos de enrutamiento o sensibles a la seguridad, como X-Forwarded-*, Proxy-* o Sec-*. Estas cabeceras llevan la identidad al upstream protegido; no inician sesión de un usuario en la interfaz web de BunkerWeb.
El primer par es _1 y el segundo es _2; la UI numera las reglas desde 1. Con un recuento explícito de 2, se requieren ambos pares; un atributo ausente deniega el acceso, mientras que un valor configurado vacío es una denegación. Con all, todas las reglas deben coincidir; con any, basta una regla coincidente. Sin reglas, se permite el acceso a todos los usuarios autenticados. En un ámbito de servicio, la UI hereda la lista de reglas global hasta que elija una lista de servicio; guardar una lista de servicio reemplaza esa lista heredada, incluso cuando el reemplazo está explícitamente vacío. Deje SAML_ACL_RULE_COUNT vacío para descubrir reglas numeradas hasta las primeras 100 posiciones. Establézcalo en 0 para borrar todas las reglas. Un modo no válido o una lista explícita malformada deniega por defecto. SAML_ACL_DENIED_URL redirige cuando está establecido; de lo contrario, BunkerWeb devuelve su estado de denegación.
Capacidad de memoria compartida para la protección contra repetición en una instancia.
Cada ID de aserción aceptado se añade atómicamente al almacén de repeticiones durante el tiempo en que todavía podría aceptarse. El ID de AuthnRequest pendiente es un valor de correlación de sesión separado. En una instancia, aumente SAML_REPLAY_DICT_SIZE cuando el diccionario compartido sea demasiado pequeño. Para réplicas, habilite el modo de sesión USE_REDIS=yes del núcleo y dirija cada instancia al mismo servicio Redis para que las claves de repetición utilicen el almacén compartido. Mantenga también SESSIONS_SECRET del núcleo idéntico en cada réplica; de lo contrario, un worker no puede leer una sesión creada por otro. De forma predeterminada, las sesiones utilizan cookies seguras y restringidas al host, con HttpOnly, Secure y SameSite=None. Con Redis habilitado, los datos de sesión pasan a un almacén Redis con espacio de nombres en lugar de la cookie. SessionNotOnOrAfter del IdP puede finalizar una sesión antes que los tiempos de espera configurados. Una aserción consumida sigue consumida si falla un paso posterior del callback.
Solicitar SAML_LOGOUT_PATH borra el estado autenticado, guarda una correlación de cierre de sesión pendiente e inicia el SLO de front-channel. BunkerWeb envía una solicitud de cierre de sesión firmada mediante el binding Redirect. Después de una LogoutResponse firmada y válida, destruye la sesión local y redirige el navegador a SAML_LOGOUT_REDIRECT. Una LogoutRequest iniciada por el IdP puede llegar a SAML_SLS_PATH; el SLS valida el emisor, el destino, el NameID, el índice de sesión y el estado de repetición, destruye la sesión local y devuelve una respuesta firmada al IdP. Si no existe una sesión local, la ruta de cierre de sesión destruye la sesión vacía y redirige localmente.
Actualmente SAML admite el inicio de sesión de navegador iniciado por el SP con una AuthnRequest Redirect firmada y una respuesta ACS POST. No admite el inicio de sesión iniciado por el IdP, aserciones cifradas ni la importación y actualización automáticas de metadatos del IdP. Mantenga el IdP configurado para firmar documentos/aserciones y enviar la respuesta con binding POST. Los cuerpos POST de autenticación y cierre de sesión están limitados a 256 KiB; las solicitudes demasiado grandes se rechazan antes de procesarse.
La UI no habilita SAML: compruebe el origen HTTPS, los tres certificados/claves, la clave y el certificado RSA coincidentes, los valores de entidad/SSO del IdP y las cuatro rutas locales distintas. Se rechaza una configuración no válida y la solicitud deniega por defecto con 503; ninguna solicitud llega al upstream.
El IdP rechaza la AuthnRequest: compare el ID de entidad del SP, las URL ACS/SLS exactas, el certificado SP, el ajuste RSA-SHA256 y el requisito de firma del cliente. En Keycloak, compruebe que Use metadata descriptor URL esté desactivado y que el certificado SP proporcionado manualmente esté actualizado.
La ACS devuelve un error o 503: verifique el certificado de firma del IdP, la cobertura de la firma de la aserción, el emisor, el destino, la sincronización del reloj, el binding de respuesta, la correlación de solicitud pendiente y que el ID de aserción no se haya consumido ya. Compruebe que el IdP envíe los atributos asignados.
Un usuario se autentica pero recibe una denegación: habilite los atributos ACL esperados, confirme los pares numerados y SAML_ACL_RULE_COUNT, y compruebe all frente a any. Un valor de atributo vacío o un claim ausente pueden denegar por diseño.
Una sesión desaparece detrás de un balanceador de carga: utilice el mismo almacén Redis y el mismo secreto de sesión del núcleo en cada réplica. Redis debe estar disponible cuando USE_REDIS=yes; la protección contra repetición y las sesiones no recurren silenciosamente al estado por worker.
El plugin LDAP SSO agrega Single Sign-On basado en LDAP a sus servicios de BunkerWeb. Proporciona un formulario de inicio de sesión, autentica a los usuarios contra un directorio LDAP, crea una sesión y, opcionalmente, reenvía el nombre de usuario autenticado a su upstream mediante una cabecera configurable.
El plugin admite dos modos de autenticación:
Modo búsqueda-luego-bind (recomendado, también llamado "modo de búsqueda empresarial"): una cuenta de servicio busca en el directorio al usuario y luego realiza el bind como el DN encontrado para verificar la contraseña. Se habilita cuando LDAP_USER_SEARCH_BASE_DN está configurado.
Modo bind directo: construye el DN del usuario a partir de una plantilla (LDAP_USER_DN_TEMPLATE) y realiza el bind directamente. Se usa como respaldo cuando el modo de búsqueda no está configurado.
LDAP/LDAPS/STARTTLS: conexión mediante LDAP simple, LDAPS (TLS desde el inicio) o actualización STARTTLS.
Modo búsqueda-luego-bind: la cuenta de servicio realiza la búsqueda de usuarios con base, filtro, alcance y límites de tamaño/tiempo configurables.
Respaldo con bind directo: autenticación basada en plantilla de DN cuando el modo de búsqueda no es necesario.
Filtro de autorización: filtro LDAP adicional opcional para restringir el acceso más allá de la autenticación básica.
Pool de conexiones: keepalive con tamaño de pool y timeout configurables para reducir las ida y vuelta al servidor LDAP.
Gestión de sesiones: TTL configurable con limpieza automática de sesiones.
Reenvío de cabecera de usuario: pasa el nombre de usuario autenticado a los upstreams mediante una cabecera configurable (por defecto: X-User).
Rutas de login/logout: endpoints dedicados para autenticación y terminación de sesión.
Las credenciales se envían en texto plano por defecto
Con la configuración predeterminada (LDAP_LDAPS=no, LDAP_STARTTLS=no), las contraseñas de los usuarios se transmiten en texto claro al servidor LDAP. Habilite siempre LDAP_LDAPS=yes (con LDAP_PORT=636) o LDAP_STARTTLS=yes en producción. Mantenga LDAP_SSL_VERIFY=yes para prevenir ataques de degradación TLS.
Plantilla del filtro de búsqueda LDAP. Use el marcador {username}.
LDAP_AUTHZ_FILTER
multisite
no
Filtro LDAP de autorización adicional opcional (combinado con AND al filtro de búsqueda).
LDAP_USER_SEARCH_SCOPE
subtree
multisite
no
Alcance de la búsqueda LDAP: base, onelevel o subtree.
LDAP_USER_SEARCH_DEREF_ALIASES
always
multisite
no
Modo de desreferencia de alias LDAP: always, never, in_searching o finding_base.
LDAP_USER_SEARCH_SIZE_LIMIT
10
multisite
no
Número máximo de entradas LDAP devueltas por la búsqueda de usuarios.
LDAP_USER_SEARCH_TIME_LIMIT
10
multisite
no
Tiempo máximo de búsqueda LDAP de usuarios en segundos.
LDAP_USER_SEARCH_ATTRIBUTES
dn
multisite
no
Atributos solicitados durante la búsqueda de usuarios (separados por espacios).
LDAP_USER_SEARCH_DN_FIELD
object_name
multisite
no
Nombre del campo en la respuesta de búsqueda para extraer el DN del usuario. El valor predeterminado object_name es el campo DN devuelto por la librería LDAP subyacente; normalmente no necesita cambiarlo.
LDAP_USER_SEARCH_REQUIRE_UNIQUE
yes
multisite
no
Exigir exactamente un resultado de búsqueda antes de autenticar al usuario.
Modo bind directo
Configuración
Predeterminado
Contexto
Múltiple
Descripción
LDAP_USER_DN_TEMPLATE
uid={username},ou=people,dc=example,dc=com
multisite
no
Plantilla de DN de usuario para bind directo. Debe incluir {username} al configurarlo.
Sesión y rutas
Configuración
Predeterminado
Contexto
Múltiple
Descripción
LDAP_USERNAME_REGEX
^[A-Za-z0-9@._-]+$
multisite
no
Regex PCRE para validar los nombres de usuario enviados.
LDAP_LOGIN_PATH
/ldap/login
multisite
no
Ruta de la página de inicio de sesión expuesta por el plugin LDAP.
LDAP_LOGOUT_PATH
/ldap/logout
multisite
no
Ruta de cierre de sesión expuesta por el plugin LDAP.
LDAP_SESSION_TTL
3600
multisite
no
Duración de validez de la sesión LDAP en segundos.
LDAP_REALM
LDAP SSO
multisite
no
Realm de autenticación mostrado en el formulario de inicio de sesión LDAP.
LDAP_USER_HEADER
X-User
multisite
no
Cabecera para enviar el nombre de usuario autenticado al upstream (vacío para deshabilitar).
LDAP_REDIRECT_AFTER_LOGIN
/
multisite
no
Ruta relativa de respaldo tras inicio de sesión exitoso cuando no se proporciona un destino de redirección.
LDAP_REDIRECT_AFTER_LOGOUT
/
multisite
no
Ruta relativa para redirigir a los usuarios tras el cierre de sesión.
Prefiera el modo búsqueda-luego-bind sobre el bind directo: admite búsquedas flexibles de usuarios en múltiples atributos (uid, mail, sAMAccountName, UPN).
Use LDAPS (LDAP_LDAPS=yes) o STARTTLS (LDAP_STARTTLS=yes) en producción para cifrar las credenciales en tránsito.
Al habilitar LDAPS (LDAP_LDAPS=yes), recuerde también establecer LDAP_PORT=636. El puerto no cambia automáticamente.
Mantenga LDAP_SSL_VERIFY=yes salvo que esté realizando pruebas con certificados autofirmados.
Ajuste LDAP_KEEPALIVE_POOL_SIZE para que coincida con el volumen esperado de usuarios concurrentes y reducir la sobrecarga de conexiones LDAP.
Establezca LDAP_USER_HEADER como vacío para deshabilitar el reenvío de identidad a los upstreams.
El plugin OpenAPI Validator aplica su contrato de API validando las solicitudes entrantes contra una especificación OpenAPI / Swagger. Asegura que la ruta solicitada exista, que el método HTTP esté permitido y, opcionalmente, valida los parámetros de consulta, cabecera, cookie y ruta contra sus definiciones de esquema.
Un trabajo programado (openapi-download.py) obtiene el documento OpenAPI de una URL o archivo y lo guarda en caché en el disco (cada hora por defecto).
En el momento de la inicialización de NGINX, el plugin compila las rutas de la especificación almacenada en caché y las guarda en un almacenamiento interno compartido.
Durante el procesamiento de la solicitud, el plugin hace coincidir la solicitud con las rutas compiladas y aplica la validación.
El plugin Cache PRO habilita el almacenamiento en caché de respuestas a nivel de reverse proxy usando directivas NGINX proxy_cache*. Es útil para absorber lecturas repetidas de contenido cacheable, proteger a los upstreams durante picos de carga y servir contenido obsoleto durante fallos breves del backend.
Cómo funciona
Cada valor global CACHE_PATH* crea una directiva proxy_cache_path en el contexto HTTP.
Un servicio empieza a usar la caché solo cuando CACHE_ZONE coincide con una de las zonas declaradas en CACHE_PATH*.
Las configuraciones a nivel de servicio controlan después la clave de caché, las condiciones de bypass/no-cache, el locking, el uso de stale y las reglas de validez.
Si se define CACHE_HEADER, BunkerWeb añade una cabecera de respuesta que expone $upstream_cache_status como HIT, MISS, BYPASS, EXPIRED o STALE.
Lista de características
Caché de respuestas de reverse proxy con rutas y zonas configurables.
Activación de caché por servicio mediante CACHE_ZONE.
Cabecera opcional para exponer el estado de la caché con $upstream_cache_status.
Controles detallados para bypass, no-cache, clave, métodos, locking, stale y revalidación.
Varias reglas de validez mediante configuraciones CACHE_VALID*.
Lista de configuraciones
Configuración
Predeterminado
Contexto
Múltiple
Descripción
CACHE_PATH
global
sí
Ruta y parámetros para una caché.
CACHE_ZONE
multisite
no
Nombre de la zona de caché a usar (definida en una configuración CACHE_PATH).
CACHE_HEADER
X-Cache
multisite
no
Añade una cabecera que expone el estado de la caché.
CACHE_BACKGROUND_UPDATE
no
multisite
no
Habilita o deshabilita la actualización en segundo plano de la caché.
CACHE_BYPASS
multisite
no
Lista de variables que determinan si se debe omitir la caché.
CACHE_NO_CACHE
$http_pragma$http_authorization
multisite
no
Evita almacenar en caché si ciertas variables están definidas.
CACHE_KEY
$scheme$proxy_host$request_uri
multisite
no
Clave usada para identificar elementos cacheados.
CACHE_CONVERT_HEAD_TO_GET
yes
multisite
no
Convierte solicitudes HEAD en GET al cachear.
CACHE_LOCK
no
multisite
no
Bloquea solicitudes concurrentes mientras se llena la caché.
CACHE_LOCK_AGE
5s
multisite
no
Pasa la solicitud al upstream si el bloqueo dura ese tiempo.
CACHE_LOCK_TIMEOUT
5s
multisite
no
Pasa la solicitud al upstream si el bloqueo persiste durante ese tiempo.
CACHE_METHODS
GET HEAD
multisite
no
Solo cachea respuestas para estos métodos HTTP.
CACHE_MIN_USES
1
multisite
no
Número de solicitudes antes de guardar la respuesta en caché.
CACHE_REVALIDATE
no
multisite
no
Revalida entradas expiradas con solicitudes condicionales al upstream.
CACHE_USE_STALE
off
multisite
no
Determina cuándo se puede servir contenido obsoleto.
CACHE_VALID
10m
multisite
sí
Define la duración de caché con códigos HTTP opcionales.
Este plugin solo se aplica al tráfico reverse proxy. No cachea contenido servido directamente desde archivos estáticos locales ni servicios stream/TCP.
CACHE_ZONE debe coincidir con una zona definida en un valor CACHE_PATH* mediante keys_zone=<nombre>:<tamaño>.
Si CACHE_ZONE está vacío para un servicio, no se aplican directivas de caché a ese servicio.
Usa sufijos numéricos para valores repetidos como CACHE_PATH_1, CACHE_PATH_2, CACHE_VALID_1 y CACHE_VALID_2.
Mantén fuera de la caché el tráfico autenticado o específico de usuario salvo que CACHE_KEY varíe explícitamente según ese estado.
CACHE_LOCK=yes y CACHE_BACKGROUND_UPDATE=yes ayudan a reducir estampidas hacia el origen.
El plugin ACME proporciona gestión avanzada de certificados mediante el protocolo ACME con soporte para Autoridades de Certificación personalizadas (Step CA, Vault PKI, Sectigo, Google Trust Services, etc.). Complementa el plugin integrado de Let's Encrypt agregando soporte para CA personalizadas, desafíos DNS-01 y TLS-ALPN-01, certificados wildcard, monitoreo de certificados con alertas de expiración, monitoreo de logs de Certificate Transparency y stapling OCSP mejorado.
Cuándo usar ACME vs el plugin integrado de Let's Encrypt
Si solo necesita certificados de Let's Encrypt con desafíos HTTP-01, el plugin integrado de Let's Encrypt (AUTO_LETS_ENCRYPT=yes) es suficiente. Use el plugin ACME cuando necesite CA personalizadas, desafíos DNS-01 o TLS-ALPN-01, certificados wildcard o monitoreo de certificados con alertas.
Soporte para CA personalizadas: use cualquier Autoridad de Certificación compatible con ACME, no solo Let's Encrypt.
Múltiples tipos de desafío: HTTP-01, DNS-01 (requerido para wildcards) y TLS-ALPN-01.
Integración con proveedores DNS: soporte integrado para Cloudflare, Route53, DigitalOcean, OVH y más.
External Account Binding (EAB): para CA que requieren claves preregistradas (Sectigo, Google Trust Services).
Certificados wildcard: mediante desafío DNS-01.
Monitoreo de certificados: rastrea la expiración de todos los certificados gestionados (incluido Let's Encrypt OSS) con umbrales de alerta configurables.
Alertas de expiración: envía alertas por webhook o correo electrónico cuando los certificados se acercan a su vencimiento.
Monitoreo de Certificate Transparency: consulta crt.sh para detectar emisiones no autorizadas de certificados para sus dominios.
Stapling OCSP mejorado: obtención y almacenamiento proactivo de respuestas OCSP.
Tipos de clave configurables: ECDSA (256/384) o RSA (2048/4096).
El desafío HTTP-01 requiere LETS_ENCRYPT_PASSTHROUGH=yes¶
Al usar ACME_CHALLENGE=http (el valor predeterminado), debe establecer LETS_ENCRYPT_PASSTHROUGH=yes en el mismo servicio.
El plugin principal de Let's Encrypt de BunkerWeb incluye tanto un bloque de ubicación NGINX como un handler de acceso Lua para /.well-known/acme-challenge/. Dado que el bloque de ubicación NGINX coincide antes de que se ejecute cualquier código de plugin Lua, intercepta las solicitudes del desafío antes de que ACME PRO pueda atenderlas. Establecer LETS_ENCRYPT_PASSTHROUGH=yes deshabilita ambos mecanismos para que ACME PRO pueda gestionar correctamente los tokens del desafío HTTP-01.
Esto solo es necesario para HTTP-01. Los desafíos DNS-01 y TLS-ALPN-01 no se ven afectados.
Si el servidor upstream detrás de BunkerWeb ya ejecuta su propio cliente ACME y debe encargarse él mismo de la validación HTTP-01, establezca ACME_PASSTHROUGH=yes en el servicio. ACME PRO dejará de renderizar su bloque de ubicación /.well-known/acme-challenge/ y no añadirá las rutas del desafío a la lista blanca en la fase access, de modo que los archivos de validación servidos por el upstream lleguen intactos a la CA.
Mantenga ACME_PASSTHROUGH=no (el valor predeterminado) cuando desee que ACME PRO obtenga y renueve los certificados por sí mismo. La combinación estándar HTTP-01 para los servicios gestionados por ACME PRO es LETS_ENCRYPT_PASSTHROUGH=yes (para que el plugin OSS principal de Let's Encrypt libere su ubicación del desafío) junto con ACME_PASSTHROUGH=no. Establezca ACME_PASSTHROUGH=yes únicamente cuando el upstream sea el propietario del ciclo de vida del certificado — en este modo BunkerWeb no intentará emitir un certificado para ese servicio.
Esta configuración refleja el comportamiento del LETS_ENCRYPT_PASSTHROUGH del núcleo OSS y solo afecta a HTTP-01; los desafíos DNS-01 y TLS-ALPN-01 no se ven afectados.
El plugin ACME se reordena automáticamente para ejecutarse primero en la fase NGINX ssl_certificate, asegurando que los certificados del desafío TLS-ALPN-01 se sirvan antes de que otros plugins que proporcionan certificados (selfsigned, letsencrypt, customcert) puedan cortocircuitar el bucle.
Al usar ACME junto con otros plugins PRO que dependen de TLS válido (p. ej. OpenID Connect, UI SSO), se recomienda agregar explícitamente acme justo después de customcert en las configuraciones de orden de fases relevantes:
Los plugins externos/PRO no listados en las configuraciones PLUGINS_ORDER_* se agregan alfabéticamente después de los plugins principales ordenados explícitamente.
No habilite USE_ACME y AUTO_LETS_ENCRYPT en el mismo servicio
El plugin ACME y el plugin integrado de Let's Encrypt usan almacenamiento, endpoints de API y claves de caché independientes, pero habilitar ambos en el mismo servicio causará conflictos. Use uno u otro por servicio. En modo multisite, diferentes servicios pueden usar diferentes plugins -- por ejemplo, app1.example.com_USE_ACME=yes y app2.example.com_AUTO_LETS_ENCRYPT=yes.
Solicitar la extensión OCSP Must-Staple en el certificado.
ACME_MAX_RETRIES
3
multisite
no
Número de reintentos de generación del certificado en caso de fallo (0 deshabilita reintentos).
ACME_PREFERRED_CHAIN
multisite
no
CN del emisor preferido de la cadena de certificados cuando la CA ofrece múltiples cadenas.
ACME_CA_CERT_PATH
multisite
no
Ruta al certificado raíz de la CA para servidores ACME privados.
External Account Binding (EAB)
Configuración
Predeterminado
Contexto
Múltiple
Descripción
ACME_EAB_KID
multisite
no
Key ID de External Account Binding (requerido por algunas CA).
ACME_EAB_HMAC_KEY
multisite
no
Clave HMAC de External Account Binding (codificada en base64).
Desafío DNS-01
Configuración
Predeterminado
Contexto
Múltiple
Descripción
ACME_DNS_PROVIDER
multisite
no
Proveedor DNS para los desafíos DNS-01.
ACME_DNS_CREDENTIAL_ITEM
multisite
sí
Credencial del proveedor DNS en formato key value (p. ej. cloudflare_api_token YOUR_TOKEN). Use sufijos numéricos para múltiples elementos (p. ej. ACME_DNS_CREDENTIAL_ITEM_1). Los valores pueden estar codificados en base64.
ACME_DNS_CREDENTIAL_DECODE_BASE64
yes
multisite
sí
Decodificar automáticamente credenciales del proveedor DNS en base64. Deshabilite si sus credenciales son texto plano que coincide con base64 válido.
ACME_DNS_PROPAGATION
default
multisite
no
Tiempo de espera para la propagación DNS en segundos (default o un número).
Monitoreo de certificados
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_ACME_MONITORING
yes
global
no
Habilitar el monitoreo de expiración de certificados para todos los certificados gestionados (incluido Let's Encrypt OSS).
ACME_ALERT_DAYS
30 14 7 1
global
no
Lista de umbrales de días separados por espacios que activan alertas de expiración.
Alertas (webhook)
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_ACME_ALERT_WEBHOOK
no
global
no
Enviar alertas de certificados por webhook.
ACME_ALERT_WEBHOOK_URLS
global
no
Lista de URLs de webhook separadas por espacios para alertas.
Alertas (correo electrónico)
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_ACME_ALERT_EMAIL
no
global
no
Enviar alertas de certificados por correo electrónico.
ACME_ALERT_SMTP_EMAILS
global
no
Lista de destinatarios de correo separados por espacios.
ACME_ALERT_SMTP_HOST
global
no
Host SMTP para correos de alertas de certificados.
ACME_ALERT_SMTP_PORT
465
global
no
Puerto SMTP (SSL=465, TLS=587).
ACME_ALERT_SMTP_FROM_EMAIL
global
no
Dirección de correo del remitente para alertas de certificados.
ACME_ALERT_SMTP_FROM_USER
global
no
Usuario de autenticación SMTP.
ACME_ALERT_SMTP_FROM_PASSWORD
global
no
Contraseña de autenticación SMTP.
ACME_ALERT_SMTP_SSL
SSL
global
no
Tipo de conexión: no, SSL o TLS.
Monitoreo de Certificate Transparency
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_ACME_CT_MONITORING
no
global
no
Habilitar el monitoreo de logs CT mediante crt.sh para detectar emisiones no autorizadas de certificados.
ACME_CT_MONITORED_DOMAINS
global
no
Lista de dominios a monitorear separados por espacios. Déjelo vacío para detección automática.
Stapling OCSP
Configuración
Predeterminado
Contexto
Múltiple
Descripción
USE_ACME_OCSP_STAPLING
no
multisite
no
Habilitar stapling OCSP mejorado con obtención y almacenamiento proactivo de respuestas.
ACME_OCSP_CACHE_SIZE
1m
global
no
Tamaño del diccionario compartido para el almacenamiento de respuestas OCSP.
El monitoreo de certificados (USE_ACME_MONITORING) está habilitado por defecto y también rastrea los certificados de Let's Encrypt OSS. Configure los umbrales de ACME_ALERT_DAYS y al menos un canal de alertas (webhook o correo electrónico) para recibir avisos de expiración.
Habilite el monitoreo CT (USE_ACME_CT_MONITORING=yes) para detectar certificados no autorizados emitidos para sus dominios mediante logs de Certificate Transparency.
Use claves ECDSA (valor predeterminado) para certificados más pequeños y rápidos. Cambie a RSA solo cuando se requiera compatibilidad con clientes antiguos.
Al usar desafíos DNS-01, ajuste ACME_DNS_PROPAGATION si su proveedor DNS tarda en propagar los registros.
Establezca ACME_MAX_RETRIES=0 para deshabilitar los reintentos automáticos si prefiere investigar los fallos manualmente.
Coexistencia con el plugin integrado de Let's Encrypt¶
ACME PRO y el plugin de Let's Encrypt OSS usan almacenamiento, endpoints de API y claves de caché completamente separados. Ambos pueden estar activos simultáneamente en diferentes servicios en modo multisite:
MULTISITE:"yes"SERVER_NAME:"app1.example.comapp2.example.com"# ACME PRO para app1 (CA privada)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"# necesario para HTTP-01# Let's Encrypt integrado para app2app2.example.com_AUTO_LETS_ENCRYPT:"yes"
Fallo en el desafío HTTP-01: asegúrese de que LETS_ENCRYPT_PASSTHROUGH=yes esté configurado; sin él, el bloque de ubicación principal de BunkerWeb intercepta las solicitudes del desafío antes de que ACME PRO pueda atenderlas. Verifique también que el puerto 80 sea accesible desde el servidor ACME y que AUTO_LETS_ENCRYPT no esté habilitado para el mismo servicio.
Fallo en el desafío TLS-ALPN-01: asegúrese de que el puerto 443 sea accesible desde el servidor ACME y que ningún otro plugin esté sirviendo un certificado antes de ACME en la fase ssl_certificate. Revise PLUGINS_ORDER_SSL_CERTIFICATE en caso de duda.
Fallo en el desafío DNS-01: verifique las credenciales del proveedor DNS en ACME_DNS_CREDENTIAL_ITEM y ajuste ACME_DNS_PROPAGATION si su proveedor tarda en propagar los registros.
El certificado no se renueva: revise ACME_RENEWAL_DAYS y los logs del programador. El trabajo acme-renew se ejecuta diariamente y renueva los certificados que están dentro del umbral configurado.
El plugin obtiene el nombre de host comodín a partir del primer valor de SERVER_NAME e inyecta un nombre de servidor comodín estándar de NGINX durante la generación de la configuración.
No cambia la lógica de manejo de solicitudes más allá de la coincidencia de hostnames.
Los hosts comodín no son certificados comodín
Este plugin solo afecta al enrutamiento HTTP. Indica a NGINX qué hostnames debe aceptar el servicio.
No aprovisiona un certificado TLS comodín.
Para servir *.example.com por HTTPS, sigue necesitando un certificado comodín compatible, normalmente con una de estas opciones:
USE_LETS_ENCRYPT_WILDCARD=yes con el plugin integrado de Let's Encrypt
ACME_WILDCARD=yes con el plugin ACME PRO usando un desafío DNS-01
Solo la primera entrada de SERVER_NAME se convierte en comodín
Si example.com va primero, el plugin genera *.example.com.
Si app.example.com va primero, genera *.app.example.com, lo que normalmente corresponde al nivel de comodín equivocado.
La segunda entrada ayuda a Let's Encrypt a detectar el dominio base correcto
Con solo un dominio apex, la detección del certificado comodín puede fallar en algunos dominios de sufijo público como example.co.uk.
El segundo hostname no necesita un backend real
Use cualquier valor estable como app.example.com o www.example.com.