Dans l'architecture réseau classique de Linux, l'ensemble des interfaces réseau partagent une unique table de routage globale : la base d'informations de transfert principale (FIB). Pour un poste de travail standard ou un serveur doté d'une seule connexion réseau, cette structure unifiée remplit son rôle sans difficulté.

Cependant, sur les passerelles de réseaux privés virtuels (VPN), les routeurs multi-WAN et les infrastructures mutualisées (multi-tenants), ce modèle centralisé engendre des vulnérabilités critiques. Lorsque plusieurs interfaces partagent le même domaine de routage, des conflits de passerelle par défaut surviennent régulièrement. Si une interface de tunnel chiffré s'interrompt brutalement, le système risque de basculer instantanément sur l'interface physique (Wi-Fi ou Ethernet), exposant des paquets non chiffrés et des requêtes DNS aux intercepteurs du réseau local.

Afin de juguler ces fuites, les ingénieurs réseau recouraient traditionnellement aux espaces de noms réseau de Linux (netns). Bien que les namespaces procurent une isolation totale en dupliquant la totalité de la pile réseau (sockets, boucles locales, règles netfilter et sysctl), ils imposent une surcharge de calcul pénalisante. Le transfert de données entre namespaces requiert des paires d'interfaces virtuelles veth ou des programmes eBPF, provoquant des copies redondantes de structures sk_buff et limitant le débit sur les liens à 40GbE et 100GbE.

Pour atteindre un niveau d'isolation rigoureux sans subir la lourdeur des namespaces, le noyau Linux a intégré le concept de Virtual Routing and Forwarding (VRF), propulsé par le sous-système Layer 3 Master Device (l3mdev).

