VPS — Sécurité UFW (Pare-feu)¶
Contexte¶
Configuration du pare-feu UFW sur le VPS Hetzner après la migration Hermes Workspace. Objectif : n'exposer publiquement que les ports strictement nécessaires.
Configuration appliquée¶
# Réinitialisation
sudo ufw --force reset
# Politique par défaut
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Ports autorisés depuis l'extérieur
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP (Caddy)
sudo ufw allow 3001/tcp # Hermes Workspace (via Caddy — auth obligatoire)
sudo ufw allow 2019/tcp # Hermes Dashboard (via Caddy — basic auth)
sudo ufw allow 7682/tcp # ttyd terminal (via Caddy — basic auth)
# Accès interne : containers Docker → gateway et dashboard Hermes
# ⚠️ Utiliser 172.16.0.0/12 et pas 172.17.0.0/16 — les réseaux Docker Compose
# utilisent 172.18.x.x, 172.19.x.x, etc. selon l'ordre de création
sudo ufw allow from 172.16.0.0/12 to any port 8642 comment 'Docker containers -> hermes gateway'
sudo ufw allow from 172.16.0.0/12 to any port 9119 comment 'Docker containers -> hermes dashboard'
# ⚠️ Les DEUX ports sont nécessaires : sans 9119, le workspace reste en mode "portable"
# (sessions et skills indisponibles). Avec les deux : mode "zero-fork" complet.
# Activation
sudo ufw --force enable
Ports intentionnellement bloqués depuis l'extérieur¶
| Port | Service | Raison du blocage |
|---|---|---|
| 8642 | Hermes Gateway API | Accès interne uniquement (Docker + systemd) |
| 9119 | Hermes Dashboard (direct) | Accès via Caddy (2019) uniquement |
| 3000 | Hermes Workspace (direct) | Accès via Caddy (3001) uniquement |
| 7681 | ttyd (direct) | Accès via Caddy (7682) uniquement |
| 3901 | Backend PsychoEnLigne | API interne, pas exposée publiquement |
| 5432 | PostgreSQL | Base de données — jamais exposée |
| 6379 | Redis | Cache — jamais exposé |
Vérification¶
sudo ufw status verbose
# → Status: active
# → To Action From
# → 22/tcp ALLOW Anywhere
# → 80/tcp ALLOW Anywhere
# → 3001/tcp ALLOW Anywhere
# → 2019/tcp ALLOW Anywhere
# → 7682/tcp ALLOW Anywhere
Architecture de sécurité en couches¶
Internet
↓ (ports 3001, 2019, 7682 uniquement)
Caddy (reverse proxy + basic auth + mot de passe workspace)
↓
Services internes (ports 3000, 9119, 7681)
↓
Gateway Hermes (port 8642 — localhost + Docker uniquement)
Règle importante : Caddy est la seule porte d'entrée¶
Tous les services sont protégés par Caddy avant d'être exposés :
- Workspace : mot de passe HERMES_PASSWORD
- Dashboard : HTTP Basic Auth (hermes + mot de passe haché)
- Terminal ttyd : HTTP Basic Auth
Le port 8642 (gateway) n'est accessible que depuis localhost ou host.docker.internal (conteneur Docker).
Piège Docker + UFW #ufw¶
Symptôme : hermes-workspace UI affiche "Not available on this backend" — le container ne peut pas joindre host.docker.internal:8642.
Cause : Docker Compose crée ses propres réseaux bridge (172.18.x.x, 172.19.x.x…), distincts de docker0 (172.17.x.x). Une règle UFW limitée à 172.17.0.0/16 ne couvre pas les réseaux Compose.
Solution : autoriser 172.16.0.0/12 (couvre tous les réseaux Docker de 172.16 à 172.31) :
ufw allow from 172.16.0.0/12 to any port 8642 comment 'Docker containers -> hermes gateway'
Diagnostic :
# Vérifier l'IP du container
docker inspect <container> --format '{{json .NetworkSettings.Networks}}' | python3 -m json.tool | grep Gateway
# Test de connectivité depuis le container
docker exec <container> curl -s -o /dev/null -w 'HTTP %{http_code}' http://host.docker.internal:8642/
# HTTP 404 = gateway joignable (OK) / HTTP 000 = bloqué par UFW
Liens connexes¶
- shared/architecture/hermes-workspace-migration — architecture complète Hermes Workspace
- shared/architecture/infrastructure-partagee-postgres-redis — postgres/redis sur shared_infra
- PsychoEnLigneV2/architecture/cicd-options-deploiement-automatique — CI/CD GitHub Actions