IPTables

De Justine's wiki
Aller à la navigation Aller à la recherche

Généralités : les pare-feux Linux

https://cybersecuritynews.com/linux-firewall-iptables/ https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture

Un pare-feu Linux est un appareil ou un composant quelconque qui inspecte le traffic réseau et décide le laisser passer ou non. Iptables est un outil permettant de gérer les règles de pare-feu sous Linux. La sécurité réseau a évolué avec les différents types de pare-feux qui ont existé à travers les âges : traditionnellement, les fw gèrent les couches 3 et 4, soit les couches routage et transport. Mais des pare-feux plus récents peuvent agir sur les couches plus hautes, par exemple pour analyser le trafic au niveau applicatif.

Iptables, c'est quoi

IPTables est une interface en ligne de commandes qui permet de configurer des règles spécifiques, lesquelles iront forcer le kernel avec sa couche netfilter à faire des actions comme inspecter, modifier ou dropper des paquets. Le fait d'utiliser IPtables permet d'accéder à des fonctions de pare-feu, mais aussi des fonctionnalités de routeur.

Différents modules de kernel et programmes sont utilisés pour différents protocoles : iptables est valide pour ipv4, ip6tables pour ipv6, arptables pour arp, ebtables pour les trames ethernet; etc. Le projet nftables, lui, a été développé pour la performance et la scalabilité et son fonctionnement est différent.

Comment marche le filtrage de paquets

Une policy iptables est construite avec un set ordonné de règles, lesquelles disent au kernel les actions qu'il devrait faire sur certains types de paquets.

Hooks netfilter

Il y a 5 hooks netfilter que les programmes peuvent utiliser. Alors qu'un paquet passe dans la stack, il va déclencher les modules de kernel associés à ces hooks (l'image étant que le paquet passant dans la stack s'accroche à certains crochets, un peu comme un steak sur un tapis roulant je suppose :thinking:). Les hooks déclenchés dépendent de la direction du paquet (in ou out), sa destination, et si il a déjà été droppé ou rejeté dans le passé.

Les hooks suivants représentent des points bien définis de la stack:

  • NF_IP_PRE_ROUTING : Sera activé par n'importe quel traffic entrant peu après son arrivée dans la stack. Ce hook est pris en compte avant toute décision de routage.
  • NF_IP_LOCAL_IN : Sera activé par un paquet entrant qui a été routé, si celui-ci est destiné au système local.
  • NF_IP_FORWARD : Activé après qu'un paquet entrant ait été routé vers un autre host que le système local.
  • NF_IP_LOCAL_OUT : Activé par n'importe quel traffic à destination de l'extérieur, qui a été créé sur le système local, dès son entrée dans la stack.
  • NF_IP_POST_ROUTING : Activé par n'importe quel traffic forwardé ou sortant après le routage et avant l'envoi sur le câble.

Les modules de kernel qui veulent s'enregistrer auprès de ces hooks (pour pouvoir faire des choses lors du déclenchement des hooks) doivent fournir un numéro de priorité pous savoir dans quels ordre ils seront appellés. Ainsi, on peut connecter plusieurs modules à chacun des hooks, le tout dans un ordre déterminé. Chaque module sera appellé à son tour et rendra une décision au framework netfilter pour indiquer ce qu'il doit advenir du paquet.

Tables et chaînes

Iptables utilise des tables pour stocket ses règles : il s'agit de tables au même sens que dans une BDD. Ces tables sont chacune fonction d'un type de décision, et vont stocker des règles en rapport : par exemple, la table nat stocke tout ce qui a trait au nat. La table filter gère le filtrage des paquets en fonction de leur destination, par exemple.

