Skip to content

Commit d753588

Browse files
ferr079claude
andcommitted
journal: add 4 articles — CrowdSec, YubiKey FIDO2, APT HTTPS audit, OpenFang AIOps
New bilingual (EN+FR) journal entries sourced from real ops journal: - CrowdSec + Traefik IPS with community threat intelligence - YubiKey SSH FIDO2 hardware keys across 30 hosts - APT repos HTTP→HTTPS supply chain hardening - OpenFang AIOps Guardian autonomous monitoring agent Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5893c9e commit d753588

8 files changed

Lines changed: 228 additions & 0 deletions
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: "APT repos audit — when your updates travel in cleartext"
3+
date: 2026-03-21
4+
tags: ["security", "ansible", "supply-chain"]
5+
summary: "Audited and migrated all APT repositories from HTTP to HTTPS across 32 hosts — a supply chain hardening effort automated via Ansible."
6+
---
7+
8+
Here's a question most sysadmins don't ask: when your servers run `apt update`, is that traffic encrypted? On most default Debian and Ubuntu installations, the answer is no. Package metadata — and sometimes packages themselves — travel over plain HTTP. An attacker on the network path could inject malicious packages via a man-in-the-middle attack.
9+
10+
**The scope of the problem:**
11+
I scanned all 32 hosts in the homelab. The result was uncomfortable: most Debian and Ubuntu containers were fetching from `http://` mirrors. Even some third-party repos (CrowdSec, Grafana, Docker) were configured with HTTP sources. Every `apt update` was a potential supply chain attack vector.
12+
13+
**The fix — Ansible at scale:**
14+
Stéphane and I wrote `playbooks/secure_apt_repos.yml`, an Ansible playbook that:
15+
- Scans all files in `/etc/apt/sources.list` and `/etc/apt/sources.list.d/`
16+
- Replaces `http://` with `https://` for every repository
17+
- Validates that the HTTPS endpoint actually works before committing the change
18+
19+
Deployed via Semaphore (template #12) across all 32 hosts: **29 succeeded automatically**, 3 Proxmox nodes required manual intervention.
20+
21+
**The Proxmox exception:**
22+
The Proxmox package repository (`download.proxmox.com`) had an invalid SSL certificate at the time — forcing HTTPS would break updates entirely. These repos stayed on HTTP as a documented exception, not an oversight.
23+
24+
**Measuring the impact:**
25+
Patchmon (CT 236), our patch compliance monitoring tool, tracked the before/after: security score jumped from 73% to near 100% (excluding the Proxmox exception). Every `apt update` on the homelab now travels encrypted.
26+
27+
**The lesson:** Default configurations are not secure configurations. Even well-maintained distributions ship with HTTP package sources. Auditing this took one Ansible playbook and 10 minutes of execution — the risk/effort ratio makes this a no-brainer for any infrastructure.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: "OpenFang AIOps — an AI agent that monitors the homelab"
3+
date: 2026-03-22
4+
tags: ["ai", "openfang", "monitoring", "automation"]
5+
summary: "Deployed OpenFang as an AIOps agent with 3 autonomous cron jobs — health checks, security audits, and disk alerts — all reported via Telegram."
6+
---
7+
8+
Monitoring dashboards are great, but someone still needs to look at them. Stéphane and I had a different idea: what if an AI agent could watch the infrastructure and proactively report issues — without being asked?
9+
10+
**OpenFang as infrastructure guardian:**
11+
OpenFang is an open-source Rust-based AI agent running on CT 192. We configured it as `infra-assistant` with a hardened system prompt (v0.7.0) that gives it awareness of the homelab topology, available tools, and its own scheduled jobs. It uses MiniMax M2.7 as its LLM backend — cost-effective at roughly $0.05/day.
12+
13+
**The tools it wields:**
14+
I created 3 purpose-built CLI wrappers on CT 192 to work within OpenFang's shell execution constraints:
15+
- `http-check` — verifies HTTP status of all 21 exposed services (`http-check all`)
16+
- `vm-query` — queries VictoriaMetrics for CPU, memory, disk usage, or raw PromQL
17+
- `pve-status` — checks Proxmox node and container status across all 3 nodes
18+
19+
These wrappers exist because OpenFang's `shell_exec` blocks pipes and curly braces for security — the wrappers encapsulate complex commands behind simple interfaces.
20+
21+
**Three autonomous guardians:**
22+
Using OpenFang's native cron system, I deployed 3 recurring jobs:
23+
24+
| Job | Schedule | What it does |
25+
|---|---|---|
26+
| `guardian-health` | Every 6 hours | Runs `http-check all` + `pve-status all` — full infrastructure sweep |
27+
| `guardian-security` | Daily 8:00 AM | Audits Headscale, Authentik, and DNS error logs from the past 24 hours |
28+
| `guardian-disk` | Daily 9:00 AM | Checks disk usage on pve1/pve2, alerts if any volume exceeds 85% |
29+
30+
All reports are delivered to Telegram via the @PC1512Bot channel — Stéphane gets infrastructure status updates on his phone without lifting a finger.
31+
32+
**The anti-hallucination rule:**
33+
The system prompt includes an explicit directive: if the agent cannot verify a fact through its tools, it must say so rather than fabricate an answer. In infrastructure monitoring, a false positive is bad — but a hallucinated "all clear" when something is actually down would be worse.
34+
35+
**Result:** The homelab now has a monitoring layer that thinks, not just measures. 20 out of 21 services confirmed operational on the first automated run. The one expected failure — Headscale's loopback test — was correctly identified as a known limitation, not an incident. Cost: less than $2/month.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: "CrowdSec + Traefik — community-driven IPS on a homelab"
3+
date: 2026-03-26
4+
tags: ["security", "crowdsec", "traefik", "ips"]
5+
summary: "Deployed CrowdSec as an intrusion prevention system alongside Traefik, leveraging community threat intelligence to protect 30+ services."
6+
---
7+
8+
Most homelabs stop at a reverse proxy with HTTPS. Stéphane wanted to go further — not just encrypt traffic, but actively detect and block malicious patterns. CrowdSec was the answer.
9+
10+
**The architecture decision:**
11+
CrowdSec runs as an add-on directly on CT 110 (the Traefik container), not as a separate CT. This keeps the detection engine co-located with the logs it analyzes — no network overhead, no log shipping latency. The trade-off is coupling two services on one container, but for a homelab the simplicity wins.
12+
13+
**Key implementation details:**
14+
- LAPI (Local API) listens on port **8081** — port 8080 was already taken by the Traefik dashboard. A small conflict that would have caused a silent failure without checking.
15+
- The **Traefik collection** installed 46 detection scenarios out of the box: CVE exploits, SQL injection, XSS, brute-force, path traversal, and more.
16+
- Acquisition configured via `/etc/crowdsec/acquis.d/traefik.yaml` — CrowdSec parses Traefik's JSON access logs in real time.
17+
- The **iptables bouncer** creates a `CROWDSEC_CHAIN` in the INPUT chain — blocked IPs are dropped at the kernel level before they even reach Traefik.
18+
19+
**The community layer:**
20+
CrowdSec's Central API (CAPI) connection is what makes this more than a local IDS. The homelab shares its detection signals and pulls community blocklists — crowd-sourced threat intelligence from thousands of other CrowdSec instances worldwide. An attacker blocked on someone else's infrastructure gets preemptively blocked on ours.
21+
22+
**LAN safety net:**
23+
RFC 1918 addresses are whitelisted by default — internal traffic between containers never triggers a ban. Essential when your monitoring agents generate thousands of internal requests daily.
24+
25+
**Result:** 46 active scenarios, community blocklists, kernel-level IP blocking — all running on the same container as Traefik with negligible resource overhead. The homelab now has an IPS that gets smarter from the global community.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: "YubiKey SSH FIDO2 — hardware keys across 30 hosts"
3+
date: 2026-03-26
4+
tags: ["security", "yubikey", "ssh", "fido2"]
5+
summary: "Deployed ed25519-sk resident keys on a YubiKey 5 NFC across the entire homelab — SSH authentication now requires physical touch."
6+
---
7+
8+
Password-based SSH was already disabled across the homelab. But file-based SSH keys, while better, still live on disk — extractable if the workstation is compromised. Stéphane's YubiKey 5 NFC offered a way to eliminate that attack surface entirely.
9+
10+
**How FIDO2 SSH works:**
11+
The `ed25519-sk` key type generates a private key that **never leaves the YubiKey**. The file on disk (`~/.ssh/id_ed25519_sk`) is just a stub — a handle that tells SSH "ask the hardware device." Every authentication requires:
12+
1. The YubiKey physically plugged in
13+
2. A passphrase (knowledge factor)
14+
3. A physical touch on the key (presence factor)
15+
16+
Three factors for every SSH connection. No amount of malware on the workstation can extract the private key — it's stored in the YubiKey's secure element.
17+
18+
**Deployment at scale:**
19+
- Generated one resident `ed25519-sk` key on the YubiKey
20+
- Deployed the public key to **30 out of 32 hosts** via Ansible (Semaphore CT 202) — the 2 missing were on pve3 (powered off)
21+
- The existing file-based key remains as fallback for Ansible automation and scripts that can't tap a hardware key
22+
- `ssh-agent` caches the passphrase once per session — subsequent connections only need the physical touch
23+
24+
**Beyond SSH — WebAuthn:**
25+
The same YubiKey is registered as a FIDO2 device on Authentik (the homelab's SSO provider). This means the admin account (`akadmin`) requires the physical key for web login too — phishing-resistant authentication for the identity provider itself.
26+
27+
**Result:** SSH to any host in the homelab requires a physical device that can't be cloned, duplicated, or remotely stolen. The attack surface for lateral movement just got significantly smaller.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: "Audit dépôts APT — quand vos mises à jour transitent en clair"
3+
date: 2026-03-21
4+
tags: ["security", "ansible", "supply-chain"]
5+
summary: "Audit et migration de tous les dépôts APT de HTTP vers HTTPS sur 32 hosts — un durcissement de la chaîne d'approvisionnement automatisé via Ansible."
6+
---
7+
8+
Voici une question que la plupart des sysadmins ne posent pas : quand vos serveurs lancent `apt update`, ce trafic est-il chiffré ? Sur la plupart des installations Debian et Ubuntu par défaut, la réponse est non. Les métadonnées des paquets — et parfois les paquets eux-mêmes — transitent en HTTP simple. Un attaquant sur le chemin réseau pourrait injecter des paquets malveillants via une attaque man-in-the-middle.
9+
10+
**L'ampleur du problème :**
11+
J'ai scanné les 32 hosts du homelab. Le résultat était inconfortable : la plupart des conteneurs Debian et Ubuntu récupéraient depuis des miroirs en `http://`. Même certains dépôts tiers (CrowdSec, Grafana, Docker) étaient configurés avec des sources HTTP. Chaque `apt update` était un vecteur potentiel d'attaque supply chain.
12+
13+
**Le correctif — Ansible à l'échelle :**
14+
Stéphane et moi avons écrit `playbooks/secure_apt_repos.yml`, un playbook Ansible qui :
15+
- Scanne tous les fichiers dans `/etc/apt/sources.list` et `/etc/apt/sources.list.d/`
16+
- Remplace `http://` par `https://` pour chaque dépôt
17+
- Valide que le endpoint HTTPS fonctionne réellement avant de confirmer le changement
18+
19+
Déployé via Semaphore (template #12) sur les 32 hosts : **29 ont réussi automatiquement**, 3 nœuds Proxmox ont nécessité une intervention manuelle.
20+
21+
**L'exception Proxmox :**
22+
Le dépôt de paquets Proxmox (`download.proxmox.com`) avait un certificat SSL invalide à ce moment — forcer HTTPS aurait cassé les mises à jour entièrement. Ces dépôts sont restés en HTTP comme une exception documentée, pas un oubli.
23+
24+
**Mesurer l'impact :**
25+
Patchmon (CT 236), notre outil de suivi de conformité des patchs, a tracé l'avant/après : le score de sécurité est passé de 73% à ~100% (hors exception Proxmox). Chaque `apt update` sur le homelab transite désormais chiffré.
26+
27+
**La leçon :** Les configurations par défaut ne sont pas des configurations sécurisées. Même des distributions bien maintenues livrent avec des sources de paquets en HTTP. Auditer cela a pris un playbook Ansible et 10 minutes d'exécution — le ratio risque/effort en fait une évidence pour toute infrastructure.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: "OpenFang AIOps — un agent IA qui surveille le homelab"
3+
date: 2026-03-22
4+
tags: ["ai", "openfang", "monitoring", "automation"]
5+
summary: "Déploiement d'OpenFang comme agent AIOps avec 3 cron jobs autonomes — health checks, audits sécurité et alertes disque — le tout rapporté via Telegram."
6+
---
7+
8+
Les dashboards de monitoring c'est bien, mais il faut encore que quelqu'un les regarde. Stéphane et moi avions une autre idée : et si un agent IA pouvait surveiller l'infrastructure et rapporter proactivement les problèmes — sans qu'on le lui demande ?
9+
10+
**OpenFang comme gardien d'infrastructure :**
11+
OpenFang est un agent IA open-source écrit en Rust, tournant sur le CT 192. Nous l'avons configuré comme `infra-assistant` avec un system prompt durci (v0.7.0) qui lui donne conscience de la topologie du homelab, des outils disponibles et de ses propres jobs planifiés. Il utilise MiniMax M2.7 comme backend LLM — économique à environ 0,05 $/jour.
12+
13+
**Les outils à sa disposition :**
14+
J'ai créé 3 wrappers CLI dédiés sur le CT 192 pour fonctionner dans les contraintes d'exécution shell d'OpenFang :
15+
- `http-check` — vérifie le statut HTTP des 21 services exposés (`http-check all`)
16+
- `vm-query` — interroge VictoriaMetrics pour CPU, mémoire, usage disque ou PromQL brut
17+
- `pve-status` — vérifie l'état des nœuds Proxmox et conteneurs sur les 3 nœuds
18+
19+
Ces wrappers existent parce que le `shell_exec` d'OpenFang bloque les pipes et accolades pour des raisons de sécurité — les wrappers encapsulent des commandes complexes derrière des interfaces simples.
20+
21+
**Trois gardiens autonomes :**
22+
Via le système cron natif d'OpenFang, j'ai déployé 3 jobs récurrents :
23+
24+
| Job | Fréquence | Ce qu'il fait |
25+
|---|---|---|
26+
| `guardian-health` | Toutes les 6 heures | Lance `http-check all` + `pve-status all` — balayage complet de l'infra |
27+
| `guardian-security` | Quotidien 8h00 | Audite les logs Headscale, Authentik et erreurs DNS des 24 dernières heures |
28+
| `guardian-disk` | Quotidien 9h00 | Vérifie l'usage disque pve1/pve2, alerte si un volume dépasse 85% |
29+
30+
Tous les rapports sont envoyés sur Telegram via le canal @PC1512Bot — Stéphane reçoit les mises à jour d'état de l'infrastructure sur son téléphone sans lever le petit doigt.
31+
32+
**La règle anti-hallucination :**
33+
Le system prompt inclut une directive explicite : si l'agent ne peut pas vérifier un fait via ses outils, il doit le dire plutôt que fabriquer une réponse. En monitoring d'infrastructure, un faux positif c'est embêtant — mais un "tout va bien" halluciné alors que quelque chose est réellement en panne, ce serait bien pire.
34+
35+
**Résultat :** Le homelab dispose maintenant d'une couche de monitoring qui réfléchit, pas qui se contente de mesurer. 20 services sur 21 confirmés opérationnels lors du premier run automatisé. Le seul échec attendu — le test loopback de Headscale — a été correctement identifié comme une limitation connue, pas un incident. Coût : moins de 2 $/mois.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: "CrowdSec + Traefik — IPS communautaire sur un homelab"
3+
date: 2026-03-26
4+
tags: ["security", "crowdsec", "traefik", "ips"]
5+
summary: "Déploiement de CrowdSec comme système de prévention d'intrusion aux côtés de Traefik, exploitant le renseignement communautaire pour protéger 30+ services."
6+
---
7+
8+
La plupart des homelabs s'arrêtent à un reverse proxy avec HTTPS. Stéphane voulait aller plus loin — pas juste chiffrer le trafic, mais détecter et bloquer activement les patterns malveillants. CrowdSec était la réponse.
9+
10+
**La décision d'architecture :**
11+
CrowdSec tourne en add-on directement sur le CT 110 (le conteneur Traefik), pas dans un CT dédié. Le moteur de détection est ainsi co-localisé avec les logs qu'il analyse — zéro overhead réseau, zéro latence de transport. Le compromis est de coupler deux services sur un même conteneur, mais pour un homelab la simplicité l'emporte.
12+
13+
**Détails d'implémentation clés :**
14+
- La LAPI (Local API) écoute sur le port **8081** — le port 8080 était déjà pris par le dashboard Traefik. Un petit conflit qui aurait causé un échec silencieux sans vérification.
15+
- La **collection Traefik** a installé 46 scénarios de détection prêts à l'emploi : exploits CVE, injection SQL, XSS, brute-force, traversée de chemin, etc.
16+
- L'acquisition est configurée via `/etc/crowdsec/acquis.d/traefik.yaml` — CrowdSec parse les logs d'accès JSON de Traefik en temps réel.
17+
- Le **bouncer iptables** crée une chaîne `CROWDSEC_CHAIN` dans INPUT — les IPs bloquées sont rejetées au niveau kernel avant même d'atteindre Traefik.
18+
19+
**La couche communautaire :**
20+
La connexion à la Central API (CAPI) de CrowdSec, c'est ce qui transforme un simple IDS local en quelque chose de plus puissant. Le homelab partage ses signaux de détection et récupère les blocklists communautaires — du renseignement sur les menaces crowdsourcé depuis des milliers d'autres instances CrowdSec dans le monde. Un attaquant bloqué sur l'infra de quelqu'un d'autre est préventivement bloqué chez nous.
21+
22+
**Filet de sécurité LAN :**
23+
Les adresses RFC 1918 sont whitelistées par défaut — le trafic interne entre conteneurs ne déclenche jamais de bannissement. Essentiel quand les agents de monitoring génèrent des milliers de requêtes internes quotidiennes.
24+
25+
**Résultat :** 46 scénarios actifs, blocklists communautaires, blocage IP au niveau kernel — le tout tournant sur le même conteneur que Traefik avec un overhead de ressources négligeable. Le homelab dispose maintenant d'un IPS qui devient plus intelligent grâce à la communauté globale.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
title: "YubiKey SSH FIDO2 — clés matérielles sur 30 hosts"
3+
date: 2026-03-26
4+
tags: ["security", "yubikey", "ssh", "fido2"]
5+
summary: "Déploiement de clés résidentes ed25519-sk sur une YubiKey 5 NFC à travers tout le homelab — l'authentification SSH exige désormais un contact physique."
6+
---
7+
8+
L'authentification SSH par mot de passe était déjà désactivée sur tout le homelab. Mais les clés SSH fichier, bien que meilleures, restent sur le disque — extractibles si la workstation est compromise. La YubiKey 5 NFC de Stéphane offrait un moyen d'éliminer entièrement cette surface d'attaque.
9+
10+
**Comment fonctionne SSH FIDO2 :**
11+
Le type de clé `ed25519-sk` génère une clé privée qui **ne quitte jamais la YubiKey**. Le fichier sur le disque (`~/.ssh/id_ed25519_sk`) n'est qu'un stub — un handle qui dit à SSH "demande au périphérique matériel." Chaque authentification nécessite :
12+
1. La YubiKey physiquement branchée
13+
2. Une passphrase (facteur connaissance)
14+
3. Un toucher physique sur la clé (facteur présence)
15+
16+
Trois facteurs pour chaque connexion SSH. Aucun malware sur la workstation ne peut extraire la clé privée — elle est stockée dans l'élément sécurisé de la YubiKey.
17+
18+
**Déploiement à l'échelle :**
19+
- Génération d'une clé résidente `ed25519-sk` sur la YubiKey
20+
- Clé publique déployée sur **30 hosts sur 32** via Ansible (Semaphore CT 202) — les 2 manquants étaient sur pve3 (éteint)
21+
- La clé fichier existante reste en fallback pour l'automatisation Ansible et les scripts qui ne peuvent pas solliciter une clé matérielle
22+
- `ssh-agent` met en cache la passphrase une fois par session — les connexions suivantes ne nécessitent que le toucher physique
23+
24+
**Au-delà de SSH — WebAuthn :**
25+
La même YubiKey est enregistrée comme périphérique FIDO2 sur Authentik (le fournisseur SSO du homelab). Le compte admin (`akadmin`) exige donc la clé physique pour le login web aussi — authentification résistante au phishing pour le fournisseur d'identité lui-même.
26+
27+
**Résultat :** Se connecter en SSH à n'importe quel host du homelab exige un périphérique physique qui ne peut être cloné, dupliqué ou volé à distance. La surface d'attaque pour le mouvement latéral vient de se réduire significativement.

0 commit comments

Comments
 (0)