IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Le filtrage avec iptables


précédentsommairesuivant

8. La machine d'état

Ce chapitre aborde et explique en détail la machine d'état. Après avoir lu ceci, vous devriez avoir pleinement compris son fonctionnement. Vous parcourrez un nombre important d'exemples sur la façon dont les états sont traités par la machine d'état elle-même. Ces cas concrets devraient vous éclairer parfaitement.

8-1. Introduction

La machine d'état correspond à une partie spéciale à l'intérieur d'iptables. En fait, elle porte très mal son nom puisqu'il s'agit en réalité d'une machine de traçage de connexion. Cependant, la plupart des gens la connaissent sous la première appellation. Au cours de ce chapitre, les deux noms sont utilisés indistinctement comme ils sont synonymes. Ceci ne devrait pas trop vous perturber. Le traçage de connexion est effectué afin que l'architecture de Netfilter puisse connaître l'état d'une connexion spécifique. Les pare-feux qui implémentent ceci sont habituellement appelés pare-feux à état. Un pare-feu à état est généralement bien plus sûr qu'un pare-feu sans état, puisqu'il impose une plus grande rigueur sur l'écriture des livres de règles.

Dans iptables, les paquets peuvent être reliés aux connexions tracées dans quatre états différents, qui sont connus sous les noms de NEW, ESTABLISHED, RELATED et INVALID. Chacun de ces états sera approfondi plus loin. Avec la correspondance --state, il est facile de contrôler qui, ou ce qui, est autorisé à démarrer de nouvelles sessions.

L'intégralité du traçage de connexion est effectué par une structure particulière à l'intérieur du noyau appelée conntrack. La structure conntrack peut soit être chargée comme un module, soit être interne au noyau. La plupart du temps, on a besoin de fonctions supplémentaires de traçage de connexion autre que celles proposées par défaut dans le moteur conntrack. De ce fait, des parties spécifiques de conntrack prennent en charge les protocoles TCP, UDP et ICMP. Ces modules capturent des informations spécifiques et uniques sur les paquets, afin de pouvoir tracer chaque flux de données. L'information récupérée par conntrack lui permet de connaître l'état dans lequel se trouve chaque flux actuellement. Par exemple, un flux UDP est, en général, identifié uniquement par son adresse IP destination, son adresse IP source, son port destination et son port source .

Dans les noyaux précédents, il était possible d'activer ou désactiver la défragmentation. Cependant, depuis qu'iptables et Netfilter ont été incorporés avec, en particulier, le traçage de connexion, cette option a disparu. La raison en est simple, le traçage de connexion ne peut pas fonctionner correctement sans défragmenter les paquets, par conséquent la défragmentation a été intégrée dans conntrack, et elle est réalisée automatiquement. Elle ne peut donc plus être désactivée, sauf en désactivant le traçage de connexion. En définitive, la défragmentation a toujours cours si le traçage de connexion est actif.

Le traçage de connexion est entièrement pris en charge dans la chaîne PREROUTING, sauf pour les paquets générés en local, qui sont pris en charge dans la chaîne OUTPUT. Ceci signifie qu'iptable effectue tous les calculs d'état dans la chaîne PREROUTING. Si on envoie le premier paquet d'un flux, l'état est défini comme NEW dans la chaîne OUTPUT, et quand on reçoit un paquet de réponse, l'état passe à ESTABLISHED, et ainsi de suite. Si le premier paquet n'est pas envoyé par nous-même, l'état NEW est naturellement défini dans la chaîne PREROUTING. Ainsi, tous les changements d'état et calculs sont réalisés dans les chaînes PREROUTING et OUTPUT de la table nat.

8-2. Les entrées de conntrack

Examinons rapidement le contenu d'une donnée d'entrée de conntrack et lisons-la dans /proc/net/ip_conntrack. Ce lien contient une liste de toutes les entrées actuelles de la base de données de conntrack. Si vous avez chargé le module ip_conntrack, faites un cat de /proc/net/ip_conntrack pour obtenir quelque chose comme ceci :

 
Sélectionnez
tcp      6 117 SYN_SENT src=192.168.1.6 dst=192.168.1.9 sport=32775 \
     dport=22 [UNREPLIED] src=192.168.1.9 dst=192.168.1.6 sport=22 \
     dport=32775 [ASSURED] use=2

