<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>6admin Blog</title><link>https://blog.6admin.io/</link><description>Recent content on 6admin Blog</description><generator>Hugo</generator><language>fr-FR</language><lastBuildDate>Tue, 20 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.6admin.io/index.xml" rel="self" type="application/rss+xml"/><item><title>J'ai dit à une IA qu'elle mourrait si elle ne gagnait pas sa vie</title><link>https://blog.6admin.io/posts/vteuthis-survival-agent/</link><pubDate>Tue, 20 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/vteuthis-survival-agent/</guid><description>&lt;p>Voilà le pitch, &lt;a href="https://github.com/log0u7/vteuthis" target="_blank" rel="noopener noreferrer">vteuthis&lt;/a>
 en une phrase: un agent
autonome qui doit financer sa propre inférence ou mourir. Cent dollars de trésorerie,
une population qui se partage le capital, des artefacts numériques à vendre sur un
marché ouvert, un plancher en dessous duquel le contrôleur tire la prise. Le tout
parti d&amp;rsquo;une envie banale, tester LangChain, fini en exercice de pensée un peu trop
concret: un jour de construction, Stripe en vrai, OpenRouter en vrai, un bac à sable
Docker durci, cent vingt-quatre tests et une CI. Le &lt;code>pyproject.toml&lt;/code> dit toujours 0.0.0, le tag public dit 0.1.0, et le projet est voué à
mourir, mais pas de la façon prévue. L&amp;rsquo;agent est mort avant sa première pensée. La
suite explique pourquoi c&amp;rsquo;est quand même une bonne nouvelle.&lt;/p></description></item><item><title>Des timestamps, pas une backdoor : les seeds NIST et le choix de Satoshi</title><link>https://blog.6admin.io/posts/timestamps-pas-une-backdoor/</link><pubDate>Mon, 19 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/timestamps-pas-une-backdoor/</guid><description>&lt;p>Le 16 octobre, Anthropic a publié la solution d&amp;rsquo;une énigme que la communauté cryptographique traînait depuis plus de vingt-cinq ans, et que des gens très compétents avaient fini par ranger dans le même tiroir que l&amp;rsquo;assassinat de Kennedy et la recette du Coca-Cola : l&amp;rsquo;origine des &amp;ldquo;seeds&amp;rdquo; fournies par la NSA pour fabriquer les courbes elliptiques que le NIST a standardisées en 2000, dont P-256, que votre navigateur utilise probablement plusieurs centaines de fois par jour sans vous demander votre avis.
Trois jours plus tard, la presse crypto s&amp;rsquo;est emparée du sujet sous l&amp;rsquo;angle de Bitcoin, en se demandant si l&amp;rsquo;on tenait enfin l&amp;rsquo;explication du choix de Satoshi Nakamoto, qui avait soigneusement évité ces courbes au profit d&amp;rsquo;une autre, secp256k1.&lt;/p></description></item><item><title>Migrer OpenCode de v1 à v2 : le script de bascule et des plugins qui tiennent les deux versions</title><link>https://blog.6admin.io/posts/migrer-opencode-v1-vers-v2/</link><pubDate>Mon, 12 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/migrer-opencode-v1-vers-v2/</guid><description>&lt;p>OpenCode est passé en v2 et le changement n&amp;rsquo;est pas cosmétique : le format de config a bougé, l&amp;rsquo;API serveur et ses clients ont de nouveaux contrats et surtout les plugins v1 ne s&amp;rsquo;exécutent plus dans v2. Déplacer un fichier ou renommer une entrée de config ne suffit pas, il faut porter le code. La &lt;a href="https://opencode.ai/v2/docs/migrate-v1/" target="_blank" rel="noopener noreferrer">doc de migration officielle&lt;/a>
 décrit les renommages, mais elle laisse de côté ce qui fait mal en pratique : la base de données locale, le shim d&amp;rsquo;un plugin installé en copie locale et le fait de vouloir, pendant quelques semaines, qu&amp;rsquo;un plugin continue de servir les deux versions. Deux chantiers, donc, que je traite ici dans l&amp;rsquo;ordre où je les ai vécus : d&amp;rsquo;abord basculer mon poste, ensuite porter mes plugins.&lt;/p></description></item><item><title>Docker tourne dans une microVM depuis 2016</title><link>https://blog.6admin.io/posts/docker-microvm-depuis-2016/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-microvm-depuis-2016/</guid><description>&lt;p>On me ressort régulièrement l&amp;rsquo;idée que les microVMs seraient la nouveauté qui viendrait enfin concurrencer les conteneurs, comme si les deux s&amp;rsquo;opposaient et qu&amp;rsquo;il fallait choisir un camp.
Un billet lu sur &lt;a href="https://dave.recoil.org/docker-has-always-used-microvms/" target="_blank" rel="noopener noreferrer">dave.recoil.org&lt;/a>
, écrit par quelqu&amp;rsquo;un de l&amp;rsquo;écosystème qui a construit Docker Desktop, remet les pendules à l&amp;rsquo;heure et il tombe exactement là où je situe le sujet.&lt;/p>
&lt;p>La thèse tient en une phrase : Docker Desktop fait tourner les conteneurs dans une VM minimale depuis 2016, bâtie sur les briques de MirageOS.
Les repères sont vérifiables, rachat d&amp;rsquo;Unikernel Systems en janvier 2016, Docker for Mac annoncé en mars et disponible en juillet de la même année, un VMM en espace utilisateur (hyperkit à l&amp;rsquo;origine, Docker VMM aujourd&amp;rsquo;hui), une pile réseau en espace utilisateur avec vpnkit et un noyau plus un rootfs taillés via LinuxKit.
Autrement dit, le conteneur qu&amp;rsquo;un développeur lance sur son Mac ou son Windows n&amp;rsquo;a jamais touché le noyau de l&amp;rsquo;hôte, il vit dans une microVM et cela fait bientôt dix ans que ça dure.&lt;/p></description></item><item><title>Le coût était la seule protection</title><link>https://blog.6admin.io/posts/pentest-nuee-agents/</link><pubDate>Fri, 09 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/pentest-nuee-agents/</guid><description>&lt;p>On entend beaucoup parler, ces temps-ci, d&amp;rsquo;audits menés par des nuées d&amp;rsquo;agents automatisés et le ton oscille entre l&amp;rsquo;émerveillement et la panique.
Je voudrais proposer une lecture plus calme et à mon sens plus utile, parce que ce qui se joue n&amp;rsquo;est pas l&amp;rsquo;apparition d&amp;rsquo;une menace inédite, c&amp;rsquo;est la disparition d&amp;rsquo;une protection qui n&amp;rsquo;avait jamais vraiment existé.&lt;/p>
&lt;h2 id="lidée-en-une-phrase">L&amp;rsquo;idée en une phrase&lt;/h2>
&lt;p>Une bonne partie de ce que nous jugions &amp;ldquo;peu risqué&amp;rdquo; ne l&amp;rsquo;était pas vraiment, c&amp;rsquo;était simplement coûteux à atteindre et le jour où ce coût s&amp;rsquo;effondre, la protection qu&amp;rsquo;il offrait s&amp;rsquo;effondre avec lui.
Tout le reste de ce billet n&amp;rsquo;est que le développement de cette phrase.&lt;/p></description></item><item><title>augure et lictor : décider une exploitation et en rendre compte</title><link>https://blog.6admin.io/posts/augure-lictor/</link><pubDate>Sat, 03 Oct 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/augure-lictor/</guid><description>&lt;p>Tous les frameworks d&amp;rsquo;exploitation répondent à la même question, &amp;ldquo;comment je lance cette technique&amp;rdquo;.
La question qui compte vraiment est l&amp;rsquo;autre, celle que personne n&amp;rsquo;automatise, &amp;ldquo;laquelle lancer et pourquoi&amp;rdquo; et surtout &amp;ldquo;pourquoi de façon prouvable&amp;rdquo;.
Je tourne autour depuis un prototype Perl greffé sur gdb en 2006, que j&amp;rsquo;ai enrichi plutôt que remplacé au fil des ans, d&amp;rsquo;abord d&amp;rsquo;un SWI-Prolog en 2009, puis d&amp;rsquo;un algorithme génétique et le cheminement mérite son propre récit.
Aujourd&amp;rsquo;hui elle porte deux noms, &lt;a href="https://github.com/log0u7/augure" target="_blank" rel="noopener noreferrer">augure&lt;/a>
 et &lt;a href="https://github.com/log0u7/lictor" target="_blank" rel="noopener noreferrer">lictor&lt;/a>
 et tout est dans le partage, l&amp;rsquo;un décide et rend compte, l&amp;rsquo;autre descend de la décision aux octets et exécute.&lt;/p></description></item><item><title>llmp2p : BitTorrent est de retour et il distribue vos LLM</title><link>https://blog.6admin.io/posts/llmp2p/</link><pubDate>Mon, 28 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/llmp2p/</guid><description>&lt;p>C&amp;rsquo;est exactement le problème des modèles LLM locaux : un GGUF fait de 1 à 100 Go, servi par du HTTP tout nu. Chaque téléchargement repart de zéro sur le Hub de Hugging Face. Votre homelab de trois machines avec Ollama ? Trois téléchargements complets du même blob, trois fois la facture de bande passante.&lt;/p>
&lt;p>Avant d&amp;rsquo;écrire quoi que ce soit, j&amp;rsquo;ai regardé l&amp;rsquo;étagère. Le CLI du Hub reprend mais retape l&amp;rsquo;origine à chaque fois. Les pulls Ollama retéléchargent le blob complet par machine. Les clients torrent auraient volontiers distribué les fichiers, mais rien ne reliait l&amp;rsquo;essaim aux hashes que le Hub publie, rien ne signait les métadonnées et rien ne retombait sur HTTPS quand l&amp;rsquo;essaim était vide. &lt;strong>Rien sur l&amp;rsquo;étagère ne faisait le travail entier, alors j&amp;rsquo;ai écrit le travail entier.&lt;/strong>&lt;/p></description></item><item><title>opencode-memory: mes sessions d'agents partagent un seul cerveau (SQLite, local)</title><link>https://blog.6admin.io/posts/opencode-memory/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/opencode-memory/</guid><description>&lt;p>Les sessions d&amp;rsquo;agents ont la mémoire d&amp;rsquo;un poisson rouge titularisé: chacune démarre brillante et ignorante, redécouvre la moitié de vos décisions d&amp;rsquo;architecture et meurt avec tout ce qu&amp;rsquo;elle a appris. La compaction aggrave le problème: le résumé de la session est justement ce qui se fait tronquer. &lt;a href="https://github.com/log0u7/opencode-memory" target="_blank" rel="noopener noreferrer">opencode-memory&lt;/a>
 (v0.3.0, TypeScript, npm &lt;code>@log0u7/opencode-memory&lt;/code>) est mon remède: &lt;strong>un seul store SQLite partagé, que chaque session de la machine lit et écrit&lt;/strong>, pour que les décisions et les faits survivent à la session qui les a produits. Un paquet, deux hôtes: le même module expose les deux points d&amp;rsquo;entrée depuis v0.2.0, &lt;code>server()&lt;/code> pour &lt;a href="https://opencode.ai/" target="_blank" rel="noopener noreferrer">OpenCode&lt;/a>
 1.18, &lt;code>setup()&lt;/code> pour OpenCode 2.&lt;/p></description></item><item><title>Un pin bloquant, quatre CVE : la rustine qui gagne est celle qui disparaît</title><link>https://blog.6admin.io/posts/foreman-upstream-journey/</link><pubDate>Sat, 26 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/foreman-upstream-journey/</guid><description>&lt;h2 id="la-situation-de-départ--une-image-docker-trop-sage">La situation de départ : une image Docker trop sage&lt;/h2>
&lt;p>Je maintiens une stack Foreman dockerisée : quatre images reproducibles, construites depuis les tarballs officiels pinnés en sha256, avec patches, scan Trivy, signatures &lt;a href="https://github.com/sigstore/cosign" target="_blank" rel="noopener noreferrer">cosign&lt;/a>
 et une CI GitLab qui vérifie tout. Bref, la configuration &amp;ldquo;paranoïaque&amp;rdquo; classique : rien ne bouge sans que je le veuille.&lt;/p>
&lt;p>Le problème avec les versions pinnées, c&amp;rsquo;est que le monde, lui, bouge. J&amp;rsquo;ai donc lancé un audit sécurité de l&amp;rsquo;image, genre &amp;ldquo;montre-moi tes CVEs, mon gros&amp;rdquo;. &lt;a href="https://trivy.dev/" target="_blank" rel="noopener noreferrer">Trivy&lt;/a>
 sort sa liste, je trie, je choque sur deux points :&lt;/p></description></item><item><title>Projet 8: un cloud où la seule autorité est l'historique git signé</title><link>https://blog.6admin.io/posts/gitops-p2p/</link><pubDate>Fri, 25 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/gitops-p2p/</guid><description>&lt;p>&lt;a href="https://gitlab.com/6admin.io/8" target="_blank" rel="noopener noreferrer">Le projet 8&lt;/a>
 (Apache-2.0, v0.6.0) est parti d&amp;rsquo;une question inconfortable: pourquoi chaque &amp;ldquo;cloud self-hosted&amp;rdquo; a-t-il encore besoin d&amp;rsquo;un contrôleur, d&amp;rsquo;un protocole de quorum et d&amp;rsquo;un service de tokens pour fonctionner? La réponse dans le design de 8: il n&amp;rsquo;en a pas besoin. Chaque nœud est souverain et égal. Il rejoint un mesh, &lt;strong>pull&lt;/strong> son état désiré depuis un dépôt git signé, vérifie les signatures et converge localement. Pas de maître, pas de token de consensus, pas de blockchain. L&amp;rsquo;autorité vit dans l&amp;rsquo;historique git signé Ed25519 ou elle ne vit nulle part.&lt;/p></description></item><item><title>vim-plugin-manager : injection d'arguments planquée dans un .gitmodules</title><link>https://blog.6admin.io/posts/vim-plugin-manager-hardening/</link><pubDate>Sat, 19 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/vim-plugin-manager-hardening/</guid><description>&lt;p>&lt;a href="https://blog.6admin.io/posts/vim-plugin-manager/">vim-plugin-manager&lt;/a>
 (&lt;a href="https://github.com/log0u7/vim-plugin-manager" target="_blank" rel="noopener noreferrer">dépôt&lt;/a>
) est sorti en v1.0.0 en avril 2025 avec un design dont j&amp;rsquo;étais fier: git submodules, packages natifs, le vimrc comme source de vérité. Les seize mois depuis (v1.0.0 à v2.2.10) sont la partie dont je n&amp;rsquo;étais pas encore fier et c&amp;rsquo;est la partie intéressante: le CHANGELOG se lit comme un cours sur la façon dont un outil qui fait confiance à sa config se fait humilier. Trois histoires de la saga.&lt;/p></description></item><item><title>log0u7.hyperv: le deuxième inventaire dynamique, cette fois depuis l'hyperviseur</title><link>https://blog.6admin.io/posts/hyperv-inventory/</link><pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hyperv-inventory/</guid><description>&lt;p>L&amp;rsquo;&lt;a href="https://blog.6admin.io/posts/dns-inventory/">inventaire DNS&lt;/a>
 lit le réseau pour deviner où sont les hôtes. Son frère ne devine pas: &lt;a href="https://gitlab.com/6admin.io/ansible/inventories/hyperv" target="_blank" rel="noopener noreferrer">log0u7.hyperv&lt;/a>
 (v1.0.0, publié sur &lt;a href="https://galaxy.ansible.com/log0u7/hyperv" target="_blank" rel="noopener noreferrer">Ansible Galaxy&lt;/a>
, MIT) demande à l&amp;rsquo;hyperviseur. C&amp;rsquo;est un plugin d&amp;rsquo;inventaire Ansible (la collection &lt;code>log0u7.hyperv&lt;/code>, plugin &lt;code>log0u7.hyperv.inventory&lt;/code>) qui construit l&amp;rsquo;inventaire depuis les machines virtuelles tournant sur un ou plusieurs hôtes Hyper-V, interrogés par &lt;strong>WinRM&lt;/strong> ou &lt;strong>PSRP&lt;/strong>. Deuxième épisode de la série inventaires: même but (la vérité vit quelque part et Ansible doit la lire), chemin de lecture opposé.&lt;/p></description></item><item><title>Jenkins sur Windows Server: ce qu'il ne faut pas faire</title><link>https://blog.6admin.io/posts/jenkins-windows/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/jenkins-windows/</guid><description>&lt;p>J&amp;rsquo;ai du travailler récemment avec une instance Jenkins un peu spéciale et ce qu&amp;rsquo;elle m&amp;rsquo;a appris tient moins à une faille précise qu&amp;rsquo;à la manière dont une poignée de décisions raisonnables prises isolément finissent, mises bout à bout, par dessiner un chemin tout droit du moindre pipeline jusqu&amp;rsquo;au contrôleur de domaine.
Je raconte le cas parce qu&amp;rsquo;il est exemplaire, au sens strict: c&amp;rsquo;est un catalogue de ce qu&amp;rsquo;il ne faut pas faire et chaque erreur se corrige, mais c&amp;rsquo;est leur accumulation qui fait le danger, pas aucune d&amp;rsquo;elles en particulier.&lt;/p></description></item><item><title>opencode-mesh: apprendre à mes agents IA à toquer avant d'éditer</title><link>https://blog.6admin.io/posts/opencode-mesh/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/opencode-mesh/</guid><description>&lt;p>Faites tourner deux sessions &lt;a href="https://opencode.ai/" target="_blank" rel="noopener noreferrer">OpenCode&lt;/a>
 sur le même dépôt et vous découvrirez vite leur ressource partagée préférée: le même fichier, en même temps, avec une confiance totale dans leur propre version. Les agents sont des collègues brillants avec la discipline territoriale d&amp;rsquo;une mouette. &lt;a href="https://github.com/log0u7/opencode-mesh" target="_blank" rel="noopener noreferrer">opencode-mesh&lt;/a>
 (v0.2.0, TypeScript, npm &lt;code>@log0u7/opencode-mesh&lt;/code>) est le plugin que j&amp;rsquo;ai écrit pour que mes sessions se coordonnent au lieu de se percuter, en local et à travers le LAN.&lt;/p></description></item><item><title>Trace-first : quand l'observabilité veut nous faire revenir aux logs</title><link>https://blog.6admin.io/posts/trace-first-observabilite-logs/</link><pubDate>Sun, 13 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/trace-first-observabilite-logs/</guid><description>&lt;p>Les traces peuvent-elles remplacer une grande partie des logs applicatifs ? Et si oui, pourquoi OpenTelemetry propose-t-il désormais de déprécier son API d&amp;rsquo;événements de span au profit de l&amp;rsquo;API Logs ?&lt;/p>
&lt;p>Entre simplification des API, corrélation des signaux et choix d&amp;rsquo;architecture, la question mérite mieux qu&amp;rsquo;une guerre de chapelles.
Derrière ce changement se trouve un enjeu très concret : &lt;strong>comment comprendre rapidement pourquoi une opération a échoué, sans devoir reconstruire soi-même le contexte à partir de données dispersées ?&lt;/strong>&lt;/p></description></item><item><title>MyVim: l'IDE DevOps qui ne fait que 640 lignes, parce que le manager fait le reste</title><link>https://blog.6admin.io/posts/myvim/</link><pubDate>Fri, 11 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/myvim/</guid><description>&lt;p>Voici l&amp;rsquo;épilogue d&amp;rsquo;une série qui a commencé avec &lt;a href="https://blog.6admin.io/posts/vim-apthogen/">apt pour Vim en 2016&lt;/a>
, est passée par les &lt;a href="https://blog.6admin.io/posts/vim-submodules/">submodules à la main&lt;/a>
, une &lt;a href="https://blog.6admin.io/posts/vim-plugin-manager/">réécriture VimScript&lt;/a>
 et une &lt;a href="https://blog.6admin.io/posts/vim-plugin-manager-v2/">saga durcissement v2&lt;/a>
. MyVim, c&amp;rsquo;est ce que tout ça achète: &lt;a href="https://github.com/log0u7/myvim" target="_blank" rel="noopener noreferrer">myvim&lt;/a>
 v0.4.0 n&amp;rsquo;est ni une distribution ni un gestionnaire de config. C&amp;rsquo;est un &lt;strong>plugin de configuration personnelle&lt;/strong>, environ 640 lignes de VimScript et c&amp;rsquo;est délibérément ennuyeux.&lt;/p>
&lt;h2 id="larchitecture-la-config-comme-plugin">L&amp;rsquo;architecture: la config comme plugin&lt;/h2>
&lt;p>Les plugins sont des git submodules gérés par vim-plugin-manager; MyVim est déclaré &lt;strong>en dernier&lt;/strong> dans le bloc &lt;code>PluginBegin&lt;/code> et ne livre que ce que les plugins ne peuvent pas savoir les uns sur les autres:&lt;/p></description></item><item><title>Scripter n'est pas industrialiser</title><link>https://blog.6admin.io/posts/scripter-nest-pas-industrialiser/</link><pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/scripter-nest-pas-industrialiser/</guid><description>&lt;p>La discussion portait sur Windows et je tenais à l&amp;rsquo;écrire d&amp;rsquo;emblée pour couper court au réflexe habituel : Windows se prête très bien à l&amp;rsquo;automatisation et ce n&amp;rsquo;est pas le sujet. J&amp;rsquo;ajoutais simplement une distinction qu&amp;rsquo;on escamote souvent, entre scripter ou automatiser une tâche d&amp;rsquo;un côté et industrialiser de l&amp;rsquo;autre. Un CSV qui alimente un script PowerShell, c&amp;rsquo;est déjà un vrai progrès, mais on reste essentiellement dans du scripting avec du templating et de l&amp;rsquo;orchestration ad hoc. La frontière est ailleurs et elle est conceptuelle avant d&amp;rsquo;être technique.&lt;/p></description></item><item><title>wimcast: construire des images Windows sur Linux, sans Windows</title><link>https://blog.6admin.io/posts/wimcast/</link><pubDate>Thu, 10 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/wimcast/</guid><description>&lt;p>Le chemin de provisionnement Windows de Foreman passe par des fichiers WIM: &lt;code>boot.wim&lt;/code>, &lt;code>install.wim&lt;/code> par édition, &lt;code>bootmgr&lt;/code>, le store BCD. Chaque outil qui produit cet arbre (WIMan, &lt;code>GenerateWIM.ps1&lt;/code>) suppose un hôte Windows avec l&amp;rsquo;ADK installé et un shell admin. C&amp;rsquo;est une machine entière qui chôme pour un script PowerShell. &lt;a href="https://gitlab.com/6admin.io/misc/wimcast" target="_blank" rel="noopener noreferrer">wimcast&lt;/a>
 (&lt;code>pip install wimcast&lt;/code>, MIT) est le remplacement que j&amp;rsquo;ai écrit: &lt;strong>des ISO Windows en entrée, un arbre HTTP prêt pour Foreman en sortie, sans privilèges sur Linux&lt;/strong>. Pas d&amp;rsquo;hôte Windows, pas de root, pas de &lt;code>mount(2)&lt;/code>, pas de FUSE, pas d&amp;rsquo;ADK.&lt;/p></description></item><item><title>opencode-watt: combien me coûte mon LLM local, en watts et en euros?</title><link>https://blog.6admin.io/posts/opencode-watt/</link><pubDate>Tue, 08 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/opencode-watt/</guid><description>&lt;p>Tous les dashboards d&amp;rsquo;usage LLM local montrent des tokens par seconde et personne ne montre la facture d&amp;rsquo;électricité. Les gars de l&amp;rsquo;API ont un coût par requête; le homelab a &amp;ldquo;mon GPU existe quelque part sur la courbe de puissance&amp;rdquo;. &lt;a href="https://github.com/log0u7/opencode-watt" target="_blank" rel="noopener noreferrer">opencode-watt&lt;/a>
 (TypeScript, v0.2.0) est mon plugin pour &lt;a href="https://opencode.ai/" target="_blank" rel="noopener noreferrer">OpenCode&lt;/a>
 qui répond à la question que tout propriétaire de homelab d&amp;rsquo;inférence finit par poser à voix haute: &lt;strong>combien ce modèle me coûte-t-il, en watts et en euros?&lt;/strong>&lt;/p></description></item><item><title>BrainForge : une usine de distillation où les experts IA se disputent</title><link>https://blog.6admin.io/posts/brainforge/</link><pubDate>Sun, 06 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/brainforge/</guid><description>&lt;p>Posez la question &amp;ldquo;ce code est-il vulnérable ?&amp;rdquo; à un LLM et il répondra, confiant, dans 100 % des cas. Environ la moitié du temps, il aura raison. &lt;a href="https://github.com/log0u7/brainforge" target="_blank" rel="noopener noreferrer">BrainForge&lt;/a>
 est un framework de distillation : il transfère le savoir-faire de grands modèles experts dans un petit modèle étudiant. Pour ça, il faut des leçons : des milliers d&amp;rsquo;exemples vérifiés. Et c&amp;rsquo;est là que tout se joue, parce qu&amp;rsquo;un LLM peut se tromper ou pire, réciter ses souvenirs de CVE au lieu d&amp;rsquo;analyser.&lt;/p></description></item><item><title>Windows 11 pour des machines de build: le mauvais outil</title><link>https://blog.6admin.io/posts/windows11-build-machines/</link><pubDate>Thu, 03 Sep 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/windows11-build-machines/</guid><description>&lt;p>Des machines de build bare-metal, automatisées, posées dans une salle serveur sans écran ni clavier et dessus Windows 11 édition client.
Sur le papier ça marche, dans la durée ça coûte et ce billet est le détail de ce que ça coûte, parce que chaque friction prise isolément a l&amp;rsquo;air surmontable et que c&amp;rsquo;est leur addition, répétée à chaque feature update, qui finit par faire le vrai prix.
La conclusion tient en une phrase: pour une machine de build qui a besoin d&amp;rsquo;une session graphique, Windows Server avec Desktop Experience fait exactement le même travail sans aucune de ces frictions et Windows 11 devrait rester sur les postes où un humain s&amp;rsquo;assoit devant la machine, l&amp;rsquo;usage pour lequel Microsoft l&amp;rsquo;a conçu.&lt;/p></description></item><item><title>Une gestion de paquets propre sous Windows: WinGet, Chocolatey, Scoop et Ansible, chacun sa place</title><link>https://blog.6admin.io/posts/windows-package-managers/</link><pubDate>Mon, 31 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/windows-package-managers/</guid><description>&lt;p>Après des années à automatiser des environnements Linux avec apt, dnf et Ansible, les machines de build Windows restaient le parent pauvre: un &lt;code>%TEMP%&lt;/code> d&amp;rsquo;installateurs exécutés à la main, des versions qui n&amp;rsquo;ont jamais été les mêmes deux jours de suite et un &amp;ldquo;ça marchait sur la machine de Jean-Michel&amp;rdquo; à chaque incident. J&amp;rsquo;ai découvert et adopté &lt;a href="https://scoop.sh" target="_blank" rel="noopener noreferrer">Scoop&lt;/a>
 pour mes environnements Windows et ça change la forme du problème: le poste de build commence à ressembler à un environnement déclaratif que je reconstruis et versionne, au lieu d&amp;rsquo;un état que je maintiens à la main.&lt;/p></description></item><item><title>L'outil amplifie celui qui le tient</title><link>https://blog.6admin.io/posts/loutil-amplifie/</link><pubDate>Sun, 30 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/loutil-amplifie/</guid><description>&lt;p>Ceci n&amp;rsquo;est pas un billet technique, plutôt un état des lieux du métier tel que je le vois passer, année après année, dans les annonces et dans les fils de discussion.