+--------------------------------------------------------------------------+
|          ARCHITECTURE DE ROUTAGE MULTI-TABLES LINUX VRF ET L3MDEV        |
+--------------------------------------------------------------------------+
|                                                                          |
|   +------------------------------------------------------------------+   |
|   |                     APPLICATIONS ESPACE UTILISATEUR              |   |
|   |                                                                  |   |
|   |   +-------------------+                     +----------------+   |   |
|   |   | Client sécurisé   |                     | Démon d'admin  |   |   |
|   |   |  (ip vrf exec)    |                     | (SSH / métriques|  |   |
|   +---+---------+---------+---------------------+--------+-------+---+   |
|                 | SO_BINDTODEVICE                        |               |
|                 v (vrf-secure)                           v               |
|   +------------------------------------------------------------------+   |
|   |                        PILE RÉSEAU DU NOYAU LINUX                |   |
|   |                                                                  |   |
|   |   [ Maître VRF: vrf-secure ]            [ VRF par défaut / main ]|   |
|   |   [ Table FIB ID: 100      ]            [ Table FIB ID: 254     ]    |
|   |                                                                  |   |
|   |   Recherche FIB (Isolée):               Recherche FIB (Globale): |   |
|   |   default dev riceguard0                default via 192.168.1.1  |   |
|   |   10.8.0.0/24 dev riceguard0            192.168.1.0/24 dev eth0  |   |
|   |             |                                    |               |   |
|   |             |                                    |               |   |
|   |   +---------v---------+                +---------v---------+     |   |
|   |   | Interface asservie|                | Interface physique|     |   |
|   |   | riceguard0        |                | eth0 (WAN / Wi-Fi)|     |   |
|   |   +---------+---------+                +---------+---------+     |   |
|   +-------------|------------------------------------|---------------+   |
|                 v                                    v                   |
|     +-----------------------+            +-----------------------+       |
|     | Tunnel VPN chiffré    |            | Accès réseau physique |       |
|     | (Zéro fuite de données|            | (Aucune fuite de flux)|       |
|     +-----------------------+            +-----------------------+       |
|                                                                          |
+--------------------------------------------------------------------------+

Fonctionnement interne de Linux VRF et du sous-système l3mdev

Dans Linux, une VRF est implémentée sous forme de pilote de périphérique réseau virtuel (drivers/net/vrf.c). Contrairement aux espaces de noms réseau, un périphérique maître VRF ne duplique pas l'ensemble de la pile protocolaire : il encapsule un identifiant de table de routage FIB spécifique.

Les interfaces réseau (physiques ou virtuelles) sont associées comme esclaves au périphérique VRF. Dès lors, l'infrastructure l3mdev prend le relais lors des décisions de routage :

1. Confinement du routage entrant et sortant

Lorsqu'un paquet IP parvient sur une interface asservie à une VRF, le noyau fait appel au pilote l3mdev. Ce dernier redirige la consultation de la table FIB vers la table dédiée à cette VRF (par exemple la table 100).

Les routes de la table 100 étant hermétiques vis-à-vis de la table principale (table 254), toute fuite inter-domaines est prévenue :

  • Filtrage de chemin inverse (rp_filter) : la validation de l'adresse IP source s'effectue strictement dans le cadre de la table VRF, bloquant les tentatives d'usurpation.
  • Confinement du trafic sortant : les processus affectés à la VRF ne peuvent emprunter les routes par défaut de la table globale.

2. Association des sockets au domaine VRF

Les processus du système peuvent lier leur trafic réseau à une VRF donnée à l'aide de trois méthodes éprouvées :

  1. Option de socket SO_BINDTODEVICE : le descripteur de socket est directement associé au nom du maître VRF (vrf-secure). Tous les appels de lecture et d'écriture respectent les routes de cette VRF.
  2. Cgroups v2 et commande ip vrf exec : grâce au point d'ancrage BPF cgroup (cgroup/sock_create), un administrateur peut exécuter un arbre complet de processus dans une VRF sans modifier leur code source.
  3. Option SO_BINDTOIFINDEX : une méthode optimisée permettant d'associer un socket via l'index de l'interface sans verrouillage lourd.
+--------------------------------------------------------------------------+
|            COMPARAISON TECHNIQUE : VRF CONTRE NETWORK NAMESPACES         |
+--------------------------------------------------------------------------+
| Propriété architecturale | VRF (l3mdev)           | Network Namespaces    |
+--------------------------+------------------------+-----------------------+
| Séparation du routage    | Table FIB dédiée       | Clone complet du stack|
| Empreinte mémoire        | Négligeable (<10 Ko)   | Significative (>1 Mo) |
| Transfert inter-domaines | Zero-copy dans le noyau| Surcharge veth et BPF |
| Espace des sockets       | Partagé sur l'hôte     | Totalement scindé     |
| Gestion des paramètres   | Centralisée            | Duplication requise   |
| Débit maximal            | Débit physique 40G-100G| Pertes sous forte charge|
+--------------------------------------------------------------------------+

Prise en charge des démons d'écoute avec tcp_l3mdev_accept

L'un des défis récurrents du routage partitionné concerne les services d'écoute. Dans une configuration standard, si un résolveur DNS local (comme Unbound) ou un serveur SSH écoute sur 0.0.0.0:53, il n'appartient qu'au domaine global. Les interfaces situées dans d'autres VRF ne peuvent dialoguer avec lui car leurs requêtes FIB sont cloisonnées.

Pour éviter de multiplier les instances de serveurs pour chaque groupe de clients, le noyau Linux met à disposition des commutateurs sysctl spécialisés :

# Permet aux démons TCP globaux de recevoir les connexions de toutes les VRF
sysctl -w net.ipv4.tcp_l3mdev_accept=1

# Permet aux démons UDP globaux de traiter les paquets de toutes les VRF
sysctl -w net.ipv4.udp_l3mdev_accept=1

Lorsque tcp_l3mdev_accept est actif, un paquet TCP SYN reçu sur une interface de VRF concorde avec le socket d'écoute global. Dès que le noyau engendre le socket enfant, il l'associe automatiquement au maître VRF de l'interface réceptrice. Tous les paquets de réponse sont réexpédiés via la table de cette même VRF, éliminant tout risque d'asymétrie de routage.

Guide pratique : déploiement d'une passerelle VPN hermétique

La configuration d'une VRF sur un nœud Linux s'opère via les commandes de la suite iproute2 :

Étape 1 : Créer le maître VRF

Création d'un périphérique virtuel vrf-vpn attaché à la table de routage 100 :

# Création du maître VRF lié à la table 100
ip link add dev vrf-vpn type vrf table 100

# Activation de l'interface VRF
ip link set dev vrf-vpn up

Étape 2 : Asservir les interfaces du tunnel et des clients

Rattachement de l'interface du tunnel (riceguard0) et du réseau local (vlan20) au maître VRF :

# Association des interfaces à vrf-vpn
ip link set dev riceguard0 master vrf-vpn
ip link set dev vlan20 master vrf-vpn

# Démarrage des interfaces
ip link set dev riceguard0 up
ip link set dev vlan20 up

Étape 3 : Renseigner la table de routage de la VRF

Configuration des routes au sein de la table 100 :

# Sous-réseau du tunnel VPN
ip route add 10.8.0.0/24 dev riceguard0 table 100

# Sous-réseau local des clients
ip route add 192.168.20.0/24 dev vlan20 table 100

# Passerelle par défaut orientée exclusivement dans le tunnel
ip route add default dev riceguard0 table 100

Étape 4 : Vérification et diagnostic

Vérification de la séparation des tables et tests de connectivité :

# Inspection de la table 100
ip route show table 100

# Test d'émission ICMP restreint à la VRF
ip vrf exec vrf-vpn ping -c 3 10.8.0.1

# Contrôle de l'intégrité de la table principale
ip route show table main

Si le tunnel riceguard0 se déconnecte, les flux de la table 100 perdent leur route par défaut et sont immédiatement détruits par le noyau. L'interface physique eth0 résidant dans la table globale, aucune trame cliente ne peut s'échapper en clair.

Synergies avec le moteur RiceGuard et VPNRice

Sur les infrastructures en production de VPNRice, le moteur de tunnel au niveau du noyau RiceGuard interagit directement avec les VRF Linux et l3mdev pour garantir un très haut niveau de sécurité :

  1. Suppression définitive des fuites DNS : les systèmes d'exploitation modernes ont tendance à envoyer des requêtes DNS simultanées sur toutes les interfaces disponibles. En enfermant l'interface RiceGuard et le résolveur dans une VRF étanche, les requêtes ne peuvent jamais transiter sur le réseau Wi-Fi local.
  2. Routage multi-WAN à haute cadence : les concentrateurs supportant des milliers de connexions parallèles isolent chaque segment d'utilisateurs sans subir de ralentissement de débit.
  3. Cloisonnement du plan d'administration : les ports de maintenance (SSH, collecteurs de télémétrie) sont cantonnés dans une VRF de gestion hors-bande, inaccessible aux flux circulant dans les tunnels utilisateurs.

Recommandations d'exploitation

Lors du déploiement en production, quelques bonnes pratiques s'imposent :

  • Activation du filtrage strict : fixer net.ipv4.conf.all.rp_filter=1 pour immuniser le système contre l'usurpation d'adresses entre domaines.
  • Règles de pare-feu homogènes : utiliser les critères iifname ou oifname ciblant le périphérique maître VRF dans nftables pour centraliser le contrôle d'accès.
  • Dimensionnement du conntrack : les VRF partageant la table globale de suivi des connexions de la machine, le paramètre nf_conntrack_max doit être calibré en conséquence.

L'alliance de Linux VRF et du sous-système l3mdev constitue un standard d'ingénierie exemplaire pour concevoir des passerelles VPN alliant étanchéité absolue et performance maximale.