Cet exemple contient toute l'information gérée par le module conntrack pour savoir dans quel état se trouve une connexion. Tout d'abord, il y a le protocole, ici tcp. Ensuite, encore le protocole, mais codé en décimal. Après cela, on voit combien de temps doit survivre cette entrée de conntrack. La valeur à cet instant est de 117 secondes, elle est decrémentée régulièrement jusqu'à ce qu'on voie à nouveau du trafic pour cette connexion. Cette valeur est alors réinitialisée à la valeur par défaut pour l'état en question à cet instant donné. Ensuite vient l'état actuel de cette entrée. Dans le cas présenté ci-dessus, on visualise une connexion qui est dans l'état SYN_SENT. La valeur interne d'une connexion est légèrement différente de celles utilisées en externe avec iptables. La valeur SYN_SENT indique que cette connexion a seulement vu un paquet TCP SYN dans une direction. Puis, on voit l'adresse IP source, l'adresse IP destination, le port source et le port destination. Arrivé à ce niveau, on voit un mot-clé spécifique qui signale qu'aucun trafic n'a été observé en retour pour cette connexion. Enfin, on voit ce qui est attendu pour les paquets en réponse. Entre autres, l'adresse IP source et l'adresse IP destination (qui sont inversées, puisque le paquet attendu doit être dirigé dans l'autre sens). La même chose s'applique au port source et port destination de la connexion. Ces valeurs nous intéressent particulièrement.

Les entrées du traçage de connexion peuvent prendre un ensemble de valeurs différentes, toutes spécifiées dans les en-têtes de conntrack et disponibles dans les fichiers linux/include/netfilter-ipv4/ip_conntrack*.h. Ces valeurs dépendent du sous-protocole IP qu'on utilise. Les protocoles TCP, UDP et ICMP correspondent à des valeurs fixées et spécifiées dans le fichier linux/include/netfilter-ipv4/ip_conntrack.h. Ceci sera analysé plus en détail lors de l'analyse de chaque protocole ; cependant, ils ne seront pas employés intensivement dans ce chapitre, puisqu'ils ne sont pas utilisés en dehors du fonctionnement interne de conntrack. Ainsi, en fonction de l'évolution de cet état, on change la valeur du temps restant avant la destruction de la connexion.

Récemment, un nouveau patch est devenu disponible dans patch-o-matic, appelé tcp-window-tracking. Il ajoute, entre autres, toutes les temporisations précitées aux variables spéciales sysctl, ce qui signifie qu'elles peuvent être modifiées à la volée, alors que le système est toujours en fonctionnement. Par conséquent, il ne devient plus indispensable de recompiler le noyau à chaque changement dans les temporisations.

Tout ceci peut être modifié par le biais d'appels système spécifiques, disponibles dans le répertoire /proc/sys/net/ipv4/netfilter. Vous devriez regarder en particulier les variables /proc/sys/net/ipv4/netfilter/ip_ct_*.

Quand une connexion a observé du trafic dans les deux directions, l'entrée de conntrack efface le fanion [UNREPLIED] , et donc le réinitialise. Elle le remplace par le fanion [ASSURED], vers la fin. Il signale que cette connexion est confirmée, donc elle ne sera pas supprimée si on atteint le maximum de connexions tracées possibles. En fait, les connexions estampillées [ASSURED] ne seront pas supprimées, au contraire des connexions non confirmées (sans le fanion [ASSURED]). Le nombre maximum de connexions gérées par la table de traçage de connexion dépend d'une variable qui peut être définie à l'aide de la fonction ip-sysctl dans les noyaux récents. La valeur par défaut prise en charge varie fortement avec la quantité de mémoire disponible. Avec 128 Mo de RAM, vous pourrez avoir 8192 entrées possibles, et avec 256 Mo, ce sera 16376 entrées. Vous pouvez lire et définir vos réglages à l'aide de /proc/sys/net/ipv4/ip_conntrack_max.

Un moyen différent de faire ceci, plus efficace, est de placer la taille de la fonction de hachage pour le module ip_conntrack une fois qu'il est chargé. Dans des circonstances normales ip_conntrack_max égale 8 * la taille de la fonction de hachage. En d'autres termes, placer cette taille à 4096 fera que ip_conntrack_max aura 32 768 entrées conntrack. Un exemple de ce qui pourrait être :

 
Sélectionnez
work3:/home/blueflux# modprobe ip_conntrack hashsize=4096
work3:/home/blueflux# cat /proc/sys/net/ipv4/ip_conntrack_max
32768
work3:/home/blueflux#

8-3. États de l'espace utilisateur

Comme vous l'avez vu, les paquets peuvent prendre différents états à l'intérieur du noyau, en fonction du protocole considéré. Cependant, à l'extérieur du noyau, seuls 4 états sont disponibles, comme expliqué précédemment. Ces états peuvent être associés à la correspondance state qui est capable de sélectionner les paquets à partir de l'état actuel du traçage de connexion. Les états valides sont NEW, ESTABLISHED, RELATED et INVALID. Le tableau suivant décrit brièvement chacun d'eux.

Tableau 7.1. États de l'espace utilisateur

État Explication
NEW L'état NEW indique que le paquet est le premier de la connexion. Cela signifie que, pour une connexion donnée, le premier paquet que le module conntrack aperçoit est apparié. Par exemple, si on rencontre un paquet SYN et que c'est le premier paquet d'une connexion, on établit la correspondance. Cependant, le paquet peut aussi ne pas être de type SYN et considéré tout de même dans l'état NEW. Ceci peut s'avérer problématique dans certaines situations, mais peut aussi être extrêmement utile quand on doit récupérer les connexions perdues issues d'autres pare-feux, ou quand une connexion a dépassé son temps de survie, mais n'est pas réellement fermée.
ESTABLISHED L'état ESTABLISHED résulte de l'observation d'un trafic dans les deux sens, et donc établit une correspondance avec ce type de paquet. Les connexions établies (ESTABLISHED) sont particulièrement simples à comprendre. La seule condition pour entrer dans l'état ESTABLISHED est qu'un hôte ayant envoyé un paquet reçoive plus tard une réponse de l'hôte destinataire de ce paquet. À la réception du paquet de réponse, l'état NEW est transformé en ESTABLISHED. Les messages d'erreur et de redirection ICMP peuvent aussi être considérés comme ESTABLISHED, si on a généré un paquet qui en retour génère le message ICMP.
RELATED L'état RELATED est un des états les plus astucieux. Une connexion est considérée comme RELATED quand elle est liée à une autre connexion déjà établie, donc dans l'état ESTABLISHED. Ainsi, pour qu'une connexion soit identifiée comme RELATED, on doit tout d'abord disposer d'une autre connexion dans l'état ESTABLISHED. Cette connexion ESTABLISHED crée alors une connexion extérieure à la connexion principale. La nouvelle connexion créée est donc considérée comme RELATED, si le module conntrack l'identifie comme en relation avec l'autre. Les exemples suivants peuvent être considérés comme RELATED : les connexions FTP-data sont liées au port FTP control, et les connexions DCC interviennent par l'intermédiaire de IRC. Ceci permet d'utiliser des réponses ICMP, des transferts FTP et des DCC pour travailler convenablement à travers un pare-feu. Remarquez que la plupart des protocoles TCP et certains protocoles UDP qui reposent sur ce mécanisme sont particulièrement complexes. Ils envoient des informations de connexion à l'intérieur des données utiles, qui par conséquent nécessitent des modules assistant (helper) spécifiques pour être correctement interprétées.
INVALID L'état INVALID signifie que le paquet ne peut pas être identifié ou qu'il n'a aucun état connu. Il peut y avoir plusieurs raisons à cela : par exemple, un système en dépassement de mémoire ou des messages d'erreur ICMP ne répondant à aucune connexion connue. Généralement, il est préférable de supprimer tout ce qui se trouve dans cet état.
UNTRACKED C'est l'état UNTRACKED. En bref, si un paquet est marqué dans la table raw avec la cible NOTRACK, ce paquet sera vu comme UNTRACKED dans la machine d'état. Ceci indique aussi que toutes les connexions RELATED ne seront pas vues, ainsi certaines précautions doivent être prises lorsque vous utilisez cet état, car la machine d'état ne sera pas capable de voir les messages ICMP, etc.

Ces états peuvent être utilisés avec la correspondance --state pour sélectionner les paquets à partir de leur état de traçage de connexion. C'est ce qui rend la machine d'état si puissante et efficace pour votre pare-feu. Auparavant, nous devions souvent ouvrir tous les ports supérieurs à 1024 pour permettre le trafic inverse à destination de notre réseau local. Avec la machine d'état à l'œuvre, ce n'est plus nécessaire, puisqu'il est possible d'ouvrir le pare-feu pour les réponses sans l'ouvrir pour le reste du trafic.

8-4. Connexions TCP

Dans cette section et les suivantes, nous examinerons plus en détail les états et comment ils sont gérés pour les trois protocoles élémentaires TCP, UDP et ICMP. Nous verrons aussi comment les états sont gérés par défaut, s'ils ne peuvent être assimilés à un quelconque de ces trois protocoles. Nous choisissons de démarrer avec le protocole TCP, car c'est un protocole à état en lui-même, avec nombre de caractéristiques intéressantes en rapport avec la machine d'état d'iptables.

Une connexion TCP démarre toujours avec l'établissement d'une liaison en 3 phases, qui met en place et négocie la connexion qui servira pour le transfert des données. Toute la session commence par un paquet SYN, suivi d'un paquet SYN/ACK et se termine par un paquet ACK pour accuser réception de l'établissement de la session. À cet instant, la connexion est établie et prête à envoyer des données. Le problème est le suivant : comment le traçage de connexion peut-il s'accrocher à cette étape ? En fait, très simplement.

En ce qui concerne l'utilisateur, le traçage de connexion fonctionne de façon identique pour tout type de connexion. Observez le schéma ci-dessous pour comprendre dans quel état se trouve le flux aux différentes étapes de la connexion. Comme vous le voyez, le code du traçage de connexion ne suit pas vraiment les étapes de la connexion TCP du point de vue de l'utilisateur. Dès qu'un paquet SYN arrive, il considère la connexion comme nouvelle (NEW). Dès qu'un paquet de réponse SYN/ACK est observé, il considère la connexion comme établie (ESTABLISHED). Si vous réfléchissez une seconde, vous comprendrez pourquoi. Avec cette implémentation particulière, vous pouvez autoriser des paquets NEW et ESTABLISHED à quitter votre réseau local, et autoriser seulement des connexions ESTABLISHED en retour, et ça fonctionnera sans problème. A contrario, si la machine de traçage de connexion considérait l'établissement complet de la connexion comme NEW, il serait impossible d'arrêter les connexions issues de l'extérieur vers le réseau local, puisqu'il faudrait à nouveau autoriser le retour de paquets NEW. Pour rendre les choses encore plus compliquées, il existe de nombreux autres états internes qui sont utilisés pour les connexions TCP à l'intérieur du noyau, mais qui ne sont pas disponibles dans l'espace utilisateur. Brièvement, ils respectent les états standard spécifiés dans la RFC 793 - Transmission Control Protocol aux pages 21-23.

Image non disponible

Comme vous pouvez le voir, c'est tout à fait simple, du point de vue de l'utilisateur. Cependant, en regardant la construction complète du point de vue du noyau, c'est un peu plus compliqué. Voyons un exemple. Regardons exactement comment les états de connexion changent dans la table /proc/net/ip_conntrack. Le premier état est rapporté sur le reçu d'un premier paquet SYN dans la connexion.

 
Sélectionnez
tcp      6 117 SYN_SENT src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 [UNREPLIED] src=192.168.1.35 dst=192.168.1.5 sport=23 \
     dport=1031 use=1

Comme nous l'indique l'entrée ci-dessus, nous avons un état précis dans lequel un paquet SYN a été envoyé, (le drapeau SYN_SENT est placé), et pour lequel aucune réponse n'a été envoyée (en témoigne le drapeau [UNREPLIED]). L'état interne suivant sera joint quand nous verrons un autre paquet dans l'autre direction.

 
Sélectionnez
tcp      6 57 SYN_RECV src=192.168.1.5 dst=192.168.1.35 sport=1031 \
     dport=23 src=192.168.1.35 dst=192.168.1.5 sport=23 dport=1031 \
     use=1

Maintenant nous avons reçu un SYN/ACK correspondant en retour. Dès que ce paquet a été reçu, l'état change encore une fois, cette fois vers SYN_RECV. SYN_RECV nous indique que le SYN d'origine a été délivré correctement et que le SYN/ACK en retour passe aussi à travers le pare-feu proprement. D'ailleurs, cette entrée de traçage de connexion a observé le trafic dans les deux directions et considère désormais qu'il y a été répondu. Ceci n'est pas explicite, mais nous assumons, comme l'était le fanion [UNREPLIED] ci-dessus. L'étape finale sera atteinte lorsque nous aurons vu le ACK dans l'établissement d'une liaison à trois voies.

 
Sélectionnez
tcp      6 431999 ESTABLISHED src=192.168.1.5 dst=192.168.1.35 \
     sport=1031 dport=23 src=192.168.1.35 dst=192.168.1.5 \
     sport=23 dport=1031 [ASSURED] use=1

Dans le dernier exemple, nous avons obtenu le ACK final dans l'établissement d'une liaison à trois voies et la connexion a pris l'état ESTABLISHED, pour autant que les mécanismes internes de iptables soient avisés. Normalement, le flux de données sera ASSURED maintenant.

Une connexion peut aussi être dans l'état ESTABLISHED, mais pas [ASSURED]. Ceci survient lorsque nous avons une connexion captée ouverte (nécessite le patch tcp-window-tracking et le ip_conntrack_tcp_loose placé à 1 ou plus haut). Par défaut, sans le patch tcp-window-tracking, c'est ce comportement qui s'applique, et il n'est pas modifiable.

Quand une connexion TCP est close, elle est faite de cette façon et prend les états suivants.

Image non disponible

Comme vous pouvez le voir, la connexion n'est jamais réellement fermée jusqu'à ce que le ACK soit envoyé. Notez que cette figure décrit simplement comment elle est fermée dans des circonstances normales. Une connexion peut aussi, par exemple, être fermée par l'envoi d'un RST (reset), si celle-ci a été refusée. Dans ce cas, la connexion sera fermée immédiatement.

Quand la connexion TCP a été fermée, elle entre dans l'état TIME_WAIT, qui est, par défaut, de deux minutes. Ceci est utilisé pour que tous les paquets sortants puissent encore passer à travers notre table de règles, même après que la connexion a été fermée. Ceci est employé comme une sorte de tampon pour que les paquets qui ont été immobilisés dans un ou plusieurs routeurs engorgés puissent encore passer le pare-feu, ou vers une autre fin de connexion.

Si la connexion est réinitialisée par un paquet RST, l'état est modifié en CLOSE. Ce qui indique que la connexion a, par défaut, 10 secondes avant que la connexion complète soit fermée définitivement. Les paquets RST ne sont pas reconnus dans aucun sens, et couperont la connexion directement. Il existe aussi d'autres états que ceux dont nous avons parlé. Voici une liste complète des états qu'un flux TCP peut prendre, et leur valeur de délai d'attente.

Tableau 7.2. États internes

État Délai
NONE 30 minutes
ESTABLISHED 5 jours
SYN_SENT 2 minutes
SYN_RECV 60 secondes
FIN_WAIT 2 minutes
TIME_WAIT 2 minutes
CLOSE 10 secondes
CLOSE_WAIT 12 heures
LAST_ACK 30 secondes
LISTEN 2 minutes

Ces valeurs ne sont pas absolues. Elles peuvent changer en fonction des versions du noyau, et également par le système de fichiers dans les variables /proc/sys/net/ipv4/netfilter/ip_ct_tcp_*. Les valeurs par défaut seront, cependant, justes en pratique. Ces valeurs sont établies en secondes.

Notez aussi que le domaine utilisateur de la machine d'état ne doit pas voir les fanions TCP (i.e., RST, ACK et SYN sont des fanions) placés dans les paquets TCP. Ce n'est généralement pas recommandé, car vous pourriez autoriser les paquets dans l'état NEW à traverser le pare-feu, mais quand vous spécifiez le fanion NEW, vous indiquez les paquets SYN.

Ce n'est pas ce qui se produit avec l'implémentation de l'état ; ce qui veut dire, même un paquet avec aucun bit de placé ou un fanion ACK, sera compté comme NEW. Ceci peut être utilisé pour faire de la redondance de pare-feu, mais c'est en général très déconseillé pour un réseau domestique, dans lequel vous avez un seul pare-feu. Pour en savoir plus vous pouvez utiliser la commande expliquée dans la section Section B.2, « Paquets NEW non-SYN »B.2. Paquets NEW non-SYN de l'annexe Annexe B,Annexe B. Problèmes et questions courants. Un autre moyen est d'installer l'extension tcp-window-tracking depuis patch-o-matic, et de placer /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_loose à zéro, le pare-feu effacera tous les paquets NEW en ayant le fanion SYN placé.

8-5. Connexions UDP

Les connexions UDP ne sont pas des connexions à part entière, mais plutôt des connexions « sans état ». Il y a plusieurs raisons pour cela, la principale parce qu'elles ne contiennent aucun établissement ou fermeture de connexion ; la plupart n'ont pas de liaison. En recevant deux datagrammes UDP dans un ordre spécifique, on ne peut savoir dans quel ordre ils ont été envoyés. Cependant, il est toujours possible de placer des états sur les connexions dans le noyau. Voyons comment une connexion peut être tracée et à quoi elle ressemblerait dans le conntrack.

Image non disponible

Comme on peut le voir, la connexion circule presque exactement de la même façon qu'une connexion TCP. Ceci, du point de vue de l'utilisateur. En interne, l'information conntrack est un peu différente, mais intrinsèquement les détails sont les mêmes. Premièrement, regardons les entrées après que le paquet UDP initial a été envoyé.

 
Sélectionnez
udp      17 20 src=192.168.1.2 dst=192.168.1.5 sport=137 dport=1025 \
     [UNREPLIED] src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 use=1

Comme vous pouvez le voir entre la première et la deuxième valeur, c'est un paquet UDP. Le premier est le nom du protocole, le second le numéro du protocole. C'est identique pour une connexion TCP. La troisième valeur indique combien de secondes cet état s'est maintenu. Après cela, nous avons les valeurs du paquet que nous avons vu et les probabilités que les paquets sur cette connexion nous joignent depuis l'expéditeur. Ce sont la source, la destination, le port source et le port destination. À ce point le fanion [UNREPLIED] nous indique qu'il n'y a pas eu de réponse au paquet. Enfin, nous avons une courte liste de probabilités de retour de paquets. Notez que les dernières entrées sont en ordre inverse des premières valeurs. Le délai d'attente est de 30 secondes dans ce cas, par défaut.

 
Sélectionnez
udp      17 170 src=192.168.1.2 dst=192.168.1.5 sport=137 \
     dport=1025 src=192.168.1.5 dst=192.168.1.2 sport=1025 \
     dport=137 [ASSURED] use=1

À ce point le serveur a vu une réponse au premier paquet envoyé et la connexion est maintenant considérée comme ESTABLISHED. Ce n'est pas indiqué dans le traçage de connexion comme vous pouvez le voir. La principale différence est que le fanion [UNREPLIED] est maintenant fourni. D'ailleurs, le temps d'attente par défaut a changé pour passer à 180 secondes - mais dans cet exemple il a été décrémenté pour passer à 170 secondes - avec un délai de 10 secondes, il sera de 160 secondes. Une chose qui a été oubliée et qui peut changer légèrement est le fanion [ASSURED] décrit ci-dessus. Pour placer le fanion [ASSURED] sur un traçage de connexion, il doit y avoir un paquet en réponse au paquet NEW.

 
Sélectionnez
udp      17 175 src=192.168.1.5 dst=195.22.79.2 sport=1025 \
     dport=53 src=195.22.79.2 dst=192.168.1.5 sport=53 \
     dport=1025 [ASSURED] use=1

Ici, la connexion est assurée. La connexion a exactement le même aspect que dans l'exemple précédent. Si cette connexion n'est pas utilisée dans les 180 secondes, elle est hors délai. 180 secondes est comparativement une valeur basse, mais qui devrait être suffisante dans la plupart des cas. Cette valeur est réinitialisée complètement pour chaque paquet qui correspond à la même entrée et passe à travers le pare-feu, comme pour tous les états internes.

8-6. Connexions ICMP

Les paquets ICMP sont loin d'être un flux véritable, car ils sont seulement utilisés pour le contrôle et n'établissent jamais aucun type de connexion. Il existe quatre types ICMP qui généreront cependant des paquets en retour, et qui possèdent deux états différents. Ces messages ICMP peuvent prendre les états NEW et ESTABLISHED. Les types ICMP dont nous parlons sont les requêtes et réponses Echo, les requêtes et réponses Timestamp, les requêtes et réponses Information, et enfin les requêtes et réponses de Masque d'Adresse. En dehors de ça, les requêtes d'horodatage et d'information sont obsolètes et seront probablement supprimées. Cependant, les messages Echo sont utilisés dans plusieurs cas comme le ping sur des hôtes. Les requêtes de masque d'adresse ne sont pas utilisées souvent, mais peuvent être utiles quelques fois. Pour en avoir une idée, voyons l'image suivante.

Image non disponible

Comme vous pouvez le voir dans l'image ci-dessus, l'hôte envoie une requête écho vers la cible, laquelle est considérée comme NEW par le pare-feu. La cible répond alors avec un écho que le pare-feu considère dans l'état ESTABLISHED. Quand la première requête écho a été vue, les entrées état suivantes se dirigent vers le ip_conntrack.

 
Sélectionnez
icmp     1 25 src=192.168.1.6 dst=192.168.1.10 type=8 code=0 \
     xml:id=33029 [UNREPLIED] src=192.168.1.10 dst=192.168.1.6 \
     type=0 code=0 xml:id=33029 use=1

Ces entrées semblent un peu différentes des états standard pour TCP et UDP. Le protocole est présent, et la temporisation, de même que les adresses source et destination. Le problème survient après. Nous avons maintenant trois nouveaux champs appelés type, code et id. Il n'y a rien de spécial, le champ type contient le type ICMP et le champ code contient le code ICMP. Toutes les variables sont présentées dans l'annexe Annexe C,Annexe C. Types ICMP. Le dernier champ id, contient l'ID ICMP. Chaque paquet ICMP obtient une ID quand il est envoyé, et lorsque le destinataire reçoit le message ICMP, il place la même ID dans le nouveau message ICMP, que l'expéditeur reconnaîtra dans la réponse et il pourra alors se connecter avec la requête ICMP correcte.

Dans le champ suivant, nous avons reconnu le fanion [UNREPLIED]. Ce fanion nous indique que nous observons une entrée de traçage de connexion, dont le trafic est dans une direction. Enfin, nous voyons la probabilité de réponse à un paquet ICMP, qui est l'inversion des adresses IP source et destination. Comme pour le type et le code, ils ont été modifiés en valeurs correctes pour le paquet de retour, ainsi une requête écho est changée en réponse écho et ainsi de suite. L'ID ICMP est préservée depuis le paquet requête.

Le paquet réponse est considéré comme ESTABLISHED, ainsi que nous l'avons déjà expliqué. Cependant, nous pouvons savoir avec certitude qu'après la réponse ICMP, il n'y aura plus de trafic régulier dans la même connexion. Pour cette raison, l'entrée de traçage de connexion est détruite une fois que la réponse a traversé la structure de Netfilter.

Dans chacun des cas ci-dessus, la requête est considérée comme NEW, tandis que la réponse est considérée comme ESTABLISHED. Voyons cela de plus près. Quand le pare-feu voit un paquet requête, il le considère comme NEW. Quand l'hôte envoie un paquet en réponse à la requête, il est considéré comme ESTABLISHED.

Notez que cela indique que le paquet réponse doit apparier le critère donné par l'entrée de traçage de connexion pour être considéré comme établi, de la même façon que tous les autres types de trafic.

Les requêtes ICMP ont un délai par défaut de 30 secondes, que vous pouvez modifier dans l'entrée /proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout. C'est, en général, une bonne valeur de temps d'attente, car elle permet de capturer la plupart des paquets en transit.

Une autre partie très importante de ICMP est le fait qu'il est utilisé pour indiquer aux hôtes les événements au niveau des connexions spécifiques UDP et TCP ou des tentatives de connexion. Pour cette raison, les réponses ICMP seront très souvent reconnues comme RELATED. Un exemple simple est le ICMP Host unreachable ou ICMP Network unreachable. Ceci est toujours généré en retour vers notre hôte s'il tente une connexion vers quelque autre hôte, mais que le réseau ou l'hôte en question ne soit pas connecté, ainsi le dernier routeur essayant de joindre le site répondra par un message ICMP nous l'indiquant. Dans ce cas, la réponse ICMP est considérée comme un paquet RELATED. L'image suivante explique ceci.

Image non disponible

Dans l'exemple ci-dessus, nous envoyons un paquet SYN vers une adresse spécifique. Ceci est considéré comme une connexion NEW par le pare-feu. Cependant, le réseau que le paquet essaie de joindre est injoignable, donc un routeur va nous renvoyer une erreur ICMP indiquant que le réseau est injoignable. Le code de traçage de connexion peut reconnaître ce paquet comme RELATED, ainsi la réponse ICMP est correctement envoyée au client. En attendant, le pare-feu a détruit l'entrée de traçage de connexion depuis qu'il a eu connaissance du message d'erreur.

Le même comportement que ci-dessus est observé pour les connexions UDP avec les problèmes identiques que précédemment. Tous les messages ICMP envoyés en réponse aux connexions UDP sont considérés comme RELATED. Voyons l'image suivante.

Image non disponible

Un paquet UDP est envoyé à un hôte. Cette connexion UDP est considérée comme NEW. Cependant, le réseau est interdit d'accès administrativement par un pare-feu quelconque ou un routeur. Donc, notre pare-feu reçoit un « ICMP Network Prohibited » en retour. Le pare-feu sait que ce message d'erreur ICMP est en relation avec la connexion UDP déjà ouverte et envoie un paquet RELATED au client. À ce niveau, le pare-feu supprime les entrées de traçage de connexion, et le client reçoit le message ICMP.

8-7. Connexions par défaut

Dans certains cas, la machine conntrack ne sait pas comment traiter un protocole spécifique. Ceci se produit lorsqu'elle ne connaît pas le protocole en particulier, ou ne sait pas comment il fonctionne. Dans ces cas-là, elle utilise un comportement par défaut. Ce comportement est utilisé sur, par exemple, NETBLT, MUX et EGP. Ce comportement ressemble au traçage de connexion UDP. Le premier paquet est considéré comme NEW, et le trafic en réponse comme ESTABLISHED.

Quand ce comportement par défaut est utilisé, tous les paquets ont la même valeur de délai par défaut. Ceci peut être paramétré via la variable /proc/sys/net/ipv4/netfilter/ip_ct_generic_timeout. La valeur par défaut est ici de 600 secondes, soit 10 minutes. En fonction du trafic, ceci peut avoir besoin d'être modifié. Spécialement si vous renvoyez le trafic par satellite, ce qui peut prendre du temps.

8-8. Connexions non tracées et la table raw

UNTRACKED est un terme plutôt spécial quand il est employé dans le traçage de connexion avec Linux. De façon simple, il est utilisé pour sélectionner les paquets qui ont été marqués dans la table raw pour ne pas être tracés.

La table raw a été créée spécialement pour cette raison. Dans cette table vous placez une marque NOTRACK sur les paquets que vous ne voulez pas tracer dans Netfilter.

Notez que je parle de paquets, pas de connexion, car la marque est placée actuellement pour chaque paquet entrant.

Comme nous l'avons déjà indiqué, conntrack et la machine d'état sont plutôt gourmands en ressources. Pour cette raison, ce peut être une bonne idée de parfois désactiver le traçage de connexion et la machine d'état.

Un exemple, vous avez un routeur supportant beaucoup de trafic et vous voulez tracer les flux entrants et sortants, mais pas le trafic routé. Vous pouvez alors placer la marque NOTRACK sur tous les paquets non destinés au pare-feu lui-même en ACCEPTant tous les paquets à destination de votre hôte dans la table raw, et ensuite placer NOTRACK pour tout le trafic restant. Ce qui vous permet d'avoir une vérification complète du trafic entrant pour le routeur lui-même, mais en même temps sauvegarder de la ressource machine en ne traçant pas la totalité du trafic.

Un autre exemple, NOTRACK peut être utilisé lorsque vous avez un serveur web générant beaucoup de trafic et que vous désirez le tracer complètement, mais vous ne voulez pas perdre de la puissance processeur. Vous pouvez alors placer une règle qui désactive le traçage sur le port 80 sur toutes les adresses IP locales, ou celles actuellement utilisées pour le trafic web. Vous pouvez ensuite sans problème tracer tous les autres services, sauf pour le trafic web.

Il existe cependant certains problèmes avec NOTRACK que vous devez prendre en considération. Si une connexion complète est placée avec NOTRACK, vous ne pourrez pas tracer chaque connexion particulière, conntrack et nat ne fonctionnent pas pour les connexions non tracées, ni avec les erreurs relatives à ICMP. En d'autres termes, vous devrez les ouvrir manuellement. Quand il s'agit de protocoles complexes comme FTP et SCTP, ce peut être assez difficile à gérer.

8-9. Protocoles complexes et traçage de connexion

Certains protocoles sont plus complexes que d'autres. Ce qui fait que, lorsqu'ils interfèrent avec du traçage de connexion, ils peuvent être plus difficiles à tracer correctement. De bons exemples en sont les protocoles ICQ, IRC et FTP. Chacun des ces protocoles transporte l'information dans les données utiles des paquets, et donc nécessitent un traçage de connexion spécial pour bien fonctionner.

Voici une liste des protocoles complexes supportés par le noyau Linux, et la version du noyau dans laquelle il a été implémenté.

Tableau 7.3. Support des protocoles complexes

Nom du protocole Version du noyau
FTP 2.3
IRC 2.3
TFTP 2.5
Amanda 2.5
  • FTP
  • IRC
  • TFTP

Prenons le protocole FTP comme premier exemple. Ce protocole ouvre en premier une seule connexion appelée contrôle de session FTP. Quand nous lançons des commandes dans cette session, d'autres ports sont ouverts pour transporter le reste des données relatives à ces commandes spécifiques. Ces connexions peuvent être réalisées de deux manières, de façon active ou passive. Quand une connexion est en mode actif, le client FTP envoie au serveur un port et une adresse IP pour se connecter. Après cela, le client FTP ouvre le port et le serveur le connecte depuis un domaine de ports non privilégiés (>1024) et envoie les données sur celui-ci.

Le problème est que le pare-feu ne connaît pas ces connexions, car elles ont été négociées dans les données utiles du protocole. À cause de ça, le pare-feu sera incapable de savoir s'il doit laisser le serveur connecté au client sur ces ports spécifiques.

La solution est d'ajouter une aide spéciale au module de traçage de connexion qui scannera les données dans le contrôle de connexion à la recherche d'information et de syntaxes spécifiques. Quand il fonctionne avec l'information correcte, il indique cette information spécifique comme RELATED et le serveur sera capable de tracer la connexion. Voyons l'image suivante pour comprendre les états quand le serveur FTP a envoyé le retour de connexion au client.

Image non disponible

Le FTP passif fonctionne de la façon inverse. Le client FTP indique au serveur qu'il désire certaines données spécifiques, le serveur lui répond avec l'adresse IP à connecter et le port. Le client pourra, au reçu de ces données, se connecter à ce port depuis son propre port 20 (port FTP), et obtenir les données en question. Si vous avez un serveur FTP derrière votre pare-feu, vous aurez besoin de ce module en supplément de vos modules standard iptables pour permettre aux clients sur l'Internet de se connecter au serveur FTP correctement. C'est la même chose si vous êtes très restrictif pour vos utilisateurs, et les laissez se connecter seulement aux serveurs HTTP et FTP sur l'Internet, et que vous bloquez tous les autres ports. Regardons l'image suivante à propos du FTP passif.

Image non disponible

Certains assistants conntrack sont déjà disponibles dans le noyau lui-même. Plus spécifiquement, les protocoles FTP et IRC possèdent des assistants. Si vous ne trouvez pas les assistants conntrack dont vous avez besoin dans le noyau, vous devriez regarder l'arborescence patch-o-matic dans le domaine utilisateur iptables. L'arborescence patch-o-matic peut contenir davantage d'assistants conntrack, comme ceux des protocoles ntalk ou H.323. S'ils ne sont pas disponibles dans l'arborescence patch-o-matic, vous avez plusieurs options. Soit vous cherchez dans le source CVS d'iptables, s'il a été récemment modifié, soit vous contactez la liste de diffusion Netfilter-develAnnexe E. Autres ressources et liens et demandez leurs disponibilités. Sinon, et s'il n'y a pas de projet en vue, lisez le Rusty Russell's Unreliable Netfilter Hacking HOW-TO dont le lien est dans Annexe E,Annexe E. Autres ressources et liens.

Les assistants conntrack peuvent être soit compilés statiquement dans le noyau, soit en modules. S'ils sont compilés en modules, vous pouvez les charger avec les commandes suivantes :

 
Sélectionnez
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
modprobe ip_conntrack_tftp
modprobe ip_conntrack_amanda

Notez que le traçage de connexion n'a rien à voir avec le NAT, et donc vous pouvez avoir besoin de davantage de modules si vous NATez les connexions. Par exemple, si vous voulez NATer et tracer les connexions FTP, vous aurez besoin du module NAT. Tous les assistants NAT débutent avec ip_nat_ et suivants ; exemple, l'assistant FTP NAT sera nommé ip_nat_ftp et le module IRC nommé ip_nat_irc. Les assistants conntrack suivent la même convention, et donc l'assistant IRC conntrack s'appellera ip_conntrack_irc, alors que l'assistant FTP conntrack sera nommé ip_conntrack_ftp. Comme dans la sortie d'écran ci-dessus.

8-10. Chapitre suivant

Dans le prochain chapitre nous verrons comment sauvegarder et restaurer les tables de règles en utilisant les programmes iptables-save et iptables-restore distribués avec les applications iptables.


précédentsommairesuivant

Copyright © 2001-2006 Oskar Andreasson
La permission est accordée de copier, distribuer et/ou modifier ce document selon les termes de la « GNU Free Documentation License », version 1.1; en précisant les sections « Introduction » et toutes les sous-sections, avec les en-têtes « Auteur: Oskar Andreasson ». Une copie de la licence est inclue dans la section intitulée « GNU Free Documentation License ».
Tous les scripts de ce tutoriel sont couverts par la GNU General Public License. Les scripts sont de source libre; vous pouvez les redistribuer et/ou les modifier selon les termes de la GNU General Public License publiée par la « Free Software Foundation », version 2.
Ces scripts sont distribués dans l'espoir qu'ils seront utiles, mais SANS AUCUNE GARANTIE; sans même la garantie implicite qu'ils soient VENDABLES ou une QUELCONQUE APTITUDE POUR UN PROPOS PARTICULIER. Voir la GNU General Public License pour plus de détails.
Vous devriez avoir une copie de la GNU General Public License dans ce tutoriel, dans la section intitulée « GNU General Public License »; si ce n'est pas le cas, écrivez à la Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.