====== Services de surveillance ======
Dernière mise à jour : juillet 2026
Stack Docker de supervision sur le serveur **cahute** (192.168.1.9) : logs conteneurs (Dozzle), disponibilité (Uptime-Kuma), portail (Homepage). Accès par sous-domaines via le proxy Caddy.
===== Vue d'ensemble =====
^ Service ^ Rôle ^ Port publié ^ Port interne ^ Sous-domaine ^
| Dozzle | Logs Docker en temps réel | 8888 | 8080 | %%https://logs.beafrancois.fr%% |
| Uptime-Kuma | Supervision up/down | 3001 | 3001 | %%https://status.beafrancois.fr%% |
| Homepage | Portail / tableau de bord | 3002 | 3000 | %%https://surveillance.beafrancois.fr%% |
Accès direct (LAN) : %%http://192.168.1.9:8888%% (Dozzle), %%http://192.168.1.9:3001%% (Uptime-Kuma), %%http://192.168.1.9:3002%% (Homepage).
===== Déploiement Docker =====
* Compose : ''/mnt/stockage/docker/compose/surveillance/docker-compose.yml''
* Données : ''/mnt/stockage/docker/data/{uptime-kuma,homepage}''
* Réseau Docker : ''surveillance_net''
* Tous les ports sont **bindés sur 192.168.1.9** (pas 0.0.0.0)
==== docker-compose.yml ====
services:
dozzle:
image: amir20/dozzle:latest
container_name: dozzle
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "192.168.1.9:8888:8080"
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: unless-stopped
volumes:
- /mnt/stockage/docker/data/uptime-kuma:/app/data
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "192.168.1.9:3001:3001"
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
restart: unless-stopped
environment:
- HOMEPAGE_ALLOWED_HOSTS=surveillance.beafrancois.fr
volumes:
- /mnt/stockage/docker/data/homepage:/app/config
ports:
- "192.168.1.9:3002:3000"
networks:
default:
name: surveillance_net
Commandes :
cd /mnt/stockage/docker/compose/surveillance
docker compose up -d # démarrer / appliquer les changements
docker compose up -d homepage # redémarrer un seul service
docker compose logs -f uptime-kuma
===== Notes par service =====
==== Dozzle ====
Accès en lecture seule au socket Docker (''docker.sock:ro'') pour lire les logs de tous les conteneurs. Pas de volume de données (sans état).
==== Uptime-Kuma ====
Données persistées dans ''/mnt/stockage/docker/data/uptime-kuma''. Accède aussi au socket Docker (monitoring des conteneurs). Configuration des sondes via son interface web.
==== Homepage ====
Config dans ''/mnt/stockage/docker/data/homepage'' (fichiers YAML : services.yaml, widgets.yaml, settings.yaml…).
**⚠️ HOMEPAGE_ALLOWED_HOSTS** : Homepage (v0.9+) rejette toute requête dont le ''Host'' n'est pas autorisé, avec l'erreur **« Host validation failed »** (protection anti DNS-rebinding). Chaque nom d'accès doit être listé dans cette variable (séparés par des virgules, **sans espace**) :
- HOMEPAGE_ALLOWED_HOSTS=surveillance.beafrancois.fr
# plusieurs hôtes :
- HOMEPAGE_ALLOWED_HOSTS=localhost:3000,surveillance.beafrancois.fr
Après modif : ''docker compose up -d homepage''.
===== Configuration réseau =====
==== DNS local (routeur OpenWrt) ====
Entrées faisant pointer les sous-domaines vers le proxy Caddy (192.168.1.25) :
uci add_list dhcp.@dnsmasq[0].address='/surveillance.beafrancois.fr/192.168.1.25'
uci add_list dhcp.@dnsmasq[0].address='/status.beafrancois.fr/192.168.1.25'
uci add_list dhcp.@dnsmasq[0].address='/logs.beafrancois.fr/192.168.1.25'
uci commit dhcp
/etc/init.d/dnsmasq restart
(Ces entrées apparaissent comme des ''dhcp.@domain[n]'' — name + ip=192.168.1.25.)
==== Reverse proxy Caddy (proxy .25) ====
Blocs Caddyfile. ''tls internal'' (cert auto-signé, pas de DNS public). Le filtre ''@denied'' restreint l'accès web aux réseaux de confiance (LAN, wifi invité, VPN) :
surveillance.beafrancois.fr {
@denied not remote_ip 192.168.1.0/24 192.168.115.0/24 10.1.100.0/24
respond @denied 403
tls internal
reverse_proxy 192.168.1.9:3002
}
status.beafrancois.fr {
@denied not remote_ip 192.168.1.0/24 192.168.115.0/24 10.1.100.0/24
respond @denied 403
tls internal
reverse_proxy 192.168.1.9:3001
}
logs.beafrancois.fr {
@denied not remote_ip 192.168.1.0/24 192.168.115.0/24 10.1.100.0/24
respond @denied 403
tls internal
reverse_proxy 192.168.1.9:8888
}
Recharge : ''docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile''
==== Pare-feu UFW (serveur) ====
Règles visant à n'autoriser que le proxy (.25) sur les ports monitoring :
sudo ufw allow from 192.168.1.25 to any port 3001 proto tcp
sudo ufw allow from 192.168.1.25 to any port 3002 proto tcp
sudo ufw allow from 192.168.1.25 to any port 8888 proto tcp
===== ⚠️ LIMITATION IMPORTANTE — Docker contourne UFW =====
**Les règles UFW ci-dessus ne s'appliquent PAS aux conteneurs Docker.** Docker insère ses propres règles iptables (chaînes FORWARD / DOCKER) **en amont d'UFW**. Le trafic vers un port publié par Docker court-circuite donc les règles UFW ''INPUT''.
**Conséquence constatée :** l'accès direct %%http://192.168.1.9:8888%% (Dozzle) reste joignable depuis le VPN (10.1.100.x) malgré la règle « from .25 only ». À l'inverse, **Cockpit (9090), service bare-metal**, est bien filtré par UFW (il passe par ''INPUT'') — ce qui prouve la différence conteneur vs bare-metal.
**Portée du problème :** cela concerne **tous** les conteneurs à ports publiés, LLDAP inclus (6360, 17170). Les restrictions UFW supposées sur ces ports ne sont pas réellement appliquées au trafic Docker.
**Ce qui protège malgré tout :**
* Le binding sur ''192.168.1.9'' (pas 0.0.0.0) limite l'exposition à cette interface.
* Le filtre ''@denied'' de Caddy restreint l'accès **par les sous-domaines**.
* Mais l'accès **direct IP:port** aux conteneurs n'est pas bloqué pour les réseaux qui atteignent .9.
**Solution à mettre en place (session dédiée) :** installer **''ufw-docker''**, qui réintègre le trafic Docker sous contrôle d'UFW (règles dans la chaîne ''DOCKER-USER''). ⚠️ À faire prudemment : ufw-docker bloque par défaut l'accès externe aux conteneurs, il faut ensuite ré-autoriser explicitement chaque service — **LLDAP en priorité** (6360 pour LAN+wifi+VPN), sinon l'authentification de tout le parc casse. Garder un compte local de secours et tester l'auth après chaque étape.
===== Accès distant (VPN) =====
Depuis l'extérieur, via WireGuard (serveur WG sur le routeur .90) : les sous-domaines résolvent grâce au DNS poussé par le tunnel (voir doc VPN). Rappel : dnsmasq doit écouter sur l'interface du tunnel (''wg1'') pour que la résolution DNS fonctionne à travers le VPN.