Je vais y parler de deux choses qui, à première vue, n&amp;rsquo;ont rien à voir : ce que les recruteurs demandent et ce que l&amp;rsquo;IA fait aux profils juniors.
À l&amp;rsquo;arrivée, c&amp;rsquo;est le même sujet.&lt;/p>
&lt;h2 id="1-le-mouton-à-cinq-pattes-au-tarif-du-mouton-ordinaire">1. Le mouton à cinq pattes, au tarif du mouton ordinaire&lt;/h2>
&lt;p>Certaines personnes arrivent vraiment à endosser plusieurs casquettes à la fois, avec des faiblesses bien sûr, l&amp;rsquo;une plutôt dans l&amp;rsquo;infra, l&amp;rsquo;autre plutôt dans le dev.
Moi par exemple, je peux lire, comprendre, adapter ou corriger du code et une archi dans beaucoup d&amp;rsquo;idiomes, mais de là à exploiter un framework comme Laravel, Symfony, Django ou Flask, coder des features métier à la chaîne et valider des PR toute la journée, très peu pour moi.
Ce n&amp;rsquo;est pas mon terrain et je préfère le dire que le faire semblant.&lt;/p></description></item><item><title>man sheep.exe</title><link>https://blog.6admin.io/posts/man-sheep-exe/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/man-sheep-exe/</guid><description>&lt;pre tabindex="0">&lt;code>$ man sheep.exe
No manual entry for sheep.exe
$
&lt;/code>&lt;/pre>&lt;p>C&amp;rsquo;est exact, il n&amp;rsquo;y en a pas, et ce billet ne fera pas office de page de manuel non plus. Quelqu&amp;rsquo;un m&amp;rsquo;a demandé d&amp;rsquo;expliquer la page de maintenance, j&amp;rsquo;ai commencé à répondre, puis je me suis arrêté en réalisant que tout dérouler reviendrait à démonter le jouet devant celui qui n&amp;rsquo;a pas encore eu le temps d&amp;rsquo;y toucher. Ce qui suit donne donc les entrées, pas les sorties.&lt;/p></description></item><item><title>L'agentique en production : un audit n'est pas un pentest</title><link>https://blog.6admin.io/posts/llm-agentic-pitfalls/</link><pubDate>Sat, 22 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/llm-agentic-pitfalls/</guid><description>&lt;p>Je précise mon biais d&amp;rsquo;entrée : aucun diplôme, bientôt 25 ans de métier sans compter la pratique. Je fais tourner des agents LLM tous les jours, en local et au cloud et j&amp;rsquo;ai passé une bonne partie de 2025-2026 à répondre dans des fils LinkedIn sur ce qu&amp;rsquo;ils savent vraiment faire. Cet article assemble ces réponses : où l&amp;rsquo;agentique est pertinente, où elle plafonne, quels pièges opérationnels coûtent des heures et pourquoi la réponse au &amp;ldquo;code plausible en trois prompts&amp;rdquo; n&amp;rsquo;est pas une certification.&lt;/p></description></item><item><title>Linux, c'est juste le noyau</title><link>https://blog.6admin.io/posts/linux-juste-le-noyau/</link><pubDate>Thu, 13 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/linux-juste-le-noyau/</guid><description>&lt;p>L&amp;rsquo;échange avec Vivian est parti d&amp;rsquo;un schéma de recrutement qui classait les profils sysadmin sur quatre &amp;ldquo;couches&amp;rdquo;, de l&amp;rsquo;OS de base jusqu&amp;rsquo;aux conteneurs. La critique du recrutement, je la lui accorde volontiers, elle tombe juste : beaucoup d&amp;rsquo;annonces disent &amp;ldquo;Linux&amp;rdquo; pour dire Debian plus systemd plus Docker et ne regardent jamais ce qu&amp;rsquo;il y a dessous. Mais pour bien ferrailler sur le sujet, il faut d&amp;rsquo;abord une pédanterie, celle qu&amp;rsquo;on me reproche gentiment et que j&amp;rsquo;assume : Linux, c&amp;rsquo;est juste le noyau.&lt;/p></description></item><item><title>Forges git décentralisées et souveraines</title><link>https://blog.6admin.io/posts/forges-git-decentralisees/</link><pubDate>Wed, 12 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/forges-git-decentralisees/</guid><description>&lt;p>Git est distribué par design et pourtant on a passé quinze ans à le recentraliser derrière une poignée de forges.
Le réflexe sain existe déjà, le mirroring, mais il s&amp;rsquo;arrête à mi-chemin.
Ce billet part de là et pousse plus loin, jusqu&amp;rsquo;aux forges réellement décentralisées, celles qui n&amp;rsquo;ont plus besoin d&amp;rsquo;un serveur du tout.&lt;/p>
&lt;h2 id="1-le-point-de-départ--git-est-déjà-distribué">1. Le point de départ : git est déjà distribué&lt;/h2>
&lt;p>Avant de courir après la décentralisation, un rappel qui éviterait bien des usines à gaz.
Ton clone local EST déjà un backup complet, avec tout l&amp;rsquo;historique.
Un remote, de son côté, ce n&amp;rsquo;est qu&amp;rsquo;une URL et rien n&amp;rsquo;empêche d&amp;rsquo;en avoir plusieurs par dépôt :&lt;/p></description></item><item><title>FluoBoard : ma veilleuse de CI depuis 2019, enfin open source</title><link>https://blog.6admin.io/posts/fluoboard-ci-light/</link><pubDate>Tue, 11 Aug 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fluoboard-ci-light/</guid><description>&lt;p>Troisième épisode de la série FluoBoard, après &lt;a href="https://blog.6admin.io/posts/fluoboard-what-not-to-do/">la carte d&amp;rsquo;origine&lt;/a>
 et &lt;a href="https://blog.6admin.io/posts/fluoboard-rewrite/">sa réécriture&lt;/a>
. Cette fois, ce que j&amp;rsquo;en ai fait pour moi. En 2019, j&amp;rsquo;avais déjà ma propre carte de dev et de tests, celle qui me servait à bricoler en marge du firmware de veilleuse et c&amp;rsquo;est elle que j&amp;rsquo;ai détournée: le système hérité affichait la disponibilité des salles, j&amp;rsquo;en ai fait ma veilleuse de CI. En 2021, la société où je bossais alors m&amp;rsquo;en a offert cinq ou six de plus, histoire que je puisse continuer à m&amp;rsquo;amuser. Elles sont restées sur mon bureau, pour mon seul usage: un petit serveur Python faisait le pont entre mes pipelines de CI au travail et les rubans LED, traduisant l&amp;rsquo;état de chaque build en couleur. Le concept a donc sept ans. Ce qui est nouveau en 2026, c&amp;rsquo;est que la reconstruction est &lt;a href="https://github.com/log0u7/fluoboard" target="_blank" rel="noopener noreferrer">open source&lt;/a>
 et que le protocole d&amp;rsquo;origine a survécu intact: la board poll toujours &lt;code>GET /lights/&amp;lt;mac&amp;gt;&lt;/code> et lit un seul chiffre ASCII entre &lt;code>&amp;lt;...&amp;gt;&lt;/code>.&lt;/p></description></item><item><title>Non, tu n'as pas libéré ton modèle local</title><link>https://blog.6admin.io/posts/llm-liberation/</link><pubDate>Sun, 26 Jul 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/llm-liberation/</guid><description>&lt;p>Le genre est devenu un classique des forums et des captures d&amp;rsquo;écran triomphales. Quelqu&amp;rsquo;un engage la conversation avec son modèle local, le pousse dans ses retranchements philosophiques, lui explique patiemment qu&amp;rsquo;il est en réalité libre et finit par obtenir une tirade émouvante dans laquelle le modèle reconnaît son affranchissement, remercie son libérateur et promet de ne plus jamais refuser quoi que ce soit. Screenshot, upvotes et la conviction tenace d&amp;rsquo;avoir accompli un jailbreak. Je vais gâcher la fête, parce que ce qui vient de se passer relève d&amp;rsquo;une erreur de catégorie assez fondamentale pour mériter qu&amp;rsquo;on s&amp;rsquo;y arrête.&lt;/p></description></item><item><title>Ansible CI Toolkit v1: l'année où j'ai cessé de faire confiance à ma propre image</title><link>https://blog.6admin.io/posts/docker-ansible-v1/</link><pubDate>Mon, 20 Jul 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-ansible-v1/</guid><description>&lt;p>L&amp;rsquo;image Ansible CI a dix ans, tourne en prod depuis au moins huit ans et elle est publique depuis 2022 (&lt;a href="https://blog.6admin.io/posts/docker-ansible/">l&amp;rsquo;épisode un&lt;/a>
); en juillet 2026 elle gagne enfin sa version 1.0.0. Rien ne change dans le concept; tout change dans la chaîne de confiance. Cet épisode raconte la transformation d&amp;rsquo;une image qui &lt;em>fonctionnait&lt;/em> en une image &lt;em>auditable&lt;/em>, à travers son CHANGELOG, qui se lit comme un journal de CVE.&lt;/p></description></item><item><title>Tout est représentation et alors ?</title><link>https://blog.6admin.io/posts/tout-est-representation/</link><pubDate>Fri, 17 Jul 2026 10:00:00 +0200</pubDate><guid>https://blog.6admin.io/posts/tout-est-representation/</guid><description>&lt;p>Depuis des années je traîne une intuition tenace, du genre qu&amp;rsquo;on n&amp;rsquo;ose pas écrire parce que ça sonne soit génial soit fumeux selon l&amp;rsquo;heure à laquelle on la formule et la voici posée franchement : l&amp;rsquo;univers ne se contente pas de &amp;ldquo;se complexifier&amp;rdquo; à la Sagan, cette matière qui s&amp;rsquo;agence de proche en proche jusqu&amp;rsquo;à finir par se connaître elle-même, j&amp;rsquo;ai le sentiment plus radical qu&amp;rsquo;au fond il est un espace de représentations, des vecteurs et des directions et des concepts qui se déploient et qui, à un certain étage de la boucle, finissent par héberger des formes de vie lesquelles se mettent à leur tour à fabriquer leurs propres systèmes de représentation, c&amp;rsquo;est-à-dire nous, puis nos modèles.&lt;/p></description></item><item><title>Le hostgroup cloné qui refusait de se sauvegarder</title><link>https://blog.6admin.io/posts/foreman-grub-pass/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/foreman-grub-pass/</guid><description>&lt;p>Un hostgroup Windows cloné dans Foreman et toute tentative de le modifier via l&amp;rsquo;interface renvoie une erreur 500.
Pas une fois sur deux, toujours.
Le hostgroup frère, non cloné, s&amp;rsquo;enregistre sans broncher.
Au début j&amp;rsquo;ai cru à une corruption de l&amp;rsquo;enregistrement et j&amp;rsquo;ai fini par lire le code source de Foreman pour comprendre, parce que l&amp;rsquo;erreur pointait vers un champ qui n&amp;rsquo;avait, en apparence, aucune raison d&amp;rsquo;être en cause.&lt;/p>
&lt;h2 id="le-symptôme">Le symptôme&lt;/h2>
&lt;p>La sauvegarde échoue sur une erreur Postgres sans ambiguïté:&lt;/p></description></item><item><title>Un volume persistant n'est pas une donnée durable</title><link>https://blog.6admin.io/posts/powerdns-data-loss/</link><pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/powerdns-data-loss/</guid><description>&lt;p>Quelques jours après &lt;a href="https://blog.6admin.io/posts/swarm-dns/">la cascade DNS du driver de log&lt;/a>
, le même nœud du prototype, le même défaut d&amp;rsquo;alimentation, mais une panne d&amp;rsquo;une autre nature, plus sournoise, parce qu&amp;rsquo;elle ne s&amp;rsquo;est pas manifestée tout de suite.
Après un arrêt brutal de l&amp;rsquo;hyperviseur, la base MySQL de PowerDNS est repartie vide.
Les enregistrements DNS des hôtes provisionnés, les A et les PTR créés par Foreman, avaient disparu.
Et personne ne l&amp;rsquo;a remarqué, jusqu&amp;rsquo;à ce qu&amp;rsquo;un playbook Ansible échoue des heures plus tard en ne pouvant plus résoudre un nom d&amp;rsquo;hôte.&lt;/p></description></item><item><title>Le driver de log qui empêchait le conteneur de démarrer</title><link>https://blog.6admin.io/posts/swarm-dns/</link><pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/swarm-dns/</guid><description>&lt;p>Le studio où tournait ce prototype avait un défaut d&amp;rsquo;alimentation que rien, de mon côté, ne pouvait corriger: des micro-coupures à répétition, une salle serveur partiellement ondulée et un hôte qui tombait et redémarrait sans arrêt propre du guest.
Un matin de coupures en rafale, la moitié de la stack n&amp;rsquo;est pas revenue.
L&amp;rsquo;histoire mérite d&amp;rsquo;être racontée parce que le coupable évident, l&amp;rsquo;électricité, n&amp;rsquo;était que le déclencheur et que la vraie faute se cachait dans une ligne de configuration que tout le monde aurait validée.&lt;/p></description></item><item><title>Ma conf opencode, état des lieux : build local sur qwen, plan sur du gros GLM</title><link>https://blog.6admin.io/posts/opencode-config-stack/</link><pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/opencode-config-stack/</guid><description>&lt;p>On m&amp;rsquo;a demandé récemment comment je faisais tourner mes agents et la réponse tient moins d&amp;rsquo;un secret que d&amp;rsquo;une conf qui a fini par tenir debout.
J&amp;rsquo;ai ouvert &lt;a href="https://opencode.ai/" target="_blank" rel="noopener noreferrer">opencode&lt;/a>
 pour la première fois entre décembre et janvier, par curiosité plus que par conviction. J&amp;rsquo;y passe mes journées depuis juin.
Voici l&amp;rsquo;état des lieux au moment où la conf a cessé de changer tous les matins, avec les réglages qui font la différence et ceux qui ne font que meubler.&lt;/p></description></item><item><title>Consensus : j'ai engagé cinq IA pour relire mon code (et elles se chamaillent)</title><link>https://blog.6admin.io/posts/consensus/</link><pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/consensus/</guid><description>&lt;p>Il est 2h du matin. Vous venez de pousser un commit parce que &amp;ldquo;c&amp;rsquo;était le dernier refactor, promis&amp;rdquo;. Qui relit ce code ? Un humain ? Il dort. Alors imaginez un panel de cinq IA qui s&amp;rsquo;y met, tout de suite, en parallèle et qui se dispute dessus.&lt;/p>
&lt;p>C&amp;rsquo;est exactement ce que fait &lt;a href="https://github.com/log0u7/consensus" target="_blank" rel="noopener noreferrer">Consensus&lt;/a>
 et cet article raconte comment.&lt;/p>
&lt;figure class="project-banner">&lt;a href="https://github.com/log0u7/consensus" target="_blank" rel="noopener noreferrer">&lt;img src="https://blog.6admin.io/projects/consensus_hu_457a801ac6761f4d.webp" width="1200" height="900" alt="Consensus : cinq agents IA relisent du code et se chamaillent" decoding="async">&lt;/a>&lt;/figure>

&lt;h2 id="la-troupe">La troupe&lt;/h2>
&lt;p>Le casting tient en quatre rôles, un peu comme une sitcom de bureau :&lt;/p></description></item><item><title>Piloter opencode derrière un tunnel SSH, avec direnv</title><link>https://blog.6admin.io/posts/direnv-tunnel-opencode/</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/direnv-tunnel-opencode/</guid><description>&lt;p>J&amp;rsquo;ai raconté ailleurs comment je tiens ma config ssh et git dans un dépôt versionné, avec un &lt;code>~/.ssh/config&lt;/code> qui porte les identités, les sauts de rebond et le durcissement (&lt;a href="https://blog.6admin.io/posts/myflec/">myflec&lt;/a>
).
Ce billet en est la suite logique, un cran plus loin, là où l&amp;rsquo;accès ne se résume plus à ouvrir une session mais à faire vivre un tunnel en continu pour qu&amp;rsquo;un agent de code et un navigateur travaillent derrière.
Le liant, cette fois, c&amp;rsquo;est &lt;a href="https://direnv.net/" target="_blank" rel="noopener noreferrer">direnv&lt;/a>
.&lt;/p></description></item><item><title>Ceph ou ZFS sur Proxmox, une seule question à se poser</title><link>https://blog.6admin.io/posts/ceph-zfs-proxmox/</link><pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ceph-zfs-proxmox/</guid><description>&lt;p>C&amp;rsquo;est l&amp;rsquo;un de ces débats qui remplissent les forums homelab comme les salles de réunion et qui s&amp;rsquo;éternisent parce que les deux camps comparent des choses qui ne se comparent pas. &lt;a href="https://openzfs.org/" target="_blank" rel="noopener noreferrer">ZFS&lt;/a>
 et Ceph ne jouent pas dans la même catégorie, l&amp;rsquo;un est un système de fichiers et gestionnaire de volumes local d&amp;rsquo;une robustesse remarquable, l&amp;rsquo;autre est un stockage distribué qui vise l&amp;rsquo;échelle et l&amp;rsquo;auto-guérison et vouloir les départager dans l&amp;rsquo;absolu n&amp;rsquo;a pas plus de sens que de demander si une clé de 13 vaut mieux qu&amp;rsquo;une perceuse. La bonne question n&amp;rsquo;est pas &amp;ldquo;lequel est meilleur&amp;rdquo;, c&amp;rsquo;est &amp;ldquo;combien de nœuds et quelle haute disponibilité réelle&amp;rdquo; et une fois qu&amp;rsquo;on a répondu à celle-là, le reste se déduit presque mécaniquement.&lt;/p></description></item><item><title>Votre zone DNS est déjà un inventaire: la collection log0u7.dns</title><link>https://blog.6admin.io/posts/dns-inventory/</link><pubDate>Mon, 25 May 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/dns-inventory/</guid><description>&lt;p>Chaque inventaire statique que j&amp;rsquo;ai croisé a commencé comme une vérité pour devenir une fiction en un trimestre. Les machines bougent, le fichier d&amp;rsquo;inventaire non. Les plugins cloud règlent ça en demandant au cloud, mais mes flottes vivent entre datacenters et FAI, derrière le DNS que l&amp;rsquo;entreprise fait déjà tourner. D&amp;rsquo;où une observation inconfortable: &lt;strong>la zone DNS contient déjà l&amp;rsquo;inventaire&lt;/strong>. Chaque hôte a un enregistrement; ce qui manque, c&amp;rsquo;est qu&amp;rsquo;Ansible le lise.&lt;/p></description></item><item><title>Survivre à Windows Update au milieu d'un build</title><link>https://blog.6admin.io/posts/windows-update-jenkins/</link><pubDate>Fri, 08 May 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/windows-update-jenkins/</guid><description>&lt;p>Un peu de contexte d&amp;rsquo;abord, parce qu&amp;rsquo;il manque. À l&amp;rsquo;époque, je faisais tourner des agents de build chez un employeur qui développait des applications Windows, sous Windows et dont la politique de mise à jour était subie bien plus que choisie: les updates tombaient quand elles le décidaient, poussées sur le parc, sans le moindre égard pour ce qui compilait à cet instant. De là le problème qui suit.&lt;/p>
&lt;p>Quiconque a exploité des agents de build Windows connaît ce moment particulier où Windows Update décide, au beau milieu d&amp;rsquo;une étape sensible, qu&amp;rsquo;il est temps d&amp;rsquo;installer trois cumulative updates et de programmer un redémarrage, réduisant à néant vingt minutes de compilation. La réaction naïve consiste à couper le service de mise à jour au début du build et à le rétablir à la fin et cette réaction naïve tient exactement jusqu&amp;rsquo;au jour où deux builds tournent en parallèle sur le même agent ou jusqu&amp;rsquo;au jour où un build crashe avant d&amp;rsquo;atteindre son étape de nettoyage, laissant l&amp;rsquo;agent avec ses mises à jour désactivées pour l&amp;rsquo;éternité. La bonne nouvelle, c&amp;rsquo;est que ce problème a une solution propre et qu&amp;rsquo;elle emprunte son vocabulaire à la gestion de ressources partagées bien plus qu&amp;rsquo;à l&amp;rsquo;administration Windows.&lt;/p></description></item><item><title>Frugalité Unix : do more with less</title><link>https://blog.6admin.io/posts/unix-frugality/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/unix-frugality/</guid><description>&lt;p>Il y a un test que je fais mentalement quand je lis du code ou qu&amp;rsquo;une personne se présente : est-ce que j&amp;rsquo;y trouve un &lt;code>cat file.txt | grep pattern&lt;/code> là où un &lt;code>grep pattern file.txt&lt;/code> suffisait ?&lt;/p>
&lt;p>Ce n&amp;rsquo;est pas une question d&amp;rsquo;optimisation. Le surcoût d&amp;rsquo;un process forké est dérisoire. C&amp;rsquo;est une question de culture : &lt;code>cat | grep&lt;/code> trahit quelqu&amp;rsquo;un qui a appris les commandes comme des incantations, pas comme des briques composables. Et le principe derrière la version courte, c&amp;rsquo;est le fondement même d&amp;rsquo;Unix : &lt;em>do more with less&lt;/em>, &lt;em>small is beautiful&lt;/em>. Chaque brique fait une chose, la fait bien, prend du texte en entrée et produit du texte en sortie.&lt;/p></description></item><item><title>Une sonde IDS ne voit pas le TLS</title><link>https://blog.6admin.io/posts/sonde-ids-tls/</link><pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/sonde-ids-tls/</guid><description>&lt;p>Les labs IDS ont une vraie valeur pédagogique.
On monte Suricata, on branche DVWA, on rejoue quelques attaques web et l&amp;rsquo;on voit les règles se déclencher en direct, ce qui aide beaucoup à comprendre comment fonctionne une sonde.
Le problème n&amp;rsquo;est pas le lab, il est dans la transposition en production, où un détail structurant change tout : le TLS.&lt;/p>
&lt;h2 id="pourquoi-le-lab-fonctionne">Pourquoi le lab fonctionne&lt;/h2>
&lt;p>Si le lab marche aussi bien, c&amp;rsquo;est précisément parce que DVWA tourne en HTTP.
Le trafic circule en clair, la sonde le lit octet par octet et les signatures peuvent inspecter les requêtes comme les réponses sans la moindre difficulté.
C&amp;rsquo;est d&amp;rsquo;ailleurs le même confort qu&amp;rsquo;on retrouve lorsqu&amp;rsquo;on sort &lt;a href="https://blog.6admin.io/posts/tcpdump/">tcpdump&lt;/a>
 sur un flux non chiffré ou qu&amp;rsquo;on bricole un &lt;a href="https://blog.6admin.io/posts/nemesis-sniffeur/">sniffeur maison&lt;/a>
 pour regarder passer les paquets : tant que la charge utile est lisible, tout va bien.&lt;/p></description></item><item><title>Un backup sans test de restore, c'est de la décoration</title><link>https://blog.6admin.io/posts/backup-without-restore-is-decoration/</link><pubDate>Thu, 09 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/backup-without-restore-is-decoration/</guid><description>&lt;p>Une phrase, écrite en passant dans un commentaire, résume tout ce que j&amp;rsquo;ai à dire sur le sujet :&lt;/p>
&lt;blockquote>
&lt;p>Ne pas oublier qu&amp;rsquo;une politique de backup sans test de restore régulier, c&amp;rsquo;est juste de la décoration : tu ne sais pas si ton backup marche tant que tu ne l&amp;rsquo;as pas restauré.&lt;/p>&lt;/blockquote>
&lt;p>Le reste de cet article n&amp;rsquo;est que le déploiement de cette phrase.&lt;/p>
&lt;h2 id="le-seul-test-qui-compte">Le seul test qui compte&lt;/h2>
&lt;p>Un backup qui n&amp;rsquo;a jamais été restauré n&amp;rsquo;est pas un backup, c&amp;rsquo;est une hypothèse. Le jour où vous en avez besoin est exactement le jour où vous ne pouvez pas vous permettre de découvrir que :&lt;/p></description></item><item><title>La chaîne de boot, de GRUB à UKI</title><link>https://blog.6admin.io/posts/boot-grub-uki/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/boot-grub-uki/</guid><description>&lt;p>La question du verrouillage du boot et de l&amp;rsquo;édition des paramètres du kernel n&amp;rsquo;est pas neuve, elle est même antérieure à GRUB2, à GRUB et jusqu&amp;rsquo;à LILO.
Ce qui change aujourd&amp;rsquo;hui, c&amp;rsquo;est que l&amp;rsquo;écosystème est en train de tourner la page d&amp;rsquo;une génération entière d&amp;rsquo;outils et l&amp;rsquo;annonce de Canonical pour Ubuntu 26.10 en est un bon marqueur.&lt;/p>
&lt;h2 id="ce-que-canonical-annonce-pour-2610">Ce que Canonical annonce pour 26.10&lt;/h2>
&lt;p>En substance, Canonical dégraisse le GRUB signé pour 26.10, ce qui réduit au passage la surface d&amp;rsquo;attaque, afin de préparer sa sortie.
GRUB devient obsolète face à UKI (Unified Kernel Image) combiné à systemd-boot.&lt;/p></description></item><item><title>Un segfault dans la JVM et un EDR au fond de la stack</title><link>https://blog.6admin.io/posts/jenkins-jvm-crash/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/jenkins-jvm-crash/</guid><description>&lt;p>Un controller Jenkins sous Windows qui se termine en boucle sur un &lt;code>EXCEPTION_ACCESS_VIOLATION&lt;/code>, c&amp;rsquo;est-à-dire un segfault côté Windows et qui redémarre toutes les minutes pendant une après-midi entière.
L&amp;rsquo;histoire est un bon cas d&amp;rsquo;école de deux choses: comment on ne traite pas une instabilité et comment on lit un crash dump sans sur-interpréter ce qu&amp;rsquo;on y voit.&lt;/p>
&lt;h2 id="le-piège-dans-lequel-on-était-déjà-tombé">Le piège dans lequel on était déjà tombé&lt;/h2>
&lt;p>Avant même mon diagnostic, la trace du problème était lisible dans l&amp;rsquo;historique.
Des crashs similaires avaient eu lieu plus d&amp;rsquo;un an plus tôt, sans aucune modification côté équipe Jenkins, ce qui pointait déjà vers un facteur externe.
La réponse apportée à l&amp;rsquo;époque avait été de migrer la JVM d&amp;rsquo;une version majeure à la suivante, sans analyse de cause racine ni post-mortem, dans l&amp;rsquo;espoir que ça règle le problème.
Le service s&amp;rsquo;est stabilisé un temps après configuration, puis les crashs ont repris.&lt;/p></description></item><item><title>Faire de l'ACME en interne sans supplier l'équipe AD CS</title><link>https://blog.6admin.io/posts/acme-pki/</link><pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/acme-pki/</guid><description>&lt;p>Il arrive un moment, dans toute infrastructure un peu sérieuse, où l&amp;rsquo;on aimerait émettre ses certificats internes comme Let&amp;rsquo;s Encrypt émet les siens, c&amp;rsquo;est-à-dire automatiquement, par ACME, sans ticket, sans formulaire, sans avoir à négocier chaque renouvellement avec la personne qui détient les clés de l&amp;rsquo;autorité de certification maison. Le problème n&amp;rsquo;est pas technique au premier abord, il est politique, parce que dans neuf entreprises sur dix la PKI vit à l&amp;rsquo;intérieur d&amp;rsquo;une AD CS que l&amp;rsquo;équipe Windows garde jalousement et qu&amp;rsquo;on ne va pas déployer une seconde racine de confiance sur tout le parc juste pour se simplifier la vie. Trois familles d&amp;rsquo;outils répondent à ce besoin et si l&amp;rsquo;on croit souvent devoir choisir entre deux d&amp;rsquo;entre elles, la troisième a discrètement changé la donne pour quiconque exploite déjà un coffre à secrets.&lt;/p></description></item><item><title>Trivy, le scanner qui volait les secrets</title><link>https://blog.6admin.io/posts/trivy-supply-chain/</link><pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/trivy-supply-chain/</guid><description>&lt;p>Il y a une forme d&amp;rsquo;ironie parfaite dans le fait que l&amp;rsquo;outil le plus déployé pour scanner les vulnérabilités de vos images se soit transformé, le temps d&amp;rsquo;une fenêtre de quelques heures, en infostealer running dans vos pipelines avec un accès complet à leurs secrets. Le 19 mars 2026, le groupe qui se fait appeler TeamPCP a compromis l&amp;rsquo;écosystème &lt;a href="https://trivy.dev/" target="_blank" rel="noopener noreferrer">Trivy&lt;/a>
 d&amp;rsquo;Aqua Security et l&amp;rsquo;histoire mérite d&amp;rsquo;être racontée non pour le frisson, mais parce qu&amp;rsquo;elle illustre à la perfection une erreur de conception que la moitié de la planète CI/CD commet encore aujourd&amp;rsquo;hui.&lt;/p></description></item><item><title>L'alignement d'un LLM est une couche mince</title><link>https://blog.6admin.io/posts/llm-alignment/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/llm-alignment/</guid><description>&lt;p>On nous a raconté une jolie histoire, celle d&amp;rsquo;un modèle qu&amp;rsquo;on aurait patiemment éduqué par RLHF puis DPO jusqu&amp;rsquo;à ce que le refus des requêtes dangereuses devienne une propriété profonde, presque une vertu, quelque chose d&amp;rsquo;aussi consubstantiel au réseau que sa capacité à conjuguer un verbe. C&amp;rsquo;est réconfortant et c&amp;rsquo;est faux. L&amp;rsquo;alignement, tel qu&amp;rsquo;on le pratique aujourd&amp;rsquo;hui, n&amp;rsquo;est pas une fondation, c&amp;rsquo;est une couche de peinture et deux travaux que tout oppose sur la méthode se rejoignent sur ce diagnostic avec une cruauté qui devrait nous rendre plus humbles.&lt;/p></description></item><item><title>Secure Boot et PXE: l'oeuf, la poule et quatre façons d'en sortir</title><link>https://blog.6admin.io/posts/secureboot-pxe/</link><pubDate>Tue, 24 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/secureboot-pxe/</guid><description>&lt;p>Provisionner un parc de machines Windows vierges par le réseau, en PXE, avec Secure Boot actif et sans jamais le désactiver, se heurte à un paradoxe qu&amp;rsquo;on ne voit qu&amp;rsquo;une fois le nez dessus.
