Le canal auxiliaire discret : comment la qualité de service (QoS) trahit l'utilisateur

Lorsque les applications réseau émettent des paquets IP, le système d'exploitation classe le trafic à l'aide du point de code de services différenciés (DSCP - Differentiated Services Code Point), un champ de 6 bits situé dans l'octet Type of Service (ToS) d'IPv4 ou Traffic Class d'IPv6, défini par la RFC 2474. Les flux de téléphonie vocale sur IP (VoIP) appliquent la classe d'acheminement accéléré (DSCP EF, code binaire 101110, valeur 46), les visioconférences en haute définition recourent aux classes d'acheminement assuré (comme AF41, valeur 34), et les jeux en ligne requièrent des indicateurs de faible latence.

Dans une architecture de sécurité rigoureuse, l'encapsulation chiffrée (WireGuard, IPsec ESP ou OpenVPN) vise à masquer complètement les habitudes de communication de l'usager. Pour un observateur extérieur, la charge utile chiffrée se présente comme un flux binaire aléatoire.

Pourtant, de nombreuses configurations de tunnel souffrent d'une faiblesse conceptuelle : elles recopient machinalement l'octet ToS/DSCP de l'en-tête interne dans l'en-tête IP externe d'encapsulation.

Lorsqu'un fournisseur d'accès à Internet (FAI) ou un observateur sur un réseau local examine les paquets externes d'un flux VPN chiffré, il ne peut évidemment pas déchiffrer le contenu. Toutefois, comme les bits DSCP externes reflètent fidèlement les priorités internes, l'analyste obtient instantanément une classification précise des activités en cours :

  • Le FAI identifie les moments exacts de début, de fin et la cadence des appels vocaux chiffrés.
  • Les routeurs de transit différencient sans peine les téléchargements de fichiers en arrière-plan (Best Effort 000000) des sessions de terminal SSH interactives (DSCP AF11).
  • Les passerelles d'inspection approfondie (DPI) croisent la taille des trames, les salves de paquets et les étiquettes DSCP pour dresser un profil applicatif détaillé.
Tunnel vulnérable (Modèle Uniform) :
[ Paquet interne : VoIP (DSCP 46 / EF) ] ---> [ Encapsulation ] ---> [ IP externe (DSCP 46 / EF) ]
                                                                                |
                                                                                v
                                                               Le FAI détecte l'appel vocal !

Tunnel protégé (Modèle Pipe selon RFC 2983) :
[ Paquet interne : VoIP (DSCP 46 / EF) ] ---> [ Encapsulation ] ---> [ IP externe (DSCP 0 / Best Effort) ]
                                                                                |
                                                                                v
                                                               Le FAI ne voit qu'un flux uniforme

Modèles de tunnel DiffServ selon la RFC 2983 : Uniform et Pipe

Afin de normaliser l'interaction entre les services différenciés et les couches d'encapsulation, l'IETF a publié la spécification RFC 2983 (« Differentiated Services and Tunnels »). Celle-ci formalise trois architectures distinctes :

1. Le modèle Uniform (Uniform Model)

Dans le modèle Uniform, le réseau considère le tunnel comme une extension continue d'un domaine de routage unique :

  • À l'entrée du tunnel, l'en-tête externe reprend directement la valeur DSCP de l'en-tête interne.
  • Les routeurs intermédiaires planifient leurs files d'attente d'après cette priorité répliquée.
  • À la sortie, toute altération apportée au champ DSCP par les réseaux de transit est répercutée dans l'en-tête interne d'origine.

Bien que le modèle Uniform assure la continuité de la QoS de bout en bout dans des environnements de confiance, il s'avère préjudiciable sur les réseaux publics, car il dévoile les caractéristiques des applications à des tiers non habilités.

2. Le modèle Pipe (Pipe Model)

Dans le modèle Pipe, le tunnel constitue un circuit de transport dédié doté d'une politique de QoS totalement indépendante :

  • Au nœud d'entrée, l'en-tête externe reçoit une valeur DSCP définie par la politique du transporteur de tunnel, faisant abstraction de la valeur interne.
  • Le champ DSCP externe est habituellement fixé sur Best Effort (0x00) ou sur une classe de transit uniforme.
  • Les modifications appliquées par les réseaux intermédiaires n'affectent que l'acheminement externe.
  • Lors de la décapsulation, l'en-tête externe est supprimé et le paquet interne retrouve son marquage DSCP d'origine sans la moindre altération.

Le modèle Pipe établit ainsi un cloisonnement strict des métadonnées : l'observateur ne perçoit qu'une classe de trafic uniforme.

3. Le modèle Short-Pipe (Short-Pipe Model)

