4. Filtrage des flux réseaux traversant les routeurs Spoke

Pour rappel, la mise en place du filtrage réseau sur les équipements doit répondre à deux principes.

  • On considère que les équipements d'interconnexion mis en œuvre dans ces travaux pratiques délimitent des périmètres de dimension moyenne. Par conséquent, on a une connaissance exhaustive des flux réseaux sur le système. On adopte donc la règle suivante : tout trafic réseau non autorisé est interdit.

  • Le filtrage est basé sur le suivi de communication (stateful inspection). On cherche donc à écrire des règles qui décrivent le plus précisément possible le premier paquet qui doit être enregistré dans la table de suivi de communication. Ces règles de description du premier paquet doivent être placées après celles qui laissent passer le trafic correspondant ou relatif à une communication déjà enregistrée dans les tables.

  • Afin de simplifier l'étude du filtrage, on fait le choix d'autoriser tous les flux sortants émis par les routeurs Hub et Spoke.

On commence par afficher les règles actives sur un routeur Spoke à l'issue des questions de la section précédente : Section 3, « Protection de base des routeurs Hub et Spoke ».

[Attention] Attention

Les noms d'interfaces correspondent à la maquette de test.

sudo nft list ruleset
table inet raw {
        chain rpfilter {
                type filter hook prerouting priority raw; policy accept;
                iifname "ppp0" fib saddr . iif oif 0 counter packets 0 bytes 0 drop
        }

        chain icmpfilter {
                type filter hook prerouting priority raw; policy accept;
                icmp type echo-request limit rate 10/second burst 5 packets counter packets 6821 bytes 193228 accept
                icmp type echo-request counter packets 116414622 bytes 3259609416 drop
        }
}
table inet f2b-table {
        set addr-set-sshd {
                type ipv4_addr
                elements = { 10.44.1.1 }
        }

        set addr6-set-sshd {
                type ipv6_addr
                elements = { fe80::f153:4881:c7c4:f371 }
        }

        chain f2b-chain {
                type filter hook input priority filter - 1; policy accept;
                tcp dport 2222 ip saddr @addr-set-sshd reject with icmp port-unreachable
                tcp dport 2222 ip6 saddr @addr6-set-sshd reject with icmpv6 port-unreachable
        }
}

Q26.

Quel est le nom de la table du système netfilter utilisée par défaut pour le traitement des flux traversant un routeur ?

Consulter la représentation graphique Packet Flow in Netfilter et repérer le nom des tables concernées par le transfert des flux réseau.

On commence par identifier la colonne FORWARD PATH au centre de la représentation.

Dans cette colonne, on trouve les tables mangle et filter.

Une recherche sur les différences entre ces deux tables nous donne les indications suivantes.

Table filter

Cette table est principalement utilisée pour filtrer les paquets et prendre des décisions concernant l'autorisation ou le blocage du trafic. Elle sert à contrôler quels paquets sont autorisés à entrer dans le système, à le quitter ou à le traverser.

Table mangle

La table d'altération est utilisée pour la modification de paquets. Les altérations principales portent sur les en-têtes, les métadonnées et le marquage, pour permettre un traitement ultérieur par d'autres tables ou les outils de gestion de la qualité de service.

Q27.

Quel est le nom de la chaîne de traitement des flux traversant les routeurs ?

Consulter la représentation graphique Packet Flow in Netfilter et repérer les noms des chaînes de la table filter.

Comme on se concentre sur la colonne FORWARD PATH de la représentation graphique, on repère facilement la chaîne forward.

Voici une proposition de jeu de règles de filtrage à implanter dans la chaîne forward de la table filter des routeurs Spoke.

table inet filter {
    chain forward {
        type filter hook forward priority 0; policy drop;

        # Allow outbound new connections
        oifname "ppp0" ct state new counter accept

        # Allow established and related connections
        ct state established,related accept

        # Allow specific inbound traffic
        # ICMP IPv4 + IPv6
        iifname "ppp0" meta l4proto {icmp, ipv6-icmp} ct state new counter accept
        # SSH
        iifname "ppp0" tcp dport 2222 ct state new counter accept
        # HTTP(S)
        iifname "ppp0" meta l4proto {tcp, udp} th dport {80, 443} ct state new counter accept

        # Count dropped packets
        counter comment "count dropped packets"
    }
}

Q28.

Quelle est la politique par défaut appliquée par ce nouveau jeu de règles?

Rechercher le mot clé policy dans la copie ci-dessus.

La politique appliquée à tous les paquets qui passent par la chaîne forward est drop.

Tous les flux qui ne sont pas explicitement autorisés dans les règles de la chaîne forward sont jetés.

Q29.

Comment identifier le sens du flux qui traverse le routeur dans le jeu de règles proposées ?

Rechercher les mots clé associés à l'interface réseau qui raccorde le routeur Spoke au Hub

Dans la topologie étudiée, c'est l'interface ppp0 du site distant qui donne accès à tous les autres réseaux. Dans les règles proposées, cette interface est précédées des clés iifname ou oifname.

iifname

La clé se lit Input InterFace NAME et désigne les flux entrants par l'interface ppp0. Vue du routeur, on emploie l'expression inbound traffic en anglais.

oifname

La clé se lit Output InterFace NAME et désigne les flux sortants par l'interface ppp0. Vue du routeur, on emploie l'expression outbound traffic en anglais.

Q30.

