
Présentation
Mon homelab est l'infrastructure qui fait tourner mes autres projets : le SIEM de mon projet d'études, le serveur de l'assistant Hermes, un réseau Minecraft pour des amis et des services du quotidien. Il repose sur deux serveurs Dell, un PowerEdge R630 et un PowerEdge R320, réunis en cluster Proxmox VE. Un pfSense virtualisé le sépare du réseau de la box, et chaque intervention est consignée dans un dépôt git.
Deux serveurs inégaux, un quorum assumé
Les données vivent sur ZFS, en paires miroir désignées par leur by-id : un pool par nœud pour les machines, un grand miroir sur le R320 pour les sauvegardes. J'ai doublé la RAM du R630, ajouté une troisième paire au pool avec zpool add et relevé le plafond du cache ARC, que l'installeur ne réajuste pas.
Sans troisième machine pour un QDevice, j'ai donné deux voix au R630, le nœud principal, dans corosync.conf, puis arrêté corosync sur le R320 pour vérifier que le principal reste quorate seul. J'ai créé le cluster avant le pare-feu, avec le câble direct entre les serveurs comme premier lien, pour ne pas changer l'adresse des nœuds ensuite. Avant d'installer Proxmox sur le R320, j'ai mis à jour son BIOS et son iDRAC.
Un seul câble vers la box
La box n'est reliée qu'au R630, sur un pont sans adresse hôte qui sert de WAN au pfSense. Le LAN du pfSense est un pont VLAN-aware, prolongé jusqu'au R320 par le câble direct. En service, les nœuds n'ont aucune adresse sur le réseau de la box : je les administre par un VPN WireGuard. Chaque nœud garde un port non câblé, avec une adresse fixe et sans passerelle, pour reprendre la main si le pfSense tombe. J'ai d'abord activé ignore_routes_with_linkdown : sans lui, Linux aurait gardé la route d'un port sans câble.
Derrière le pfSense, chaque zone est un VLAN : services et IA, jeux, labo, TP de Master. Les règles suivent partout le même modèle, testé avec un conteneur Alpine jetable : DNS vers le pfSense, blocage journalisé d'un alias qui regroupe tous les réseaux privés, puis internet. Le DNS passe par Pi-hole et un Unbound récursif ; le pfSense ne transmet qu'à Pi-hole depuis que j'ai coupé l'option qui réinjectait les DNS de la box et contournait le blocage.
Une partie du pfSense se configure par des scripts PHP qui appellent son API interne. La plupart sont idempotents : ils n'écrivent la configuration qu'en cas de changement.
$voulu = ["format" => "rfc3164", "ipproto" => "ipv4"];
$change = false;
foreach ($voulu as $cle => $val) {
if (config_get_path("syslog/$cle") !== $val) {
config_set_path("syslog/$cle", $val);
$change = true;
}
}
if ($change) {
write_config("SIEM : journaux distants");
system_syslogd_start();
}Des services qui repartent seuls
Ma règle : un conteneur LXC si possible, une VM seulement quand il le faut (FreeBSD pour le pfSense, Windows et cibles volontairement vulnérables du labo, SIEM). Chaque conteneur de service est cloné depuis un modèle Debian non privilégié, étiqueté selon sa zone et décrit dans une note Proxmox.
L'ordre de démarrage lance le pfSense en premier avec un délai, puis le DNS, la supervision, les jeux et l'IA. Les serveurs Minecraft ont un drop-in systemd Restart=always : après un kill -9, le lobby est revenu seul. Au redémarrage complet après l'ajout de RAM, deux services du conteneur de l'IA sont partis avant que le DNS ou leur adresse soient prêts, puis ont abandonné. Ils réessaient désormais toutes les 5 secondes.
Sauvegarder, restaurer, être prévenu
Chaque nuit, sauvegarde-config.sh archive la configuration des deux nœuds, dont /etc/pve, vers le R320. Des jobs vzdump sauvegardent le pfSense chaque semaine et les conteneurs importants chaque jour. J'ai testé la restauration du pfSense dans une VM isolée, cartes débranchées et adresses MAC neuves, puis supprimé la copie.
Prometheus et Grafana suivent les nœuds. Les notifications Proxmox partent vers ntfy, comme les alertes d'Alertmanager sur la partition système : 80 %, 90 %, et plein sous 24 h d'après predict_linear. J'ai remplacé Homepage par un tableau de bord sur mesure : son collector.py lit node_exporter toutes les 2 secondes et l'API Proxmox toutes les 10 secondes, avec TLS vérifié par l'autorité du cluster, puis écrit data.json de façon atomique.
Ce que le journal m'a appris
J'administre le homelab avec Claude Code comme opérateur : il exécute en SSH, je décide et j'autorise les changements à risque. Le skill homelab-doc impose de vérifier l'état par commande, puis de mettre à jour fiches, plan réseau et journal avant de clore une tâche. generer-site.py en tire une page locale autonome, sans fichiers de clés ni de secrets.
Un handshake WireGuard ne prouve pas l'accès : il manquait une route de retour sur un nœud. Un journal matériel plein n'enregistre plus rien, donc l'absence d'erreur ne prouvait rien. Derrière la DMZ de la box, le trafic d'internet peut arriver avec une adresse locale : j'ai retiré des redirections qui exposaient le tableau de bord, et je teste désormais chaque ouverture depuis l'extérieur. Restent à faire une copie des sauvegardes hors site et un vrai troisième avis pour le quorum.