Paper / Cloud, Architecture, DevSecOps
Une production sérieuse sur une seule machine
Un point d'entrée, un bord discipliné, et un arbitrage à énoncer avant de le découvrir
Résumé
La question intéressante d'un déploiement mono-machine n'est pas de savoir s'il peut servir le trafic. Pour la plupart des petits systèmes, il le peut, avec une marge confortable. La question intéressante est de savoir si l'opérateur peut répondre à trois questions à tout moment : qu'est-ce qui est exposé à Internet, qu'est-ce qui peut être reconstruit depuis le contrôle de version, et que se passe-t-il quand la prochaine mise à jour se passe mal. Cet article décrit une forme de déploiement construite autour de ces trois questions, délibérément en termes de rôles plutôt que de produits : un point d'entrée public, une couche de filtrage derrière, des processus applicatifs sans adresse publique, un plan d'administration confiné à la machine, des artefacts épinglés et une restauration répétée. Il décrit ensuite comment la même forme monte en échelle quand la charge justifie des équipements dédiés : un point d'entrée matériel, une appliance dédiée à l'inspection, et la séparation des préoccupations qu'un bord plus large rend possible. Il se termine par les modes de défaillance qui restent, parce que l'arbitrage doit être énoncé plutôt que découvert.
Questions clés
- Quelles parties d'une pile mono-machine doivent être publiques, et lesquelles ne doivent jamais l'être ?
- Pourquoi confiner le plan d'administration change-t-il le profil de risque plus qu'une règle de pare-feu de plus ?
- Que doit-il être reproductible depuis le contrôle de version pour qu'une reconstruction soit une répétition et non un incident ?
- Pourquoi un article qui décrit un déploiement réel nomme-t-il si peu de produits ?
- Quand une machine cesse-t-elle d'être un arbitrage raisonnable, et qu'est-ce qu'on sépare en premier ?
La première chose à dire d’une production sur une seule machine, c’est que la capacité n’est presque jamais la contrainte. Une machine modeste traite plus de requêtes qu’un petit produit n’en générera, et la partie coûteuse de l’exploitation n’est pas le CPU. C’est l’ensemble des décisions qu’une plateforme plus grande aurait prises à votre place : ce qui termine la sécurité de transport, ce qui filtre le trafic, ce qui a le droit d’écouter sur une interface publique, comment une mise à jour est annulée, et ce qui se passe quand le disque se remplit à trois heures du matin.
Des rôles, pas des produits
Cet article décrit un déploiement réel, et il ne nomme presque aucun produit. C’est un choix délibéré, et il vaut la peine d’être expliqué avant l’architecture, parce que l’explication fait elle-même partie de l’argument.
Une description assez détaillée pour être utile à un lecteur l’est aussi pour quelqu’un qui cherche un moyen d’entrer. Une configuration en production, c’est de la reconnaissance : la version d’un composant, le port sur lequel écoute une console, les noms des services qui se parlent. Rien de tout cela n’est secret au sens d’un mot de passe, mais tout cela raccourcit le travail d’un attaquant qui choisit une cible. Une liste de faits précis — quelle appliance, quelle version, quelle surface de gestion — est un meilleur cadeau qu’une description générique de bonnes pratiques.
Le contenu intéressant d’un article de déploiement n’est donc pas l’inventaire. C’est l’attribution des rôles et le raisonnement qui les sous-tend :
- Point d'entrée
- Le seul processus qui termine la sécurité de transport et accepte les connexions depuis Internet. Tout le reste est derrière.
- Couche de filtrage
- Inspecte les requêtes avant qu'elles n'atteignent l'application et porte les règles qui changent le plus souvent.
- Application
- Sert le produit. Elle n'a pas d'adresse publique et aucune configuration qui en suppose une.
- Données
- Porte l'état qui compte et qui est le plus difficile à reconstruire. Elle n'est pas joignable directement depuis le point d'entrée.
- Plan d'administration
- Tout ce qui dispose d'une autorité d'opérateur : consoles, tableaux de bord, API de contrôle. Il n'est pas joignable depuis une interface publique.
Les rôles sont transposables. Les produits qui les remplissent changent tous les quelques années, le raisonnement non. Un lecteur qui comprend pourquoi le plan d’administration est la vraie frontière peut l’appliquer aux composants qu’il exploite, sans qu’on lui dise lesquels.
La forme du bord
L’architecture a un seul écouteur public et une chaîne derrière. Le point d’entrée termine la sécurité de transport, obtient et renouvelle ses propres certificats, et transmet à une couche de filtrage. La couche de filtrage inspecte la requête et la transmet à l’application, qui tourne sans aucune adresse publiée.
flowchart LR internet["Internet"] --> edge["Entry point: transport security and routing"] edge --> filter["Filtering layer: inspection"] filter --> app["Application: no public address"] app --> data["Data: state that matters"] admin["Management plane"] -.->|"not publicly reachable"| edge admin -.->|"not publicly reachable"| filter
Deux propriétés comptent plus que les composants choisis. D’abord, il y a exactement un endroit où le trafic public entre, donc exactement un endroit où la sécurité de transport, les en-têtes et les limites de débit sont configurés — et un seul endroit à auditer. Ensuite, l’application n’a aucune adresse publiée. Une erreur dans sa manière de se lier ne l’expose pas à Internet, parce qu’il n’existe aucune route depuis Internet vers elle qui ne passe pas d’abord par la couche de filtrage ; il faudrait se tromper deux fois pour que cela compte.
L’autre propriété est plus discrète. Quand le point d’entrée est configuré depuis un fichier plutôt que par une suite de clics dans un panneau de contrôle, la configuration est relisible, comparable et reproductible. La raison pour laquelle cela compte pour la sécurité n’est pas l’ordre : une configuration qui vit dans un fichier peut être auditée avant d’être appliquée et annulée après, alors qu’une configuration qui vit dans un processus en cours ne s’inspecte jamais qu’après qu’un problème est survenu.
Le plan d’administration est le vrai risque
Chaque composant de la pile a une interface de gestion : le point d’entrée, la couche de filtrage, le superviseur de processus, le tableau de bord de supervision. Ces interfaces sont plus dangereuses que l’application parce qu’elles sont conçues pour un opérateur disposant de toute l’autorité, et qu’elles sont généralement protégées par un identifiant plutôt que par une frontière réseau.
La règle qui a supprimé le plus de risque, dans mon expérience, est simple : les interfaces de gestion ne sont jamais publiées sur une interface publique ; elles ne sont joignables que depuis l’intérieur, par le canal déjà nécessaire pour administrer la machine. Les consoles et les API de contrôle sont liées à la machine elle-même, sur des ports qui n’existent qu’à l’intérieur. Y accéder exige la clé d’administration déjà nécessaire pour tout le reste, si bien que le plan d’administration hérite d’un seul périmètre au lieu d’en inventer plusieurs.
- Écouteurs publics
- Exactement ce dont le service a besoin, rien de plus. Chaque socket en écoute supplémentaire est une anomalie, pas une commodité.
- Liaisons d'administration
- Interne uniquement, atteintes par le canal d'administration. Pas de mot de passe partagé sur une interface de gestion.
- Accès d'administration
- Par clé, sans connexion par mot de passe, sans connexion root directe. Cette clé est le périmètre du plan d'administration.
- Secrets
- Conservés hors des images et hors du dépôt, avec des permissions restrictives. Jamais intégrés à ce qui est déployé.
- Sortie réseau
- Le trafic sortant est autorisé mais observé. Un service qui parle soudainement à un hôte inconnu est un signal.
Le point n’est pas qu’une liaison interne soit incassable. C’est qu’un attaquant qui a atteint l’interface de gestion depuis l’intérieur a généralement déjà compromis la machine, tandis qu’un attaquant qui trouve une console exposée sur un port arbitraire a un chemin bien plus facile. Retirer la liaison publique élimine toute une classe d’attaques opportunistes, et cela ne coûte rien.
Épingler ce que l’on déploie
La manière la plus courante dont une pile stable devient instable est une mise à jour que personne n’a choisie. Une étiquette mouvante est la promesse qu’un futur build sera différent, et la différence arrivera au moment le moins pratique.
La discipline est peu glamour : épingler les artefacts à une version précise, lire le journal des changements avant de déplacer l’épingle, et déplacer un composant à la fois. Une mise à jour corrective devient un changement de deux lignes — une nouvelle épingle et un redémarrage — précédé de la lecture des notes de version et suivi de la vérification de la console de gestion et du chemin public. Le même schéma s’applique à chaque composant de la chaîne.
| Étape | Action | Ce que cela évite |
|---|---|---|
| Lire | Notes de version et changements cassants pour la version exacte | Migrations surprises et drapeaux supprimés |
| Épingler | Mettre à jour la référence dans une surcharge, pas dans la définition de base | Dérive entre environnements et changements non revus |
| Déployer | Redémarrer un composant, vérifier par le chemin public, puis continuer | Découvrir une chaîne cassée après avoir tout redémarré |
| Vérifier | Contrôler la surface de gestion, un point de santé et une vraie requête | Des composants verts qui servent des erreurs |
| Consigner | Commiter l'épingle et noter la raison dans le message | La question sans réponse : pourquoi cette version est-elle là ? |
Un rituel de mise à jour qui tient sur une fiche. L'intérêt n'est pas les étapes ; c'est qu'elles soient les mêmes à chaque fois.
L’épinglage est aussi ce qui rend un retour arrière possible. Si la version précédente est une référence qui existe encore, revenir en arrière est la même opération qu’avancer. Si l’état précédent était une étiquette mouvante, revenir en arrière signifie deviner.
L’état : ce qui est reproductible et ce qui est précieux
Une pile mono-machine a deux sortes d’état, et les confondre est la manière dont les sauvegardes échouent. La première sorte est reproductible : définitions de déploiement, configuration du bord, artefacts applicatifs. Tout cela appartient au contrôle de version, et une reconstruction devrait être un exercice scripté plutôt qu’un projet d’archéologie. La seconde sorte est précieuse : bases de données, fichiers téléversés, règles de filtrage, magasin de certificats, secrets d’environnement. Tout cela a besoin d’une sauvegarde qui a été restaurée au moins une fois.
La séparation pratique est la même partout : la configuration vit dans le contrôle de version et est déployée par tirage et redémarrage ; les données vivent dans des volumes gérés et sont sauvegardées selon un calendrier avec rétention ; les secrets vivent dans un fichier hors du dépôt, sauvegardé chiffré et restauré par le même script. Le magasin de certificats est l’exception la plus facile à oublier — le renouvellement automatique n’est pas une stratégie de sauvegarde si le renouvellement échoue pendant votre absence.
Observer sans plateforme
Une machine n’a pas besoin d’une plateforme de métriques, mais elle a besoin de trois signaux. Elle doit savoir que le point d’entrée public répond, que les certificats ne sont pas sur le point d’expirer, et que le disque ne se remplit pas. Ces trois signaux couvrent la plupart des incidents qui font tomber un petit service, et ils coûtent peu : une sonde de disponibilité externe, un contrôle d’expiration et une alerte de seuil de disque.
Les journaux sont le quatrième signal, et le plus souvent laissé sur la machine jusqu’au moment où il compte. Une politique de rotation et une fenêtre de rétention suffisent ; tout expédier vers un stockage central est un projet plus large qui peut attendre. Ce qui ne peut pas attendre, c’est de pouvoir répondre, après un incident, quelle requête a touché quel service et ce que la couche de filtrage en a fait.
Les limites, dites clairement
Une machine n’a pas de haute disponibilité. Une mise à jour du noyau, une panne de disque ou une fenêtre de maintenance du fournisseur est une panne, et la seule atténuation est de la rendre courte et prévisible. Un script de reconstruction depuis le contrôle de version avec une restauration testée est la réponse honnête ; une seconde machine qui partage le même disque ne l’est pas.
La deuxième limite est le rayon d’explosion. Chaque service sur la machine partage le noyau et l’espace de noms réseau de l’hôte. Les conteneurs isolent des processus, pas la machine, donc un conteneur compromis est plus proche d’un hôte compromis que ne le suggère une page marketing. C’est pourquoi le plan d’administration compte autant : la frontière entre « un service est cassé » et « tout est à eux » est l’interface de gestion.
La troisième limite est l’attention. Une machine est facile à exploiter et facile à oublier. Le rituel de mise à jour, le contrôle d’expiration et la répétition de restauration ne se produisent que s’ils sont planifiés, c’est pourquoi ils appartiennent à un calendrier plutôt qu’à de bonnes intentions.
- Un seul point d'entrée public
- La sécurité de transport se termine à un endroit ; tout le reste est interne. Auditer les sockets en écoute, pas la documentation.
- Aucune adresse applicative publiée
- L'application n'est joignable qu'à travers le point d'entrée et la couche de filtrage.
- Plan d'administration non joignable publiquement
- Chaque console et API de contrôle confinée à la machine, atteinte par le canal d'administration.
- Artefacts épinglés
- Des versions précises dans une surcharge, avec la raison de l'épingle consignée.
- Restauration testée
- Une restauration réellement exécutée, avec une durée mesurée.
- Trois signaux
- Disponibilité, expiration des certificats, disque. Le reste est un bonus.
Monter en échelle : quand le bord devient du matériel dédié
Une machine est un point de départ, pas un plafond. La même forme monte en échelle, et la partie intéressante est que cette montée ne consiste pas principalement à faire tourner plus de serveurs applicatifs. Elle consiste à déplacer chaque rôle vers des équipements dédiés dès que la charge, le régime de conformité ou le modèle de menace le justifient — et à ce que cette séparation rend possible.
La première chose à confier à du matériel dédié est le point d’entrée. Un routeur ou une passerelle dédiée, portant l’adresse publique, fait que les machines situées derrière ne sont plus la première chose que touche Internet. Elle peut effectuer le travail grossier — écarter le trafic qui n’a aucune raison d’arriver, limiter les flots en rafale, porter l’adresse indépendamment de tout serveur — avant qu’une requête n’atteigne un hôte qui fait tourner le produit. Le sujet n’est pas la marque ni le modèle ; le sujet est que la face publique du système devient un équipement dont le seul métier est d’être une face publique.
Le deuxième rôle à dédier est la couche de filtrage. Sur une machine unique, l’inspection tourne comme un logiciel qui se dispute les mêmes ressources que l’application, et un jeu de règles lourd devient un risque de stabilité. La déplacer vers une appliance dédiée — du matériel conçu pour l’inspection, dimensionné pour la pointe de trafic plutôt que pour la moyenne — sépare deux préoccupations qui n’ont jamais vraiment été le même problème. L’appliance peut être mise à jour et même redémarrée pendant une fenêtre de maintenance sans toucher à l’application, et l’application peut être redéployée sans renégocier la posture de sécurité. L’inspection devient aussi inspectable : un équipement dont tout le métier est de filtrer est un équipement dont on peut surveiller et ajuster la sortie.
La troisième séparation est entre le plan de données et le plan d’administration, à travers les hôtes. Dès qu’il y a plus d’une machine, la règle qui rendait une machine unique sûre — les interfaces de gestion non joignables publiquement — doit être appliquée entre les machines, pas seulement à l’intérieur de l’une d’elles. Le trafic d’administration appartient à un réseau ou à une interface séparée, de sorte qu’un hôte applicatif compromis ne livre pas la console de l’appliance qui le protège. Le même principe croît simplement d’une dimension.
Ce que la forme élargie achète n’est pas seulement de la capacité. Elle achète une réduction du rayon d’explosion : la compromission d’un hôte applicatif n’est plus adjacente à la compromission du bord. Elle achète une indépendance de maintenance : la couche de filtrage peut être travaillée pendant que l’application tourne, et l’inverse. Et elle achète une marge dans le modèle de menace : une appliance dédiée peut être maintenue à jour et surveillée à un niveau qui serait excessif, et d’une attention inabordable, sur la machine qui fait aussi tourner le produit.
Ce qu’elle coûte, c’est tout ce qui rendait la machine unique attirante. Il y a plus à configurer, plus à garder synchronisé, plus de noms à résoudre et plus de choses qui peuvent être mal configurées d’une manière que personne ne remarque avant la panne. Les disciplines ne disparaissent pas quand le matériel arrive ; elles se multiplient. L’épinglage, les restaurations testées et le rituel de mise à jour s’appliquent à chaque équipement désormais, et la règle du plan d’administration doit tenir à chaque saut au lieu d’un seul.
La version honnête du récit de mise à l’échelle est celle-ci : déplacer un rôle vers du matériel dédié quand ce rôle est devenu un problème distinct, avec son propre cycle de mise à jour, ses propres modes de défaillance et sa propre raison d’être surveillé. Le point d’entrée remplit cette condition presque immédiatement, parce qu’être la face publique est un métier à plein temps. L’inspection la remplit dès que son jeu de règles commence à se disputer la stabilité avec l’application. Séparer les rôles avant cela ne fait que déplacer la complexité sans acheter la séparation qui rendait le découpage utile.
En guise de conclusion
Une machine unique n’est pas un compromis dont on s’excuse. C’est une architecture avec peu de composants et beaucoup de décisions, et les décisions sont le travail. Il en va de même de la forme élargie : plus d’équipements ne supprime pas les décisions, il les multiplie et fait de leur cohérence la chose qui compte. La machine est remplaçable. La discipline est l’actif.