Aller au contenu

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