Le modèle Short-Pipe opère de la même manière que le modèle Pipe sur le segment de transit. La divergence intervient au nœud de sortie : l'interface de décapsulation gère ses files d'attente locales selon la classe de transport externe avant d'acheminer le paquet restauré vers son destinataire final.

Vulnérabilités du modèle Uniform sur les réseaux commerciaux

Les solutions VPN grand public et les passerelles professionnelles d'accès distant transitent par des infrastructures ouvertes. L'adoption du modèle Uniform y introduit des risques notables :

Vecteur de risque Conséquence du modèle Uniform Protection du modèle Strict Pipe
Profilage du trafic Élevé : le FAI isole la voix, la vidéo et les données Nul : flux externe rigoureusement identique (Best Effort)
Bridage sélectif Le FAI ralentit spécifiquement les flux vidéo (AF4x) Le trafic est traité équitablement comme de l'UDP standard
Canaux auxiliaires Détection de frappe au clavier par étiquettes interactives Les variations temporelles sont lissées par l'en-tête commun
Altération externe Les routeurs de transit polluent la QoS interne Toutes les modifications externes sont écartées à la sortie

Lorsque les intermédiaires peuvent lire les étiquettes DSCP externes, ils peuvent instaurer des politiques de limitation ciblées sans avoir besoin de compromettre la cryptographie employée.

Découpler la notification de congestion (ECN) du nettoyage DSCP

Une maladresse courante lors de la neutralisation des fuites de métadonnées consiste à remettre l'octet ToS complet à zéro. Cet octet de 8 bits se subdivise en réalité en deux sous-ensembles fonctionnels :

 0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
|          DSCP         |  ECN  |
+---+---+---+---+---+---+---+---+
     Point de code         Avis de congestion
     (Bits 0 à 5)             (Bits 6 et 7)
  1. DSCP (Bits 0 à 5) : Détermine la priorité du paquet. Cette zone doit être masquée (000000) sur l'en-tête externe afin d'empêcher les fuites de métadonnées.
  2. ECN (Bits 6 et 7) : Gère la notification explicite de congestion selon les RFC 3168 et RFC 6040. Ces bits permettent aux routeurs d'alerter les extrémités d'une saturation imminente des mémoires tampons sans provoquer de pertes de paquets (00 = Incompatible, 01 = ECT(1), 10 = ECT(0), 11 = CE - Congestion subie).

Si un administrateur remet à zéro l'octet complet (ToS = 0x00), il désactive involontairement le protocole ECN. Les algorithmes de gestion active des files d'attente (AQM tels que CoDel, FQ-CoDel ou CAKE) dépendent d'ECN pour juguler le bufferbloat. Sans ces signaux, les routeurs intermédiaires n'ont d'autre choix que d'éliminer des paquets, induisant des à-coups de latence et une baisse du débit.

La RFC 6040 formule des directives rigoureuses pour l'encapsulation d'ECN :

  • À l'encapsulation, les bits ECN externes doivent refléter les capacités du paquet interne.
  • À la décapsulation, si l'en-tête externe a reçu un avertissement de congestion (11), ce signal doit impérativement être fusionné dans l'en-tête interne.

Une passerelle sécurisée doit par conséquent nettoyer le champ DSCP (bits 0 à 5) tout en conservant et propageant minutieusement les indicateurs ECN (bits 6 et 7).

Configuration dans le noyau Linux : XFRM, WireGuard et Netfilter Mangle

1. Gestion avec Linux IP-XFRM (IPsec)

Dans les déploiements IPsec sous Linux pilotés par l'outil ip xfrm, la structure d'état du noyau (struct xfrm_state) reconduit par défaut le champ ToS interne vers l'extérieur. Il est possible de fixer la valeur de l'en-tête externe via iproute2 :

# Consultation des états XFRM enregistrés
ip xfrm state show

# Définition d'un champ ToS externe fixe pour satisfaire le modèle Pipe RFC 2983 :
ip xfrm state update src 203.0.113.10 dst 198.51.100.20 \
    proto esp spi 0x1000 reqid 1 mode tunnel \
    tos 0x00

2. Implémentation dans le pilote WireGuard

Dans le module officiel WireGuard pour Linux (drivers/net/wireguard/), la procédure d'émission prend en charge l'en-tête UDP externe dans le fichier send.c :

/* Extrait schématique du traitement de l'en-tête WireGuard */
static void wg_send_packet(struct wg_device *wg, struct sk_buff *skb)
{
    ...
    /* WireGuard conserve l'ECN tout en remettant le DSCP externe à zéro */
    u8 ds = ip_tunnel_ecn_encap(0, ip_hdr(skb), skb);
    ...
}