Pour chaque table, les règles sont organisées dans des chaînes. Tandis que les tables sont définies de façon généraliste, les chaînes représentent quels "hooks" seront associés. En somme, les chaînes déterminent à quelle condition les règles seront évaluées. Les chaînes reprennent les noms des hooks netfilter:

  • PREROUTING représente NF_IP_PRE_ROUTING
  • INPUT représente NF_IP_LOCAL_IN
  • FORWARD représente NF_IP_FORWARD
  • OUTPUP représente NF_IP_LOCAL_OUT
  • POSTROUTING représente NF_IP_POST_ROUTING.

Chaque table ayant plusieurs chaînes, elle peut intervenir à plusieurs endroits de la stack. Cela dit, toutes les tables n'ont pas toutes les chaînes, cela dépend de ce qui est logique avec leur nature. Il n'y a que 5 hooks, ce qui fait que les chaînes de plusieurs tables sont présentes à chaque hook : par exemple, il existe 3 tables ayant des chaînes PREROUTING. Elles sont donc hiérarchisées entre elles au niveau du hook.

Il existe plusieurs tables:

  • filter : la plus utilisée. Prend des décisions pour laisser un paquet continuer vers sa destination ou non. C'est la table de filtrage qui fait le gros de ce qu'on attend d'un fw.
  • nat : Sert à implémenter la traduction d'adresses. Les règles de cette table vont déterminer les modifications du paquet en lien avec la source / la dest afin d'avoir du nat.
  • mangle : Utilisée pour altérer les en-têtes IP du paquet de plusieurs façons. Elle peut par exemple ajuster le ttl, modifiant ainsi le nombre de sauts valides pour le paquet. Elle peut aussi mettre une marque sur le paquet à destination du kernel, qui ne touche pas au contenu mais permettra divers traitements.
  • raw : iptables est statefull, donc les paquets sont gérés en fonction de leur relation à ce qui s'est passé avant. Ainsi, netfilter permet de voir les paquets comme faisant partie d'une connection et pas simplement comme des colis. Cette logique de connection s'applique très tôt après que le paquet soit arrivé sur l'interface réseau. La table raw ne sert qu'à une chose : permettre de marquer les paquets pour s'échapper de cette logique de connection.
  • security : Utilisée pour gérer les marques en lien avec le contexte de sécurité interne de SELinux.

Lien entre tables et chaînes

Le tableau qui suit indique quelles chaînes sont dispo pour chaque table, de gauche à droite en fonction de l'ordre des hooks. Lu de haut en bas, il indique l'ordre dans lequel les tables accèdent aux hooks. Il faut noter que la table NAT a été subdivisée : DNAT est pour Destination NAT et SNAT pour Source NAT. On indique aussi des points du routage sont prises et ou la gestion des connections est activées afin de donner une vue généraliste du processus :

Ordre de traversée des chaînes

En supposant qu'on sait comment router le paquet et qu'il a le droit d'être là en fonction des règles de fw, le flux suivant représente le chemin traversé selon la situation:

  • Paquets entrant pour le système local : PREROUTING -> INPUT
  • Paquets entrants à forwarder : PREROUTING -> FORWARD -> POSTROUTING
  • Paquets générés localement : OUTPUT -> POSTROUTING

Ainsi, un paquet entrant pour le système local va passer par PREROUTING et activer les chaînes des tables raw, mangle, nat; puis par INPUT et activer les chaines des tables mangle,filter,security,nat. Dans cet ordre.

Règles IPTables

Les règles se placent à l'intérieur des chaînes. Lorsqu'un paquet déclenche la chaîne, il est comparé aux règles, une par une et dans l'ordre.

Match

La portion 'matching' d'une règle spécifie les critères pour lesquels un paquet pour l'action (ou target) de la règle soit exécutée. Le système de matching est souple et peut être étendu à l'aide des extensions d'IPTables disponibles au niveau du système. Les règles peuvent matcher sur :

  • protocole
  • adresse source / dst
  • port source / dst
  • réseau source / dst
  • interface entrée / sortie,
  • les headers
  • l'état de la connection
  • et autres, les critères pouvant être combinés.

