NixOS pour administrer un cluster Talos air-gapped
Publié le :

Mon cluster Kubernetes Talos Linux air-gapped fonctionne. Le CNI Cilium, les contrôleurs CCM/CSI OUTSCALE et le registre privé Harbor : tout est en place. Mais un élément me gêne depuis le début : la machine d’administration reste un OS classique, mutable, avec une surface d’attaque bien trop large. Services inutiles activés par défaut, dérive de configuration inévitable, audit de sécurité complexe. Voici comment NixOS ↗ s’est imposé pour construire une machine d’administration minimaliste, cohérente avec l’architecture immuable de Talos.
Contexte : mon cluster Talos Air-Gapped
Talos Linux est un OS minimaliste conçu pour Kubernetes. Pas de SSH, pas de shell, pas de gestionnaire de paquets. L’OS entier se configure via une API et des fichiers YAML. Cette approche élimine toute une classe de vecteurs d’attaque et garantit une reproductibilité totale.
Pour fonctionner en air-gapped, j’ai suivi ce plan :
- Dans un premier VPC, j’ai popé une machine d’administration tournant sous
RHEL 10 sur lequel j’ai passé le role CIS Benchmars BP28
Enhanced. Cette machine héberge les outils
talosctl,kubectlethelmpour piloter l’ensemble de l’infrastructure. - J’ai construit ensuite avec Packer une image Talos Linux personnalisée avec ImageCache pour embarquer les images système nécessaires au déploiement des nœuds sans accès Internet. Parmi ces images, on trouve les images de conteneurs Talos, Cilium ↗, les contrôleurs CCM/CSI OUTSCALE et Harbor.
- Entre les deux VPC, j’ai mis en place du Peering pour permettre à la machine d’administration de communiquer avec le cluster Talos.
- Dans un second VPC, j’ai provisionné tous les noeuds Talos Linux (control planes et workers) en utilisant l’image Talos avec ImageCache. Le cluster est totalement air-gapped, sans accès Internet.
Le cluster démarre, les workloads tournent. Techniquement, c’est un succès. Mais en regardant l’ensemble de l’architecture, un point faible saute aux yeux.
Pourquoi je ne veux plus d’une machine d’admin classique
Ma machine d’administration actuelle tourne sous RHEL 10. Elle héberge
talosctl, kubectl, helm et les fichiers de configuration du cluster. C’est
depuis cette machine que je provisionne les nœuds et déploie les applications.
Le problème est structurel. RHEL 10, comme Ubuntu ou Debian, est un OS mutable. Chaque mise à jour système modifie l’état de la machine. Chaque installation de paquet, chaque configuration manuelle crée une dérive par rapport à l’état initial. Après six mois d’exploitation, deux machines censément identiques peuvent présenter des différences subtiles, mais significatives.
Cette dérive pose plusieurs problèmes concrets. La reconstruction de la machine en cas de panne nécessite de se souvenir de toutes les modifications apportées. La documentation de l’état réel du système devient un exercice permanent. L’audit de sécurité doit composer avec des écarts entre l’état attendu et l’état réel.
J’ai construit un cluster Kubernetes immuable administré depuis une machine mutable. L’incohérence architecturale me gêne.
Pourquoi un OS immuable ?
Un OS immuable fonctionne différemment. Le système de fichiers racine est en lecture seule. Les modifications passent par un mécanisme déclaratif qui génère une nouvelle image système. Chaque changement est tracé, versionné, reproductible.
Les bénéfices pour une machine d’administration sont directs. L’anti-drift est garanti par construction : le système ne peut pas dériver puisqu’il ne peut pas être modifié en place. La reproductibilité permet de reconstruire une machine identique à partir de sa définition. Le rollback autorise un retour instantané à un état précédent en cas de problème.
Pour un environnement air-gapped durci selon les recommandations BP28 Enhanced ↗ de l’ANSSI, ces propriétés deviennent essentielles. L’immuabilité réduit la surface d’attaque et simplifie l’audit de conformité.
Pourquoi NixOS s’est imposé
J’ai évalué plusieurs candidats pour construire cette machine d’administration immuable.
- Talos Linux est exclu d’emblée. C’est un OS pour Kubernetes, pas pour administrer Kubernetes. Il n’offre ni shell ni outils utilisateur.
- Flatcar Container Linux ↗ cible les nœuds de cluster, pas les postes d’administration. Il manque les outils nécessaires pour gérer un cluster Talos.
- openSUSE MicroOS ↗ propose une approche transactionnelle
intéressante avec
transactional-update. Mais la configuration reste procédurale : on décrit des opérations, pas un état final. - NixOS ↗ fonctionne différemment. L’intégralité du système se décrit dans un fichier de configuration déclaratif. Ce fichier définit les paquets installés, les services actifs, les utilisateurs, le pare-feu, la configuration réseau. À partir de cette définition, Nix génère une image système complète et cohérente.
Deux machines construites à partir du même fichier configuration.nix sont
strictement identiques. La dérive de configuration devient impossible. Le
fichier de configuration constitue à lui seul la documentation exhaustive du
système.
NixOS permet également de construire des profils de durcissement déclaratifs. Les recommandations BP28 Enhanced se traduisent en configuration Nix versionnable et auditable.
Mon plan pour construire la machine d’administration immuable
Je ne suis pas un spécialiste de NixOS. Mon expérience se limite à quelques tests en VM et à la lecture de la documentation. Mais l’approche déclarative me parle : elle correspond exactement à ce que je recherche pour cette machine d’administration. Voici mes objectifs pour cette construction.
La première phase concerne l’installation de base. NixOS s’installe depuis
une ISO, puis se configure entièrement via configuration.nix. Je souhaite
définir le partitionnement avec un volume système chiffré pour l’OS et un
second volume chiffré dédié aux données sensibles (configurations Talos,
kubeconfig, secrets). Cette séparation devrait faciliter les sauvegardes et
permettre de reconstruire le système sans perdre les données d’administration.
La deuxième phase porte sur les outils d’administration. Le fichier de
configuration devra déclarer l’installation de talosctl, kubectl, helm et
leurs dépendances. Je veux figer les versions pour garantir la compatibilité
avec le cluster.
La troisième phase implémente le durcissement BP28 Enhanced.
J’espère pouvoir désactiver les services inutiles, configurer le pare-feu
nftables, restreindre les permissions et activer l’audit système. L’idéal
serait de traduire chaque recommandation ANSSI en directive de configuration
Nix.
La quatrième phase valide la reproductibilité. Je documenterai le processus
de reconstruction de la machine d’administration depuis zéro, à partir du seul
fichier configuration.nix stocké dans un dépôt Git.
Architecture finale cohérente
L’architecture cible présente une cohérence totale.
Le cluster Kubernetes repose sur Talos Linux, un OS immuable dédié à l’orchestration de conteneurs. Les nœuds se provisionnent via une API, se configurent de manière déclarative, ne dérivent jamais.
La machine d’administration repose sur NixOS, un OS immuable dédié aux postes de travail et serveurs. La machine se configure de manière déclarative, se reconstruit à l’identique, ne dérive jamais.
Les images de conteneurs sont servies par Harbor en mode air-gapped. Les Helm Charts sont stockés localement. L’ensemble fonctionne sans accès Internet.
Cette architecture élimine les éléments mutables de la chaîne d’administration. L’état de chaque composant est défini par sa configuration, pas par son historique de modifications.
La suite
Les prochains articles détailleront la construction effective de la machine d’administration NixOS. Je documenterai la configuration de base, l’intégration des outils, le durcissement BP28 Enhanced et les procédures de maintenance.
Un chantier important reste à mener : la mise en place d’OpenBao ↗ pour la gestion centralisée des secrets et la distribution de certificats TLS. Ce fork open source de HashiCorp Vault fournira une PKI interne au cluster, permettant d’automatiser l’émission et le renouvellement des certificats pour les services Kubernetes, les communications inter-nœuds et l’ingress.
L’objectif reste de fournir une architecture de référence pour les environnements Kubernetes air-gapped souverains, où chaque composant respecte les principes d’immuabilité et de reproductibilité.