Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,11 @@ npm run e2e:ui # mode UI interactif Playwright

## Déploiement VPS

VPS OVH (`VPS-1 2027`, 2 vCores, 4 Go RAM, 40 Go, Debian 13 Trixie, zone Gravelines/GRA). Accès SSH par clé uniquement (`ssh vpsovh`, user `debian`). **L'IP publique du VPS n'est jamais écrite dans le dépôt** (ni doc, ni code, ni workflow) : le proxy Cloudflare sert justement à la cacher, la publier permettrait de contourner Cloudflare (WAF, anti-DDoS) en tapant directement Caddy. Elle vit uniquement dans le `~/.ssh/config` local (alias `vpsovh`), le secret GitHub `VPS_HOST` et le DNS Cloudflare. Elle a figuré dans ce fichier jusqu'au 2026-09-25 et reste donc dans l'historique git.
VPS OVH (`VPS-1 2027`, 2 vCores, 4 Go RAM, 40 Go, Debian 13 Trixie, zone Gravelines/GRA). Accès SSH (user `debian`) par **deux moyens, tous deux actifs** : la clé SSH (`ssh vpsovh`, inchangé) **et** le login + mot de passe de `debian` (gardé volontairement depuis le 2026-10-11 comme accès de secours si le PC qui porte la clé est perdu, cf. § Durcissement serveur). **L'IP publique du VPS n'est jamais écrite dans le dépôt** (ni doc, ni code, ni workflow) : le proxy Cloudflare sert justement à la cacher, la publier permettrait de contourner Cloudflare (WAF, anti-DDoS) en tapant directement Caddy. Elle vit uniquement dans le `~/.ssh/config` local (alias `vpsovh`), le secret GitHub `VPS_HOST` et le DNS Cloudflare. Elle a figuré dans ce fichier jusqu'au 2026-09-25 et reste donc dans l'historique git.

### Durcissement serveur

- **SSH** : `/etc/ssh/sshd_config.d/10-hardening.conf` (`PasswordAuthentication no`, `PermitRootLogin no`, `KbdInteractiveAuthentication no`). **Nommé `10-` et pas `99-`** — piège : `sshd` retient la *première* valeur rencontrée pour chaque directive dans l'ordre du glob `Include /etc/ssh/sshd_config.d/*.conf`, et `50-cloud-init.conf` (déjà présent sur une Debian OVH fraîche, avec `PasswordAuthentication yes`) est inclus *avant* un fichier `99-*`. Un drop-in `99-hardening.conf` serait donc silencieusement ignoré pour cette directive. Vérifier avec `sudo sshd -T | grep -i passwordauth` après toute modif.
- **SSH** : `/etc/ssh/sshd_config.d/10-hardening.conf` (`PasswordAuthentication yes` depuis le 2026-10-11, `PermitRootLogin no`, `KbdInteractiveAuthentication no`). La connexion par clé reste active **et** la connexion par login + mot de passe est gardée volontairement (décision de Clément, testée le 2026-10-11 avec `ssh -o PubkeyAuthentication=no`) pour garder un accès sans la clé SSH du PC ; mot de passe long de `debian` rangé dans le KeePass de Clément, avec le nom d'hôte OVH du VPS (jamais écrit dans le dépôt : il résout vers l'IP) et l'empreinte de la clé d'hôte. Protection restante : fail2ban (ci-dessous) et root interdit. Retour à la clé seule : remettre `PasswordAuthentication no` puis `sudo systemctl reload ssh`. Secours si SSH est inaccessible : console KVM de l'espace client OVH (clavier serveur passé en AZERTY via `/etc/default/keyboard` + `setupcon`) ou mode rescue. **Nommé `10-` et pas `99-`** — piège : `sshd` retient la *première* valeur rencontrée pour chaque directive dans l'ordre du glob `Include /etc/ssh/sshd_config.d/*.conf`, et `50-cloud-init.conf` (déjà présent sur une Debian OVH fraîche, avec `PasswordAuthentication yes`) est inclus *avant* un fichier `99-*`. Un drop-in `99-hardening.conf` serait donc silencieusement ignoré pour cette directive. Vérifier avec `sudo sshd -T | grep -i passwordauth` après toute modif.
- **fail2ban** : `/etc/fail2ban/jail.local` (`bantime=1h`, `maxretry=3` sur le jail `sshd`, backend `systemd` déjà fourni par le paquet Debian).
- **UFW** : OpenSSH + 80/tcp + 443/tcp uniquement. 80/443 restent ouverts au monde entier (pas seulement aux plages Cloudflare) : quelqu'un qui connaît l'IP peut joindre Caddy sans passer par Cloudflare — restriction aux plages Cloudflare prête mais pas encore appliquée : `deploy/caddy/cloudflare-only.sh` (filtre `DOCKER-USER` + `ipset`, UFW étant contourné par les ports Docker), mode d'emploi dans `deploy/caddy/README.md`, cf. `docs/TACHES.md` § Infra.
- **Docker** : dépôt officiel (pas celui de Debian), `/etc/docker/daemon.json` avec rotation des logs (`max-size: 10m`, `max-file: 3` — important vu les 40 Go de disque).
Expand Down
Loading