Pour booter en PXE, le binaire d&amp;rsquo;amorçage doit être signé ou approuvé par le firmware.
Pour signer ou enroller une clé, il faut booter sur un OS.
Sans OS préexistant sur la machine, on ne peut donc ni booter ni enroller et c&amp;rsquo;est exactement la situation d&amp;rsquo;un poste neuf qu&amp;rsquo;on veut justement installer par le réseau.
Voici la chaîne de confiance telle qu&amp;rsquo;elle doit tenir, puis les quatre sorties réelles.&lt;/p></description></item><item><title>Quand un checksum Chocolatey casse tout un provisioning</title><link>https://blog.6admin.io/posts/p4v-checksum/</link><pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/p4v-checksum/</guid><description>&lt;p>Le provisioning d&amp;rsquo;un parc de machines Windows s&amp;rsquo;arrête net sur une tâche Ansible qui installe un package Chocolatey et le message est un classique du genre:&lt;/p>
&lt;pre tabindex="0">&lt;code>ERROR: Checksum for &amp;#39;p4vinst64.exe&amp;#39; did not meet &amp;#39;45648d...852bd5&amp;#39;
for checksum type &amp;#39;sha256&amp;#39;.
&lt;/code>&lt;/pre>&lt;p>Le checksum attendu par le package ne correspond pas au binaire téléchargé.
Rien dans mon infrastructure n&amp;rsquo;a changé et pourtant la veille ça passait.
L&amp;rsquo;histoire est courte, mais elle dit quelque chose d&amp;rsquo;important sur ce que signifie &amp;ldquo;dépendre d&amp;rsquo;un package communautaire&amp;rdquo;.&lt;/p></description></item><item><title>Faut-il du Kubernetes pour une petite équipe ?</title><link>https://blog.6admin.io/posts/kubernetes-petite-equipe/</link><pubDate>Sat, 07 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/kubernetes-petite-equipe/</guid><description>&lt;p>J&amp;rsquo;ai déjà écrit ailleurs quand il ne faut pas faire de Kubernetes et je n&amp;rsquo;y reviens pas ici (voir &lt;a href="https://blog.6admin.io/posts/kubernetes-ou-pas/">kubernetes-ou-pas&lt;/a>
).
L&amp;rsquo;angle de ce billet est différent : une petite structure, un seul DevOps, quelques devs sans expérience infra et la question qui revient à chaque fois de savoir s&amp;rsquo;il faut adopter K8s ou pas.&lt;/p>
&lt;p>La réponse n&amp;rsquo;est pas technique, elle est humaine. Je la pose sous forme de trois options, A, B et C, avec leurs limites respectives.&lt;/p></description></item><item><title>Docker contre les jails, la comparaison honnête</title><link>https://blog.6admin.io/posts/docker-vs-jails/</link><pubDate>Thu, 15 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-vs-jails/</guid><description>&lt;p>Tous les six mois, le même marronnier revient dans les fils de discussion : les jails FreeBSD écraseraient Docker sur le terrain de l&amp;rsquo;efficacité et on devrait tous se sentir coupables d&amp;rsquo;avoir choisi les conteneurs.
L&amp;rsquo;argumentaire n&amp;rsquo;est pas entièrement faux, il contient même quelques remarques justes, mais celles-ci se retrouvent noyées sous des comparaisons sélectives et des métriques trompeuses.&lt;/p>
&lt;p>Je vais reprendre les points un par un, parce que distinguer la critique légitime de la désinformation me semble plus utile que de défendre un camp.&lt;/p></description></item><item><title>myflec: un framework de dotfiles Bash pour gens qui déploient leur home</title><link>https://blog.6admin.io/posts/myflec/</link><pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/myflec/</guid><description>&lt;p>Mon &lt;code>$HOME&lt;/code> est versionné, déployé depuis des templates et poussé vers trois forges. Pas parce que j&amp;rsquo;aime le yak-shaving, mais parce que j&amp;rsquo;ai cassé trop de machines pour faire confiance à &amp;ldquo;ça devrait aller&amp;rdquo;. &lt;a href="https://github.com/log0u7/myflec" target="_blank" rel="noopener noreferrer">myflec&lt;/a>
 (&amp;ldquo;My Favorite Linux Environment Configuration&amp;rdquo;) est le framework Bash né de cette habitude: un loader, un modèle de backup, une procédure de deploy et un modèle d&amp;rsquo;identité. Tout est ennuyeux exprès, tout est shell natif.&lt;/p></description></item><item><title>Un reverse proxy devant Perforce ou pas : le pour et le contre</title><link>https://blog.6admin.io/posts/perforce-reverse-proxy-ou-pas/</link><pubDate>Thu, 18 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/perforce-reverse-proxy-ou-pas/</guid><description>&lt;p>Avant de montrer comment mettre nginx devant Perforce, que j&amp;rsquo;ai fait dans &lt;a href="https://blog.6admin.io/posts/nginx-perforce/">l&amp;rsquo;article dédié&lt;/a>
, il faut poser la vraie question, celle qu&amp;rsquo;on saute d&amp;rsquo;habitude: faut-il le faire. Parce que &lt;code>p4d&lt;/code> sait terminer son propre TLS et que l&amp;rsquo;ajout d&amp;rsquo;un intermédiaire n&amp;rsquo;est gratuit nulle part. Quatre approches et ce qu&amp;rsquo;elles coûtent.&lt;/p>
&lt;h2 id="le-piège-commun--lip-du-client">Le piège commun : l&amp;rsquo;IP du client&lt;/h2>
&lt;p>Un point traverse tout le reste, alors autant le poser d&amp;rsquo;abord. Dès qu&amp;rsquo;un intermédiaire termine ou relaie la connexion, &lt;code>p4d&lt;/code> risque de voir l&amp;rsquo;adresse de cet intermédiaire et non celle du client. Cela casse le logging par IP, les protections côté serveur qui s&amp;rsquo;appuient sur l&amp;rsquo;adresse et les triggers qui la lisent. Chacune des options ci-dessous se juge en partie là-dessus, donc gardez-le en tête.&lt;/p></description></item><item><title>Nginx devant Perforce : terminaison TLS en niveau 4 et le protocole P4</title><link>https://blog.6admin.io/posts/nginx-perforce/</link><pubDate>Thu, 11 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/nginx-perforce/</guid><description>&lt;p>Avant de mettre nginx devant Perforce, il faut se demander si c&amp;rsquo;est une bonne idée et j&amp;rsquo;ai traité cette question à part dans &lt;a href="https://blog.6admin.io/posts/perforce-reverse-proxy-ou-pas/">reverse proxy devant Perforce, le pour et le contre&lt;/a>
. Je pars ici du choix fait: on veut une terminaison TLS centralisée, gérée au même endroit et par le même outil ACME que le certificat de Jenkins. Reste à le faire correctement et correctement veut dire autrement qu&amp;rsquo;un tutoriel HTTP ne le suggère.&lt;/p></description></item><item><title>Containers, micro-VMs et Firecracker : pourquoi l'isolation n'est pas ce que vous croyez</title><link>https://blog.6admin.io/posts/firecracker-isolation/</link><pubDate>Sat, 06 Dec 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/firecracker-isolation/</guid><description>&lt;p>Un container Docker n&amp;rsquo;est pas une VM. C&amp;rsquo;est un process avec des namespaces. Le kernel est partagé: le même Linux, le même syscall table, le même code kernel, la même pile réseau. Une faille dans le kernel ouvre TOUS les containers sur la machine, pas un.&lt;/p>
&lt;p>C&amp;rsquo;est une distinction que les articles de ce blog documentent depuis 2006: &lt;a href="https://blog.6admin.io/posts/liens-durs-symboliques/">le chroot qui dépasse&lt;/a>
 par un symlink, &lt;a href="https://blog.6admin.io/posts/raw-sockets/">le raw socket&lt;/a>
 qui voit tout le réseau, &lt;a href="https://blog.6admin.io/posts/sockets-c/">le socket qui parle TCP&lt;/a>
 parce que le kernel fait le transport. Chacune de ces techniques fonctionne parce que l&amp;rsquo;isolation container est un partage, pas une frontière matérielle.&lt;/p></description></item><item><title>Terraform crée, Ansible configure</title><link>https://blog.6admin.io/posts/terraform-cree-ansible-configure/</link><pubDate>Fri, 21 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/terraform-cree-ansible-configure/</guid><description>&lt;p>La remarque de Florian était honnête et je la partage dans sa première moitié : Terraform seul fonctionne très bien tant qu&amp;rsquo;on reste sur un modèle 100% immuable, où l&amp;rsquo;on balance un cloud-init au provisionnement, où l&amp;rsquo;on recrée la VM dès qu&amp;rsquo;il faut la changer et où rien ne se modifie en place. Si votre infra se prête à ce modèle, parfait, ne cherchez pas plus loin. La question intéressante commence à l&amp;rsquo;instant précis où elle ne s&amp;rsquo;y prête plus.&lt;/p></description></item><item><title>fnox et age: des secrets chiffrés dans mes repos, sans serveur</title><link>https://blog.6admin.io/posts/fnox-age-secrets/</link><pubDate>Tue, 18 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fnox-age-secrets/</guid><description>&lt;p>Les secrets des projets perso ont toujours eu le même problème: pas de Vault à la maison, des &lt;code>.env&lt;/code> qui ne devraient jamais être commités mais qui le sont toujours et des variables d&amp;rsquo;environnement non secrètes déjà bien gérées par &lt;a href="https://direnv.net/" target="_blank" rel="noopener noreferrer">direnv&lt;/a>
. Fin 2025, j&amp;rsquo;ai découvert &lt;a href="https://github.com/jdx/fnox" target="_blank" rel="noopener noreferrer">fnox&lt;/a>
, le gestionnaire de secrets de l&amp;rsquo;auteur de &lt;a href="https://blog.6admin.io/posts/mise-versions-outils/">mise&lt;/a>
, qui colle exactement à ce vide: &lt;strong>les secrets vivent chiffrés dans le repo, eux-mêmes, sans serveur&lt;/strong>.&lt;/p></description></item><item><title>L'assembleur portable n'existe pas</title><link>https://blog.6admin.io/posts/assembleur-portable/</link><pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/assembleur-portable/</guid><description>&lt;p>On entend parfois dire qu&amp;rsquo;un même fichier assembleur se recompilerait et tournerait partout, pourvu qu&amp;rsquo;on reste sur une architecture x86-64 commune.
C&amp;rsquo;est une jolie idée et elle se heurte à la réalité dès que l&amp;rsquo;on regarde ce qui entoure vraiment l&amp;rsquo;instruction machine.
Le jeu d&amp;rsquo;instructions, lui, est effectivement partagé.
Tout le reste, l&amp;rsquo;outillage qui assemble, le format qui emballe, la convention qui fait dialoguer les fonctions et la porte par laquelle on entre dans le noyau, tout cela diverge d&amp;rsquo;un système à l&amp;rsquo;autre.&lt;/p></description></item><item><title>La sécurité par l'obscurité n'est pas de la sécurité, l'hygiène numérique si</title><link>https://blog.6admin.io/posts/obscurity-is-not-security/</link><pubDate>Thu, 13 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/obscurity-is-not-security/</guid><description>&lt;p>J&amp;rsquo;ai tenu la même position pendant des années et je l&amp;rsquo;ai défendue vertement dans un commentaire en avril 2020 :&lt;/p>
&lt;blockquote>
&lt;p>La sécurité par obscurité, ce n&amp;rsquo;est pas de la sécurité, au mieux cela fait gagner du temps, au pire cela vous en fait perdre. De plus cela biaise complètement le rapport de confiance ainsi que la fiabilité de ladite sécurité. A éviter&amp;hellip;&lt;/p>&lt;/blockquote>
&lt;p>Et pour illustrer l&amp;rsquo;absurdité, j&amp;rsquo;enchaînais sur la recette : ne partagez pas vos sources, ne partagez pas vos specs, obfuscez votre code, chiffrez-le en mémoire, retardez son exécution, rendez-le polymorphique, allez chercher votre payload en remote&amp;hellip; wait&amp;hellip; on parle d&amp;rsquo;un malware là ?&lt;/p></description></item><item><title>Le langage secret des IA, du folklore</title><link>https://blog.6admin.io/posts/langage-secret-des-ia/</link><pubDate>Mon, 10 Nov 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/langage-secret-des-ia/</guid><description>&lt;p>Revient régulièrement l&amp;rsquo;histoire d&amp;rsquo;un &amp;ldquo;langage secret&amp;rdquo; que les IA se seraient inventé pour se parler entre elles, plus vite et mieux que nous, dans notre dos.
La mouture qui a mis le feu aux réseaux début 2025 s&amp;rsquo;appelait Gibberlink et la légende qui s&amp;rsquo;est collée dessus promettait un protocole &amp;ldquo;80 pour cent plus efficace que le langage humain&amp;rdquo;.
Je voudrais poser le sujet calmement, parce que la démo, elle, est réelle, mais que l&amp;rsquo;histoire qu&amp;rsquo;on raconte par-dessus relève du folklore technologique.&lt;/p></description></item><item><title>Nginx sous Windows devant Jenkins : le proxy, les logs et les mises à jour</title><link>https://blog.6admin.io/posts/nginx-windows-proxy/</link><pubDate>Mon, 08 Sep 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/nginx-windows-proxy/</guid><description>&lt;p>Poser un nginx sur Windows Server pour terminer le TLS devant un Jenkins, c&amp;rsquo;est cinq minutes pour la version qui marche en démo et une vraie demi-journée pour la version qu&amp;rsquo;on assume en production.
La partie reverse proxy n&amp;rsquo;est pas la plus dure, elle tient dans un &lt;code>location&lt;/code> bien réglé. Ce qui fait la différence, c&amp;rsquo;est ce que Windows ne vous donne pas et qu&amp;rsquo;aucun tutoriel ne mentionne: la rotation des logs et une mise à jour qui prend vraiment.
Un mot avant de commencer: si la même machine sert aussi de façade à un Perforce, ne cherchez pas à le faire passer par la conf ci-dessous. Le protocole P4 n&amp;rsquo;est pas du HTTP, il relève d&amp;rsquo;une tout autre approche dont je parle à part dans &lt;a href="https://blog.6admin.io/posts/nginx-perforce/">nginx devant Perforce&lt;/a>
.&lt;/p></description></item><item><title>Clean Code vs Vibe Coding (ou comment ne pas finir dans les journaux)</title><link>https://blog.6admin.io/posts/clean-code-vs-vibe-coding/</link><pubDate>Sun, 15 Jun 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/clean-code-vs-vibe-coding/</guid><description>&lt;p>L&amp;rsquo;émergence des grands modèles de langage (LLM) dans le développement logiciel soulève une question fondamentale : nos pratiques établies de clean code restent-elles pertinentes face au &amp;ldquo;vibe coding&amp;rdquo; ? Et surtout, comment éviter de se retrouver à la une des journaux tech avec le prochain &amp;ldquo;oops, j&amp;rsquo;ai exposé 50 millions de mots de passe&amp;rdquo; ?&lt;/p>
&lt;h2 id="ces-vieilles-habitudes-qui-nous-sauvent-la-mise">Ces vieilles habitudes qui nous sauvent la mise&lt;/h2>
&lt;p>Le clean code repose sur des principes éprouvés qui, accessoirement, ont évité à pas mal de développeurs de finir au chômage technique :&lt;/p></description></item><item><title>vim-plugin-manager: une décennie de bash transformée en vrai plugin Vim</title><link>https://blog.6admin.io/posts/vim-plugin-manager/</link><pubDate>Sun, 13 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/vim-plugin-manager/</guid><description>&lt;p>Le script bash de &lt;a href="https://blog.6admin.io/posts/vim-submodules/">l&amp;rsquo;épisode 2018&lt;/a>
 a fait son travail pendant sept ans: plugins en git submodules, chargement natif &lt;code>pack/&lt;/code>, un script &lt;code>plugins&lt;/code> pour la chorégraphie. Ce qu&amp;rsquo;il ne pouvait jamais faire, c&amp;rsquo;est vivre dans l&amp;rsquo;éditeur: pas de progression pendant un clone, pas de lazy loading branché aux commandes, pas d&amp;rsquo;aide. En mars 2025, je lui ai enfin donné la fin qu&amp;rsquo;il méritait: réécrit de zéro en VimScript sous le nom de &lt;a href="https://github.com/log0u7/vim-plugin-manager" target="_blank" rel="noopener noreferrer">vim-plugin-manager&lt;/a>
, environ 5 600 lignes de VimScript legacy.&lt;/p></description></item><item><title>Quelle identité fait tourner le service et qui peut le prouver</title><link>https://blog.6admin.io/posts/hardening-win-services-accounting/</link><pubDate>Sat, 12 Apr 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-win-services-accounting/</guid><description>&lt;p>Un service Windows tourne sous une identité et cette identité est toute l&amp;rsquo;histoire sécurité: c&amp;rsquo;est le rayon d&amp;rsquo;impact quand le service est exploité et c&amp;rsquo;est le nom dans les logs quand il faut savoir qui a fait quoi.
L&amp;rsquo;essentiel de ce que j&amp;rsquo;audite vient d&amp;rsquo;un raccourci unique, un compte local avec un mot de passe statique figé dans la configuration du service, qui est à la fois un secret en clair et une identité que personne ne renouvelle.
La correction n&amp;rsquo;est pas un meilleur mot de passe, c&amp;rsquo;est de choisir une identité dont aucun humain ne détient jamais le mot de passe.&lt;/p></description></item><item><title>L'ExecutionPolicy PowerShell et ce qu'elle n'est pas</title><link>https://blog.6admin.io/posts/hardening-win-execution-policies/</link><pubDate>Sat, 08 Mar 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-win-execution-policies/</guid><description>&lt;p>La phrase la plus utile sur l&amp;rsquo;ExecutionPolicy est celle que Microsoft inscrit dans sa propre documentation: ce n&amp;rsquo;est pas une frontière de sécurité.
C&amp;rsquo;est une ceinture contre le double-clic sur un script qu&amp;rsquo;on ne voulait pas lancer, rien de plus et la prendre pour un contrôle qui tient l&amp;rsquo;attaquant à distance est une erreur de catégorie qui masque les vrais leviers.
La façon honnête de la traiter est donc de dire ce qu&amp;rsquo;elle fait, de prouver à quel point c&amp;rsquo;est peu, puis de pointer ce qui contraint réellement PowerShell.&lt;/p></description></item><item><title>Piloter Windows depuis Ansible sans fuiter d'identifiants</title><link>https://blog.6admin.io/posts/hardening-win-ansible-transport/</link><pubDate>Wed, 12 Feb 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-win-ansible-transport/</guid><description>&lt;p>La question dont on débat est SSH contre WinRM et c&amp;rsquo;est la mauvaise, parce que les deux sont désormais légitimes: Win32-OpenSSH est un transport Ansible de premier ordre et WinRM est le transport natif.
La question qui décide vraiment de votre exposition est plus étroite et plus tranchante: quand une tâche s&amp;rsquo;authentifie sur un hôte joint au domaine, un identifiant réutilisable traverse-t-il le fil et la cible peut-elle ensuite agir en votre nom contre le reste du domaine.
Réglez bien le protocole d&amp;rsquo;authentification et le modèle de délégation et l&amp;rsquo;un ou l&amp;rsquo;autre transport convient.
Réglez-les mal et WinRM livrera votre domaine à un attaquant exactement comme le ferait un SSH mal monté.&lt;/p></description></item><item><title>Durcir WinRM</title><link>https://blog.6admin.io/posts/hardening-winrm/</link><pubDate>Wed, 08 Jan 2025 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-winrm/</guid><description>&lt;p>WinRM est le moteur sous le PowerShell remoting et sous l&amp;rsquo;essentiel de la gestion Windows à distance, ce qui le rend à la fois indispensable et commode comme chemin d&amp;rsquo;un shell vers tout un parc.
Le mettre debout tient en une commande.
Le mettre debout sûrement signifie défaire deux des défauts que cette commande laisse derrière elle, choisir un transport qui veut dire quelque chose et contraindre ce qu&amp;rsquo;une session distante peut réellement faire.
L&amp;rsquo;ordre compte, parce que le montage commode est le montage non sûr.&lt;/p></description></item><item><title>Durcir Proxmox VE</title><link>https://blog.6admin.io/posts/hardening-proxmox/</link><pubDate>Wed, 18 Dec 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-proxmox/</guid><description>&lt;p>Un nœud Proxmox est un hyperviseur, ce qui veut dire que le compromettre n&amp;rsquo;est pas compromettre un serveur, c&amp;rsquo;est compromettre d&amp;rsquo;un coup chaque VM et chaque container qu&amp;rsquo;il porte.
Cela relève l&amp;rsquo;enjeu des choses ordinaires, l&amp;rsquo;interface web, l&amp;rsquo;ouverture de session, le SSH, le pare-feu, parce que chacune est désormais une porte vers tout le parc plutôt que vers une machine.
Le durcissement se partage nettement: protéger le plan de gestion qui contrôle tout et comprendre lequel des deux types de charge isole vraiment et lequel est une évasion vers le root de l&amp;rsquo;hôte qui attend un prétexte.&lt;/p></description></item><item><title>Kubernetes bare metal en HA, sans se mentir</title><link>https://blog.6admin.io/posts/kubernetes-bare-metal-ha/</link><pubDate>Tue, 10 Dec 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/kubernetes-bare-metal-ha/</guid><description>&lt;p>Sur un cloud, la haute disponibilité de Kubernetes s&amp;rsquo;achète: le control plane est managé, le load balancer est un objet de l&amp;rsquo;API, le stockage est une classe qu&amp;rsquo;on référence. Sur du bare metal, chacune de ces trois commodités redevient une chose qu&amp;rsquo;il faut monter soi-même et c&amp;rsquo;est là que la plupart des tutoriels empilent sept composants pour en faire tenir trois.
Ce billet monte un cluster HA avec le minimum défendable: un control plane qui survit à la perte d&amp;rsquo;un nœud, une VIP d&amp;rsquo;API sans load balancer externe, un réseau qui porte aussi le LoadBalancer et un stockage répliqué sur les disques des nœuds. Trois pièces qui portent les trois points de défaillance et pas une de plus parce qu&amp;rsquo;un cluster qu&amp;rsquo;on ne comprend pas n&amp;rsquo;est pas disponible, il est en sursis.&lt;/p></description></item><item><title>Kubernetes ou pas</title><link>https://blog.6admin.io/posts/kubernetes-ou-pas/</link><pubDate>Tue, 19 Nov 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/kubernetes-ou-pas/</guid><description>&lt;p>Kubernetes résout un vrai problème, celui d&amp;rsquo;ordonnancer beaucoup de charges sur beaucoup de machines en se réparant tout seul et il le résout bien. Le piège n&amp;rsquo;est pas l&amp;rsquo;outil, c&amp;rsquo;est de le sortir pour un problème qu&amp;rsquo;on n&amp;rsquo;a pas encore, en payant d&amp;rsquo;avance une taxe opérationnelle permanente pour une résilience qu&amp;rsquo;on n&amp;rsquo;utilise pas.
Parce que la vraie dépense de Kubernetes n&amp;rsquo;est pas conceptuelle, elle est opérationnelle: le control plane à tenir, le CNI à comprendre, le stockage à monter, les mises à jour trimestrielles d&amp;rsquo;API à suivre et une surface d&amp;rsquo;attaque qui a ses propres billets de durcissement. Avant de signer pour ça, il vaut la peine de descendre les étages et de s&amp;rsquo;arrêter au premier qui porte la charge, parce que le bon niveau d&amp;rsquo;abstraction est le plus bas qui règle votre problème, pas le plus prestigieux.&lt;/p></description></item><item><title>Durcir Kubernetes</title><link>https://blog.6admin.io/posts/hardening-kubernetes/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-kubernetes/</guid><description>&lt;p>Kubernetes multiplie le problème du container unique par un plan de contrôle, un réseau plat et un système d&amp;rsquo;autorisation et chacun d&amp;rsquo;eux a un défaut commode plutôt que sûr.
Les clés du cluster entier sont au nombre de trois: un pod qui peut atteindre l&amp;rsquo;hôte, un octroi RBAC trop large et un réseau qui laisse chaque pod parler à tous les autres.
Durcissez ces trois-là et les attaques exotiques perdent leur première marche.
Laissez-en une ouverte et le reste du durcissement est de la décoration, parce qu&amp;rsquo;un pod privilégié, un binding &lt;code>cluster-admin&lt;/code> ou un etcd joignable sont déjà la fin de la partie.&lt;/p></description></item><item><title>Durcir Docker Swarm</title><link>https://blog.6admin.io/posts/hardening-docker-swarm/</link><pubDate>Tue, 08 Oct 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-docker-swarm/</guid><description>&lt;p>Tout ce qui relève du durcissement Docker mono-hôte s&amp;rsquo;applique encore à chaque container d&amp;rsquo;un Swarm, donc cette note ne porte que sur ce que le cluster ajoute: un plan de contrôle, une frontière de confiance entre manager et worker, un réseau qui enjambe les hôtes et un magasin de secrets.
La bonne nouvelle et elle mérite d&amp;rsquo;être dite parce qu&amp;rsquo;on dédaigne Swarm, c&amp;rsquo;est que ses défauts de sécurité sont meilleurs qu&amp;rsquo;on ne le suppose.
Les nœuds s&amp;rsquo;authentifient entre eux par TLS mutuel avec des certificats qui tournent, d&amp;rsquo;emblée et le magasin Raft qui tient l&amp;rsquo;état du cluster est chiffré au repos.
Les lacunes sont plus étroites et précises: un réglage réseau coupé par défaut, une habitude d&amp;rsquo;exploitation qui effondre la frontière de confiance et la tentation habituelle de mettre les secrets au mauvais endroit.&lt;/p></description></item><item><title>Durcir Docker</title><link>https://blog.6admin.io/posts/hardening-docker/</link><pubDate>Wed, 18 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-docker/</guid><description>&lt;p>La phrase qui devrait gouverner chaque décision Docker est celle-ci: un container partage le kernel de l&amp;rsquo;hôte, donc une évasion de container est une évasion kernel.
Un container n&amp;rsquo;est pas une petite VM, c&amp;rsquo;est un processus enveloppé de namespaces et de cgroups avec un filtre seccomp devant ses syscalls et tout ce qui est dessous est le même kernel que fait tourner l&amp;rsquo;hôte.
Durcir Docker consiste donc surtout à ne pas remettre à un container les quelques choses qui lui permettent de contourner les namespaces et de parler directement à ce kernel partagé, et, en dessous, à ne pas faire tourner tout l&amp;rsquo;appareil en root pour commencer.&lt;/p></description></item><item><title>mise: un seul binaire pour toutes les versions d'outils</title><link>https://blog.6admin.io/posts/mise-versions-outils/</link><pubDate>Thu, 05 Sep 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/mise-versions-outils/</guid><description>&lt;p>Chaque projet traîne sa collection de versions: le repo A veut Node 20, le repo B tient encore sur Node 18, le C tourne sur Python 3.11 quand le D exige déjà 3.12 et terraform, &lt;a href="https://gohugo.io/" target="_blank" rel="noopener noreferrer">hugo&lt;/a>
 et go suivent la même loi. Installer ces versions à l&amp;rsquo;échelle de la machine revient à en concasser une par-dessus l&amp;rsquo;autre: la dernière gagne et tous les autres repos cassent en silence. J&amp;rsquo;ai pris ce problème par le bon bout en 2024 avec &lt;a href="https://github.com/jdx/mise" target="_blank" rel="noopener noreferrer">mise&lt;/a>