WireGuard applique nativement une déclinaison protectrice du modèle Pipe : les paquets UDP externes reçoivent une valeur DSCP nulle tout en combinant correctement les bits ECN. Cependant, certaines interfaces en espace utilisateur sur d'autres systèmes d'exploitation peuvent écraser cette précaution en héritant des options par défaut des sockets hôtes.

Normalisation du trafic sortant avec eBPF et Nftables

Pour assurer une isolation irréprochable des métadonnées sur l'ensemble des protocoles de tunnel, des règles de filtrage peuvent être mises en place à la sortie de la machine.

1. Filtrage via Nftables

La règle nftables suivante cible les datagrammes UDP du tunnel (port 51820) pour forcer les 6 bits supérieurs du champ ToS à zéro tout en préservant les 2 bits inférieurs d'ECN :

table inet vpn_sanitizer {
    chain egress_filter {
        type filter hook postrouting priority mangle; policy accept;

        # Assigne cs0 au DSCP externe, conserve les bits 6-7 (masque ECN 0x03)
        udp dport 51820 ip dscp set cs0
        udp dport 51820 ip6 dscp set cs0
    }
}

2. Normalisation par programme eBPF (tc-bpf)

Sur les passerelles gérant d'importants volumes de données, un programme eBPF attaché au point d'ancrage de sortie clsact réécrit les en-têtes directement dans la mémoire tampon du noyau avec un impact CPU minime :

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>

SEC("classifier/egress_dscp")
int sanitize_outer_dscp(struct __sk_buff *skb)
{
    void *data = (void *)(long)skb->data;
    void *data_end = (void *)(long)skb->data_end;
    struct ethhdr *eth = data;

    if ((void *)(eth + 1) > data_end)
        return BPF_OK;

    if (eth->h_proto == __constant_htons(ETH_P_IP)) {
        struct iphdr *iph = (void *)(eth + 1);
        if ((void *)(iph + 1) > data_end)
            return BPF_OK;

        /* Vérifie s'il s'agit d'un flux UDP destiné au port du tunnel */
        if (iph->protocol == IPPROTO_UDP) {
            /* Maintient ECN (masque 0x03) et efface les 6 bits DSCP */
            __u8 old_tos = iph->tos;
            __u8 new_tos = old_tos & 0x03;

            if (old_tos != new_tos) {
                bpf_l3_csum_replace(skb, offsetof(struct iphdr, check),
                                    old_tos, new_tos, sizeof(new_tos));
                iph->tos = new_tos;
            }
        }
    }
    return BPF_OK;
}

char _license[] SEC("license") = "GPL";

Mise en œuvre de l'isolation Pipe dans le protocole RiceGuard

VPNRice place la préservation des métadonnées au centre de son architecture logicielle. Par le biais du protocole RiceGuard, les postes clients et les passerelles appliquent le modèle Strict Pipe selon les principes de la RFC 2983 :

[ Trafic Applicatif Utilisateur ]
  - Visioconférence : DSCP AF41 (0x22)
  - Jeux en ligne :   DSCP CS2  (0x10)
  - Navigation web :  DSCP CS0  (0x00)
             |
             v
[ Moteur d'Encapsulation Client RiceGuard ]
  1. Sauvegarde des états DSCP et ECN internes en mémoire de session.
  2. Chiffrement complet de la charge utile via ChaCha20-Poly1305.
  3. Construction de l'en-tête IP/UDP externe avec DSCP fixé à CS0 (0x00).
  4. Calcul des bits ECN externes selon la RFC 6040.
             |
             v
[ Réseau de Transit Public / FAI ]
  - Aspect extérieur : flux UDP totalement uniforme et indifférencié.
  - Impossibilité d'isoler la voix, la vidéo ou les flux interactifs.
             |
             v
[ Passerelle de Décapsulation RiceGuard ]
  1. Contrôle d'authenticité et déchiffrement des données.
  2. Lecture des signaux de congestion ECN externes et réintégration interne.
  3. Rétablissement des étiquettes DSCP internes pour le réseau de destination.
  1. Aspect extérieur uniforme : Tous les paquets circulant entre les équipements et l'infrastructure VPNRice affichent la même classe de service CS0. Aucun observateur ne peut distinguer les échanges prioritaires des transferts classiques.
  2. Préservation du signal ECN : Grâce au respect scrupuleux de la RFC 6040, RiceGuard relaie les signaux de congestion précoce, aidant les routeurs à prévenir la saturation sans détruire de paquets.
  3. Contrôle matériel dans le noyau : Les filtres intégrés préviennent toute distorsion de configuration causée par l'environnement local de la machine hôte.

En éliminant les fuites de métadonnées relatives à la qualité de service, VPNRice garantit une discrétion absolue face aux analyses de trafic les plus poussées.