diff --git a/docs/adr/0019-stockage-objet-garage-et-cycle-de-vie-des-mesures.md b/docs/adr/0019-stockage-objet-garage-et-cycle-de-vie-des-mesures.md index 03e01ef..d276ca5 100644 --- a/docs/adr/0019-stockage-objet-garage-et-cycle-de-vie-des-mesures.md +++ b/docs/adr/0019-stockage-objet-garage-et-cycle-de-vie-des-mesures.md @@ -39,8 +39,7 @@ sans shell : la garde sur les secrets vit dans le `Makefile` (`garage-garde`, ap **Nœud unique assumé.** `replication_factor = 1` et moteur `sqlite`, avec un instantané des métadonnées toutes les six heures. La documentation de Garage réserve ce facteur aux déploiements de test : ici la machine est unique, la redondance n'existe pour aucun autre service, -et le coffre LUKS de l'[ADR 0020](0020-chiffrement-au-repos-coffre-luks-et-sse-c.md) porte les -volumes. LMDB, le moteur par défaut, se corrompt à l'arrêt brutal et rien ne le reconstruirait. +et le chiffrement au repos est traité à part ([ADR 0020](0020-chiffrement-au-repos-coffre-luks-et-sse-c.md)). LMDB, le moteur par défaut, se corrompt à l'arrêt brutal et rien ne le reconstruirait. **La rétention de `reading` est un traitement du backend, ordonnancé par Airflow.** Le DAG `retention` lance chaque nuit `app.etl.reading_retention` ([ADR 0008](0008-airflow-execute-le-code-du-backend.md)), diff --git a/docs/adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md b/docs/adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md index 2d85256..9efd9b6 100644 --- a/docs/adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md +++ b/docs/adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md @@ -22,6 +22,17 @@ console au démarrage : tout redémarrage doit aboutir sans saisie. ## Décision +**Constat du 24/09, qui borne tout ce qui suit.** La machine `eadl-2025-nantes-g3` n'est pas une +machine virtuelle mais un conteneur LXC Ubuntu 24.04 sur un hôte Proxmox (`systemd-detect-virt` +répond `lxc`, aucun `/dev/mapper/control`, aucun périphérique loop, pas de `/dev/fuse`, module +`dm_crypt` inaccessible). LUKS, comme tout chiffrement au niveau bloc ou FUSE, y est impossible. +Le chiffrement au repos du disque de ce conteneur ne peut se faire que sur l'hôte Proxmox +(volume LUKS ou ZFS chiffré sous le conteneur), par l'administrateur de l'école : la demande +lui est adressée, et jusqu'à sa réponse la base et les métadonnées Garage sont en clair sur ce +disque. `scripts/coffre-luks.sh` détecte ce cas et refuse de démarrer. Ce qui suit reste la +décision pour toute machine où le device-mapper est disponible (la cible k3s de `10-infra.md`, +ou une vraie VM), et le SSE-C des archives est en place dès aujourd'hui. + **Un coffre LUKS2 sous tous les volumes Docker, posé par `scripts/coffre-luks.sh`.** - Le coffre est un **fichier image creux** (`/srv/enervision/coffre.img`, 30 Go par défaut) diff --git a/docs/architecture/00-vue-ensemble.md b/docs/architecture/00-vue-ensemble.md index 92ece14..056fd9a 100644 --- a/docs/architecture/00-vue-ensemble.md +++ b/docs/architecture/00-vue-ensemble.md @@ -141,10 +141,11 @@ consolidée. Argon2id, RBAC à trois rôles. Détail dans [20-backend.md](20-backend.md), décisions dans les [ADR 0002](../adr/0002-authentification-jwt-et-refresh-opaque.md) et [0003](../adr/0003-autorisation-rbac-a-trois-roles.md). -- **Chiffrement au repos.** Sur la VM, tous les volumes Docker (base, Garage, Airflow, - supervision) vivent dans un coffre LUKS2 dont Docker exige le montage pour démarrer ; les - archives de mesures déposées sur Garage sont en plus chiffrées par clé client (SSE-C). Ce que - cela protège et ne protège pas : [ADR 0020](../adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md). +- **Chiffrement au repos.** Les archives de mesures déposées sur Garage sont chiffrées par clé + client (SSE-C). Le coffre LUKS des volumes Docker (`scripts/coffre-luks.sh`) est prêt pour une + vraie VM, mais la machine ENI est un conteneur LXC sans device-mapper : le chiffrement de son + disque relève de l'hôte Proxmox, demandé à l'école. Ce qui est couvert et ce qui ne l'est pas : + [ADR 0020](../adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md). - **Interdire par défaut.** Toute route exige un jeton, sauf quatre exceptions listées dans un fichier de test qui interroge réellement chaque route sans identifiant. - **Révocation immédiate.** Le compte est relu en base à chaque requête : une désactivation ou un diff --git a/docs/architecture/10-infra.md b/docs/architecture/10-infra.md index 528f9e5..2cd38f9 100644 --- a/docs/architecture/10-infra.md +++ b/docs/architecture/10-infra.md @@ -302,7 +302,11 @@ l'`apply` n'est pas rejouable sans qu'un administrateur du dépôt en crée un n ### Coffre LUKS des volumes Docker (issue #42) -Statut : `En cours`, script écrit, jamais encore joué sur la VM. Décision et modèle de menace dans +Statut : `Bloqué par la plateforme`. La machine ENI est un conteneur LXC sur Proxmox, sans +device-mapper ni loop : `scripts/coffre-luks.sh` s'y arrête sur sa garde, et le chiffrement du +disque de ce conteneur relève de l'hôte Proxmox, demandé à l'administrateur de l'école. Ce qui +est en place aujourd'hui : le SSE-C des archives déposées sur Garage. Le runbook ci-dessous vaut +pour une vraie VM (cible k3s, ou remplacement du conteneur). Décision et modèle de menace dans l'[ADR 0020](../adr/0020-chiffrement-au-repos-coffre-luks-et-sse-c.md). Un fichier image LUKS2 (`/srv/enervision/coffre.img`, clé `/root/enervision-coffre.key`) est monté sur `/srv/enervision/coffre`, et `/var/lib/docker/volumes` est bind-monté depuis ce coffre : les diff --git a/infra/garage/README.md b/infra/garage/README.md index cc3360f..607c1d4 100644 --- a/infra/garage/README.md +++ b/infra/garage/README.md @@ -11,8 +11,8 @@ Stockage objet S3 de la stack, un conteneur par projet Compose (ADR 0019). Il ne - Ports, sur `127.0.0.1` seulement : `GARAGE_S3_PORT` (3900) pour l'API S3, `GARAGE_ADMIN_PORT` (3903) pour `/health` (sans jeton) et `/metrics` (jeton `GARAGE_METRICS_TOKEN`, scruté par Prometheus). Le RPC 3901 n'est pas publié. -- Nœud unique, `replication_factor = 1`, moteur sqlite : aucune redondance, le coffre LUKS de la - VM (ADR 0020) et l'instantané des métadonnées toutes les six heures sont les seules protections. +- Nœud unique, `replication_factor = 1`, moteur sqlite : aucune redondance, l'instantané des + métadonnées toutes les six heures est la seule protection ; chiffrement au repos : ADR 0020. ```bash docker compose exec garage /garage status diff --git a/scripts/coffre-luks.sh b/scripts/coffre-luks.sh index 4adc1bb..0e575be 100755 --- a/scripts/coffre-luks.sh +++ b/scripts/coffre-luks.sh @@ -48,6 +48,11 @@ installer() { verifier_prerequis() { [[ "$(id -u)" -eq 0 ]] || erreur "à lancer en root" + # Constaté le 24/09 : la machine ENI est un conteneur LXC, sans device-mapper ni loop. LUKS y + # est impossible ; le chiffrement de son disque relève de l'hôte Proxmox (ADR 0020). + [[ "$(systemd-detect-virt --container 2>/dev/null || true)" != lxc ]] \ + || erreur "conteneur LXC : pas de device-mapper ni de loop, LUKS impossible ici ; le chiffrement du disque se fait sur l'hôte (ADR 0020)" + [[ -e /dev/mapper/control ]] || erreur "/dev/mapper/control absent : device-mapper indisponible, LUKS impossible ici" [[ "$COFFRE_IMAGE" != /var/lib/docker/* ]] \ || erreur "l'image $COFFRE_IMAGE ne doit pas vivre sous /var/lib/docker, que le coffre recouvre" installer cryptsetup || erreur "cryptsetup introuvable dans apt"