Aller au contenu principal

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​

  1. Définissez la politique SSH du cluster (PUT /api/v1/clusters/{id}/ssh-policy) : compte d'amorçage (par défaut navin-bootstrap), autorités de certification utilisateur approuvées, RSA autorisé ou non (jamais sous 3072 bits), domaine de confiance SPIFFE, délai de rotation.
  2. 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 avec visudo -cf.
  3. 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.
  4. 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é, chacun pass, warning ou blocking. L'empreinte du rapport est stable pour les mêmes observations.
  5. 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 et root sont 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, CapabilityBoundingSet explicite, ReadWritePaths limité 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​

  1. Un utilisateur disposant de hosts:manage demande l'accès à un hôte avec un motif, une clé publique SSH, le compte et une durée (60 s à 4 h).
  2. Deux autres utilisateurs approuvent. Le demandeur ne peut pas approuver, personne n'approuve deux fois.
  3. 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 par GET /agent/v1/breakglass/ca.pub) et RevokedKeys (KRL fournie par GET /agent/v1/breakglass/revoked-keys).
  4. Enregistrez les preuves de session (POST /api/v1/breakglass/{id}/evidence : début, empreinte des commandes, fin). La tâche breakglass.expire marque la demande expirée à la fin de la durée ; /revoke y 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.