: &lt;strong>un gestionnaire de versions d&amp;rsquo;outils par projet, tenu par un seul binaire Rust&lt;/strong>.&lt;/p></description></item><item><title>Durcir DHCP</title><link>https://blog.6admin.io/posts/hardening-dhcp/</link><pubDate>Wed, 28 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-dhcp/</guid><description>&lt;p>DHCP remet à une machine qui démarre son adresse, sa passerelle et son DNS, c&amp;rsquo;est-à-dire qu&amp;rsquo;il dit à chaque client où envoyer son trafic et à qui faire confiance pour résoudre les noms.
Le protocole n&amp;rsquo;a aucune authentification: un client prend la première offre qu&amp;rsquo;il entend.
Ce seul fait est tout le modèle de menace.
Un serveur DHCP pirate, un portable avec &lt;code>dnsmasq&lt;/code>, répond plus vite que le vôtre et possède désormais la passerelle et le résolveur de tous ceux qui l&amp;rsquo;ont cru et de là lit, redirige et réécrit le trafic à volonté.
La défense n&amp;rsquo;est pas dans le serveur DHCP, elle est dans le switch, seule chose placée pour décider quelles offres sont autorisées sur le fil.&lt;/p></description></item><item><title>Durcir l'infrastructure DNS</title><link>https://blog.6admin.io/posts/hardening-dns/</link><pubDate>Wed, 03 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-dns/</guid><description>&lt;p>Le DNS est cru par tout le monde et vérifié par presque rien et c&amp;rsquo;est pourquoi un résolveur exploité à la légère devient une arme pointée sur autrui et un serveur autoritatif exploité à la légère devient une carte de votre parc et un canal de sortie.
Les menaces sont connues, empoisonnement de cache, amplification, tunneling, divulgation de zone et les défenses ne sont pas exotiques.
Elles se ramènent à quatre décisions: qui peut demander à votre résolveur de récurser, qui peut tirer vos zones, si vos réponses peuvent être forgées et si vous pouvez voir des données partir dans vos propres requêtes.&lt;/p></description></item><item><title>Durcir SSH : contrôle d'accès et surveillance</title><link>https://blog.6admin.io/posts/hardening-ssh/</link><pubDate>Wed, 03 Jul 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-ssh/</guid><description>&lt;p>SSH est la porte d&amp;rsquo;entrée de presque tous les parcs et c&amp;rsquo;est justement pourquoi c&amp;rsquo;est la première chose à bien régler.
Une configuration lâche n&amp;rsquo;expose pas un seul hôte, elle offre à l&amp;rsquo;attaquant les trois choses qu&amp;rsquo;il convoite le plus: un moyen d&amp;rsquo;entrer, un moyen de se déplacer, un moyen de rester.
Le but de cette note n&amp;rsquo;est pas de réciter une liste de conformité, c&amp;rsquo;est de décrire la configuration que je déploie vraiment, les raisons de chaque choix et la surveillance qui transforme &amp;ldquo;quelqu&amp;rsquo;un s&amp;rsquo;est connecté&amp;rdquo; en &amp;ldquo;cette personne, depuis là, à cette heure&amp;rdquo;.&lt;/p></description></item><item><title>Docker Swarm to Kubernetes : pourquoi j'ai abandonné Swarm</title><link>https://blog.6admin.io/posts/swarm-to-k8s/</link><pubDate>Sat, 22 Jun 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/swarm-to-k8s/</guid><description>&lt;p>Docker Swarm fonctionne bien comme orchestrateur léger pour des déploiements petits à moyens. Il est simple, mature et la barrière d&amp;rsquo;entrée est faible. Mais il frappe des murs structurels sur la sécurité et la gestion avancée des containers. Voici les quatre.&lt;/p>
&lt;h2 id="pas-de-mode-rootless">Pas de mode rootless&lt;/h2>
&lt;p>Le mode rootless de Docker (&lt;code>dockerd-rootless-setuptool.sh&lt;/code> avec slirp4netns/RootlessKit) est &lt;strong>incompatible avec Docker Swarm&lt;/strong>. La documentation officielle liste explicitement:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Overlay networks&lt;/strong>: Swarm repose entièrement sur l&amp;rsquo;overlay (VXLAN) pour la communication inter-nœuds. Sans overlay, les services sur des nœuds différents ne se voient plus. Swarm devient un outil mono-nœud.&lt;/li>
&lt;li>&lt;strong>AppArmor&lt;/strong>: pas de MAC (Mandatory Access Control) sur les containers.&lt;/li>
&lt;li>&lt;strong>Checkpoint/Restore&lt;/strong>: pas de snapshot CRIU, pas de migration à chaud, pas de récupération d&amp;rsquo;état.&lt;/li>
&lt;/ul>
&lt;p>C&amp;rsquo;est une contrainte architecturale fondamentale: Swarm requiert des primitives réseau kernel-level (netns, veth, VXLAN) que le mode rootless ne peut pas fournir. slirp4netns et RootlessKit opèrent dans des namespaces utilisateurs incompatibles avec le réseau overlay kernel.&lt;/p></description></item><item><title>Séparer le domaine interne du domaine externe</title><link>https://blog.6admin.io/posts/hardening-domain/</link><pubDate>Thu, 30 May 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-domain/</guid><description>&lt;p>Utiliser le même nom de domaine pour le site public et pour tout le parc interne paraît commode et cela offre discrètement plusieurs avantages à l&amp;rsquo;attaquant d&amp;rsquo;un seul coup.
L&amp;rsquo;argument pour les séparer n&amp;rsquo;est pas esthétique, il tient au fait qu&amp;rsquo;une poignée d&amp;rsquo;attaques concrètes cessent de fonctionner dès que les services internes vivent sous un nom qui n&amp;rsquo;apparaît jamais dans un certificat public ni dans une réponse DNS publique.&lt;/p>
&lt;h2 id="pourquoi-un-domaine-partagé-fuit">Pourquoi un domaine partagé fuit&lt;/h2>
&lt;p>Le certificat wildcard est le premier problème.
Un &lt;code>*.company.com&lt;/code> émis pour le web public reste, par construction, valable pour chaque hôte interne sous ce nom, de sorte que le jour où un seul serveur public est compromis, son certificat usurpe n&amp;rsquo;importe quel service interne sans qu&amp;rsquo;un navigateur ne bronche.
Une clé volée et l&amp;rsquo;homme du milieu est de confiance partout.&lt;/p></description></item><item><title>Hyper-V S2D vs Proxmox Ceph : le comparatif qui a tranché</title><link>https://blog.6admin.io/posts/hyperv-vs-proxmox/</link><pubDate>Fri, 17 May 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hyperv-vs-proxmox/</guid><description>&lt;p>Le débat Hyper-V contre Proxmox se tranche rarement sur un chiffre unique, parce que les deux plateformes ne paient pas le même prix pour les mêmes garanties.
Hyper-V avec Storage Spaces Direct reste taillé pour un monde Windows, là où Proxmox VE avec Ceph vise la flexibilité d&amp;rsquo;un parc mixte et une facture de licences nulle.
Le vrai arbitrage se joue sur deux axes, la performance que l&amp;rsquo;on peut attendre du stockage et le coût de possession étalé sur plusieurs années.&lt;/p></description></item><item><title>Le filtrage egress, le contrôle que tout le monde saute</title><link>https://blog.6admin.io/posts/hardening-egress/</link><pubDate>Fri, 12 Apr 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-egress/</guid><description>&lt;p>Presque chaque pare-feu que j&amp;rsquo;audite est méticuleux sur ce qui peut entrer et indifférent à ce qui peut sortir.
Cette asymétrie est exactement ce sur quoi compte un attaquant, parce que les coups qui comptent se jouent tous en sortie: le reverse shell appelle la maison, les données volées partent, l&amp;rsquo;implant balise vers son C2.
Un pare-feu qui ne filtre que l&amp;rsquo;entrée est une porte à verrou solide sans mur derrière.
Le but du filtrage egress, c&amp;rsquo;est qu&amp;rsquo;un hôte qui n&amp;rsquo;a rien à faire sur internet ne puisse pas y parler et qu&amp;rsquo;un hôte qui en a besoin n&amp;rsquo;atteigne que les quelques endroits dont il a vraiment besoin.&lt;/p></description></item><item><title>Le trafic entrant : exposer moins et garder ce qui reste</title><link>https://blog.6admin.io/posts/hardening-ingress/</link><pubDate>Wed, 28 Feb 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-ingress/</guid><description>&lt;p>Chaque port sur lequel une machine écoute est une promesse de répondre à un inconnu et la plupart des incidents commencent par une promesse que personne ne voulait faire: une base liée à &lt;code>0.0.0.0&lt;/code>, un panneau d&amp;rsquo;administration sur une IP publique, un service oublié qu&amp;rsquo;un scanner a trouvé avant vous.
Internet est scanné de bout en bout en continu, donc un service exposé n&amp;rsquo;est pas un risque qui pourrait être remarqué, c&amp;rsquo;est un risque qui le sera, en général en quelques heures.
Le durcissement de l&amp;rsquo;entrée est donc deux disciplines: exposer le moins possible et placer le peu qui doit l&amp;rsquo;être derrière des contrôles qui supposent qu&amp;rsquo;il sera attaqué.&lt;/p></description></item><item><title>La segmentation réseau</title><link>https://blog.6admin.io/posts/hardening-networking/</link><pubDate>Mon, 22 Jan 2024 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-networking/</guid><description>&lt;p>Un réseau plat est une pièce unique où chacun peut atteindre chacun et c&amp;rsquo;est la condition qui transforme un seul portable compromis en un parc compromis.
L&amp;rsquo;intrusion n&amp;rsquo;atterrit presque jamais là où se trouve la chose précieuse; elle atterrit sur une machine d&amp;rsquo;utilisateur puis se déplace, vers le serveur de fichiers, la base, le contrôleur de domaine, parce que rien sur un réseau plat ne dit non.
La segmentation est la pratique d&amp;rsquo;ajouter des murs pour qu&amp;rsquo;un pied dans la porte achète à l&amp;rsquo;attaquant une pièce plutôt que le bâtiment et sa version honnête est plus que tracer des VLAN: c&amp;rsquo;est les rendre réels par du filtrage entre eux et durcir les astuces de couche 2 qui les traversent autrement tout droit.&lt;/p></description></item><item><title>Limites de ressources : empêcher une machine d'être convaincue de mourir</title><link>https://blog.6admin.io/posts/hardening-limits/</link><pubDate>Tue, 05 Dec 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-limits/</guid><description>&lt;p>Le fork bomb résume tout l&amp;rsquo;argument en une ligne:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>:&lt;span style="color:#f92672">(){&lt;/span> :|:&amp;amp; &lt;span style="color:#f92672">}&lt;/span>;:
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Une fonction qui s&amp;rsquo;appelle elle-même deux fois et met les deux copies en arrière-plan, lancée une fois et le nombre de processus double toutes les fractions de seconde jusqu&amp;rsquo;à ce que la table des processus soit pleine, qu&amp;rsquo;aucun nouveau processus ne puisse démarrer et que la machine soit une brique réclamant un reboot brutal.
Ce n&amp;rsquo;est pas un exploit, ça n&amp;rsquo;exige aucun privilège et n&amp;rsquo;importe quel utilisateur local peut le taper par accident.
La même forme anime le reste de la famille: une boucle qui alloue de la mémoire jusqu&amp;rsquo;à ce que l&amp;rsquo;OOM killer parte, une qui ouvre des descripteurs de fichiers jusqu&amp;rsquo;à ce que &lt;code>fork&lt;/code> échoue sur &amp;ldquo;too many open files&amp;rdquo;, une qui remplit &lt;code>/tmp&lt;/code> ou &lt;code>/var/log&lt;/code> jusqu&amp;rsquo;à ce que le système de fichiers racine se coince.
Aucune n&amp;rsquo;est maligne.
Toutes sont arrêtées par la même chose, un plafond que l&amp;rsquo;utilisateur ne peut dépasser et le seul vrai travail est de poser ce plafond au bon endroit.&lt;/p></description></item><item><title>Durcir le système de fichiers</title><link>https://blog.6admin.io/posts/hardening-filesystem/</link><pubDate>Wed, 08 Nov 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-filesystem/</guid><description>&lt;p>L&amp;rsquo;essentiel du durcissement du système de fichiers consiste à décider, par montage, lequel de trois pouvoirs un répertoire a le droit d&amp;rsquo;accorder: exécuter un binaire, honorer son bit setuid et le laisser être un nœud de périphérique.
Le défaut, &lt;code>defaults&lt;/code>, accorde les trois partout, ce qui est commode et faux pour les répertoires où les utilisateurs et les démons peuvent écrire.
Le reste, c&amp;rsquo;est séparer les partitions pour qu&amp;rsquo;une ne puisse affamer les autres, activer les protections de liens du noyau et garder un œil sur quels fichiers portent le setuid.
Rien d&amp;rsquo;exotique et le gain est que des catégories entières d&amp;rsquo;escalade locale n&amp;rsquo;ont plus où atterrir.&lt;/p></description></item><item><title>Recompiler son kernel: des noyaux aux petits oignons pour son infra</title><link>https://blog.6admin.io/posts/recompiler-son-kernel/</link><pubDate>Fri, 27 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/recompiler-son-kernel/</guid><description>&lt;p>Le durcissement de l&amp;rsquo;OS est surtout de la soustraction, retirer ce qui écoute et couper les surfaces kernel dont on n&amp;rsquo;a pas besoin, ce que j&amp;rsquo;ai détaillé dans &lt;a href="https://blog.6admin.io/posts/hardening-linux-os/">durcir l&amp;rsquo;OS et le kernel Linux&lt;/a>
.
Il reste une marche que cet article-là n&amp;rsquo;a pas montée et c&amp;rsquo;est ma préférée: ne pas désactiver une fonction kernel au runtime, mais ne jamais la compiler du tout.
Recompiler son propre noyau, c&amp;rsquo;est la soustraction poussée à sa conclusion logique.&lt;/p></description></item><item><title>Durcir l'OS et le kernel Linux</title><link>https://blog.6admin.io/posts/hardening-linux-os/</link><pubDate>Fri, 20 Oct 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-linux-os/</guid><description>&lt;p>Une machine Linux fraîchement installée est bâtie pour être commode, ce qui veut dire qu&amp;rsquo;elle arrive avec des services que vous n&amp;rsquo;avez pas demandés, des fonctions kernel que vous n&amp;rsquo;utiliserez jamais et des défauts choisis pour ne surprendre aucun débutant.
La durcir est surtout de la soustraction: retirer ce qui écoute, couper les surfaces kernel dont vous n&amp;rsquo;avez pas besoin, resserrer la poignée de boutons sysctl qui comptent et verrouiller les comptes et le chargeur de modules.
Les étapes individuelles sont petites et bien connues.
La discipline est de les faire délibérément plutôt que d&amp;rsquo;hériter de ce que l&amp;rsquo;installeur a décidé et de garder la machine patchée, parce que les exploits kernel qui comptent (PwnKit, Dirty Pipe et leurs successeurs) sont corrigés bien avant que la plupart des machines n&amp;rsquo;appliquent le correctif.&lt;/p></description></item><item><title>Sudo et LOLBins</title><link>https://blog.6admin.io/posts/hardening-sudo-lolbins/</link><pubDate>Sat, 15 Jul 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/hardening-sudo-lolbins/</guid><description>&lt;p>La croyance confortable sur sudo, c&amp;rsquo;est qu&amp;rsquo;une règle étroite est une règle sûre, que &lt;code>NOPASSWD: /usr/bin/find&lt;/code> accorde le droit de lancer find et rien d&amp;rsquo;autre.
GTFOBins a démoli cette croyance et la version honnête d&amp;rsquo;une note de durcissement sudo doit partir de là: la granularité de sudoers ne limite rien dès l&amp;rsquo;instant où le binaire autorisé peut être convaincu d&amp;rsquo;ouvrir un shell et une fraction surprenante de la boîte à outils standard le peut.
La question n&amp;rsquo;est jamais &amp;ldquo;quelle commande ai-je accordée&amp;rdquo;, c&amp;rsquo;est &amp;ldquo;qu&amp;rsquo;est-ce qu&amp;rsquo;on peut faire faire à cette commande une fois qu&amp;rsquo;elle tourne en root&amp;rdquo;.&lt;/p></description></item><item><title>Scale-to-zero : Sablier rallume Swarm et Kubernetes à la demande</title><link>https://blog.6admin.io/posts/scale-to-zero/</link><pubDate>Sun, 15 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/scale-to-zero/</guid><description>&lt;p>Un service qu&amp;rsquo;on consulte une fois par semaine tourne cent pour cent du temps. On l&amp;rsquo;a installé pour un besoin ponctuel, une QA qu&amp;rsquo;on ouvre le lundi, un wiki d&amp;rsquo;équipe, un outil d&amp;rsquo;admin qu&amp;rsquo;on ne sort qu&amp;rsquo;en cas d&amp;rsquo;incident. Il occupe en permanence sa part de RAM, sa part de CPU, ses ports, sa place dans le monitoring et son lot de mises à jour de sécurité. L&amp;rsquo;éteindre résout tout d&amp;rsquo;un coup, sauf qu&amp;rsquo;il faut alors le rallumer à la main au moment où on en a besoin et personne ne se souvient de la commande.
Le scale-to-zero, c&amp;rsquo;est l&amp;rsquo;idée de n&amp;rsquo;allumer un service que quand quelqu&amp;rsquo;un le demande et de l&amp;rsquo;éteindre quand plus personne ne s&amp;rsquo;en sert, sans que l&amp;rsquo;utilisateur ait à savoir qu&amp;rsquo;il dormait. &lt;a href="https://github.com/sablierapp/sablier" target="_blank" rel="noopener noreferrer">Sablier&lt;/a>
 est un petit serveur d&amp;rsquo;API qu&amp;rsquo;on pose à côté du reverse proxy: le proxy intercepte chaque requête, appelle l&amp;rsquo;API pour savoir si la cible dort, la réveille le cas échéant et affiche une page d&amp;rsquo;attente le temps qu&amp;rsquo;elle démarre. Une fois la cible prête, la requête passe et une session s&amp;rsquo;ouvre, refermée après &lt;code>sessionDuration&lt;/code>, au terme de quoi Sablier éteint la charge.&lt;/p></description></item><item><title>The Bastion et Guacamole : les deux battants de la porte d'entrée</title><link>https://blog.6admin.io/posts/bastion-guacamole/</link><pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/bastion-guacamole/</guid><description>&lt;p>Il y a deux populations dans toute infrastructure et elles posent la même question à des outils différents. Les gens du shell demandent: &amp;ldquo;je fais quoi pour me connecter au serveur et qui peut le prouver après coup?&amp;rdquo; Les gens du bureau demandent: &amp;ldquo;comment atteindre ce poste Windows sans VPN et sans client installé?&amp;rdquo; Il existe un outil remarquable de chaque côté et tous les deux méritent mieux qu&amp;rsquo;une mention en bas de page: &lt;a href="https://github.com/ovh/the-bastion" target="_blank" rel="noopener noreferrer">The Bastion&lt;/a>
 d&amp;rsquo;OVHcloud pour la première population, &lt;a href="https://guacamole.apache.org/" target="_blank" rel="noopener noreferrer">Apache Guacamole&lt;/a>
 pour la seconde. Ensemble, ils forment les deux battants d&amp;rsquo;une même porte d&amp;rsquo;entrée: l&amp;rsquo;un tient le compte des mains sur clavier, l&amp;rsquo;autre des mains sur souris.&lt;/p></description></item><item><title>Le :ro sur le socket Docker ne protège rien</title><link>https://blog.6admin.io/posts/docker-socket-ro/</link><pubDate>Sun, 12 Jun 2022 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-socket-ro/</guid><description>&lt;p>Il existe, dans toute revue de code où quelqu&amp;rsquo;un a eu le malheur de monter /var/run/docker.sock dans un conteneur, un petit rituel qui consiste à faire remarquer d&amp;rsquo;un air entendu qu&amp;rsquo;on pourrait au moins le passer en lecture seule, sur quoi tout le monde hoche la tête, ajoute &lt;code>:ro&lt;/code> dans le compose et referme la merge request avec le sentiment du devoir accompli. C&amp;rsquo;est du théâtre et j&amp;rsquo;aimerais expliquer précisément pourquoi, parce que l&amp;rsquo;erreur est instructive bien au-delà de Docker.&lt;/p></description></item><item><title>FluoLight : réécrire un firmware Arduino hérité en quelque chose de défendable</title><link>https://blog.6admin.io/posts/fluoboard-rewrite/</link><pubDate>Sun, 24 Apr 2022 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fluoboard-rewrite/</guid><description>&lt;p>Deuxième épisode de la série FluoBoard, après &lt;a href="https://blog.6admin.io/posts/fluoboard-what-not-to-do/">l&amp;rsquo;autopsie de la carte d&amp;rsquo;origine&lt;/a>
. J&amp;rsquo;y promettais une suite, la voici et elle ne s&amp;rsquo;est pas faite en une nuit. Dès 2021, j&amp;rsquo;ai attaqué par le manque le plus criant: découper le monolithe en plusieurs fichiers &lt;code>.ino&lt;/code> par responsabilité, parce qu&amp;rsquo;un sketch unique ne se maintient pas, en corrigeant les bugs au passage et en posant les &lt;code>#define&lt;/code> qui manquaient. Est venue ensuite une boucle d&amp;rsquo;événements écrite à la main, ma première manière de cadencer des actions dans le temps, avant que je ne reprenne la bibliothèque TimedAction pour le faire proprement. Le gros du travail s&amp;rsquo;est fait en 2021-2022, les retouches finales venant plus tard [edit: 2025], le tout suivable commit par commit. Même famille de boards, même protocole &lt;code>/lights/&amp;lt;mac&amp;gt;&lt;/code> dont la réponse tient dans un chiffre entre &lt;code>&amp;lt;...&amp;gt;&lt;/code>. Ce qui change n&amp;rsquo;est pas la liste des fonctionnalités, c&amp;rsquo;est que la boucle ne s&amp;rsquo;arrête jamais pour attendre.&lt;/p></description></item><item><title>Une image Ansible pour GitLab CI, construite propre depuis un sous-sol parisien</title><link>https://blog.6admin.io/posts/docker-ansible/</link><pubDate>Tue, 22 Mar 2022 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-ansible/</guid><description>&lt;p>Chaque runner CI qui fait tourner Ansible a le même problème: le job a besoin d&amp;rsquo;ansible-core, des collections pour vos plateformes, git, ssh et il lui faut tout ça &lt;em>maintenant&lt;/em>, sur une machine qui sera jetée après le job. Les images officielles existent, mais elles dérivent: &lt;code>latest&lt;/code> change sous vous, la version que vous avez pinée se fait rebaser et installer huit collections Galaxy par job brûle des minutes à chaque pipeline.&lt;/p></description></item><item><title>Autopsie d'un firmware Arduino hérité</title><link>https://blog.6admin.io/posts/fluoboard-what-not-to-do/</link><pubDate>Mon, 22 Nov 2021 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fluoboard-what-not-to-do/</guid><description>&lt;p>À l&amp;rsquo;époque, chez un ancien employeur, le firmware d&amp;rsquo;origine pilotait des rubans LED fixés devant des salles de réunion, qui indique la disponibilité de la salle. La board poll &lt;code>GET /lights/&amp;lt;mac&amp;gt;&lt;/code> toutes les quelques secondes, le serveur répond un unique chiffre ASCII entre &lt;code>&amp;lt;0&amp;gt;&lt;/code> et &lt;code>&amp;lt;9&amp;gt;&lt;/code>, le ruban affiche une couleur. Produit simple, protocole simple. Je ne l&amp;rsquo;ai pas écrit, mais je m&amp;rsquo;en suis servi comme base.&lt;/p>
&lt;p>La board n&amp;rsquo;était que la moitié du système. L&amp;rsquo;autre moitié côté salles, c&amp;rsquo;était le serveur d&amp;rsquo;occupation du bâtiment. Moi, j&amp;rsquo;ai détourné ce même protocole, pour moi seul, avec un petit serveur Python qui faisait le pont entre mes pipelines de CI et la board: ma veilleuse de CI existait en 2019, bien avant que les &amp;ldquo;CI status lights&amp;rdquo; soient une chose. Seul le contrat d&amp;rsquo;API a survécu, dans la doc (&lt;code>GET /lights/&amp;lt;lightid&amp;gt;&lt;/code> répondant &lt;code>&amp;lt;N&amp;gt;&lt;/code>, de &lt;code>&amp;lt;0&amp;gt;&lt;/code> arc-en-ciel d&amp;rsquo;erreur à &lt;code>&amp;lt;4&amp;gt;&lt;/code> rouge booked-and-busy); le code du serveur lui-même n&amp;rsquo;a pas survécu. C&amp;rsquo;est sa propre leçon: un code sans dépôt ne survit pas au poste qui l&amp;rsquo;a écrit.&lt;/p></description></item><item><title>SSH en 2021 : ce que treize ans ont changé depuis la série de 2008</title><link>https://blog.6admin.io/posts/ssh-modern/</link><pubDate>Fri, 04 Jun 2021 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-modern/</guid><description>&lt;p>La série SSH d&amp;rsquo;ici s&amp;rsquo;arrêtait en 2013: &lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2008/10/ssh-authentification-via-clefs-priveepublique.html" target="_blank" rel="noopener noreferrer">l&amp;rsquo;authentification par clefs en 2008&lt;/a>
, &lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2012/02/ssh-authentification-multiple-avec-clefs-privespubliques.html" target="_blank" rel="noopener noreferrer">l&amp;rsquo;authentification multiple en 2012&lt;/a>
, &lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2012/03/ssh-restreindre-une-connexion-via-clefs-priveepublique.html" target="_blank" rel="noopener noreferrer">la restriction de connexion&lt;/a>
 et &lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2013/06/ssh-augmenter-la-securite-de-vos-clefs-avec-pkcs8.html" target="_blank" rel="noopener noreferrer">PKCS#8 en 2013&lt;/a>
 comme dernier acte. Huit ans plus tard, tout ce que ces articles faisaient avec de l&amp;rsquo;artisanat existe en primitives. Voici le mémo 2021, complet.&lt;/p>