Targets

Les targets, qui sont les actions déclenchées lors d'un match, peuvent être divisées en 2 catégories:

  • Terminating targets : Ce genre de target termine l'évaluation de la chaîne : on ne traite plus de règles après celles-ci et on renvoie le contrôle au hook netfilter. En fonction de la valeur retournée, on peut dropper le paquet ou le laisser continuer sur la chaine.
  • Non-terminating targets : Celles-ci ne terminent pas l'évaluation de la chaîne. Elles font une action et laisse l'évaluation de la chaîne continuer. Bien que toute chaîne doive donner une décision finale, un certain nombre de non-terminating targets peuvent avoir lieu entretemps.

La disponibilité de chacune des targets dépend de la table et de la chaîne, cela est fonction du contexte.

Jumping et chaînes utilisateur

Bien que les chaînes soit fortement liées aux hooks netfilter, l'utilisateur peut créer ses propres chaînes qui seront prises en compte. Les jump targets sont des actions qui font que l'évaluation passera à une autre chaîne pour prise en compte. Les règles vont dans les chaînes utilisateurs de la même manière que pour les autres chaînes; cependant, elle ne seront atteintes qu'après un jump vers celle-ci. En effet, les chaînes utilisateur n'agissent que comme une extension de la chaîne y menant : lors de l'évaluation dans une chaîne utilisateur, l'évaluation retournera à la chaîne d'origine si on atteint une target RETURN ou le bout de la chaîne utilisateur. L'évaluation peut aussi JUMP vers une autre chaîne.

Suivi de connexions

Le suivi de connexion implémenté par-dessus netfilter a déjà été évoqué avec la table raw. Ce suivi de connexion permet à iptables de voir les paquets dans le contexte d'une connexion et non pas comme un simple paquet tout seul et ainsi d'avoir un pare-feu stateful.

Le suivi de connexion s'applique très tôt après l'arrivée d'un paquet dans la stack, et la seule logique appliquée avant ça est la table raw ainsi que certains contrôles de sanité. Le système vérifie chaque paquet en regard d'un ensemble de connexions existantes, et mets à jour le statut des connexions si besoin. Les paquets marqués avec NOTRACK dans une règle de la table raw échapperont à cette logique de connexion.

Une connexion peut avoir plusieurs états:

  • NEW : Si un paquet arrive, qu'il n'est pas associé à une connexion et est valide en tant que premier paquet, une connexion NEW est ajoutée. Cela se produit pour TCP par exemple, mais aussi pour des protocoles sans connexion comme UDP.
  • ESTABLISHED : Une connection NEW qui reçoit une réponse valide passe à l'état ESTABLISHED. En TCP, cela signifie un syn/ack, et pour UDP ou ICMP une réponse ou la source et la destination du paquet sont inversées par rapport au premier paquet.
  • RELATED : Les paquets ne faisant pas partie d'une connexion mais étant en lien avec l'une de celles-ci sont marqués RELATED. Cela peut signifier une connexion "helper", comme avec le FTP et ses transmissions d'envoi de données ou bien des réponses ICMP à des tentatives de connexion d'autres protocoles.
  • INVALID : Les paquets n'étant pas liés à une connexion et ne pouvant pas commencer une connexion sont marqués comme INVALID. Ils peuvent par exemple être impossible à identifier, inroutables, etc.
  • UNTRACKED : Les paquets seront marqués UNTRACKED si une règle de la table raw leur fait bypasser le tracking.
  • SNAT : État virtuel dans lequel l'adresse source a été altérée par le NAT. Utilisé par le système de tracking pour qu'il soit au courant qu'il doit changer l'adresse lors de la réponse.
  • DNAT : Même chose, mais avec l'adresse de destination. Ainsi, le système saura qu'il doit changer l'adresse de réponse lors du routage du paquet.

Aller plus loin

Article sur les stratégies de fw