Sécurité des nœuds : amorçage SSH, enrôlement, bris de glace et mise à jour de l'agent
Ce guide couvre les hôtes que le Platform Manager administre par son agent de nœud. Le contrat est dans
CONTRACT.md, section 7.15.
Amorçage SSH
- Définissez la politique SSH du cluster (
PUT /api/v1/clusters/{id}/ssh-policy) : compte d'amorçage (par défautnavin-bootstrap), autorités de certification utilisateur approuvées, RSA autorisé ou non (jamais sous 3072 bits), domaine de confiance SPIFFE, délai de rotation. - Sur l'hôte, créez le compte d'amorçage et installez le fichier sudoers affiché par la console (Agents de nœud,
Amorçage SSH, Prévisualiser le plan) ou par
POST /api/v1/hosts/bootstrap/plan. Il ne contient que des commandes exactes (installation du binaire et de l'unité de l'agent,systemctl daemon-reload,systemctl enable --now, suppression pour le retour arrière,nm-agent register --options-file) ; le manager le valide avecvisudo -cf. - Renseignez la clé d'hôte (ou l'autorité de certification d'hôte) : le manager n'apprend jamais une clé d'hôte
à la volée et utilise toujours
StrictHostKeyChecking=yes. Une clé inconnue ou modifiée arrête l'exécution (ssh_host_key_refused). Une chaîne de bastions utilise les mêmes clés d'inventaire à chaque saut. - Lancez les vérifications préalables (
POST /api/v1/hosts/preflight) : SSH, système d'exploitation, DNS direct et inverse, décalage d'horloge, disque libre, ports requis et joignabilité, chacunpass,warningoublocking. L'empreinte du rapport est stable pour les mêmes observations. - Lancez l'amorçage (
POST /api/v1/hosts/bootstrap). L'identifiant est une clé Ed25519 ou un certificat utilisateur OpenSSH d'une AC approuvée ; les mots de passe etrootsont refusés. L'exécution vérifie d'abord la signature du binaire de l'agent, ajoute une clé temporaire àauthorized_keys, installe le binaire et l'unité durcie (NoNewPrivileges,ProtectSystem=strict,ProtectHome,PrivateTmp,CapabilityBoundingSetexplicite,ReadWritePathslimité au répertoire d'état), enregistre l'agent, puis retire la clé temporaire et le répertoire de transit. Une seconde exécution ne change rien de ce qui est en place ; un échec annule les fichiers qu'elle a créés.
La clé privée et le jeton d'amorçage restent dans la mémoire du manager le temps de l'exécution : PostgreSQL ne
conserve qu'une référence (key_ref: memory), les journaux sont masqués par l'analyseur de secrets.
Limite : l'unité durcie ne laisse l'agent écrire que dans son répertoire d'état. Les hôtes où l'agent doit écrire
les répertoires Navin (/etc/navin, /opt/navin, /var/lib/navin) demandent un fichier complémentaire relu qui
les ajoute à ReadWritePaths.
Enrôlement
POST /api/v1/hosts/enroll renvoie un jeton nme_... valable 15 minutes au plus, pour un FQDN et une clé d'agent
(empreinte : sha256 du SubjectPublicKeyInfo DER). L'agent le présente une seule fois à POST /agent/v1/enroll avec
une CSR de cette clé ; réutilisation, expiration, autre hôte ou autre clé sont refusés et audités. La réponse
contient le certificat mTLS (avec l'identifiant SPIFFE dans le SAN quand un domaine de confiance est défini), l'AC
du manager, la clé des commandes et la clé des paquets. La réponse de pulsation indique cert_renew_due quand le
certificat entre dans la fenêtre de rotation ; l'agent renouvelle par POST /agent/v1/renew, le certificat
précédent est révoqué et listé dans GET /agent/v1/crl.pem.
La quarantaine (POST /api/v1/hosts/{id}/quarantine) bloque tâches, commandes et renouvellements ; la révocation
(/revoke) révoque aussi tous les certificats et refuse tout appel de l'agent ; /recover lève une quarantaine. Un
hôte révoqué ne revient que par un nouvel enrôlement.
Bris de glace
- Un utilisateur disposant de
hosts:managedemande l'accès à un hôte avec un motif, une clé publique SSH, le compte et une durée (60 s à 4 h). - Deux autres utilisateurs approuvent. Le demandeur ne peut pas approuver, personne n'approuve deux fois.
- La seconde approbation émet un certificat utilisateur OpenSSH signé par l'AC de bris de glace du manager, valable
jusqu'à la fin de la durée. Configurez les hôtes avec
TrustedUserCAKeys(AC fournie parGET /agent/v1/breakglass/ca.pub) etRevokedKeys(KRL fournie parGET /agent/v1/breakglass/revoked-keys). - Enregistrez les preuves de session (
POST /api/v1/breakglass/{id}/evidence: début, empreinte des commandes, fin). La tâchebreakglass.expiremarque la demande expirée à la fin de la durée ;/revokey met fin plus tôt.
Mise à jour de l'agent
Publiez le nouveau binaire sous mirror/agent/nm-agent avec nm-agent.sig (signé avec la clé agent_packages),
puis appelez POST /api/v1/hosts/{id}/agent-update. L'agent reçoit une commande signée agent.update, vérifie
l'empreinte et la signature, exécute nm-agent version sur le nouveau binaire, garde l'ancien sous
nm-agent.prev, échange et redémarre. La première pulsation confirme la mise à jour ; sans pulsation avant
l'échéance, le binaire précédent est restauré (par la surveillance du nouvel agent, ou par
nm-agent.prev update-check dans ExecStartPre).
Le test selfupdate_binary_test.go compile le vrai nm-agent, l'échange, et vérifie que le vrai binaire
précédent se restaure sans pulsation en gardant le répertoire d'état, ou confirme après une pulsation.