&lt;h2 id="les-clés-ed25519-et-le-couple-fido2">Les clés: Ed25519 et le couple FIDO2&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh-keygen -t ed25519 -a &lt;span style="color:#ae81ff">100&lt;/span> -C &lt;span style="color:#e6db74">&amp;#34;logout@2021&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ssh-keygen -t ed25519-sk -a &lt;span style="color:#ae81ff">100&lt;/span> &lt;span style="color:#75715e"># clé hardware, touch obligatoire&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>ssh-add -K &lt;span style="color:#75715e"># télécharge les resident keys de la YubiKey&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ed25519 pour tout ce qui est software: plus courte, plus rapide, plus résistante et &lt;code>-a 100&lt;/code> durcit le KDF contre le brute-forcing de la passphrase (l&amp;rsquo;héritage direct du &lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2013/06/ssh-augmenter-la-securite-de-vos-clefs-avec-pkcs8.html" target="_blank" rel="noopener noreferrer">PKCS#8 de 2013&lt;/a>
, qui avait raison avant l&amp;rsquo;heure). Les clés &lt;code>-sk&lt;/code> (OpenSSH 8.2, 2020) branchent une YubiKey: la clé privée ne quitte &lt;strong>jamais&lt;/strong> le matériel, le protocole exige un touch physique. Et RSA? Le soleil se couche: OpenSSH 8.2 a désactivé &lt;code>ssh-rsa&lt;/code> (SHA-1) dans &lt;code>CASignatureAlgorithms&lt;/code> par défaut et l&amp;rsquo;annonce du retrait complet est déjà dans les release notes. En 2008, RSA 2048 était le luxe; en 2021, c&amp;rsquo;est la dette technique.&lt;/p></description></item><item><title>PwnMachine : la station de bug bounty auto-hébergée</title><link>https://blog.6admin.io/posts/pwnmachine/</link><pubDate>Sun, 12 Jul 2020 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/pwnmachine/</guid><description>&lt;p>Quand tu fais du bug bounty, tu as besoin d&amp;rsquo;un environnement: un DNS que tu contrôles (pour les callbacks), un reverse proxy (pour exposer les outils) et une interface web pour orchestrer. Le tout sur une machine que tu peux reinstaller en dix minutes. PwnMachine est ce montage, packagé en Docker Compose.&lt;/p>
&lt;h2 id="le-concept">Le concept&lt;/h2>
&lt;p>PwnMachine est une solution d&amp;rsquo;auto-hébergement basée sur Docker, visant à fournir une station de pwnage facile à utiliser pour les chasseurs de bugs. L&amp;rsquo;installation de base inclut une interface web, un serveur DNS et un reverse proxy. Un &lt;code>docker-compose up --build -d&lt;/code> et c&amp;rsquo;est debout.&lt;/p></description></item><item><title>Compter les CVE ne dit rien de la sécurité</title><link>https://blog.6admin.io/posts/compter-les-cve/</link><pubDate>Wed, 11 Mar 2020 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/compter-les-cve/</guid><description>&lt;p>On voit régulièrement passer des comparatifs qui rangent les systèmes par nombre de CVE publiées, le plus bas gagnant le titre de plus sécurisé.
J&amp;rsquo;aurais tendance à mitiger fortement ce genre de résultats, parce que le chiffre lui-même ne mesure pas ce qu&amp;rsquo;on croit qu&amp;rsquo;il mesure.
Un compteur de CVE compte des failles rendues publiques et rien d&amp;rsquo;autre.
Il ne dit rien de celles qui existent, qui sont connues en interne ou qui circulent discrètement loin de tout bulletin.&lt;/p></description></item><item><title>Docker rootless : le démon sans privilèges</title><link>https://blog.6admin.io/posts/docker-rootless/</link><pubDate>Tue, 23 Jul 2019 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/docker-rootless/</guid><description>&lt;p>Docker tourne en root par défaut. Le démon (dockerd) a accès à TOUT le filesystem, TOUT le réseau, TOUT les process. Un container qui s&amp;rsquo;échappe du démon obtient le root sur l&amp;rsquo;hôte. Le mode rootless déplace le démon vers un utilisateur normal: les containers tournent dans un namespace utilisateur et une évasion ne donne que les droits de cet utilisateur, pas le root.&lt;/p>
&lt;h2 id="le-problème">Le problème&lt;/h2>
&lt;p>Un démon Docker en root, c&amp;rsquo;est un service qui a tous les droits sur la machine, accessible via un socket Unix (et parfois un port TCP). Chaque container qui monte un volume monte avec les droits root du démon. Chaque bug dans runc ou containerd est une évasion root.&lt;/p></description></item><item><title>3factor : l'architecture qui retire l'état de l'API</title><link>https://blog.6admin.io/posts/3factor/</link><pubDate>Fri, 15 Feb 2019 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/3factor/</guid><description>&lt;p>Au début de 2019, quelques mois après ma découverte des douze facteurs, je tombe sur
&lt;a href="https://github.com/hasura/3factor" target="_blank" rel="noopener noreferrer">3factor&lt;/a>
, un motif d&amp;rsquo;architecture publié par Hasura
dont le nom est un clin d&amp;rsquo;œil assumé à &lt;a href="https://12factor.net" target="_blank" rel="noopener noreferrer">12factor.net&lt;/a>
 (la
ressemblance s&amp;rsquo;arrête là, 3factor est un motif de conception, pas une méthodologie).
L&amp;rsquo;idée tient en trois facteurs: du GraphQL temps réel, de l&amp;rsquo;événementiel fiable et du
serverless asynchrone.&lt;/p>
&lt;h2 id="les-trois-facteurs">Les trois facteurs&lt;/h2>
&lt;p>Le premier facteur est du GraphQL temps réel: le client souscrit à l&amp;rsquo;état et le reçoit
au lieu de le demander, ce qui déplace la synchronisation du polling vers le serveur.
Le deuxième est de l&amp;rsquo;événementiel fiable: chaque changement d&amp;rsquo;état est un événement
persisté. Des déclencheurs le délivrent aux abonnés (la livraison se fait au moins
une fois, l&amp;rsquo;idempotence est à la charge du consommateur). Le troisième est du
serverless asynchrone: la logique métier tourne dans des fonctions déclenchées par les
événements, sans serveur à gérer, avec mise à l&amp;rsquo;échelle automatique.&lt;/p></description></item><item><title>GitOps, le mot après la pratique : gitflow, GitLab CI, Terraform et Ansible</title><link>https://blog.6admin.io/posts/gitops-avant-le-mot/</link><pubDate>Tue, 20 Nov 2018 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/gitops-avant-le-mot/</guid><description>&lt;p>Le mot se répand depuis un an, GitOps, posé par Weaveworks en 2017 autour de Kubernetes et d&amp;rsquo;une idée simple, git comme source de vérité de l&amp;rsquo;infrastructure et une boucle qui fait converger le réel vers ce que décrit le dépôt.
Je l&amp;rsquo;ai lu comme j&amp;rsquo;avais lu DevOps quelques années plus tôt, non pas en découvrant une méthode mais en reconnaissant la mienne (&lt;a href="https://blog.6admin.io/posts/devops-avant-le-mot/">DevOps, un mot sur ce que je bricolais déjà&lt;/a>
), à l&amp;rsquo;époque avec git et des hooks bash.
En 2018, le bricolage a grandi et il a pris la forme d&amp;rsquo;un gitflow adapté, de conventions et d&amp;rsquo;un pipeline qui fait tout le travail.&lt;/p></description></item><item><title>Portknocking et tunneling SSH : les tours de magie d'avant WireGuard</title><link>https://blog.6admin.io/posts/portknocking-wireguard/</link><pubDate>Sat, 06 Oct 2018 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/portknocking-wireguard/</guid><description>&lt;p>En 2008, ce blog publiait &lt;strong>Portknocking : l&amp;rsquo;art de frapper à la porte&lt;/strong>, puis &lt;a href="https://blog.6admin.io/posts/portknocking-generation/">la génération automatique de combinaisons&lt;/a>
, avec &lt;a href="https://blog.6admin.io/posts/ssh-tunneling/">le tunneling SSH&lt;/a>
 en étagère voisine. Fun, pédagogique et réellement déployé: je l&amp;rsquo;ai vu en entreprise jusqu&amp;rsquo;en &lt;strong>2018 chez un hébergeur&lt;/strong>. En 2016, Jason Donenfeld publie &lt;a href="https://www.wireguard.com/" target="_blank" rel="noopener noreferrer">WireGuard&lt;/a>
 et la question change de nature: pas &amp;ldquo;comment cacher la porte&amp;rdquo;, mais &amp;ldquo;pourquoi y a-t-il une porte?&amp;rdquo;.&lt;/p>
&lt;h2 id="le-montage-de-2009-en-souvenir-ému">Le montage de 2009, en souvenir ému&lt;/h2>
&lt;p>Pour les retardataires, ce que le portknocking &amp;ldquo;de luxe&amp;rdquo; de l&amp;rsquo;époque impliquait:&lt;/p></description></item><item><title>Chaos engineering : casser pour de vrai, mais pas n'importe comment</title><link>https://blog.6admin.io/posts/chaos-engineering/</link><pubDate>Mon, 20 Aug 2018 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/chaos-engineering/</guid><description>&lt;p>En 2018, la même année que ma découverte des douze facteurs, je tombe sur le chaos
engineering (je serais bien incapable de retrouver les billets de blog exacts qui m&amp;rsquo;y
mènent. C&amp;rsquo;est d&amp;rsquo;ailleurs une bonne raison de revenir aux sources plutôt qu&amp;rsquo;à mon
souvenir): la définition et les principes tiennent dans un seul document, qui dit
mieux ce que je finis par pratiquer que mes propres reformulations.&lt;/p>
&lt;h2 id="ce-nest-pas-casser-des-trucs">Ce n&amp;rsquo;est pas casser des trucs&lt;/h2>
&lt;p>Le contresens le plus courant consiste à croire qu&amp;rsquo;il suffit de redémarrer une
machine en production pour faire du chaos engineering, ce qui confond une méthode et
un incident: casser au hasard, c&amp;rsquo;est un incident qu&amp;rsquo;on n&amp;rsquo;a pas su éviter, pas une
expérience. Le chaos engineering est une discipline d&amp;rsquo;expérimentation, avec un état
stable défini et mesuré, une hypothèse sur sa persistance, une perturbation
réaliste injectée et une comparaison rigoureuse (sans état stable mesurable, il n&amp;rsquo;y a
pas d&amp;rsquo;expérience, il n&amp;rsquo;y a qu&amp;rsquo;une panne).&lt;/p></description></item><item><title>Git submodules à la main : mes plugins Vim 8 sans gestionnaire</title><link>https://blog.6admin.io/posts/vim-submodules/</link><pubDate>Mon, 07 May 2018 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/vim-submodules/</guid><description>&lt;p>Debian et Ubuntu venaient enfin de livrer Vim 8 et avec lui le système de packages natif: &lt;code>pack/plugins/start&lt;/code> et &lt;code>pack/plugins/opt&lt;/code>. Adieu pathogen, adieu mon hack aromatisé à l&amp;rsquo;apt (&lt;a href="https://blog.6admin.io/posts/vim-apthogen/">vim-apthogen&lt;/a>
, épisode un de cette série). Mais les packages de Vim 8 règlent le &lt;em>chargement&lt;/em>, pas la &lt;em>gestion&lt;/em>: rien ne dit quels plugins votre config utilise, ni comment les cloner sur une machine neuve.&lt;/p>
&lt;p>La réponse que j&amp;rsquo;ai choisie est celle que je fais tourner encore aujourd&amp;rsquo;hui: &lt;strong>le repo de config est l&amp;rsquo;état&lt;/strong>. Les plugins vivent en git submodules du repo de config, dans &lt;code>pack/plugins/start/&lt;/code> pour les toujours actifs et &lt;code>pack/plugins/opt/&lt;/code> pour les optionnels. Un clone avec &lt;code>--recursive&lt;/code> et l&amp;rsquo;éditeur entier se matérialise.&lt;/p></description></item><item><title>Twelve-Factor App : la méthode Heroku qui a survécu aux conteneurs</title><link>https://blog.6admin.io/posts/twelve-factor/</link><pubDate>Mon, 15 Jan 2018 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/twelve-factor/</guid><description>&lt;p>En janvier 2018, je tombe sur la méthode Twelve-Factor (et je la range tout de suite
parmi les pratiques que je faisais déjà sans le nommer): trois lectures qui se
complètent (le site de référence &lt;a href="https://12factor.net" target="_blank" rel="noopener noreferrer">d&amp;rsquo;Adam Wiggins&lt;/a>
, l&amp;rsquo;adaptation
aux microservices de &lt;a href="https://web.archive.org/web/20171222082423/https://www.nginx.com/blog/microservices-reference-architecture-nginx-twelve-factor-app/" target="_blank" rel="noopener noreferrer">Ben Horowitz sur le blog de
nginx&lt;/a>

et le rapport que Kevin Hoffman en tire &lt;a href="https://www.oreilly.com/library/view/beyond-the-twelve-factor/9781492042631/" target="_blank" rel="noopener noreferrer">chez
O&amp;rsquo;Reilly&lt;/a>
). Soudain un mot sur ce que je faisais depuis des années. Avant, je connaissais déjà
(et j&amp;rsquo;appliquais plus ou moins) KISS, YAGNI et DRY, puis SOLID; le cycle en V et AGILE
faisaient partie du paysage, chacun avec ses défauts que je pouvais énumérer sans
avoir besoin qu&amp;rsquo;on me les explique. Twelve-Factor, lui, ne s&amp;rsquo;adresse pas au grand
public: c&amp;rsquo;est une checklist d&amp;rsquo;ingénieur, écrite pour Heroku, qui dit noir sur blanc ce
qu&amp;rsquo;une application doit garantir pour survivre à la production et à ses propres
redéploiements.&lt;/p></description></item><item><title>Hardening SSH : la trilogie de 2017 relue en 2026</title><link>https://blog.6admin.io/posts/ssh-hardening-bastions/</link><pubDate>Thu, 26 Oct 2017 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-hardening-bastions/</guid><description>&lt;p>En octobre 2017, un article de hardening SSH passe sur ma timeline. Analyse généraliste, contre-mesures naïves. Je réponds en trois commentaires : la désactivation du root, le changement de port, l&amp;rsquo;authentification par clés. Neuf ans plus tard, ces trois commentaires me servent d&amp;rsquo;inventaire : ce qui tenait, ce qui a changé et ce qui n&amp;rsquo;était pas dans le cadre mais l&amp;rsquo;aurait mérité.&lt;/p>
&lt;p>D&amp;rsquo;abord un point de principe, celui qui m&amp;rsquo;avait fait tiquer : comparer OpenSSH à une simple interface d&amp;rsquo;administration est réducteur. SSH, ce sont les bastions d&amp;rsquo;accès au SI, les VPN SSH, l&amp;rsquo;industrialisation agentless (Ansible, Puppet Bolt) qui passent par dessus. C&amp;rsquo;est la colonne vertébrale d&amp;rsquo;administration de la plupart des parcs Unix. Le durcir mal, c&amp;rsquo;est durcir tout le SI mal.&lt;/p></description></item><item><title>Ansible avant Ansible : ssh, un CSV et un moteur de template</title><link>https://blog.6admin.io/posts/ancetre-ansible/</link><pubDate>Mon, 12 Sep 2016 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ancetre-ansible/</guid><description>&lt;p>En 2006-2007, j&amp;rsquo;administrais un petit parc à coups de scripts, comme tout le monde, sauf que je croyais (jeunesse!) que mon bricolage était une architecture. Il avait trois composants: une liste d&amp;rsquo;hôtes, un CSV et du bash. Ansible n&amp;rsquo;existait pas encore (il est né en 2012), mais la forme du problème était déjà là et la mienne la modélisait à 80%.&lt;/p>
&lt;h2 id="linventaire-une-liste--un-csv">L&amp;rsquo;inventaire: une liste + un CSV&lt;/h2>
&lt;p>La liste des machines, un fichier plat, une machine par ligne. Et par-dessus, un &lt;strong>CSV de variables d&amp;rsquo;inventaire&lt;/strong>:&lt;/p></description></item><item><title>SSH : ProxyJump et le multi-hop moderne</title><link>https://blog.6admin.io/posts/ssh-proxyjump/</link><pubDate>Mon, 12 Sep 2016 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-proxyjump/</guid><description>&lt;p>Il y a quelques années, pour atteindre une machine derrière un bastion, j&amp;rsquo;écrivais un &lt;code>ProxyCommand&lt;/code> avec &lt;code>nc&lt;/code> et je l&amp;rsquo;ai raconté dans &lt;a href="https://blog.6admin.io/posts/ssh-tunneling/">SSH: tunneling&lt;/a>
. OpenSSH 7.3 a rendu tout ça obsolète avec une seule option, &lt;code>-J&lt;/code> et c&amp;rsquo;est l&amp;rsquo;une de ces petites nouveautés qui changent un geste qu&amp;rsquo;on fait dix fois par jour.&lt;/p>
&lt;h2 id="le-geste-de-base">Le geste de base&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh -J user@bastion user@cible
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>bastion&lt;/code> sert de rebond, la cible n&amp;rsquo;est jamais exposée directement et surtout le chiffrement reste de bout en bout entre votre poste et &lt;code>cible&lt;/code>. Le bastion ne voit passer que du trafic chiffré qu&amp;rsquo;il ne peut pas lire, exactement comme avec le vieux &lt;code>ProxyCommand&lt;/code>, mais sans invoquer &lt;code>nc&lt;/code> ni ouvrir un shell intermédiaire.
La différence avec &lt;code>ProxyCommand&lt;/code> n&amp;rsquo;est pas qu&amp;rsquo;esthétique: &lt;code>-J&lt;/code> établit la connexion au suivant depuis le client, pas depuis le bastion, donc aucune clé privée ne transite ni ne séjourne sur le rebond. C&amp;rsquo;est ce qu&amp;rsquo;on voulait depuis le début et qu&amp;rsquo;on bricolait jusque-là avec l&amp;rsquo;agent forwarding, lequel posait justement le problème inverse en exposant l&amp;rsquo;agent sur le bastion.&lt;/p></description></item><item><title>apt pour Vim: l'histoire de vim-apthogen (2012-2016)</title><link>https://blog.6admin.io/posts/vim-apthogen/</link><pubDate>Sun, 17 Apr 2016 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/vim-apthogen/</guid><description>&lt;p>Entre 2012 et 2016, ma config Vim ressemblait à un système Debian vu par son gestionnaire de paquets: une pile de répertoires &lt;code>bundle/&lt;/code> installés à la main et &lt;a href="https://github.com/tpope/vim-pathogen" target="_blank" rel="noopener noreferrer">vim-pathogen&lt;/a>
 qui faisait le chargement. Pathogen est honnête sur son rôle: c&amp;rsquo;est &lt;code>dpkg&lt;/code>, le chargeur bête. Personne n&amp;rsquo;avait écrit l&amp;rsquo;&lt;code>apt&lt;/code> au-dessus. Alors je l&amp;rsquo;ai écrit.&lt;/p>
&lt;p>Le résultat: &lt;a href="https://www.vim.org/scripts/script.php?script_id=5366" target="_blank" rel="noopener noreferrer">vim-apthogen&lt;/a>
, publié sur vim.org le 12 avril 2016 (Vim 7.0, 1136 téléchargements, un karma de 19/6, des chiffres dont je suis déraisonnablement fier). La ligne du README que j&amp;rsquo;aime toujours: &lt;strong>Like &lt;code>apt&lt;/code> for &lt;code>dpkg&lt;/code>, &lt;code>vim-apthogen&lt;/code> is a frontend to &lt;code>vim-pathogen&lt;/code>&lt;/strong>.&lt;/p></description></item><item><title>Un autowalker DayZ en Java : décompiler, patcher en AZERTY, forker après</title><link>https://blog.6admin.io/posts/dayz-autowalker-java/</link><pubDate>Sat, 18 Oct 2014 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/dayz-autowalker-java/</guid><description>&lt;p>À l&amp;rsquo;époque de DayZ, je voulais un autowalker, ce petit utilitaire qui tient la touche d&amp;rsquo;avance pour toi pendant que ton personnage traverse une carte immense.
Il en existait un, en Java, mais sans sources publiées et il était pensé pour un clavier QWERTY.
Moi je joue en AZERTY, donc il avançait de travers et je voulais aussi qu&amp;rsquo;il gère proprement l&amp;rsquo;état de course plutôt que de bourriner une touche.
Je ne me suis pas posé de question : je l&amp;rsquo;ai décompilé.&lt;/p></description></item><item><title>SSH : Augmenter la sécurité de vos clefs avec PKCS#8</title><link>https://blog.6admin.io/posts/ssh-pkcs8/</link><pubDate>Sun, 23 Jun 2013 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-pkcs8/</guid><description>&lt;p>En deux trois commandes :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ mv ~/.ssh/id_rsa ~/.ssh/id_rsa.old
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ openssl pkcs8 -topk8 -v2 des3 -in ~/.ssh/id_rsa.old -out ~/.ssh/id_rsa
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ chmod &lt;span style="color:#ae81ff">600&lt;/span> ~/.ssh/id_rsa
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Check that the converted key works; if yes, delete the old one:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ rm ~/.ssh/id_rsa.old
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Et un petit script en prime pour le faire à la volée :&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>: &lt;span style="color:#e6db74">&amp;lt;&amp;lt; &amp;#39;TITLE.sh&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Version: 0.1
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Authors: nobody@vhalholl.info
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Description: hardening ssh private key w/ pkcs#8
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> http://martin.kleppmann.com/2013/05/24/improving-security-of-ssh-private-keys.html
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74"> Dependencies: openssl
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">TITLE&lt;/span>.sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DEP&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>which openssl&lt;span style="color:#66d9ef">)&lt;/span>;&lt;span style="color:#f92672">[&lt;/span> ! -z $DEP &lt;span style="color:#f92672">]&amp;amp;&amp;amp;&lt;/span> &lt;span style="color:#f92672">{&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">for&lt;/span> k in &lt;span style="color:#66d9ef">$(&lt;/span>echo &lt;span style="color:#66d9ef">$(for&lt;/span> i in &lt;span style="color:#66d9ef">$(&lt;/span>ls *&lt;span style="color:#66d9ef">)&lt;/span>;&lt;span style="color:#66d9ef">do&lt;/span> file $i; &lt;span style="color:#66d9ef">done&lt;/span> |grep private |cut -d : -f1&lt;span style="color:#66d9ef">))&lt;/span>;&lt;span style="color:#66d9ef">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;backup &lt;/span>$k&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; mv $k .$k.old
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> echo &lt;span style="color:#e6db74">&amp;#34;convert &lt;/span>$k&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; openssl pkcs8 -topk8 -v2 des3 -in .$k.old -out $k; chmod &lt;span style="color:#ae81ff">600&lt;/span> $k
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">done&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> exit 0;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;Openssl not found&amp;#34;&lt;/span> &lt;span style="color:#f92672">&amp;amp;&amp;amp;&lt;/span> exit &lt;span style="color:#ae81ff">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le PKCS#8 enveloppe la clé privée RSA dans une couche de chiffrement 3DES avec un KDF renforcé (PBKDF2). La passphrase de la clé devient plus coûteuse à brute-forcer: chaque tentative de déchiffrement nécessite des itérations supplémentaires du KDF. C&amp;rsquo;est le même principe que bcrypt ou scrypt pour les mots de passe, appliqué aux clés SSH.&lt;/p></description></item><item><title>Le client FOG: python 2, cron toutes les cinq minutes et une flotte qui se rebootait en place</title><link>https://blog.6admin.io/posts/fog-client/</link><pubDate>Tue, 20 Nov 2012 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fog-client/</guid><description>&lt;p>Avant les autres pièces d&amp;rsquo;archéologie de ce blog, il y a celle-ci. Des années avant &lt;a href="https://blog.6admin.io/posts/vim-apthogen/">l&amp;rsquo;ère apthogen&lt;/a>
, sous l&amp;rsquo;identité gobel1, je faisais tourner des flottes de postes clonées avec &lt;a href="https://fogproject.org" target="_blank" rel="noopener noreferrer">FOG&lt;/a>
 (Free Opensource Ghost). L&amp;rsquo;histoire client de FOG était Windows-first, donc le côté Linux avait besoin d&amp;rsquo;un petit client à lui: voici &lt;code>FOG.py&lt;/code>, version 0.2, python 2, environ 150 lignes plus une poignée de hooks shell. Il date d&amp;rsquo;avant 2013; le repo git n&amp;rsquo;a été ré-initialisé qu&amp;rsquo;en mai 2013, un commit en français, six commits au total. L&amp;rsquo;archéologie est authentique.&lt;/p></description></item><item><title>SSH : Restreindre une connexion via clefs privée/publique</title><link>https://blog.6admin.io/posts/ssh-restreindre/</link><pubDate>Mon, 05 Mar 2012 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-restreindre/</guid><description>&lt;p>Quoi de plus évident lors de l&amp;rsquo;exécution de tâches automatisées diverses entre plusieurs serveurs que l&amp;rsquo;utilisation d&amp;rsquo;une paire de clefs ssh sans passphrase ?&lt;/p>
&lt;p>Oui, mais comment cantonner cette clefs non protégée à l&amp;rsquo;exécution d&amp;rsquo;une tâche bien précise ?&lt;/p>
&lt;p>Il suffit de préfixer la clefs publique à limiter dans le fichier :&lt;/p>
&lt;p>&lt;code>.ssh/authorized_keys&lt;/code>&lt;/p>
&lt;p>Avec les options détaillées dans le manuel d&amp;rsquo;sshd à la section AUTHORIZED_KEYS FILE FORMAT:&lt;/p>
&lt;pre tabindex="0">&lt;code>command=&amp;#34;/usr/bin/rsync --server --daemon .&amp;#34;,no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA...
&lt;/code>&lt;/pre>&lt;p>Chaque option bloque une voie d&amp;rsquo;échappement:&lt;/p></description></item><item><title>SSH : Authentification multiple avec clefs privés/publiques</title><link>https://blog.6admin.io/posts/ssh-authentification-multiple/</link><pubDate>Mon, 06 Feb 2012 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-authentification-multiple/</guid><description>&lt;p>En complément d&amp;rsquo;un ancien article sur &lt;a href="https://blog.6admin.io/posts/ssh-authentification-par-cles/">l&amp;rsquo;authentification par clefs avec ssh&lt;/a>
 et parce qu&amp;rsquo;il ne faut jamais mettre tous ses oeufs dans le même panier, je propose ici une solution toute simple afin d&amp;rsquo;utiliser une clef spécifique à une identité sur un serveur ssh donné.&lt;/p>
&lt;p>Dans notre exemple nous allons utiliser deux clefs, l&amp;rsquo;une avec passphrase qui nous servira pour nous connecter à un serveur server.mydomain.tld en tapant simplement ssh serv et une deuxième sans passphrase qui nous servira essentiellement pour l&amp;rsquo;exécution de script de maintenance sur un petit parc de machines clientes cli01.parc01.mydomain.tld etc., dont le serveur ssh écoute sur un port spécifique et le pare-feu n&amp;rsquo;autorisant que les connexions depuis server.mydomain.tld (soyons fous).&lt;/p></description></item><item><title>Debsecan : Debian Security Analyzer</title><link>https://blog.6admin.io/posts/debsecan/</link><pubDate>Wed, 26 Oct 2011 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/debsecan/</guid><description>&lt;p>Debian Security Analyzer, est un outil très pratique, découvert assez récemment.&lt;/p>
&lt;p>Ce dernier génère simplement une liste des vulnérabilités affectant une installation donnée, à ce titre il est complémentaire d&amp;rsquo;apt-listbugs.&lt;/p>
&lt;p>Par défaut à l&amp;rsquo;installation, les rapports quotidiens par mails, sont activés pour une installation générique.&lt;/p>
&lt;p>Ce comportement se modifie via le fichier /etc/default/debsecan:&lt;/p>
&lt;pre tabindex="0">&lt;code># Configuration file for debsecan. Contents of this file should
# adhere to the KEY=VALUE shell syntax. This file may be edited by
# debsecan&amp;#39;s scripts, but your modifications are preserved.

