Menu Fermer

Conntrack sur Linux : comment ça marche

Conntrack pour tracking connexion est un composant de la pile réseau et Netfilter qui permet de suivre les connexions réseaux.
Notamment avec Conntrack vous pouvez facilement suivre l’état des connexions réseaux (NEW, ESTABLISHED, RELATED et INVALID).
Enfin, cela permet de rendre le pare-feu Linux en mode stateful firewall.
Ainsi, on peut utiliser l’état et suivi de connexion dans Iptables pour affiner les règles de pare-feu.

Dans cet article, vous trouverez des explications et descriptions de Conntrack sur Linux.

Conntrack sur Linux

Qu’est-ce que Conntrack sur Linux

Conntrack est un composant de Netfilter qui permet de suivre les connexions réseaux dans Linux.
Il trace les connexions afin de connaître leur état.

NetFilter trace les connexions dans la partie PREROUTING pour les paquets passant par une interface.
Mais aussi dans la chaîne OUTPUT et INPUT quand il s’agit de paquet liés à des processus locaux.

Schéma du NETFilter avec les différents couches
source wikipedia

Ce suivi est généralement implémenté sous la forme d’une grande table, avec au moins 6 colonnes : protocole (généralement TCP ou UDP), IP source, port source, IP de destination, port de destination et état de connexion.
Le système d’exploitation Linux stocke alors les connexions et les relations entre les connexions entrantes et sortantes.

Sous Linux, ce sous-système est appelé “conntrack” et est souvent activé par défaut.

Lister le contenu de la table conntrack sur Linux

Enfin on peut très facilement suivre la “vie” d’une connexion lorsqu’elle arrive dans la table (NEW), son statut est modifié (UPDATE) ou détruit (DESTROY).

Etat et suivi de la table conntrack sur Linux

La taille de la table conntrack est définie dans le fichier suivant.

cat /proc/sys/net/nf_conntrack_max
262144

Lorsque celle-ci est pleine, par exemple pendant une attaque DoS, les paquets suivants seront supprimées.
On peut alors trouver la mention ip_conntrack Table full. Dropping packet dans les logs et journaux Linux.

Enfin on peut utiliser ces tables pour du monitoring dans des outils de surveillance comme munin.
Cela permet de surveiller l’état des connexions d’un serveur par exemple.

Surveiller les connexions établies avec muning et le traçage de connexion conntrack

Comment lister les connexions établies et leurs états avec Conntrack

Linux propose un utilitaire conntrack-tools.
Ce dernier permet d’interroger la table afin de lister les connexions réseaux.
Cet outil peut être utilisé pour rechercher, répertorier, inspecter et maintenir le sous-système de suivi de connexion du noyau Linux.
En utilisant conntrack, vous pouvez vider une liste de tous (ou un filtre
sélection de) connexions actuellement suivies, supprimer des connexions de la table d’état, et même en ajouter de nouveaux.

Sur des distributions à base de Debian, on peut l’installer avec apt-get :

apt-get install conntrack

Il existe deux tables conntrack par défaut :

  • conntrack: il s’agit de la table par défaut. Il contient une liste de toutes les connexions actuellement suivies via le système. Si vous n’utilisez pas d’exemptions de suivi de connexion (cible NOTRACK iptables), cela signifie toutes les connexions qui transitent par le système.
  • attended : c’est le tableau des attentes. Les attentes de suivi des connexions sont le mécanisme utilisé pour “RELATED” aux connexions LIÉES à celles existantes. Les attentes sont généralement utilisées par les «assistants de suivi de connexion» (parfois appelés passerelles de niveau application [ALG]) pour des protocoles plus complexes tels que FTP, SIP, H.323.

Pour lister toutes les connexions :

conntrack -L
Lister le contenu conntrack sur Linux

Mais on peut aussi afficher la table de suivi au format oxml :

conntrack -L -o xml

Plusieurs options sont disponibles pour filtrer la liste des connexions établies.

-n, –src-nat — IP source IP NAT
-g, –dst-nat — IP IP NAT de destination
-j, –any-nat — IP source ou destination IP NAT
-m, –mark marque — Définir la marque
-c, –secmark secmark — Définir la marque de sécurité selinux
-e, –event-mask eventmask — Masque d’événement, par exemple. NOUVEAU, DÉTRUIRE

Par exemple pour lister les connexions avec 37.187.12.100 en IP source ou distante.

conntrack -L -d 37.187.12.100
Lister une adresse IP dans conntrack

Lister que les connexions ayant pour source du NAT :

conntrack -L --src-nat

Enfin il est tout à fait possible de supprimer des entrées de la table conntrack.
Par exemple pour supprimer toutes les connexions avec comme IP source 1.2.3.4 :

conntrack -D -s 1.2.3.4

Le contenu d’une entrée conntrack

Voici en détails, le contenu d’une entrée conntrack avec l’état des connexions :

tcp      6 431991 ESTABLISHED src=37.187.12.100 dst=45.129.96.30 sport=33398 dport=443 src=45.129.96.30 dst=37.187.12.100 sport=443 dport=33398 [ASSURED] mark=0 use=1

On trouve alors dans l’ordre :

  • Le protocole TCP, UDP, ICMP
  • A nouveau le protocole mais avec son numéro d’identification
  • Le temps de suivi de la connexion conntrack ici, 431991, après lequel il expire
  • L’état de la connexion, ici ESTABLISHED donc établit. On peut avoir SYN_SENT, TIME_WAIT, etc.
  • l’IP source avec src=
  • L’IP distante avec dst=
  • Le port réseau source sport=
  • Le port réseau distant dport=
  • On retrouve la même chose avec le paquet de retour et donc les IP et ports inversées
  • Le statut ASSURED nous indique que cette connexion est assurée et qu’elle ne sera pas effacée si nous atteignons le maximum de connexions suivies possibles. Ainsi, les connexions marquées comme ASSURÉES ne seront pas effacées. 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

Ci-dessous, on retrouve le même contenu pour un paquet en UDP :

udp 17 175 src=37.187.12.100 dst=213.186.33.99 sport=51413 dport=53 src=213.186.33.99 dst=37.187.12.100 sport=53 dport=51413 [ASSURED] mark=0 use=1

A lire éventuellement sur le sujet :

Les statut Conntrack

Voici les explications autour des statut conntrack :

  • EXPECTED : Il s’agit d’une connexion attendue (c’est-à-dire qu’un assistant conntrack l’a configurée)
  • SEEN_REPLY : Conntrack a vu des paquets dans les deux sens.
  • ASSURED : L’entrée Conntrack ne doit jamais être expirée prématurément.
  • CONFIRMED : La connexion est confirmée: le paquet d’origine a quitté la boîte.

Les états de connexions

Enfin les états de connexions Conntrack :

  • NEW – Un paquet demandant une nouvelle connexion, telle qu’une requête HTTP. Aucun autre paquet n’est en relation avec ce dernier.
  • ESTABLISHED – Un paquet qui fait partie d’une connexion existante.
  • RELATED – Un paquet qui demande une nouvelle connexion mais fait partie d’une connexion existante. Par exemple, FTP utilise le port 21 pour établir une connexion, mais les données sont transférées sur un port différent (généralement le port 20).
  • INVALID – Un paquet qui ne fait partie d’aucune connexion dans la table de suivi des connexions.

Conntrack dans Iptables

Iptables suit la progression des connexions tout au long du cycle de vie de la connexion, afin que vous puissiez inspecter et restreindre les connexions aux services en fonction de leur état de connexion.
Ainsi il devient un firewall stateful.

Je rappelle qu’il existe un tutoriel complet sur Iptables sur le site :

Pour cela, NEW, ESTABLISHED, RELATED et INVALID.

Tout le suivi de connexion est géré dans la chaîne PREROUTING, à l’exception des paquets générés localement qui sont traités dans la chaîne OUTPUT. Cela signifie que iptables effectuera tout le recalcul des états et ainsi de suite dans la chaîne PREROUTING. Si nous envoyons le paquet initial dans un flux, l’état est défini sur NEW dans la chaîne OUTPUT, et lorsque nous recevons un paquet de retour, l’état est changé dans la chaîne PREROUTING en ESTABLISHED, et ainsi de suite.
Si le premier paquet n’est pas originaire de nous-mêmes, l’état NEW est bien entendu défini dans la chaîne PREROUTING.
Ainsi, tous les changements d’état et calculs sont effectués dans les chaînes PREROUTING et OUTPUT de la table nat.

Exemple de règles iptables avec du suivi de connexion

On peut donc viser des connexions réseaux par leur état avec le paramètre -m –state.
En version longue, cela donne : -m conntrack –ctstate

Par exemple ci-dessous, on autorise toutes les nouvelles connexions entrantes, établies ou en lien vers le port 443.
Par contre, seules les connexions établies ou en lien avec une connexion entrante sont autorisés en sortie depuis le port 443.

iptables -A INPUT -i eth0 -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -p tcp --sport 443 -j ACCEPT

Contrairement donc, il s’agit de règle iptables pour un serveur WEB en HTTPS.

Le suivi de connexion conntrack est aussi utile pour des protocoles complexes comme FTP.
En effet, il existe un module du noyau Linux pour ce dernier : ip_conntrack_ftp
Avec ce dernier, vous pouvez faire facilement correspondre un état de connexion entre le port de connexion (21 par défaut) et le port data (20 par défaut).
La connexion au port data ne sera possible que si une connexion au port 21 est au préalable établit.

Ainsi voici les règles iptables pour un serveur FTP.
On autorise les nouvelles connexions entrantes (NEW) vers le port 21 pour un serveur FTP.

iptables -A INPUT  -p tcp -m tcp --dport 21 -m conntrack --ctstate ESTABLISHED,NEW -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 21 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

Puis la même chose pour le port 20 mais seulement si une connexion est au préalable établit (ESTABLISHED, RELATED).

iptables -A INPUT  -p tcp -m tcp --dport 20 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --dport 20 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Enfin on peut aussi autoriser la connexion entre les ports 1024:32535 pour le FTP passif.
Là aussi, seulement si une connexion a déjà été établie.

iptables -A INPUT  -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 1024: --dport 1024: -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Iptables et conntrack : des règles de pare-feu plus sures et précises

Conntrack est donc très utile dans iptables.
Cela permet d’affiner les règles et rendre ainsi le pare-feu plus précis et plus sûr.
En effet, imagions ces règles iptables :

iptables -A INPUT -i eth0 -p tcp --dport 443 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -j ACCEPT

La second règle OUTPUT ne vérifie pas l’état de connexion.
Ainsi, un processus malveillant peut très bien se connecter à un site WEB distant.
Comme par exemple, un trojan pour contacter le serveur de contrôle.
Avec le traçage de connexion conntrack, vous pouvez bloquer cela puisqu’il faut qu’une connexion liée entrant soit établie avant.

Liens