Comment est géré l'enregistrement des états de flux sortants ?

Rechercher les règles dans lesquelles les états new, established et related apparaissent.

Dans le cas des flux sortants, on voit que tous les nouveaux paquets sont autorisés à passer par l'interface ppp0 en sortie. La règle associe l'état new à l'autorisation accept.

oifname "ppp0" ct state new counter accept

Q31.

Comment est géré l'enregistrement des états de flux entrants ?

Rechercher à nouveau les règles dans lesquelles l'état new est associé à la clé iifname.

Dans le cas des flux entrants, on voit qu'une liste fermée de protocoles sont acceptés. Tous les nouveaux flux qui ne correspondent pas à l'une des règles avec la décision accept sont jetés.

Prenons l'exemple du protocole HTTP, une règle autorise l'accès aux ports 80 et 443.

iifname "ppp0" meta l4proto {tcp, udp} th dport {80, 443} ct state new counter accept

Q32.

Comment sont gérés les flux déjà admis dans le système d'enregistrement ?

Rechercher la règle qui contient les états established et related.

Cette question touche au cœur du filtrage stateful. Tout flux retour relatif à une première transaction admise ou enregistrée est accepté. C'est la raison pour laquelle on doit insister encore et encore sur le fait qu'il faut décrire le premier paquet admis dans le système d'enregistrement de la façon la plus exhaustive possible.

Voici la règle qui laisse passer tous les flux relatifs à un enregistrement déjà effectué.

ct state established,related accept

Q33.

Comment appliquer le jeu de règles proposé sur les routeurs Spoke ?

On dispose de plusieurs réponse à cette question. Dans le but de rendre l'application des règles de filtrage pérenne, on complète le fichier /etc/nftables.conf et on relance le service.

On a une fois de plus recours au heredoc.

cat << 'EOF' | sudo tee -a /etc/nftables.conf

table inet filter {
    chain forward {
        type filter hook forward priority 0; policy drop;

        # Allow outbound new connections
        oifname "ppp0" ct state new counter accept

        # Allow established and related connections
        ct state established,related accept

        # Allow specific inbound traffic
        # ICMP IPv4 + IPv6
        iifname "ppp0" meta l4proto {icmp, ipv6-icmp} ct state new counter accept
        # SSH
        iifname "ppp0" tcp dport 2222 ct state new counter accept
        # HTTP(S)
        iifname "ppp0" meta l4proto {tcp, udp} th dport {80, 443} ct state new counter accept

        # Count dropped packets
        counter comment "count dropped packets"
    }
}
EOF

Ensuite, on relance le service et on vérifie que le jeu de règles actives est complet.

sudo systemctl restart nftables.service
sudo nft list ruleset

Q34.

Comment tester les règles relatives aux flux sortants ?

Pour tester la chaîne forward dans le sens réseau d'hébergement vers le routeur Hub, il faut initier du trafic depuis les conteneurs.

Voici un exemple qui passe par la couche application : la mise à jour du catalogue de paquets de chaque conteneur.

for i in {0..2}
do
    echo ">>>>>>>>>>>>>>>>> c$i"
    incus exec c$i -- apt update
done

Une fois la mise à jour effectuée dans les conteneurs, on peut relever les compteurs associés aux règles de filtrage.

sudo nft list table inet filter
table inet filter {
        chain forward {
                type filter hook forward priority filter; policy drop;
                oifname "ppp0" ct state new counter packets 41 bytes 3078 accept
                ct state established,related accept
                iifname "ppp0" meta l4proto { icmp, ipv6-icmp } ct state new counter packets 2 bytes 188 accept
                iifname "ppp0" tcp dport 2222 ct state new counter packets 0 bytes 0 accept
                iifname "ppp0" meta l4proto { tcp, udp } th dport { 80, 443 } ct state new counter packets 1 bytes 60 accept
                counter packets 0 bytes 0 comment "count dropped packets"
        }
}

Q35.

Comment tester les règles relatives aux flux entrants ?

Il suffit de reprendre les séquences de tests présentées à la fin du support de travaux pratiques précédent : Topologie Hub & Spoke avec le protocole PPPoE à la question 21.

On reprend l'accès aux pages Web depuis le routeur Hub.

for addr in {10..12}
do
    wget -O /dev/null http://10.0.10.$addr 2>&1 | grep "HTTP "
done
for addr in {10..12}
do
    wget -O /dev/null http://[fda0:7a62:a::$(printf "%x" $addr)] 2>&1 | grep "HTTP "
done

Ensuite, on vérifie la nouvelle valeur de comptage sur la règle de filtrage concernée.

sudo nft list table inet filter
table inet filter {
        chain forward {
                type filter hook forward priority filter; policy drop;
                oifname "ppp0" ct state new counter packets 0 bytes 0 accept
                ct state established,related counter packets 81 bytes 13581 accept
                iifname "ppp0" meta l4proto { icmp, ipv6-icmp } ct state new counter packets 0 bytes 0 accept
                iifname "ppp0" tcp dport 2222 ct state new counter packets 0 bytes 0 accept
                iifname "ppp0" meta l4proto { tcp, udp } th dport { 80, 443 } ct state new counter packets 9 bytes 600 accept
                counter packets 0 bytes 0 comment "count dropped packets"
        }
}

Une fois ces règles basiques en place, on peut aborder les filtrages réseau spécifiques à la topologie de travaux pratiques.