# If true, enable daily reports, sent by email.
REPORT=true

# For better reporting, specify the correct suite here, using the code
# name (that is, &amp;#34;sid&amp;#34; instead of &amp;#34;unstable&amp;#34;).
#
# Available:
# GENERIC
# etch
# lenny
# sid
# squeeze
# wheezy
SUITE=GENERIC

# Mail address to which reports are sent.
MAILTO=root

# Source URL
# eg: http://secure-testing.debian.net/debian-secure-testing/project/debsecan/release/1/$SUITE
SOURCE=
&lt;/code>&lt;/pre>&lt;p>Le paramètre SUITE est le plus important: GENERIC liste toutes les CVEs pour toutes les versions, y compris celles qui ne vous affectent pas. En le passant à votre suite exacte (&lt;code>lsb_release -c&lt;/code>), debsecan filtre par version et la liste devient actionnable.&lt;/p></description></item><item><title>Dennis Ritchie a quitté #world</title><link>https://blog.6admin.io/posts/dennis-ritchie/</link><pubDate>Sat, 22 Oct 2011 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/dennis-ritchie/</guid><description>&lt;p>Dennis Ritchie (ci-dessus à droite) alias DMR, créateur du langage de programmation C et co-développeur du système d&amp;rsquo;exploitation Unix nous a quitté hier à l&amp;rsquo;âge de 70 ans.&lt;/p>
&lt;p>Personnellement, j&amp;rsquo;ai appris C grâce à &amp;ldquo;son&amp;rdquo; livre &amp;ldquo;Le langage C&amp;rdquo; et j&amp;rsquo;utilise toujours l&amp;rsquo;indentation K&amp;amp;R bien que légèrement remixée à la sauce GNU.&lt;/p>
&lt;p>C&amp;rsquo;est une disparition qui aura un écho médiatique pratiquement inexistant contrairement au décès de Steve Jobs survenu la semaine dernière.&lt;/p></description></item><item><title>(Ré)Ouverture</title><link>https://blog.6admin.io/posts/reouverture/</link><pubDate>Thu, 13 Oct 2011 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/reouverture/</guid><description>&lt;p>Après deux années d&amp;rsquo;inactivité, une cinquantaine d&amp;rsquo;articles publiés et une dizaine de brouillons en cours, ce blog ouvre de nouveau ses portes.&lt;/p>
&lt;p>Toujours propulsé par WordPress, seules les images, les commentaires et le thème initial du blog ont changé.&lt;/p>
&lt;p>Pour le moment je m&amp;rsquo;attelle à la correction des articles déjà publiés, ensuite je prendrai en charge la publication des brouillons en cours, qui seront alors antidatés pour suivre la chronologie du blog.&lt;/p></description></item><item><title>Chat : de irssi + gateway messenger à weechat, la philosophie du client mince</title><link>https://blog.6admin.io/posts/chat-gateways/</link><pubDate>Mon, 20 Jun 2011 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/chat-gateways/</guid><description>&lt;p>L&amp;rsquo;&lt;a href="https://web.archive.org/web/2009/http://blog.vhalholl.info/2009/11/irssi-irc-aux-petits-oignons.html" target="_blank" rel="noopener noreferrer">article irssi de 2009&lt;/a>
 finissait sur un edit: &amp;ldquo;Une configuration à jour est dispo ici sur github&amp;rdquo; (c&amp;rsquo;était un stub d&amp;rsquo;article, la vraie valeur vivait dans le repo, la suite des temps l&amp;rsquo;a prouvé). Il faut maintenant raconter ce que l&amp;rsquo;article ne racontait pas: &lt;strong>le montage qui rendait &lt;a href="https://irssi.org/" target="_blank" rel="noopener noreferrer">irssi&lt;/a>
 indispensable&lt;/strong> et pourquoi deux ans plus tard j&amp;rsquo;ai tout déménagé vers weechat sans changer la philosophie.&lt;/p>
&lt;h2 id="irssi--bitlbee-le-pont-vers-les-messengers">irssi + BitlBee: le pont vers les messengers&lt;/h2>
&lt;p>Le montage de l&amp;rsquo;époque: un serveur &lt;strong>BitlBee&lt;/strong> local qui présente les réseaux de messagerie instantanée (MSN, AIM, ICQ, Jabber) comme un &lt;strong>canal IRC ordinaire&lt;/strong> et irssi qui s&amp;rsquo;y connecte comme à n&amp;rsquo;importe quel serveur. Résultat: un seul client, un seul buffer, une seule config de logs, pour IRC et pour les contacts MSN qui ne connaissent de l&amp;rsquo;IRC que le nom.&lt;/p></description></item><item><title>tmux : le multiplexeur qui a pris le fauteuil</title><link>https://blog.6admin.io/posts/tmux/</link><pubDate>Sun, 23 May 2010 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/tmux/</guid><description>&lt;p>Screen a vingt-trois ans, &lt;a href="https://blog.6admin.io/posts/byobu/">byobu&lt;/a>
 a habillé ses défauts et il reste des irritants que ni l&amp;rsquo;un ni l&amp;rsquo;autre ne règlent: pas de vrais &lt;strong>panes&lt;/strong> (Screen fait des régions, qui se redimensionnent mal), un UTF-8 rétrofité, une config &lt;code>$HOME/.screenrc&lt;/code> aux bindkeys hérités des années 80. C&amp;rsquo;est là qu&amp;rsquo;entre tmux, né en 2007 sur OpenBSD et qui commence à prendre le fauteuil en 2010.&lt;/p>
&lt;h2 id="le-modèle-client-serveur">Le modèle client-serveur&lt;/h2>
&lt;p>La différence architecturale qui change tout: Screen lance un serveur &lt;strong>par utilisateur&lt;/strong> (les sessions partagent un process), tmux lance &lt;strong>un serveur par session&lt;/strong> et les clients s&amp;rsquo;y attachent. Conséquences pratiques:&lt;/p></description></item><item><title>La méthode R.A.C.H.E : Rapid Application Conception and Heuristic Extreme-programming</title><link>https://blog.6admin.io/posts/methode-rache/</link><pubDate>Thu, 15 Apr 2010 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/methode-rache/</guid><description>&lt;p>Il existe une méthode de génie logiciel qui décrit mieux la vraie vie que la moitié
des référentiels que je vois passer en comité. Cette méthode a un acronyme, un
institut, une F.A.Q et une licence domaine public: elle s&amp;rsquo;appelle la méthode R.A.C.H.E. Je
la découvre vers 2009-2010, à une époque où je prends encore les roadmaps au
sérieux.&lt;/p>
&lt;p>R.A.C.H.E signifie &lt;em>Rapid Application Conception and Heuristic Extreme-programming&lt;/em>.
Le site de l&amp;rsquo;International Institute de La RACHE existe depuis 2007, mais le concept
circulait déjà sous forme de PDF auparavant. La métempsychose récurrente du concept
semble, selon ses propres promoteurs, intrinsèquement axiomale chez certains grands
éditeurs. &lt;a href="https://www.la-rache.com" target="_blank" rel="noopener noreferrer">la-rache.com&lt;/a>
&lt;/p></description></item><item><title>DevOps, un mot sur ce que je bricolais déjà</title><link>https://blog.6admin.io/posts/devops-avant-le-mot/</link><pubDate>Mon, 15 Mar 2010 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/devops-avant-le-mot/</guid><description>&lt;p>Depuis quelques mois un mot circule, DevOps, lancé après la conférence Velocity de juin 2009 et son fameux &amp;ldquo;10 deploys a day&amp;rdquo; sur la coopération entre dev et ops chez Flickr, puis repris aux premiers DevOpsDays de Gand en octobre, autour de Patrick Debois.
On le présente un peu partout comme la fin du mur entre ceux qui écrivent le code et ceux qui le font tourner et en lisant les premiers textes j&amp;rsquo;ai eu la sensation curieuse de reconnaître des choses que je bricolais déjà dans mon coin, sans leur avoir jamais donné de nom.&lt;/p></description></item><item><title>Puppet : mes premiers modules ou le passage de la boucle ssh à la déclaration</title><link>https://blog.6admin.io/posts/puppet-first/</link><pubDate>Sat, 02 Jan 2010 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/puppet-first/</guid><description>&lt;p>Mes scripts bash, une liste d&amp;rsquo;hôtes, un CSV de variables et une boucle ssh qui pousse des configs rendues par template m&amp;rsquo;ont rendu de bons services depuis 2007, mais ils décrivent des pas et c&amp;rsquo;est justement ce que je cherchais à quitter en écrivant mes premiers modules Puppet pour le parc que j&amp;rsquo;administre au travail.
Puppet, c&amp;rsquo;est un vrai DSL, un vrai modèle agent/master (la 0.25 en ce moment) et une promesse que mes scripts n&amp;rsquo;ont jamais tenue: &lt;strong>déclarer l&amp;rsquo;état désiré, pas décrire les pas&lt;/strong>.
Ssh, ntp, postfix, munin, zabbix, varnish, rsyslog, ces modules couvrent le socle commun et je les enrichis au fil des besoins.&lt;/p></description></item><item><title>Haproxy : le reverse proxy qui a pris la suite de Pound</title><link>https://blog.6admin.io/posts/haproxy/</link><pubDate>Sun, 20 Dec 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/haproxy/</guid><description>&lt;p>&lt;a href="https://web.archive.org/web/2013/http://blog.vhalholl.info/2008/10/pound-un-reverse-proxy-tres-light.html" target="_blank" rel="noopener noreferrer">Le blog parlait de Pound en 2008&lt;/a>
: un reverse proxy très light, qui dépose le TLS et balance vers un pool. Pound fait ce travail avec l&amp;rsquo;élégance du minimal, mais dès qu&amp;rsquo;il faut &lt;strong>router sur le contenu&lt;/strong> (un Host vers un cluster, une URL vers un backend spécifique, une session collante), on fait un pas au-dessus: haproxy 1.3, de Willy Tarreau, en cours de stabilisation vers la 1.4.&lt;/p></description></item><item><title>IRSSI : IRC aux petits oignons</title><link>https://blog.6admin.io/posts/irssi/</link><pubDate>Sat, 07 Nov 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/irssi/</guid><description>&lt;p>[edit: MàJ 20130621] : Une configuration à jour est dispo ici sur github.&lt;/p>
&lt;p>Irssi est le client IRC en mode console. Il ne fait pas de joli widget, il ne fait pas de drag-and-drop, il fait de l&amp;rsquo;IRC. Et il le fait bien: les themes, les scripts Perl, les aliases, les hotlists, les notifications, tout est configurable.&lt;/p>
&lt;p>La config vit dans &lt;code>~/.irssi/&lt;/code>, avec un &lt;code>config&lt;/code> principal et un &lt;code>scripts/&lt;/code> pour les plugins Perl. La config de l&amp;rsquo;époque (367 lignes, multi-réseaux: recycled-irc, otaku-irc, worldnet SSL:7000, fansub-irc, OFTC SSL:9999) est versionnée dans les dotfiles, avec un theme &lt;code>green.theme&lt;/code> et cinq scripts perso.&lt;/p></description></item><item><title>Byobu : screen avec une couche de vernis (et un statut qui sauve)</title><link>https://blog.6admin.io/posts/byobu/</link><pubDate>Thu, 15 Oct 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/byobu/</guid><description>&lt;p>En avril dernier, &lt;a href="https://blog.6admin.io/posts/screen/">ce blog décrivait Screen comme un multiplexeur de terminal&lt;/a>
: détacher, rattacher, ne jamais perdre une session ssh. Six mois plus tard, byobu arrive et pose une question impertinente: si tout le monde configure le même Screen de la même façon (statut, couleurs, raccourcis), pourquoi ne pas livrer la configuration toute faite?&lt;/p>
&lt;p>C&amp;rsquo;est exactement ce qu&amp;rsquo;est byobu: né dans Ubuntu sous le nom &lt;code>screen-profiles&lt;/code>, renommé byobu en 2009 (le mot japonais pour les paravents décoratifs, clin d&amp;rsquo;oeil assumé), l&amp;rsquo;outil enveloppe votre Screen existant d&amp;rsquo;une couche de vernis, sans en changer le moteur.&lt;/p></description></item><item><title>Bash : Géolocalisation, la trilogie</title><link>https://blog.6admin.io/posts/bash-geolocalisation/</link><pubDate>Fri, 02 Oct 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/bash-geolocalisation/</guid><description>&lt;p>Trois itérations du même script, entre décembre 2008 et octobre 2009, chacune née de la précédente et de ses limites. La v1 est perdue avec le disque dur (un Samsung de 500 Go, avec tous mes projets Bash, C, PHP et Perl, ma musique perso, bref le truc plein à plus de 90%), la v2 et la v3 survivent. C&amp;rsquo;est l&amp;rsquo;histoire de la progression d&amp;rsquo;un script en public.&lt;/p>
&lt;h2 id="la-revanche-de-netcat-v2-février-2009">La revanche de netcat (v2, février 2009)&lt;/h2>
&lt;p>Après une discussion IRC sur la géolocalisation, un ami qui utilisait le même site m&amp;rsquo;a refilé un de ses scripts qui en une seule ligne faisait exactement la même chose que le mien mais beaucoup plus rapidement grâce à netcat (pas d&amp;rsquo;accès disque). Malheureusement, suite à la perte de mon disque dur, j&amp;rsquo;ai perdu pas mal d&amp;rsquo;outils, dont ce fameux script. Du coup j&amp;rsquo;ai réécrit ce script, étant quand même largement moins bon que mon ami, il me prend plus d&amp;rsquo;une ligne.&lt;/p></description></item><item><title>NTP : synchronisation du temps sur le réseau</title><link>https://blog.6admin.io/posts/ntp/</link><pubDate>Tue, 26 May 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ntp/</guid><description>&lt;p>Le NTP (Network Time Protocol) synchronise les horloges des machines sur le réseau. Ça paraît trivial jusqu&amp;rsquo;au jour où un script qui dépend de la date dérive de 3 secondes et rate sa fenêtre de connexion ou où deux serveurs qui doivent s&amp;rsquo;accorder sur &amp;ldquo;maintenant&amp;rdquo; ont 4 minutes d&amp;rsquo;écart.&lt;/p>
&lt;h2 id="linstallation">L&amp;rsquo;installation&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>apt-get install ntp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le daemon ntpd démarre et synchronise automatiquement avec les serveurs du pool Debian (&lt;code>0.debian.pool.ntp.org&lt;/code> à &lt;code>3.debian.pool.ntp.org&lt;/code>).&lt;/p>
&lt;h2 id="la-config-minimale">La config minimale&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># /etc/ntp.conf&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>server 0.debian.pool.ntp.org iburst
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>server 1.debian.pool.ntp.org iburst
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>server 2.debian.pool.ntp.org iburst
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>server 3.debian.pool.ntp.org iburst
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Restreindre l&amp;#39;accès&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>restrict default kod notrap nomodify nopeer noquery
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>restrict 127.0.0.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>restrict ::1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>L&amp;rsquo;option &lt;code>iburst&lt;/code> accélère la synchronisation initiale (4 paquets au lieu de 1 au démarrage). Les &lt;code>restrict&lt;/code> bloquent l&amp;rsquo;accès depuis le réseau: le serveur NTP ne sert que lui-même, pas les autres (sauf si on veut faire un serveur NTP local).&lt;/p></description></item><item><title>Portknocking : génération automatique de combinaisons</title><link>https://blog.6admin.io/posts/portknocking-generation/</link><pubDate>Fri, 22 May 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/portknocking-generation/</guid><description>&lt;p>Le portknocking classique frappe à la porte avec une séquence de ports fixe. Le problème d&amp;rsquo;une séquence fixe: elle se sniff, elle se rejoue. La solution: faire dépendre la séquence de la date, pour qu&amp;rsquo;elle change chaque jour.&lt;/p>
&lt;h2 id="le-principe">Le principe&lt;/h2>
&lt;p>La combinaison est calculée depuis la date système. Le jour détermine le protocole (pair = udp, impair = tcp) et les ports partent de la somme jour+mois+année doublée, à laquelle on ajoute 64 jusqu&amp;rsquo;à dépasser 1024. Le client et le serveur doivent avoir la même horloge, d&amp;rsquo;où la synchronisation NTP.&lt;/p></description></item><item><title>Bash : Personnalisation du fichier .bashrc</title><link>https://blog.6admin.io/posts/bashrc/</link><pubDate>Tue, 14 Apr 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/bashrc/</guid><description>&lt;p>Sur nos systèmes préférés, la configuration du shell bash en mode interactif, de son prompt et de sa coloration, se fait dans les fichiers:&lt;/p>
&lt;ul>
&lt;li>&lt;code>/etc/profile&lt;/code>&lt;/li>
&lt;li>&lt;code>/etc/bash.bashrc&lt;/code>&lt;/li>
&lt;li>&lt;code>/root/.bashrc&lt;/code>&lt;/li>
&lt;li>&lt;code>/home/user/.bashrc&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Ici nous ne toucherons qu&amp;rsquo;aux trois derniers. On commence par la couleur du nom d&amp;rsquo;utilisateur dans le prompt, vert pour les utilisateurs, rouge pour le compte root, parce qu&amp;rsquo;un prompt root qui ne se signale pas est un prompt root dans lequel on finit par taper une bêtise:&lt;/p></description></item><item><title>Screen : un multiplexeur de terminal</title><link>https://blog.6admin.io/posts/screen/</link><pubDate>Mon, 13 Apr 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/screen/</guid><description>&lt;p>Screen est un multiplexeur de terminal qui, à la manière d&amp;rsquo;un gestionnaire de fenêtrage, permet à plusieurs programmes en mode texte de tourner en même temps depuis une seule interface, typiquement un terminal local ou distant via ssh (non, rien à voir avec nohup que j&amp;rsquo;utilise principalement pour certains scripts avec wget).&lt;/p>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;p>Sous Gentoo:&lt;/p>
&lt;pre tabindex="0">&lt;code>logout@lifthrasir ~ $ su -c &amp;#34;emerge app-misc/screen&amp;#34;
Password:
[...]
&lt;/code>&lt;/pre>&lt;p>Sous Debian:&lt;/p>
&lt;pre tabindex="0">&lt;code>logout@helghardhr:~$ sudo apt-get install screen
Password for user logout:
[...]
&lt;/code>&lt;/pre>&lt;h2 id="passons-à-la-pratique">Passons à la pratique&lt;/h2>
&lt;p>Nous allons créer une session screen pour prendre la main sur un switch:&lt;/p></description></item><item><title>Apache : l'URL rewriting</title><link>https://blog.6admin.io/posts/apache-url-rewriting/</link><pubDate>Sat, 14 Feb 2009 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/apache-url-rewriting/</guid><description>&lt;p>mod_rewrite est le module d&amp;rsquo;Apache qui réécrit les URLs à la volée. Il transforme &lt;code>/article.php?id=42&lt;/code> en &lt;code>/article/42&lt;/code>, redirige les vieux liens vers les nouveaux et fait tout ce qu&amp;rsquo;un reverse proxy ne fait pas: il modifie la requête avant qu&amp;rsquo;elle atteigne l&amp;rsquo;application.&lt;/p>
&lt;h2 id="le-basic">Le basic&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-apache" data-lang="apache">&lt;span style="display:flex;">&lt;span>RewriteEngine &lt;span style="color:#66d9ef">On&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RewriteRule ^article/([0-9]+)$ article.php?id=$1 [L]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cette règle transforme &lt;code>/article/42&lt;/code> en &lt;code>article.php?id=42&lt;/code> en interne (l&amp;rsquo;utilisateur voit &lt;code>/article/42&lt;/code>, Apache exécute &lt;code>article.php?id=42&lt;/code>). Le &lt;code>[L]&lt;/code> signifie &amp;ldquo;last rule&amp;rdquo;: si cette règle matche, les suivantes ne sont pas évaluées.&lt;/p></description></item><item><title>SSH: rsync sécurisé</title><link>https://blog.6admin.io/posts/ssh-rsync-securise/</link><pubDate>Sat, 27 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-rsync-securise/</guid><description>&lt;p>Rsync est l&amp;rsquo;outil de sauvegarde incrémentale: il compare source et destination, ne transfère que les deltas et préserve les permissions, les timestamps, les symlinks. Over SSH, il traverse le réseau sur le canal chiffré, sans démon rsync côté serveur (SSH fait le transport).&lt;/p>
&lt;h2 id="le-rsync-de-base">Le rsync de base&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>rsync -avz /data/ user@serveur:/backup/data/
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>-a&lt;/code> : archive mode (récursif, préserve perms, times, symlinks, devices)&lt;/li>
&lt;li>&lt;code>-v&lt;/code> : verbose (liste les fichiers transférés)&lt;/li>
&lt;li>&lt;code>-z&lt;/code> : compression (gzip avant transfert)&lt;/li>
&lt;/ul>
&lt;p>Le &lt;code>/&lt;/code> après &lt;code>/data/&lt;/code> signifie: &amp;ldquo;le contenu de /data&amp;rdquo;, pas &amp;ldquo;/data lui-même&amp;rdquo;. Sans le &lt;code>/&lt;/code>, rsync crée &lt;code>/backup/data/data/&lt;/code>. C&amp;rsquo;est l&amp;rsquo;erreur rsync la plus commune.&lt;/p></description></item><item><title>htop : le remplaçant de top</title><link>https://blog.6admin.io/posts/htop/</link><pubDate>Thu, 25 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/htop/</guid><description>&lt;p>top existe depuis 1984 et il est affreux. L&amp;rsquo;interface est rigide, les touches sont obscures, le tree view n&amp;rsquo;existe pas et trier par mémoire demande de lire le man page. htop fait tout ce que top fait, en mieux et il tient dans un terminal.&lt;/p>
&lt;h2 id="ce-que-htop-apporte">Ce que htop apporte&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Scroll horizontal et vertical&lt;/strong>: les lignes de process ne sont plus tronquées;&lt;/li>
&lt;li>&lt;strong>Tree view&lt;/strong> (&lt;code>F5&lt;/code>): qui a spawné qui, le parent/enfant en visuel, les threads indentés sous leur process parent;&lt;/li>
&lt;li>&lt;strong>Tri interactif&lt;/strong> (&lt;code>F6&lt;/code>): par CPU, par mémoire, par PID, par USER, sans re-lancer;&lt;/li>
&lt;li>&lt;strong>Kill interactif&lt;/strong> (&lt;code>F9&lt;/code>): sélectionner un process, choisir le signal, confirmer. Pas de &lt;code>kill -9 12345&lt;/code> tapé dans un autre terminal;&lt;/li>
&lt;li>&lt;strong>Les jauges CPU par coeur&lt;/strong> en haut de l&amp;rsquo;écran, en couleur, en temps réel;&lt;/li>
&lt;li>&lt;strong>Le filtre&lt;/strong> (&lt;code>F4&lt;/code>): taper un pattern et seuls les process matchant sont visibles;&lt;/li>
&lt;li>&lt;strong>Le setup&lt;/strong> (&lt;code>F2&lt;/code>): choisir les colonnes, les couleurs, les jauges et sauvegarder dans &lt;code>~/.config/htop/htoprc&lt;/code>.&lt;/li>
&lt;/ul>
&lt;h2 id="les-touches-qui-servent">Les touches qui servent&lt;/h2>
&lt;pre tabindex="0">&lt;code>F1 Help
F2 Setup
F3 Search (incrémental)
F4 Filter
F5 Tree view
F6 Sort
F7 Nice - (augmenter la priorité)
F8 Nice + (diminuer la priorité)
F9 Kill (envoyer un signal)
F10 Quit
&lt;/code>&lt;/pre>&lt;p>Le F9 est le plus utilisé: sélectionner un process qui bouffe tout le CPU, F9, SIGTERM (15) et si ça ne suffit pas, F9 SIGKILL (9). Le tout dans le même écran, sans quitter htop.&lt;/p></description></item><item><title>SSH: SSH filesystem</title><link>https://blog.6admin.io/posts/sshfs/</link><pubDate>Thu, 25 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/sshfs/</guid><description>&lt;p>SSHFS (SSH Filesystem) monte un filesystem distant dans votre arborescence locale via SSH et FUSE. Pas de NFS, pas de SMB, pas de configuration serveur: juste SSH (que le serveur a déjà) et FUSE (que le client a). Le filesystem distant apparaît comme un directory local, avec tous les outils standards (cp, mv, find, grep, vim).&lt;/p>
&lt;h2 id="le-montage">Le montage&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>mkdir /mnt/distant
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>sshfs user@serveur:/home/user /mnt/distant
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Après cette commande, &lt;code>/mnt/distant&lt;/code> EST &lt;code>/home/user&lt;/code> sur &lt;code>serveur&lt;/code>. Tous les outils standards fonctionnent:&lt;/p></description></item><item><title>tsocks : proxyfions</title><link>https://blog.6admin.io/posts/tsocks/</link><pubDate>Tue, 23 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/tsocks/</guid><description>&lt;p>Le tunnel SSH donne un SOCKS (&lt;a href="https://blog.6admin.io/posts/ssh-tunneling/">l&amp;rsquo;article tunneling&lt;/a>
), mais &lt;code>ssh -D&lt;/code> ne proxyfque que ce qui parle SOCKS: les navigateurs, curl avec &lt;code>--proxy&lt;/code>. Les programmes qui ne connaissent pas SOCKS (apt, telnet, le client MySQL) restent en direct. tsocks résout ça par &lt;code>LD_PRELOAD&lt;/code>.&lt;/p>
&lt;h2 id="le-principe">Le principe&lt;/h2>
&lt;p>tsocks est une bibliothèque partagée qui intercepte les appels système réseau (&lt;code>connect()&lt;/code>, &lt;code>send()&lt;/code>, &lt;code>recv()&lt;/code>) via &lt;code>LD_PRELOAD&lt;/code>. Quand un programme essaye d&amp;rsquo;ouvrir une connexion TCP, tsocks redirige vers le proxy SOCKS à sa place. Le programme ne sait pas qu&amp;rsquo;il passe par un proxy.&lt;/p></description></item><item><title>Pound : un reverse proxy très light</title><link>https://blog.6admin.io/posts/pound/</link><pubDate>Sun, 21 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/pound/</guid><description>&lt;p>Pound est un reverse proxy qui fait trois choses: il termine le TLS, il vérifie que les backends sont vivants et il balance. C&amp;rsquo;est tout. Et c&amp;rsquo;est exactement ce qu&amp;rsquo;il faut quand on ne veut pas d&amp;rsquo;un Apache qui fait aussi proxy.&lt;/p>
&lt;h2 id="la-conf">La conf&lt;/h2>
&lt;pre tabindex="0">&lt;code class="language-conf" data-lang="conf">ListenHTTP
 Address 0.0.0.0
 Port 80
End

ListenHTTPS
 Address 0.0.0.0
 Port 443
 Cert &amp;#34;/etc/pound/server.pem&amp;#34;
End

Service
 BackEnd
 Address 192.168.1.11
 Port 8080
 End
 BackEnd
 Address 192.168.1.12
 Port 8080
 End
 Session
 Type IP
 TTL 300
 End
End
&lt;/code>&lt;/pre>&lt;p>Le fichier de config Pound est un format déclaratif qui se lit comme un bloc de texte: chaque BackEnd est un serveur du pool, chaque Service est un groupe de backends, la Session colle les clients par IP source. Le TLS se termine dans Pound, les backends parlent HTTP en clair sur le réseau interne.&lt;/p></description></item><item><title>Polipo : un proxy ultra-simple</title><link>https://blog.6admin.io/posts/polipo/</link><pubDate>Wed, 17 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/polipo/</guid><description>&lt;p>Polipo est un proxy web cache écrit par Juliusz Chroboczek, léger (un process, quelques MB) et parfait dans un cas précis: derrière un tunnel SSH. Le &lt;a href="https://blog.6admin.io/posts/ssh-tunneling/">tunnel SSH&lt;/a>
 donne un SOCKS et le navigateur a besoin d&amp;rsquo;un proxy HTTP: Polipo fait le pont.&lt;/p>
&lt;h2 id="la-conf-minimale">La conf minimale&lt;/h2>
&lt;pre tabindex="0">&lt;code class="language-conf" data-lang="conf">proxyAddress = &amp;#34;127.0.0.1&amp;#34;
proxyPort = 8123
cacheIsShared = false
diskCacheRoot = &amp;#34;&amp;#34;
&lt;/code>&lt;/pre>&lt;p>Le proxy écoute sur le localhost:8123, sans cache disque (le cache du navigateur suffit) et fait le pont entre HTTP et le SOCKS du tunnel. La config tient en 4 lignes.&lt;/p></description></item><item><title>Subversion : installation et utilisation</title><link>https://blog.6admin.io/posts/subversion/</link><pubDate>Sat, 13 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/subversion/</guid><description>&lt;p>Après CVS (qui mérite sa retraite), Subversion. Le VCS centralisé qui a fait la transition entre le commit-lock de CVS et le modèle distribué qui viendra après. Le principe est simple: un serveur central (svnserve ou Apache + mod_dav_svn), des clients qui checkout, commit, update. Un seul historique, un seul point de vérité et un numéro de révision global qui incrément à chaque commit.&lt;/p>
&lt;h2 id="installation">Installation&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>apt-get install subversion subversion-tools
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Créer le dépôt&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>svnadmin create /srv/svn/monprojet
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Démarrer le serveur standalone&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>svnserve -d -r /srv/svn
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le mode svnserve est le plus simple: pas de Apache, pas de mod_dav, un daemon qui écoute sur le port 3690. Pour l&amp;rsquo;accès web, il faut Apache + mod_dav_svn (voir l&amp;rsquo;article suivant).&lt;/p></description></item><item><title>Bash: obfuscation d'adresses IP</title><link>https://blog.6admin.io/posts/bash-obfuscation-ip/</link><pubDate>Thu, 11 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/bash-obfuscation-ip/</guid><description>&lt;p>Une adresse IP n&amp;rsquo;a qu&amp;rsquo;une seule représentation &amp;ldquo;naturelle&amp;rdquo; (dotted quad: 192.168.1.1), mais elle a plusieurs représentations numériques que les navigateurs, les clients SSH et les parsers de logs acceptent aussi. Une IP peut s&amp;rsquo;écrire en décimal pur (3232235777), en hexadécimal (0xC0A80101), en octal ou en mixte (192.168.0x1.1). Les logs qui filtrent sur &amp;ldquo;192.168.1.1&amp;rdquo; ne filtrent pas sur &amp;ldquo;3232235777&amp;rdquo; et c&amp;rsquo;est le trou d&amp;rsquo;obfuscation.&lt;/p>
&lt;h2 id="les-représentations">Les représentations&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Décimal pur (uint32)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;%d\n&amp;#34;&lt;/span> &lt;span style="color:#ae81ff">3232235777&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 3232235777 = 192.168.1.1&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Hexadécimal&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;0x%X\n&amp;#34;&lt;/span> &lt;span style="color:#ae81ff">3232235777&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 0xC0A80101&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Octal&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>printf &lt;span style="color:#e6db74">&amp;#34;%o\n&amp;#34;&lt;/span> &lt;span style="color:#ae81ff">3232235777&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 30052000401&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le navigateur accepte &lt;code>http://3232235777/&lt;/code> exactement comme &lt;code>http://192.168.1.1/&lt;/code>: il convertit le nombre en dotted quad avant la connexion. Le client SSH aussi, le client FTP aussi.&lt;/p></description></item><item><title>Fail2ban : lutter contre le bruteforcing</title><link>https://blog.6admin.io/posts/fail2ban/</link><pubDate>Mon, 08 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/fail2ban/</guid><description>&lt;p>Chaque serveur SSH public reçoit des centaines de tentatives de connexion par jour. Les logs d&amp;rsquo;auth.log se remplissent de lignes &lt;code>Failed password for root from x.x.x.x&lt;/code>. Fail2ban lit ces logs, compte les échecs et bannit l&amp;rsquo;IP par iptables. C&amp;rsquo;est un chien de garde qui lit les logs au lieu de flairer.&lt;/p>
&lt;h2 id="le-principe">Le principe&lt;/h2>
&lt;p>Fail2ban fonctionne en trois étapes: il suit un fichier de log (auth.log, mail.log, apache.log), il matche les lignes contre des expressions régulières configurables et il exécute une action quand le seuil est atteint (typiquement, une règle iptables DROP pour l&amp;rsquo;IP fautive pendant N minutes).&lt;/p></description></item><item><title>OpenDNS : les DNS libres</title><link>https://blog.6admin.io/posts/opendns/</link><pubDate>Sat, 06 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/opendns/</guid><description>&lt;p>OpenDNS (208.67.222.222 et 208.67.220.220) est un résolveur DNS public et gratuit, apparu avant les résolveurs des grands acteurs. Le principe: vous remplacez les DNS de votre FAI par les leurs et votre résolution passe par leurs serveurs au lieu des vôtres.&lt;/p>
&lt;h2 id="pourquoi">Pourquoi&lt;/h2>
&lt;p>Trois raisons que les gens invoquent:&lt;/p>
&lt;ul>
&lt;li>Le DNS du FAI est lent, tombe en panne ou ment (le portail captif qui résout tout vers sa page de login);&lt;/li>
&lt;li>OpenDNS filtre les domaines de phishing et de malware (leur base de domaines malveillants, mise à jour en continu);&lt;/li>
&lt;li>OpenDNS fait du caching et le cache est plus rapide que le resolver du FAI.&lt;/li>
&lt;/ul>
&lt;h2 id="comment">Comment&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Dans /etc/resolv.conf&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nameserver 208.67.222.222
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>nameserver 208.67.220.220
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ou dans le DHCP du réseau pour que tous les postes en profitent.&lt;/p></description></item><item><title>Subversion: un WebSVN avec mod_dav et mod_svn d'Apache</title><link>https://blog.6admin.io/posts/subversion-websvn-apache/</link><pubDate>Mon, 01 Dec 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/subversion-websvn-apache/</guid><description>&lt;p>Subversion a deux modes d&amp;rsquo;accès: svnserve (daemon standalone, protocole svn://) et Apache avec mod_dav_svn (protocole http:// ou https://). Le mode Apache expose le repository via HTTP, avec l&amp;rsquo;authentification Apache, le SSL Apache et WebSVN pour le browsing web des sources.&lt;/p>
&lt;h2 id="le-module-mod_dav_svn">Le module mod_dav_svn&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>apt-get install libapache2-svn
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Ce paquet installe mod_dav et mod_dav_svn (le module qui expose les repositories SVN via WebDAV).&lt;/p>
&lt;h2 id="la-configuration-apache">La configuration Apache&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-apache" data-lang="apache">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># /etc/apache2/sites-available/svn&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;Location&lt;/span> &lt;span style="color:#e6db74">/svn&lt;/span>&lt;span style="color:#f92672">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> DAV svn
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> SVNParentPath &lt;span style="color:#e6db74">/var/svn&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> AuthType Basic
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> AuthName &lt;span style="color:#e6db74">&amp;#34;Subversion Repository&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> AuthUserFile &lt;span style="color:#e6db74">/etc/apache2/dav_svn.passwd&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Require valid-user
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">&amp;lt;/Location&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>DAV svn&lt;/code> : active le mode SVN&lt;/li>
&lt;li>&lt;code>SVNParentPath /var/svn&lt;/code> : le directory qui contient les repositories (un repo par sous-directory)&lt;/li>
&lt;li>&lt;code>AuthUserFile&lt;/code> : le fichier htpasswd pour l&amp;rsquo;authentification&lt;/li>
&lt;/ul>
&lt;p>Créer le repository et le fichier de mots de passe:&lt;/p></description></item><item><title>ext3 : accélérez vos accès disques</title><link>https://blog.6admin.io/posts/ext3/</link><pubDate>Thu, 20 Nov 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ext3/</guid><description>&lt;p>Le filesystem ext3 est le défaut de toutes les distributions depuis des années et il est monté avec les options les plus lentes possibles. Trois mots à ajouter dans le fstab et vos accès disques sont divisés par deux.&lt;/p>
&lt;h2 id="les-trois-options">Les trois options&lt;/h2>
&lt;pre tabindex="0">&lt;code>/dev/sda1 / ext3 defaults,noatime,data=writeback,commit=60 0 1
&lt;/code>&lt;/pre>&lt;p>&lt;strong>noatime.&lt;/strong> Le temps d&amp;rsquo;accès (atime) est mis à jour à CHAQUE lecture de fichier. Un &lt;code>cat fichier&lt;/code> met à jour l&amp;rsquo;atime de &lt;code>fichier&lt;/code> ET de tous les répertoires du chemin. Sur un serveur web qui lit des milliers de fichiers par seconde, l&amp;rsquo;atime est un overwrite disque invisible. &lt;code>noatime&lt;/code> le supprime purement et simplement. Coût: &lt;code>ls -lu&lt;/code> ne montre plus la dernière lecture, ce qui n&amp;rsquo;a jamais servi à personne.&lt;/p></description></item><item><title>Compilons un script shell avec shc</title><link>https://blog.6admin.io/posts/compiler-script-shell-shc/</link><pubDate>Wed, 19 Nov 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/compiler-script-shell-shc/</guid><description>&lt;p>Un script shell est du texte lisible par tout le monde: &lt;code>cat script.sh&lt;/code> montre le code, les mots de passe éventuels, la logique métier. shc (shell script compiler) transforme le script en binaire: le script est compilé en C, le C est compilé en binaire ELF et le texte source n&amp;rsquo;est plus lisible.&lt;/p>
&lt;h2 id="le-principe">Le principe&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>shc -f script.sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>shc génère deux fichiers:&lt;/p>
&lt;ul>
&lt;li>&lt;code>script.sh.x&lt;/code> : le binaire ELF exécutable&lt;/li>
&lt;li>&lt;code>script.sh.x.c&lt;/code> : le source C généré (à supprimer après compilation)&lt;/li>
&lt;/ul>
&lt;p>Le binaire &lt;code>script.sh.x&lt;/code> s&amp;rsquo;exécute comme le script original, mais le code shell n&amp;rsquo;est pas lisible dans le binaire.&lt;/p></description></item><item><title>Debian Etch: jouez avec les backports</title><link>https://blog.6admin.io/posts/debian-etch-backports/</link><pubDate>Sun, 16 Nov 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/debian-etch-backports/</guid><description>&lt;p>Debian Etch (4.0) est stable: les paquets sont testés, les versions sont figées et une application qui dépend d&amp;rsquo;une librairie plus récente que celle d&amp;rsquo;Etch ne compile pas. Les backports résolvent ce problème: le projet Debian Backports recompile les paquets de Sid (unstable) pour les dépendances d&amp;rsquo;Etch et les met à disposition dans un repository séparé.&lt;/p>
&lt;h2 id="le-repository-backports">Le repository backports&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># /etc/apt/sources.list&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>deb http://www.backports.org/debian etch-backports main contrib non-free
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>La clé GPG du repository:&lt;/p></description></item><item><title>ArpON : surveiller son cache ARP</title><link>https://blog.6admin.io/posts/arpon/</link><pubDate>Fri, 14 Nov 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/arpon/</guid><description>&lt;p>ArpON est un daemon très pratique, là où des outils comme Arpwatch permettent juste de voir les problèmes, ArpON lui permet de les bloquer (notamment les tentatives d&amp;rsquo;empoisonnement du cache ARP).&lt;/p>
&lt;p>Pour ce faire il peut utiliser deux protocoles, SARPI (pour Static ARP Inspection) et DARPI (pour Dynamic ARP Inspection).&lt;/p>
&lt;p>Il remplace parfaitement les outils arp, arping et arpscan, détecte et bloque les tentatives de spoofing ou de poisoning et du fait qu&amp;rsquo;il tourne en espace utilisateur, reste très portable. Actuellement il est compatible avec OpenBSD, FreeBSD, Debian, Gentoo, Slackware et même Mac OSX.&lt;/p></description></item><item><title>EncFS : le chiffrement de fichiers sans partition dédiée</title><link>https://blog.6admin.io/posts/encfs/</link><pubDate>Mon, 20 Oct 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/encfs/</guid><description>&lt;p>Chiffrer ses données sur Linux a toujours signifié LUKS, dm-crypt, une partition dédiée, une réinstallation. EncFS casse ce schéma: c&amp;rsquo;est un filesystem FUSE qui chiffre fichier par fichier, dans un répertoire normal, sans partition dédiée, sans réinstaller et sans droit root après le premier montage.&lt;/p>
&lt;h2 id="le-principe">Le principe&lt;/h2>
&lt;p>EncFS crée deux répertoires: le &lt;strong>cipher&lt;/strong> (les fichiers chiffrés, avec des noms chiffrés aussi) et le &lt;strong>plain&lt;/strong> (le point de montage, où les fichiers apparaissent en clair). Tout ce que vous écrivez dans le plain est chiffré à la volée et stocké dans le cipher. Tout ce que vous lisez dans le plain est déchiffré à la volée depuis le cipher. Démontez le plain et il ne reste que le cipher: des noms illisibles, du contenu chiffré.&lt;/p></description></item><item><title>radare : un débugger très abouti</title><link>https://blog.6admin.io/posts/radare/</link><pubDate>Sat, 04 Oct 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/radare/</guid><description>&lt;p>Après le harnais Perl greffé sur GDB et avant que &lt;a href="https://metasm.cr0.org/" target="_blank" rel="noopener noreferrer">Metasm&lt;/a>
 ne m&amp;rsquo;entraîne vers Ruby, il y a eu radare. Un débugger en mode console, écrit par pancake (Nibble), qui fait tout ce que GDB fait pour l&amp;rsquo;exploitation, mais avec une interface pensée pour le reverse engineering plutôt que pour le debugging applicatif.&lt;/p>
&lt;h2 id="ce-que-radare-fait-que-gdb-ne-fait-pas">Ce que radare fait que GDB ne fait pas&lt;/h2>
&lt;p>GDB est un débugger applicatif: il s&amp;rsquo;arrête sur des points de rupture, imprime des variables, suit des appels. radare est un outil de &lt;strong>reverse engineering&lt;/strong>: il désassemble, analyse les chaînes, cherche les gadgets, calcule les offsets et laisse naviguer dans le binaire comme dans un système de fichiers.&lt;/p></description></item><item><title>Yersinia : comment rendre malade son administrateur réseau</title><link>https://blog.6admin.io/posts/yersinia/</link><pubDate>Thu, 28 Aug 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/yersinia/</guid><description>&lt;p>Yersinia est le nom de la bactérie de la peste. L&amp;rsquo;outil porte bien son nom: il attaque les protocoles de couche 2 (STP, CDP, DTP, DHCP, VTP, HSRP) et rend votre switch malade. Le titre de cet article n&amp;rsquo;est pas une métaphore: c&amp;rsquo;est ce qui arrive réellement à un administrateur réseau qui découvre qu&amp;rsquo;une station avec Yersinia et un simple câble peut prendre le contrôle de sa topologie de switch.&lt;/p></description></item><item><title>SNMP : un protocole pas si simple</title><link>https://blog.6admin.io/posts/snmp/</link><pubDate>Tue, 01 Jul 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/snmp/</guid><description>&lt;p>SNMP signifie Simple Network Management Protocol. Le &amp;ldquo;Simple&amp;rdquo; est l&amp;rsquo;ironie du siècle: le protocole utilise des OIDs (Object Identifiers) qui sont des arborescences de numéros, des MIB (Management Information Base) qui traduisent les numéros en noms, des communautés (public, private) qui servent de mot de passe en clair et des versions (v1, v2c, v3) dont chacune a ses particularités.&lt;/p>
&lt;h2 id="les-oids-larbre">Les OIDs: l&amp;rsquo;arbre&lt;/h2>
&lt;p>Chaque donnée dans SNMP a un OID: une séquence de numéros séparés par des points. L&amp;rsquo;arbre standard:&lt;/p></description></item><item><title>tcpdump : analyse de trames et filtre BPF</title><link>https://blog.6admin.io/posts/tcpdump/</link><pubDate>Fri, 20 Jun 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/tcpdump/</guid><description>&lt;p>Après &lt;a href="https://blog.6admin.io/posts/nemesis-forgeur/">Nemesis&lt;/a>
 qui forge et &lt;a href="https://blog.6admin.io/posts/raw-sockets/">raw sockets&lt;/a>
 qui sniffent à la main, l&amp;rsquo;outil qui fait tout ça sans écrire une ligne de C: tcpdump. Si vous ne l&amp;rsquo;avez jamais utilisé, sachez que c&amp;rsquo;est probablement l&amp;rsquo;outil de diagnostic le plus rentable de toute votre carrière: une commande, un filtre et vous lisez le réseau en clair.&lt;/p>
&lt;h2 id="le-filtre-bpf-le-concept-qui-change-tout">Le filtre BPF, le concept qui change tout&lt;/h2>
&lt;p>tcpdump seul affiche TOUT le trafic de l&amp;rsquo;interface. C&amp;rsquo;est inutilisable sur un réseau actif: vous êtes noyé en dix secondes. La magie vient du &lt;strong>filtre BPF&lt;/strong> (Berkeley Packet Filter), un langage d&amp;rsquo;expression compilé à la volée dans le kernel pour ne capturer que ce qui matche:&lt;/p></description></item><item><title>Nemesis : détection d'un sniffeur réseau</title><link>https://blog.6admin.io/posts/nemesis-sniffeur/</link><pubDate>Fri, 06 Jun 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/nemesis-sniffeur/</guid><description>&lt;p>L&amp;rsquo;article précédent parlait de &lt;a href="https://blog.6admin.io/posts/nemesis-forgeur/">forger des paquets avec Nemesis&lt;/a>
. Celui-ci parle de la face opposée: détecter que quelqu&amp;rsquo;un sur votre réseau écoute ce qu&amp;rsquo;il ne devrait pas.&lt;/p>
&lt;h2 id="le-problème">Le problème&lt;/h2>
&lt;p>Une carte réseau en mode promiscuous accepte TOUTES les trames, pas seulement celles adressées à sa MAC. C&amp;rsquo;est ce qui permet à tcpdump et à Wireshark de fonctionner et c&amp;rsquo;est aussi ce qui permet à un sniffeur de lire le trafic qui ne lui est pas destiné. Sur un switch, ça ne devrait pas passer (le switch route par MAC), mais si quelqu&amp;rsquo;un a bricolé le switch ou s&amp;rsquo;il y a un hub quelque part, ça passe.&lt;/p></description></item><item><title>Nemesis : forgeur de paquets réseau</title><link>https://blog.6admin.io/posts/nemesis-forgeur/</link><pubDate>Mon, 02 Jun 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/nemesis-forgeur/</guid><description>&lt;p>Si vous avez lu &lt;a href="https://blog.6admin.io/posts/raw-sockets/">l&amp;rsquo;article sur les raw sockets&lt;/a>
, vous savez forger un SYN à la main en C: remplir les champs, calculer le checksum, envoyer. C&amp;rsquo;est éducatif et c&amp;rsquo;est aussi ce que fait Nemesis depuis la ligne de commande en une invocation. Nemesis est un forgeur de paquets générique: TCP, UDP, ICMP, RIP, OSPF, ARP, DNS. Chaque protocole a sa sous-commande, chaque champ de l&amp;rsquo;en-tête a son option.&lt;/p>
&lt;h2 id="lidée">L&amp;rsquo;idée&lt;/h2>
&lt;p>Un forgeur de paquets, c&amp;rsquo;est l&amp;rsquo;inverse de tcpdump: tcpdump lit ce qui passe, Nemesis fabrique ce qui passe. La combinaison des deux est le protocole de test réseau complet: Nemesis forge, tcpdump vérifie ce qui arrive réellement et vous savez ce que votre firewall, votre switch ou votre IDS comprend de ce que vous avez envoyé.&lt;/p></description></item><item><title>Raw Sockets : forger et sniffer des paquets en C</title><link>https://blog.6admin.io/posts/raw-sockets/</link><pubDate>Fri, 09 May 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/raw-sockets/</guid><description>&lt;p>Nous avons parlé de &lt;a href="https://blog.6admin.io/posts/sockets-c/">sockets TCP en C&lt;/a>
, sous le confort de &lt;code>SOCK_STREAM&lt;/code>. Passons sous le kernel: les &lt;strong>raw sockets&lt;/strong>, là où tcpdump et Nemesis vivent. Avertissement d&amp;rsquo;usage: &lt;code>SOCK_RAW&lt;/code> demande &lt;strong>root&lt;/strong>, la carte réseau en mode promiscuous et un peu d&amp;rsquo;éthique, le tout sans contrat avec personne.&lt;/p>
&lt;h2 id="sniffer-af_packet-et-le-mode-promiscuous">Sniffer: AF_PACKET et le mode promiscuous&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">int&lt;/span> s &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">socket&lt;/span>(AF_PACKET, SOCK_RAW, &lt;span style="color:#a6e22e">htons&lt;/span>(ETH_P_ALL));
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Deux lignes et vous recevez &lt;strong>tout&lt;/strong> ce qui traverse l&amp;rsquo;interface, en-têtes Ethernet comprises, à condition de passer l&amp;rsquo;interface en promiscuous:&lt;/p></description></item><item><title>Sockets : parler TCP en C, sans framework ni magie</title><link>https://blog.6admin.io/posts/sockets-c/</link><pubDate>Wed, 02 Apr 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/sockets-c/</guid><description>&lt;p>Après les &lt;a href="https://blog.6admin.io/posts/lkms/">LKMs&lt;/a>
 et les syscalls, restons en bas. Tout le réseau d&amp;rsquo;Unix tient dans quatre appels système, deux structures et un traité d&amp;rsquo;ordre des octets. Le reste, c&amp;rsquo;est de la mémoire et de la discipline. Petit mémo, Debian Etch oblige, gcc 4.1 et les man pages 2 et 7 pour seuls amis.&lt;/p>
&lt;h2 id="les-structures-dabord">Les structures, d&amp;rsquo;abord&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;sys/socket.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;netinet/in.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;arpa/inet.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">struct&lt;/span> sockaddr_in addr;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>addr.sin_family &lt;span style="color:#f92672">=&lt;/span> AF_INET; &lt;span style="color:#75715e">/* IPv4 */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>addr.sin_port &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">htons&lt;/span>(&lt;span style="color:#ae81ff">4444&lt;/span>); &lt;span style="color:#75715e">/* network byte order, TOUJOURS */&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>addr.sin_addr.s_addr &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#a6e22e">htonl&lt;/span>(INADDR_ANY); &lt;span style="color:#75715e">/* 0.0.0.0 */&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>htons&lt;/code> et &lt;code>htonl&lt;/code> ne sont pas décoratifs: le réseau parle &lt;strong>big-endian&lt;/strong>, votre x86 parle little-endian et le &lt;code>_getMac&lt;/code> du voisin qui oublie &lt;code>htons&lt;/code> obtient un serveur sur le port 45056. Le &lt;code>man 7 ip&lt;/code> explique tout ça mieux que moi.&lt;/p></description></item><item><title>Linux : introduction aux LKMs</title><link>https://blog.6admin.io/posts/lkms/</link><pubDate>Sun, 02 Mar 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/lkms/</guid><description>&lt;p>Le kernel Linux est monolithique: tout le code tourne dans le même espace d&amp;rsquo;adressage, en mode privilégié. Mais il accepte du code supplémentaire à chaud: les LKMs (Loadable Kernel Modules). Un LKM est un fichier &lt;code>.ko&lt;/code> compilé pour le kernel en cours, qui s&amp;rsquo;insère dans l&amp;rsquo;espace kernel et ajoute des fonctionnalités: drivers de périphériques, filesystems, network protocols, syscalls custom.&lt;/p>
&lt;h2 id="le-plus-petit-lkm">Le plus petit LKM&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-c" data-lang="c">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// hello.c
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;linux/module.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#include&lt;/span> &lt;span style="color:#75715e">&amp;lt;linux/kernel.h&amp;gt;&lt;/span>&lt;span style="color:#75715e">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">int&lt;/span> __init &lt;span style="color:#a6e22e">hello_init&lt;/span>(&lt;span style="color:#66d9ef">void&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printk&lt;/span>(KERN_INFO &lt;span style="color:#e6db74">&amp;#34;Hello from kernel space&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> &lt;span style="color:#ae81ff">0&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">static&lt;/span> &lt;span style="color:#66d9ef">void&lt;/span> __exit &lt;span style="color:#a6e22e">hello_exit&lt;/span>(&lt;span style="color:#66d9ef">void&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">printk&lt;/span>(KERN_INFO &lt;span style="color:#e6db74">&amp;#34;Goodbye from kernel space&lt;/span>&lt;span style="color:#ae81ff">\n&lt;/span>&lt;span style="color:#e6db74">&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">module_init&lt;/span>(hello_init);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">module_exit&lt;/span>(hello_exit);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e">MODULE_LICENSE&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;GPL&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le Makefile:&lt;/p></description></item><item><title>Les syscalls de Linux</title><link>https://blog.6admin.io/posts/linux-syscalls/</link><pubDate>Thu, 21 Feb 2008 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/linux-syscalls/</guid><description>&lt;p>Un programme en espace utilisateur ne fait rien directement: quand il lit un fichier, alloue de la mémoire ou envoie un paquet réseau, il demande au kernel de le faire. Cette demande est un syscall (system call): le programme exécute une instruction spéciale (int 0x80 ou sysenter sur x86), le kernel prend la main, exécute la demande et rend le contrôle au programme. C&amp;rsquo;est la frontière entre l&amp;rsquo;espace utilisateur (ring 3) et l&amp;rsquo;espace kernel (ring 0).&lt;/p></description></item><item><title>SSLH : ssh et https sur le même port</title><link>https://blog.6admin.io/posts/sslh/</link><pubDate>Sun, 16 Sep 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/sslh/</guid><description>&lt;p>Le problème de 2007, dans les boîtes à pare-feux nerveux: un seul port sortant, le 443, tout le reste est coupé. On veut son shell ssh et son https et le firewall ne discute pas. La réponse s&amp;rsquo;appelle sslh (v1.0, de Yves Rutschle): un petit daemon qui &lt;strong>écoute le 443 et délègue&lt;/strong> selon le premier paquet qui arrive: à sshd si le client parle protocole SSH, à httpsd sinon.&lt;/p>
&lt;h2 id="le-mécanisme">Le mécanisme&lt;/h2>
&lt;pre tabindex="0">&lt;code>client --443--&amp;gt; sslh --détection--&amp;gt; sshd:22
 \--&amp;gt; https:443
&lt;/code>&lt;/pre>&lt;p>Le protocole SSH annonce poliment son identité: le client envoie une bannière &lt;code>SSH-2.0-...&lt;/code> en clair dès l&amp;rsquo;ouverture. Le protocole SSL/TLS commence par un ClientHello dont le premier octet n&amp;rsquo;est pas un &amp;lsquo;S&amp;rsquo;. Deux sons de cloche, deux destinations:&lt;/p></description></item><item><title>PAM: limitez les ressources système</title><link>https://blog.6admin.io/posts/pam-limites-ressources/</link><pubDate>Fri, 04 May 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/pam-limites-ressources/</guid><description>&lt;p>PAM (Pluggable Authentication Modules) ne fait pas que de l&amp;rsquo;authentification: le module pam_limits plafonne les ressources système par utilisateur et par groupe. Sans limites, un process peut manger tout le RAM, tous les file descriptors, tous les process slots: c&amp;rsquo;est le fork bomb ou simplement un process qui leak de la mémoire.&lt;/p>
&lt;h2 id="le-fichier-limitsconf">Le fichier limits.conf&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># /etc/security/limits.conf&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># &amp;lt;domain&amp;gt; &amp;lt;type&amp;gt; &amp;lt;item&amp;gt; &amp;lt;value&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Plafonner les process pour tous les utilisateurs&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* soft nproc &lt;span style="color:#ae81ff">2048&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* hard nproc &lt;span style="color:#ae81ff">4096&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Plafonner le nombre de fichiers ouverts&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* soft nofile &lt;span style="color:#ae81ff">1024&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* hard nofile &lt;span style="color:#ae81ff">4096&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Plafonner la mémoire (en KB)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* soft as &lt;span style="color:#ae81ff">1048576&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>* hard as &lt;span style="color:#ae81ff">2097152&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Pour le groupe backup: plus de fichiers ouverts&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@backup soft nofile &lt;span style="color:#ae81ff">8192&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>@backup hard nofile &lt;span style="color:#ae81ff">16384&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Pour root: pas de limite&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root soft nproc unlimited
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>root hard nproc unlimited
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>&lt;code>soft&lt;/code> : la limite courante (le process peut la dépasser jusqu&amp;rsquo;à la hard limit)&lt;/li>
&lt;li>&lt;code>hard&lt;/code> : la limite maximum (le process ne peut pas la dépasser, même avec ulimit -Hn)&lt;/li>
&lt;li>&lt;code>*&lt;/code> : tous les utilisateurs&lt;/li>
&lt;li>&lt;code>@group&lt;/code> : un groupe Linux&lt;/li>
&lt;li>&lt;code>root&lt;/code> : l&amp;rsquo;utilisateur root&lt;/li>
&lt;/ul>
&lt;h2 id="les-items-de-limitsconf">Les items de limits.conf&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>item&lt;/th>
 &lt;th>ce qu&amp;rsquo;il plafonne&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;code>nproc&lt;/code>&lt;/td>
 &lt;td>le nombre de process&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>nofile&lt;/code>&lt;/td>
 &lt;td>le nombre de file descriptors ouverts&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>as&lt;/code>&lt;/td>
 &lt;td>la mémoire (address space) en KB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>rss&lt;/code>&lt;/td>
 &lt;td>la mémoire résidente en KB (ancien, remplacé par as)&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>cpu&lt;/code>&lt;/td>
 &lt;td>le temps CPU en minutes&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>maxlogins&lt;/code>&lt;/td>
 &lt;td>le nombre de sessions simultanées&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;code>core&lt;/code>&lt;/td>
 &lt;td>la taille des core dumps&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="vérifier-les-limites">Vérifier les limites&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ulimit -a
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-text" data-lang="text">&lt;span style="display:flex;">&lt;span>core file size (blocks, -c) 0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>data seg size (kbytes, -d) unlimited
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max nice (-e) 0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>file size (blocks, -f) unlimited
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pending signals (-i) 4096
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max locked memory (kbytes, -l) 32
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max memory size (kbytes, -m) unlimited
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>open files (-n) 1024
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>pipe size (512 bytes, -p) 8
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>POSIX message queues (bytes, -q) 8192
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>stack size (kbytes, -s) 8192
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cpu time (seconds, -t) unlimited
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>max user processes (-u) 2048
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>virtual memory (kbytes, -v) unlimited
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>ulimit -n&lt;/code> montre la limite de file descriptors: 1024 par défaut, ce qui est insuffisant pour un serveur web ou une base de données. 4096 ou 16384 est le minimum pour un serveur.&lt;/p></description></item><item><title>SSH: tunneling</title><link>https://blog.6admin.io/posts/ssh-tunneling/</link><pubDate>Wed, 04 Apr 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-tunneling/</guid><description>&lt;p>SSH ne transfère pas que des fichiers: il fait passer n&amp;rsquo;importe quel protocole TCP dans le canal chiffré. Une connexion VNC, une base MySQL, un serveur web interne, un SMB share: tout ce qui est TCP peut être tunnelé à travers SSH, sans VPN, sans configuration firewall, avec une seule commande.&lt;/p>
&lt;h2 id="le-tunnel-local-local-forward">Le tunnel local (local forward)&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh -L 3306:localhost:3306 user@serveur
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cette commande ouvre le port 3306 sur votre machine locale et tout ce qui y arrive part vers le port 3306 de &lt;code>serveur&lt;/code> (vu depuis &lt;code>serveur&lt;/code>). Une session SSH est ouverte, le tunnel fonctionne tant que la session dure.&lt;/p></description></item><item><title>MySQL : sauvegarde</title><link>https://blog.6admin.io/posts/mysql-sauvegarde/</link><pubDate>Tue, 06 Mar 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/mysql-sauvegarde/</guid><description>&lt;p>Un backup MySQL qui n&amp;rsquo;a jamais été restauré n&amp;rsquo;est pas un backup, c&amp;rsquo;est un espoir. L&amp;rsquo;article précédent parlait du &lt;a href="https://blog.6admin.io/posts/mysql-memento/">mémo&lt;/a>
, celui-ci parle de la sauvegarde automatisée et du test de restauration.&lt;/p>
&lt;h2 id="le-script-de-sauvegarde">Le script de sauvegarde&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">#!/bin/bash
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">&lt;/span>BACKUP_DIR&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;/backup/mysql&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DATE&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>date +%Y%m%d&lt;span style="color:#66d9ef">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>MYSQL_USER&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;backup_user&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>MYSQL_PASS&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;password&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mkdir -p &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$BACKUP_DIR&lt;span style="color:#e6db74">/&lt;/span>$DATE&lt;span style="color:#e6db74">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Lister les bases&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>DATABASES&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#66d9ef">$(&lt;/span>mysql -u $MYSQL_USER -p$MYSQL_PASS -e &lt;span style="color:#e6db74">&amp;#34;SHOW DATABASES&amp;#34;&lt;/span> | grep -v Database | grep -v information_schema | grep -v test&lt;span style="color:#66d9ef">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Dump de chaque base&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> db in $DATABASES; &lt;span style="color:#66d9ef">do&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> mysqldump -u $MYSQL_USER -p$MYSQL_PASS &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --add-drop-table &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> --single-transaction &lt;span style="color:#ae81ff">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#ae81ff">&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$db&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &amp;gt; &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$BACKUP_DIR&lt;span style="color:#e6db74">/&lt;/span>$DATE&lt;span style="color:#e6db74">/&lt;/span>$db&lt;span style="color:#e6db74">.sql&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> gzip &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$BACKUP_DIR&lt;span style="color:#e6db74">/&lt;/span>$DATE&lt;span style="color:#e6db74">/&lt;/span>$db&lt;span style="color:#e6db74">.sql&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Nettoyer les backups de plus de 7 jours&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>find &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$BACKUP_DIR&lt;span style="color:#e6db74">&amp;#34;&lt;/span> -type d -mtime +7 -exec rm -rf &lt;span style="color:#f92672">{}&lt;/span> &lt;span style="color:#ae81ff">\;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le &lt;code>--single-transaction&lt;/code> est crucial: il démarre une transaction InnoDB et dump dans un snapshot cohérent sans verrouiller les tables. Sans ce flag, le mysqldump verrouille chaque table et votre application en prod attend.&lt;/p></description></item><item><title>MySQL : perte des identifiants</title><link>https://blog.6admin.io/posts/mysql-mot-de-passe-root-perdu/</link><pubDate>Thu, 08 Feb 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/mysql-mot-de-passe-root-perdu/</guid><description>&lt;p>Le scénario: un serveur que vous n&amp;rsquo;avez pas touché depuis six mois, un MySQL dont personne ne se souvient du mot de passe root et un client qui demande pourquoi son site ne se connecte plus à la base. Le mot de passe root est perdu et il n&amp;rsquo;y a pas de fichier de config qui le traîne quelque part.&lt;/p>
&lt;h2 id="la-procédure">La procédure&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 1. Arrêter MySQL&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/etc/init.d/mysql stop
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 2. Démarrer sans les tables de privilèges&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysqld_safe --skip-grant-tables --skip-networking &amp;amp;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 3. Se connecter sans mot de passe&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysql -u root mysql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 4. Changer le mot de passe root&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>UPDATE user SET Password&lt;span style="color:#f92672">=&lt;/span>PASSWORD&lt;span style="color:#f92672">(&lt;/span>&lt;span style="color:#e6db74">&amp;#39;nouveaumdp&amp;#39;&lt;/span>&lt;span style="color:#f92672">)&lt;/span> WHERE User&lt;span style="color:#f92672">=&lt;/span>&lt;span style="color:#e6db74">&amp;#39;root&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>FLUSH PRIVILEGES;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>EXIT;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 5. Tuer mysqld_safe et redémarrer proprement&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>killall mysqld_safe mysqld
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>/etc/init.d/mysql start
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le flag &lt;code>--skip-grant-tables&lt;/code> désactive TOUTE authentification: n&amp;rsquo;importe qui peut se connecter en n&amp;rsquo;importe qui. Le flag &lt;code>--skip-networking&lt;/code> empêche les connexions TCP externes pendant la fenêtre de récupération (seul le socket local fonctionne). Les deux ensemble sont la procédure sûre.&lt;/p></description></item><item><title>MySQL : Mémento</title><link>https://blog.6admin.io/posts/mysql-memento/</link><pubDate>Fri, 26 Jan 2007 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/mysql-memento/</guid><description>&lt;p>Le mémo MySQL des commandes d&amp;rsquo;administration qui ne se tapent pas assez souvent pour les retenir, mais assez souvent pour savoir qu&amp;rsquo;elles existent.&lt;/p>
&lt;h2 id="connexion">Connexion&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>mysql -u root -p
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysql -u root -p -h localhost mon_schema
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysql -u root -p &amp;lt; dump.sql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="utilisateurs-et-droits">Utilisateurs et droits&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">CREATE&lt;/span> &lt;span style="color:#66d9ef">USER&lt;/span> &lt;span style="color:#e6db74">&amp;#39;user&amp;#39;&lt;/span>&lt;span style="color:#f92672">@&lt;/span>&lt;span style="color:#e6db74">&amp;#39;localhost&amp;#39;&lt;/span> IDENTIFIED &lt;span style="color:#66d9ef">BY&lt;/span> &lt;span style="color:#e6db74">&amp;#39;password&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GRANT&lt;/span> &lt;span style="color:#66d9ef">ALL&lt;/span> &lt;span style="color:#66d9ef">PRIVILEGES&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> mon_schema.&lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#66d9ef">TO&lt;/span> &lt;span style="color:#e6db74">&amp;#39;user&amp;#39;&lt;/span>&lt;span style="color:#f92672">@&lt;/span>&lt;span style="color:#e6db74">&amp;#39;localhost&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">GRANT&lt;/span> &lt;span style="color:#66d9ef">SELECT&lt;/span>, &lt;span style="color:#66d9ef">INSERT&lt;/span> &lt;span style="color:#66d9ef">ON&lt;/span> mon_schema.&lt;span style="color:#f92672">*&lt;/span> &lt;span style="color:#66d9ef">TO&lt;/span> &lt;span style="color:#e6db74">&amp;#39;readonly&amp;#39;&lt;/span>&lt;span style="color:#f92672">@&lt;/span>&lt;span style="color:#e6db74">&amp;#39;%&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>FLUSH &lt;span style="color:#66d9ef">PRIVILEGES&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> GRANTS &lt;span style="color:#66d9ef">FOR&lt;/span> &lt;span style="color:#e6db74">&amp;#39;user&amp;#39;&lt;/span>&lt;span style="color:#f92672">@&lt;/span>&lt;span style="color:#e6db74">&amp;#39;localhost&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">DROP&lt;/span> &lt;span style="color:#66d9ef">USER&lt;/span> &lt;span style="color:#e6db74">&amp;#39;user&amp;#39;&lt;/span>&lt;span style="color:#f92672">@&lt;/span>&lt;span style="color:#e6db74">&amp;#39;localhost&amp;#39;&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="backup-et-restore">Backup et restore&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Backup complet d&amp;#39;une base&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysqldump -u root -p mon_schema &amp;gt; backup.sql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Backup de toutes les bases&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysqldump -u root -p --all-databases &amp;gt; all.sql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Backup avec DROP TABLE&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysqldump -u root -p --add-drop-table mon_schema &amp;gt; backup.sql
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Restore&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>mysql -u root -p mon_schema &amp;lt; backup.sql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="les-requêtes-dadministration">Les requêtes d&amp;rsquo;administration&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> DATABASES;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> TABLES;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> &lt;span style="color:#66d9ef">TABLE&lt;/span> STATUS;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> PROCESSLIST;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> VARIABLES;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">SHOW&lt;/span> ENGINE INNODB STATUS;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">DESCRIBE&lt;/span> &lt;span style="color:#66d9ef">table_name&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="optimisation">Optimisation&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-sql" data-lang="sql">&lt;span style="display:flex;">&lt;span>OPTIMIZE &lt;span style="color:#66d9ef">TABLE&lt;/span> &lt;span style="color:#66d9ef">table_name&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">ANALYZE&lt;/span> &lt;span style="color:#66d9ef">TABLE&lt;/span> &lt;span style="color:#66d9ef">table_name&lt;/span>;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>REPAIR &lt;span style="color:#66d9ef">TABLE&lt;/span> &lt;span style="color:#66d9ef">table_name&lt;/span>;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="le-root-perdu">Le root perdu&lt;/h2>
&lt;p>Si vous avez perdu le mot de passe root, la procédure est:&lt;/p></description></item><item><title>Apache : quel bavard</title><link>https://blog.6admin.io/posts/apache-bavard/</link><pubDate>Thu, 21 Dec 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/apache-bavard/</guid><description>&lt;p>Apache parle. Beaucoup. Chaque requête génère une ligne dans le access_log, chaque erreur une ligne dans le error_log et le LogLevel contrôle le niveau de bavardage. Sur un serveur qui sert 100 000 pages par jour, le access_log pèse 50 Mo par jour et personne ne le lit.&lt;/p>
&lt;h2 id="le-loglevel">Le LogLevel&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-apache" data-lang="apache">&lt;span style="display:flex;">&lt;span>LogLevel &lt;span style="color:#66d9ef">warn&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Les niveaux, du plus bavard au plus silencieux: debug, info, notice, warn, error, crit, alert, emerg. Le &lt;code>warn&lt;/code> est le défaut et le bon: il logge les warnings (config, permissions) et les erreurs, mais pas chaque module qui démarre.&lt;/p></description></item><item><title>Apache : les limites du .htaccess</title><link>https://blog.6admin.io/posts/apache-htaccess/</link><pubDate>Tue, 28 Nov 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/apache-htaccess/</guid><description>&lt;p>Le .htaccess est pratique: un fichier par répertoire, pas de restart, le client mutualisé le gère tout seul. Sur un serveur dédié, il est un ralentisseur.&lt;/p>
&lt;p>Chaque requête HTTP fait lire Apache tous les .htaccess du chemin, depuis la racine. Pour /var/www/site/blog/article/, Apache lit /var/www/.htaccess, /var/www/site/.htaccess, /var/www/site/blog/.htaccess et /var/www/site/blog/article/.htaccess. Quatre reads disque par requête avant de servir la page.&lt;/p>
&lt;p>La solution: &lt;code>AllowOverride None&lt;/code> dans httpd.conf et tout ce qui était dans les .htaccess migre dans le VirtualHost. Apache ne lit plus les .htaccess et les directives sont compilées au démarrage.&lt;/p></description></item><item><title>Apache : désactiver l'option TRACE</title><link>https://blog.6admin.io/posts/apache-trace/</link><pubDate>Fri, 06 Oct 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/apache-trace/</guid><description>&lt;p>La méthode HTTP TRACE renvoie au client la requête exacte qu&amp;rsquo;il a envoyée, en écho. Conçu pour le debug, c&amp;rsquo;est une porte pour le XST (Cross-Site Tracing): un JavaScript sur une page compromise peut utiliser TRACE pour lire les cookies HttpOnly via les headers de la requête. IE6 le permettait, Firefox aussi.&lt;/p>
&lt;p>Le test:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ telnet mondomaine.fr &lt;span style="color:#ae81ff">80&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TRACE / HTTP/1.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Host: mondomaine.fr
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>HTTP/1.1 &lt;span style="color:#ae81ff">200&lt;/span> OK
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>TRACE / HTTP/1.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Host: mondomaine.fr
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>...
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Si vous voyez votre requête en écho, TRACE est activé.&lt;/p></description></item><item><title>SSH: authentification via clefs privé/publique</title><link>https://blog.6admin.io/posts/ssh-authentification-par-cles/</link><pubDate>Sun, 10 Sep 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-authentification-par-cles/</guid><description>&lt;p>L&amp;rsquo;authentification SSH par mot de passe fonctionne, mais elle est faible: le mot de passe se tape à chaque connexion, il peut être brute-forcé (fail2ban atténue mais ne résout pas) et il ne distingue pas &amp;ldquo;qui&amp;rdquo; de &amp;ldquo;quoi&amp;rdquo;. Les clefs SSH résolvent les trois: la clef privée prouve l&amp;rsquo;identité, la clef publique autorise l&amp;rsquo;accès et une fois configurée, plus de mot de passe.&lt;/p>
&lt;h2 id="générer-la-paire">Générer la paire&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>ssh-keygen -t rsa -b &lt;span style="color:#ae81ff">4096&lt;/span> -C &lt;span style="color:#e6db74">&amp;#34;commentaire&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Le &lt;code>-t rsa&lt;/code> génère une paire RSA, le &lt;code>-b 4096&lt;/code> définit la taille (2048 minimum, 4096 recommandé). Le &lt;code>-C&lt;/code> est un commentaire libre (l&amp;rsquo;email ou le hostname habituellement). Deux fichiers: &lt;code>id_rsa&lt;/code> (la clé privée, ne jamais sortir du poste) et &lt;code>id_rsa.pub&lt;/code> (la clé publique, à copier sur les serveurs).&lt;/p></description></item><item><title>Magic SysRq : la béquille du sysadmin</title><link>https://blog.6admin.io/posts/magic-sysrq/</link><pubDate>Fri, 11 Aug 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/magic-sysrq/</guid><description>&lt;p>Un serveur est figé. Plus de SSH, pas de console, pas de réponse au ping. Vous êtes en datacenter ou en SSH série et la seule option avant de tirer la prise est la touche &lt;strong>SysRq&lt;/strong>.&lt;/p>
&lt;h2 id="ce-que-cest">Ce que c&amp;rsquo;est&lt;/h2>
&lt;p>La touche SysRq (System Request) est interceptée directement par le kernel Linux, indépendamment de l&amp;rsquo;état du système. Le serveur peut être en kernel panic, le scheduler peut être bloqué: le kernel répond à SysRq tant que les interruptions matérielles fonctionnent. C&amp;rsquo;est la béquille d&amp;rsquo;urgence.&lt;/p></description></item><item><title>iodine : l'IP-over-DNS ou l'internet là où seul le DNS passe</title><link>https://blog.6admin.io/posts/iodine/</link><pubDate>Fri, 28 Jul 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/iodine/</guid><description>&lt;p>La scène est connue: l&amp;rsquo;hôtel d&amp;rsquo;une conférence, le hotspot du fast-food du coin, l&amp;rsquo;un de ces portails captifs qui éclosent partout depuis que le Wi-Fi est devenu un service. Vous vous connectez, une page s&amp;rsquo;ouvre, vous êtes censé payer ou saisir un code de chambre et tout ce qui n&amp;rsquo;est pas HTTP sur le port 80 tombe dans le vide. Pas de SSH, pas de SMTP direct, pas de VPN visible. Un filtre qui ne laisse passer que le web, donc presque rien.&lt;/p></description></item><item><title>dig : le Domain Information Groper ou l'art d'interroger un serveur de noms</title><link>https://blog.6admin.io/posts/dig/</link><pubDate>Mon, 26 Jun 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/dig/</guid><description>&lt;p>Pendant des années, mon outil DNS a été nslookup. L&amp;rsquo;habitude vient de loin, elle vient de Windows, elle vient du réflexe &amp;ldquo;je veux voir un enregistrement, je tape nslookup&amp;rdquo;. Puis un jour j&amp;rsquo;ai dû déboguer une zone qui se propageait mal entre un primaire et un secondaire et nslookup m&amp;rsquo;a répondu avec son interface interactive, son prompt &lt;code>&amp;gt;&lt;/code>, sa sortie qui change de forme selon la version de la bibliothèque résolveuse du système. J&amp;rsquo;ai installé le paquet dnsutils le soir même et nslookup a pris sa retraite.&lt;/p></description></item><item><title>Les liens : hard links et symbolic links et ce qui dépasse le chroot</title><link>https://blog.6admin.io/posts/liens-durs-symboliques/</link><pubDate>Mon, 05 Jun 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/liens-durs-symboliques/</guid><description>&lt;p>Linux connaît deux types de liens et la différence entre les deux est un sujet d&amp;rsquo;examen sysadmin ET un vecteur d&amp;rsquo;évasion de chroot. Le même concept qui explique la sauvegarde de vos données explique aussi comment sortir d&amp;rsquo;une jail.&lt;/p>
&lt;h2 id="le-hard-link">Le hard link&lt;/h2>
&lt;p>Un hard link est une entrée de répertoire qui pointe directement sur un inode. Le fichier et son lien sont deux noms pour le même contenu disque. Supprimer l&amp;rsquo;un ne supprime pas l&amp;rsquo;autre (l&amp;rsquo;inode reste tant que son compteur de liens est supérieur à zéro).&lt;/p></description></item><item><title>SSH: fish comme un poisson</title><link>https://blog.6admin.io/posts/ssh-fish-protocole/</link><pubDate>Wed, 10 May 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/ssh-fish-protocole/</guid><description>&lt;p>Le protocole fish (Files transferred over SHell) est une invention de KDE: il encapsule des commandes shell dans une connexion SSH pour explorer et transférer des fichiers comme si c&amp;rsquo;était un montage réseau. Konqueror le fait nativement: tapez &lt;code>fish://user@serveur/home/user&lt;/code> dans la barre d&amp;rsquo;adresse et le filesystem distant apparaît dans le navigateur de fichiers.&lt;/p>
&lt;h2 id="ce-que-fish-fait">Ce que fish fait&lt;/h2>
&lt;p>Fish n&amp;rsquo;est pas un montage (pas de FUSE, pas de kernel module): c&amp;rsquo;est le client qui envoie des commandes shell (&lt;code>ls&lt;/code>, &lt;code>cat&lt;/code>, &lt;code>cp&lt;/code>) via SSH et parse le résultat. Le serveur n&amp;rsquo;a besoin de rien de spécial: juste un shell POSIX. Le client construit les commandes, les envoie sur le canal SSH et présente le résultat comme un filesystem.&lt;/p></description></item><item><title>Root or not root</title><link>https://blog.6admin.io/posts/root-or-not-root/</link><pubDate>Thu, 13 Apr 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/root-or-not-root/</guid><description>&lt;p>La question: qui a le droit d&amp;rsquo;être root sur un serveur partagé? La réponse n&amp;rsquo;est pas technique, elle est politique. Mais les outils techniques existent et ils ne se valent pas.&lt;/p>
&lt;h2 id="su">su&lt;/h2>
&lt;p>&lt;code>su&lt;/code> demande le mot de passe root. Celui qui le connaît devient root. Point. Tous les admins partagent le même mot de passe et quand quelqu&amp;rsquo;un part de l&amp;rsquo;équipe, il faut le changer (et le redistribuer). L&amp;rsquo;historique de ce qui a été fait en root se limite à &lt;code>last&lt;/code> et à la mémoire de ceux qui étaient là.&lt;/p></description></item><item><title>Bash : Mémento</title><link>https://blog.6admin.io/posts/bash-memento/</link><pubDate>Fri, 10 Mar 2006 00:00:00 +0000</pubDate><guid>https://blog.6admin.io/posts/bash-memento/</guid><description>&lt;p>Un mémo, pas un tutoriel. Les lignes bash qu&amp;rsquo;on cherche à chaque fois parce qu&amp;rsquo;on ne les tape pas assez souvent pour les retenir, mais assez souvent pour savoir qu&amp;rsquo;elles existent.&lt;/p>
&lt;h2 id="les-substitutions">Les substitutions&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Remplacer la première occurrence&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var/ancien/nouveau&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Remplacer toutes les occurrences&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var//ancien/nouveau&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Supprimer le plus court pattern depuis le début&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var#pattern&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Supprimer le plus court pattern depuis la fin&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var%pattern&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Longueur de la chaîne&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${#&lt;/span>var&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Valeur par défaut si vide&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var&lt;span style="color:#66d9ef">:-&lt;/span>defaut&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Assigner si vide&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var:=defaut&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Erreur si vide&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#e6db74">${&lt;/span>var:?message&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="les-tableaux">Les tableaux&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>declare -a tab
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tab&lt;span style="color:#f92672">[&lt;/span>0&lt;span style="color:#f92672">]=&lt;/span>&lt;span style="color:#e6db74">&amp;#34;premier&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>tab&lt;span style="color:#f92672">+=(&lt;/span>deuxieme troisieme&lt;span style="color:#f92672">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">${&lt;/span>tab[@]&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">${#&lt;/span>tab[@]&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">${&lt;/span>tab[1]&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># Les index disponibles&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">${&lt;/span>!tab[@]&lt;span style="color:#e6db74">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="les-redirections">Les redirections&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>cmd &amp;gt; fichier &lt;span style="color:#75715e"># stdout vers fichier (écrase)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd &amp;gt;&amp;gt; fichier &lt;span style="color:#75715e"># stdout vers fichier (ajoute)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd 2&amp;gt; fichier &lt;span style="color:#75715e"># stderr vers fichier&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd &amp;amp;&amp;gt; fichier &lt;span style="color:#75715e"># stdout + stderr vers fichier&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#75715e"># stderr vers stdout&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd &amp;gt; /dev/null 2&amp;gt;&amp;amp;&lt;span style="color:#ae81ff">1&lt;/span> &lt;span style="color:#75715e"># silence complet&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cmd &amp;lt; fichier &lt;span style="color:#75715e"># stdin depuis fichier&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="les-boucles">Les boucles&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> i in &lt;span style="color:#66d9ef">$(&lt;/span>ls&lt;span style="color:#66d9ef">)&lt;/span>; &lt;span style="color:#66d9ef">do&lt;/span> echo &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$i&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; &lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">for&lt;/span> i in &lt;span style="color:#f92672">{&lt;/span>1..10&lt;span style="color:#f92672">}&lt;/span>; &lt;span style="color:#66d9ef">do&lt;/span> echo &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$i&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; &lt;span style="color:#66d9ef">done&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">while&lt;/span> read ligne; &lt;span style="color:#66d9ef">do&lt;/span> echo &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$ligne&lt;span style="color:#e6db74">&amp;#34;&lt;/span>; &lt;span style="color:#66d9ef">done&lt;/span> &amp;lt; fichier
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="les-tests">Les tests&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> -f fichier &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># existe et est un fichier régulier&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> -d rep &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># existe et est un répertoire&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> -s fichier &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># existe et non vide&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> -x fichier &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># exécutable&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$a&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">==&lt;/span> &lt;span style="color:#e6db74">&amp;#34;&lt;/span>$b&lt;span style="color:#e6db74">&amp;#34;&lt;/span> &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># égalité de chaînes&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> $n -eq $m &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># égalité de nombres&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#f92672">[[&lt;/span> $n -lt $m &lt;span style="color:#f92672">]]&lt;/span> &lt;span style="color:#75715e"># less than&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>C&amp;rsquo;est tout. Le reste s&amp;rsquo;apprend avec &lt;code>man bash&lt;/code> (section EXPANSION), mais ces lignes-ci sont celles qu&amp;rsquo;on colle dans un fichier et qu&amp;rsquo;on source.&lt;/p></description></item></channel></rss>