Paillasse/docs/runbooks/https.md
Adam Belkacemi 80840b9f62 limite l'attente vers Kuma sur le site de statut et précise sa mise en place
Kuma 1.23 ne répond jamais pour une page de statut inexistante. Le runbook
détaille maintenant le champ sous-domaine d'OVH et la création de la page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 10:50:30 +02:00

60 lines
3.9 KiB
Markdown

# Runbook — HTTPS, en-têtes de sécurité, page de statut (étape 12)
## Où sont les choses
| Élément | Emplacement |
|---|---|
| Certificat | `/etc/letsencrypt/live/syllabuslab.fr/` (un seul certificat : `syllabuslab.fr`, `www`, et `status` quand son DNS existe) |
| Renouvellement | `certbot.timer` (deux fois par jour), authentificateur nginx, puis `systemctl reload nginx` |
| Alerte d'expiration | métrique `syllabus_certificat_expiration_timestamp` (script `/usr/local/sbin/syllabus-expiration-certificat`, cron quotidien), règles `CertificatExpireBientot` et `CertificatNonMesure` (`kolla/config/prometheus/alertes.rules`) |
| Vhost | `ansible/roles/portail/templates/nginx-portail.conf.j2` → `/etc/nginx/sites-available/portail.conf` |
| TLS et en-têtes | `/etc/nginx/snippets/syllabus-tls.conf`, `syllabus-entetes.conf` (rôle `portail`) |
| CSP | `portail/app/Http/Middleware/PolitiqueSecuriteContenu.php` ; violations dans `storage/logs/laravel.log` (« Violation CSP ») |
| Décisions | [ADR 0004](../adr/0004-https-csp-et-exposition.md) |
Tout est posé par `ansible-playbook portail.yml`.
## Vérifier
```
curl -sSI https://syllabuslab.fr/connexion | grep -iE "strict-transport|content-security|x-frame"
echo | openssl s_client -connect syllabuslab.fr:443 -servername syllabuslab.fr 2>/dev/null | openssl x509 -noout -dates -ext subjectAltName
ssh paillasse "sudo certbot renew --dry-run" # renouvellement simulé (environnement de test Let's Encrypt)
ssh paillasse "sudo grep -c 'Violation CSP' /var/www/portail/storage/logs/laravel.log"
```
## Activer la page de statut
1. Ajouter chez OVH un enregistrement A : champ « Sous-domaine » = `status` (seulement : OVH ajoute `.syllabuslab.fr` ; saisir le nom complet crée `status.syllabuslab.fr.syllabuslab.fr`), cible `163.172.4.195`.
2. Vérifier qu'il est publié : `dig +short A status.syllabuslab.fr @ns111.ovh.net`.
3. Dans Uptime Kuma (par tunnel), menu « Pages de statut » (pas « Ajouter une sonde ») : créer une page dont l'identifiant (slug) est `syllabus`, y ajouter les sondes à publier, enregistrer. Vérifier : `curl -m 5 http://127.0.0.1:3001/api/status-page/syllabus` sur le serveur doit répondre (Kuma 1.23 ne répond jamais pour une page inexistante).
4. `cd ansible && script -q /dev/null ansible-playbook portail.yml -i inventory.ini` : le rôle détecte le nom, l'ajoute au certificat et active le site.
5. Vérifier : `https://status.syllabuslab.fr` affiche la page ; `https://status.syllabuslab.fr/dashboard` et `/metrics` répondent 404.
## Si le certificat va expirer (alerte)
```
ssh paillasse "systemctl status certbot.timer; sudo journalctl -u certbot --since -3d | tail -30"
ssh paillasse "sudo certbot renew"
```
Causes probables : port 80 inaccessible depuis Internet, DNS modifié,
configuration Nginx invalide (`sudo nginx -t`). Limite Let's Encrypt :
5 échecs de validation par heure et par nom — corriger avant de réessayer.
## Ajouter un script à une page de l'application
La CSP stricte bloque tout script sans le nonce de la requête :
```
<script nonce="{{ Vite::cspNonce() }}">…</script>
```
Pas de `onclick="…"` : utiliser `addEventListener` dans un script avec nonce.
Pas de CDN : passer par Vite (`resources/js/`).
## Pièges (évités ou rencontrés)
- Évité par conception : une redirection `return 301` au niveau `server` s'exécute avant toute `location`, elle risquerait de court-circuiter le défi ACME que certbot insère au renouvellement. Les redirections sont dans `location /` ; `certbot renew --dry-run` réussit.
- `X25519MLKEM768` (recommandé par Mozilla v6.0) demande OpenSSL 3.5 ; Debian 12 a OpenSSL 3.0 : retiré par précaution (non essayé). À réintroduire au passage à Debian 13.
- Depuis Internet, un scan peut montrer 21, 554 et 1723 ouverts : c'est la box du réseau qui scanne (même résultat vers `192.0.2.1`, adresse inexistante). Côté serveur : `sudo ss -tlnp` et `sudo nft list chain inet filter input`.