Aplicación de acceso Dozzle/Sablier — 19 octubre 2026¶
Usuario autorizó aplicar la revisión adicional, con agentes en paralelo. Este agente ha modificado exclusivamente Dozzle/Sablier, sus sidecars internos, reglas aditivas de acceso y el cliente OIDC/claim lector específico. No ha tocado Synology, WordPress/Carmelo, daemon Docker, NAS, Bazzite ni otros secretos. Se han leído homelab-operations, access-and-decisions, homelab-add-service y la guía de altas por añadir dependencias internas. Sin rutas externas nuevas.
Resultado¶
- Dozzle v11.3.2 mantiene imagen
latestexistente, sin pull. Ahora exige OIDC Pocket ID nativo, TTL 8 horas, PKCE S256 y callback público correcto. No hay proveedor forward-proxy que permita suplantar una cabecera desde LAN. - Pocket ID 2.18.0 nativo CT213 mantiene sus usuarios/passkeys y clientes previos.
Nuevo cliente confidencial
dozzle; secreto privado en appdata/Dozzle. Claimdozzle_roles=["none"]solo en administrador existente, que permite lectura sin privilegios de acciones. Usuario sin claim queda rechazado. - Alta mediante API oficial y esquema/hash comprobados contra source 2.18.0. No había ninguna API key reutilizable: se creó una efímera con caducidad 15 min, tras copia SQLite online coherente, y se eliminó en finally. Recuento de esa clave al terminar: cero. No se han mostrado valores de secretos.
- Dozzle y Sablier ya no montan docker.sock. Usan dos proxies nginx internos y redes distintas, sin publicación de puertos. Dozzle tiene solo lectura de las rutas necesarias. Sablier 1.9 tiene lectura más start/stop/wait, validado contra su source exacto. Ambos bloquean create/exec/delete y demás rutas no incluidas.
- Actions, shell y MCP desactivados explícitamente en Dozzle; setup wizard no aparece automáticamente. Directorio /data persistente en appdata existente.
- Nginx workers necesitan propietario root para conectar al socket: son parte del plano de confianza. El filtro limita a los consumidores, no protege frente a un compromiso del propio proxy. Read-only socket no se presenta como ACL.
- Firewall 10000: permite Caddy
.40/.41, controller.212, observa.217, localhost/VM208 y llamadas internas Docker (p.ej. nopor-ingest). Resto LAN bloqueado. Dozzle 9999 sigue accesible por LAN con su autenticación nativa. - IPv6: filtro DOCKER-USER y también INPUT, que cubre el proxy IPv6 de Docker.
Se bloquean 10000, 5432 y 6379 por LAN IPv6; se mantienen las reglas IPv4 de
AudioMuse que solo permiten Bazzite
.141para PostgreSQL/Redis. - Persistencia de firewall en drop-in Docker ExecStartPost, daemon-reload y aplicación explícita ahora, sin reiniciar daemon ni el stack global.
Sesiones Sablier y conservación¶
--provider.auto-stop-on-startup=false evita apagar cargas descubiertas al
recrear el servicio. Sablier 1.9 expone --storage.file pero no lo usa fuera de
CLI/config en este source: no se afirma persistencia que no existe. Las sesiones
anteriores en RAM se han perdido y se renuevan en el siguiente acceso; las apps
que ya estaban encendidas se han conservado y pueden quedar activas hasta una
nueva sesión. No se ha sustituido la versión como efecto secundario del cambio.
Los IDs de todos los contenedores ajenos a Dozzle/Sablier coincidían con los
anteriores tras la aplicación. No se despertaron aplicaciones domésticas para
probar Sablier; se usaron fixtures sin red y sin datos persistentes.
Validación realizada¶
| Prueba | Resultado |
|---|---|
| Compose fuentes tools/Sablier y sidecars | Válido |
| Dozzle healthcheck / Sablier health | 200 / 200, Sablier healthy |
| Dozzle API eventos y logs anónimos, host/LAN | 401 |
| Dozzle API por HTTPS directo a ambos Caddy | 401 en ambos, TLS válido |
| Dozzle API por dominio público | 302 al perímetro de autenticación |
| Inicio OIDC mediante host público + forwarded HTTPS | 302 a Pocket ID, cliente dozzle, callback exacta, PKCE S256 |
| Validación secreto cliente con código deliberadamente inválido | invalid_grant, no invalid_client |
| Sablier salud desde ambos Caddy, observa y controller | 200 en los cuatro |
| Sablier desde Mac LAN y dirección ULA IPv6 | Timeout |
| Fixture Sablier inicio real | 200 y contenedor running |
| Fixture Sablier expiración | Stop/wait completados, contenedor detenido |
| Fixture no preparada, timeout 1 s | 500 esperado, sin bloquear indefinidamente |
| Lectura log sintético mediante proxy Dozzle | Correcta |
| POST create/exec y DELETE, ambos proxies | 403 |
| POST stop mediante proxy Dozzle | 403 |
| Dozzle temporal loopback, filtro solo fixture, log real | Correcto |
| Dozzle temporal ruta de acción deshabilitada | 404 |
| Aplicaciones ajenas | IDs preservados |
Login interactivo con passkey sigue pendiente del usuario; no se ha fabricado una sesión administrativa para atribuirle una prueba que no se ha hecho. La comprobación de cliente/issuer/callback/roles sí es real. No se ha realizado un reinicio de daemon/host para probar el drop-in; se ha verificado su carga y la aplicación efectiva de sus reglas. El timeout IPv6 aislado no demuestra por sí solo la ACL: se comprobó además la regla INPUT y DOCKER-USER correspondiente.
Durante la puesta en marcha hubo un fallo inicial de permisos del worker Nginx al socket. Se corrigió su usuario antes de validar, sin ampliar la ACL de API. No afectó a las aplicaciones ajenas. Se repitieron las pruebas con las fuentes finales; no se contabilizan como éxitos los ensayos intermedios fallidos.
Fuente y recuperación¶
Sidecars, firewall, validaciones y rollback.
Fuente principal del consumidor en VM208: /home/monxas/stacks/tools/compose.yaml
y /home/monxas/stacks/sablier/compose.yaml; preservados cambios previos ajenos
reverse-proxy/managed.caddy y scripts/homelab-ctl.py. Backups privados en
/home/monxas/backups/control-plane-access-20261019 y CT213
/root/backups/control-plane-access-20261019. No publicar esos archivos.
Fuentes oficiales consultadas y source contrastado: