Filtrage réseau en couches : pare-feu hyperviseur, systèmes Linux et postes Windows
Mise en place d'un filtrage à trois niveaux — hyperviseur, systèmes Linux, postes Windows — avec politique de refus par défaut, groupes de règles réutilisables, et arbitrages documentés sur les machines volontairement laissées hors périmètre.
Le contexte
Une infrastructure de neuf machines fonctionnant sur un réseau plat, sans aucun filtrage. Chaque machine était joignable sur l'ensemble de ses ports ouverts par n'importe quelle autre machine du réseau domestique — y compris les appareils que je ne contrôle pas.
Aucun pare-feu périmétrique dédié n'était en place : le projet OPNsense initialement prévu a été abandonné au profit d'une approche que je pouvais maîtriser et défendre entièrement.
L'objectif
Appliquer un principe simple : refuser par défaut, autoriser explicitement. Et l'appliquer à trois niveaux distincts plutôt qu'à un seul, pour que la compromission d'une machine ne donne pas accès aux autres.
Avec une exigence de méthode : chaque règle devait avoir une raison écrite, et chaque machine laissée sans filtrage devait avoir une justification aussi solide que celles qui en avaient.
L'architecture du filtrage
Trois couches, chacune traitant ce que les autres ne peuvent pas traiter.
| Niveau | Outil | Ce qu'il protège |
|---|---|---|
| Hyperviseur | Pare-feu Proxmox | L'accès d'administration et les machines virtuelles, avant même qu'elles reçoivent le trafic |
| Serveurs Linux | UFW + fail2ban | Les services exposés, avec bannissement des tentatives répétées |
| Postes et serveurs Windows | Pare-feu Windows par GPO | Les services applicatifs, de façon centralisée |
Pourquoi plusieurs couches ? Parce qu'elles n'échouent pas de la même manière. Le pare-feu de l'hyperviseur filtre avant que le paquet n'atteigne le système invité — il protège même une machine compromise. Le pare-feu du système filtre ce qui vient de la machine elle-même. Aucun des deux ne remplace l'autre.
Ce que j'ai réalisé
Le pare-feu de l'hyperviseur
Le pare-feu Proxmox s'applique en cascade sur trois niveaux : centre de données, nœud, puis chaque machine virtuelle. Il faut qu'il soit actif au niveau supérieur pour que les niveaux inférieurs prennent effet. Par défaut, le nœud est activé mais le centre de données ne l'est pas — ce qui fait qu'aucun filtrage n'a lieu tant qu'on ne l'active pas explicitement. Un point sur lequel beaucoup se trompent, et qui donne une fausse impression de protection.
Plutôt que d'écrire les règles machine par machine, j'ai créé un groupe de sécurité nommé, appliqué ensuite là où il est nécessaire. Modifier une règle la propage partout où le groupe est utilisé.
C'est exactement la logique des groupes de domaine local du modèle AGDLP : on met le droit sur le groupe, jamais sur l'objet.
Les règles autorisent l'interface d'administration depuis le réseau local et depuis la plage du VPN, et SSH depuis le réseau local — ce dernier n'étant pas utilisé au quotidien mais conservé comme canal de secours. Un administrateur ne se prive jamais de son second accès.
La politique d'entrée est ensuite passée en refus par défaut au niveau du centre de données.
La bascule — la seule manœuvre réellement risquée
Activer le pare-feu d'un hyperviseur qu'on administre uniquement par son interface web, c'est risquer de se verrouiller dehors : le shell intégré passe par la même connexion. Une erreur de règle, et il ne reste aucun moyen d'intervenir à distance.
Le protocole appliqué :
- écrire toutes les règles avant toute activation, et les relire ;
- vérifier le port SSH réel du système plutôt que supposer le port par défaut ;
- garder une session ouverte en parallèle pendant la manipulation ;
- connaître la commande de désactivation en ligne de commande ;
- se placer physiquement devant la machine au moment de basculer.
Le dernier point est celui qui compte. En cas de coupure, c'est trois minutes de correction en local au lieu d'une soirée perdue.
Les serveurs Linux
UFW en refus par défaut sur les serveurs de supervision et de déploiement, avec SSH restreint au réseau local sur un port non standard, et fail2ban configuré pour surveiller ce port réel — une erreur classique consiste à laisser fail2ban surveiller le port 22 alors que le service a été déplacé, ce qui le rend totalement inopérant.
Les postes Windows
Filtrage géré par stratégie de groupe, pas machine par machine. La règle la plus significative concerne l'agent de supervision : le port 10050 n'est ouvert qu'à une seule adresse source, celle du serveur Zabbix.
L'installeur de l'agent créait sa propre règle, plus permissive. Elle a été explicitement désactivée à l'installation pour que la seule règle en vigueur soit celle de la GPO.
Les arbitrages assumés
Deux machines ont été volontairement laissées sans pare-feu local. Ce sont des décisions, pas des oublis.
Le contrôleur de domaine. Active Directory expose de très nombreux services sur une plage de ports dynamique étendue, et c'est la machine dont dépend tout le reste : authentification, DNS, stratégies de groupe. Une erreur de filtrage à cet endroit provoque une panne générale du domaine. Le rapport entre le risque introduit et le gain de sécurité ne m'a pas paru favorable dans ce contexte.
En production, je traiterais ce besoin autrement : en isolant le contrôleur dans un segment réseau dédié, avec un filtrage au niveau du routage plutôt qu'au niveau de la machine.
Le serveur de déploiement. Pour une raison technique précise : une machine qui démarre par le réseau n'a pas encore d'adresse IP, ses demandes partent de 0.0.0.0, qui n'appartient à aucun sous-réseau. Aucune règle filtrée par adresse source ne peut donc les reconnaître. Filtrer ce serveur imposerait d'ouvrir les ports concernés sans restriction d'origine, ce qui vide la mesure de son sens.
Je l'ai constaté en pratique : mes premières règles UFW bloquaient les démarrages réseau pour exactement cette raison.
La validation
Le filtrage a été vérifié par le comportement observable, pas par relecture de la configuration.
Depuis un poste client : ouverture d'un partage autorisé, qui s'affiche normalement ; tentative de connexion sur un port non autorisé, qui échoue ; ping qui passe — ce qui confirme que la machine répond et que c'est bien le filtrage qui agit, et non une machine éteinte.
Le journal du pare-feu a été exploité en ligne de commande pour extraire les paquets traités avec le nom de la règle qui les a pris en charge. On y lit le groupe de règles, l'horodatage, la source, la destination et le port — la preuve que la règle attendue est bien celle qui s'applique.
Le résultat
Un filtrage effectif à trois niveaux, avec une politique de refus par défaut sur l'hyperviseur, des règles centralisées et réutilisables, et deux exclusions documentées avec leur raisonnement et la façon dont je les traiterais différemment en production.
Ce que j'en retiens
La partie technique d'un pare-feu est la plus simple. Le travail réel consiste à décider ce qu'on n'autorise pas, et à accepter que certaines machines soient de mauvaises candidates au filtrage local.
Un pare-feu configuré sans avoir identifié les flux légitimes ne protège pas : il casse. Et une règle qu'on ne sait pas justifier finit toujours par être élargie « pour que ça marche », jusqu'à ce que le filtrage ne filtre plus rien.