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. A cet instant, la connexion est
établie et prête à envoyer des données. La 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 standards spécifiés dans la RFC 793 - Transmission
Control Protocol aux pages 21-23.
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.
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.
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.
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.
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 2 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 soit 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 leurs valeurs 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.
Note | |
---|---|
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 » de l'annexe 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 |