Paillasse/docs/adr/0004-https-csp-et-exposition.md

62 lines
3.1 KiB
Markdown
Raw Normal View History

# ADR 0004 — HTTPS, CSP en deux niveaux, et ce qui est exposé sur Internet
- **Date** : 2026-10-09
- **Statut** : accepté
## Contexte
Étape 12 : le portail passe sur `syllabuslab.fr` en HTTPS. Il faut un
certificat qui se renouvelle seul, des en-têtes de sécurité, une CSP
« adaptée à xterm.js », Grafana et Uptime Kuma derrière authentification,
et une page de statut publique.
## Décisions
1. **certbot du dépôt Debian, `certonly` avec l'authentificateur nginx.**
Il obtient et renouvelle le certificat sans jamais modifier nos fichiers :
Ansible reste seul maître du vhost. Pas d'e-mail ACME (Let's Encrypt
n'envoie plus d'avis d'expiration) : c'est Prometheus qui alerte
(`CertificatExpireBientot`, moins de 14 jours).
2. **TLS : Mozilla v6.0 « intermediate »** (TLS 1.2 et 1.3, suites ECDHE),
pour les vieux postes des établissements. Sans X25519MLKEM768 (OpenSSL
3.0 sur Debian 12) ni OCSP stapling (abandonné par Let's Encrypt).
HSTS 2 ans avec `includeSubDomains`, sans `preload` (réversible).
3. **CSP en deux niveaux, posée par Laravel** (elle dépend de la page) :
- *application* (connexion, inscription, toute page authentifiée) :
`script-src 'self' 'nonce-…'`. Les scripts en ligne portent le nonce
de la requête ; xterm.js est servi par le portail (Vite) et non plus
par jsDelivr ; les gestionnaires `onclick`/`onsubmit` sont remplacés
par des écouteurs. Une injection de script serait bloquée ;
- *vitrine* (pages reprises du design) : scripts en ligne et CDN
autorisés. Ces pages contiennent 52 scripts en ligne et le CDN
d'exécution de Tailwind ; elles n'affichent aucune donnée d'utilisateur.
Les violations sont remontées à `/csp-rapport` (journal Laravel).
4. **Administration de Grafana et d'Uptime Kuma : tunnel SSH seulement**
(choix d'Adam). Il faut la clé SSH, puis le mot de passe de l'outil.
Rien de plus n'est exposé sur Internet.
5. **Page de statut sur `status.syllabuslab.fr`** : Nginx ne laisse passer
que la page de statut, son API en lecture (GET/HEAD) et ses fichiers
statiques. Tableau de bord, `/socket.io` (connexion admin) et `/metrics`
renvoient 404. Le rôle n'active ce site que si le nom résout vers le
serveur, et ajoute alors le nom au certificat (`--expand`).
## Alternatives écartées
- **CSP stricte partout** : demanderait de réécrire les ~50 pages du design
(scripts en ligne, Tailwind par CDN). Reporté (voir `docs/dette.md`).
- **Grafana et Kuma publics derrière mot de passe** : pratique, mais exposés
à la force brute pour aucun besoin actuel.
- **certbot en snap** (recommandation du projet certbot) : une deuxième
chaîne de mises à jour à surveiller ; le paquet Debian suit
unattended-upgrades comme le reste.
## Conséquences
- Toute nouvelle page de l'application qui ajoute un script doit lui donner
`nonce="{{ Vite::cspNonce() }}"`, sinon le navigateur le bloque (et le
signale dans le journal).
- `Permissions-Policy` interdit caméra et micro : à ouvrir pour la visio
(étape 15).
- Les tests et scripts doivent passer par `https://syllabuslab.fr` : le
cookie de session est `secure`.