Product SiteDocumentation Site

14.2. Pare-feu ou filtre de paquets

Un pare-feu est une passerelle filtrante : il applique des règles de filtrage aux paquets qui le traversent (c'est pourquoi il n'est utile qu'en tant que point de passage obligé).
L'absence de configuration standard explique qu'il n'y ait pas de solution prête à l'emploi. Des outils permettent en revanche de simplifier la configuration du pare-feu netfilter en visualisant graphiquement les règles définies. L'un des meilleurs est sans doute fwbuilder.
Le noyau Linux intègre le pare-feu netfilter ; les outils iptables et ip6tables permettent de le configurer. La différence entre ces deux outils se limite à ce que le premier agit sur le réseau IPv4 alors que le second intervient sur le réseau IPv6. Les deux piles réseau étant amenées à cohabiter pendant de nombreuses années, il faudra faire usage des deux outils en parallèle.

14.2.1. Fonctionnement de netfilter

netfilter dispose de quatre tables distinctes, donnant les règles régissant trois types d'opérations sur les paquets :
  • filter pour les règles de filtrage (accepter, refuser, ignorer un paquet) ;
  • nat pour modifier les adresses IP et les ports sources ou destinataires des paquets ;
  • mangle pour modifier d'autres paramètres des paquets IP (notamment le champ ToS — Type Of Service — et les options) ;
  • raw pour effectuer des manipulations manuelles sur les paquets avant que le suivi de connexion entre en jeu.
Chaque table contient des listes de règles appelées chaînes ; les chaînes standards servent au pare-feu pour traiter les paquets dans différentes circonstances prédéfinies. L'administrateur peut créer d'autres chaînes, qui ne seront employées que si l'une des chaînes standards les appelle.
La table filter compte trois chaînes standards :
  • INPUT : concerne les paquets destinés au pare-feu ;
  • OUTPUT : concerne les paquets émis par le pare-feu ;
  • FORWARD : appliquée aux paquets transitant via le pare-feu (et dont il n'est donc ni la source ni le destinataire).
La table nat dispose également de trois chaînes standards :
  • PREROUTING : modifie les paquets dès qu'ils arrivent ;
  • POSTROUTING : modifie les paquets alors qu'ils sont prêts à partir ;
  • OUTPUT : modifie les paquets générés par le pare-feu lui-même.
Ordre d'emploi des chaînes de netfilter

Figure 14.1. Ordre d'emploi des chaînes de netfilter

Chaque chaîne est une liste de règles, prévoyant une action à exécuter quand certaines conditions sont remplies. Le pare-feu parcourt séquentiellement la chaîne s'appliquant au paquet traité et dès qu'une règle est satisfaite, il « saute » (l'option -j vient de jump) à l'emplacement indiqué pour continuer le traitement. Certains de ces emplacements sont standardisés et correspondent aux actions les plus courantes. Une fois une de ces actions enclenchée, le parcours de la chaîne est interrompu parce que le sort du paquet est normalement décidé (sauf exception explicitement mentionnée ci-après) :
  • ACCEPT : autoriser le paquet à poursuivre son parcours ;
  • REJECT : rejeter le paquet (ICMP signale une erreur, l'option --reject-with type d'iptables permet de choisir le type d'erreur renvoyée) ;
  • DROP : supprimer (ignorer) le paquet ;
  • LOG : enregistrer (via syslogd) un message de log contenant une description du paquet traité (cette action retourne après exécution à sa position dans la chaîne appelante — celle qui a invoquée l'action — c'est pourquoi il est nécessaire de la faire suivre par une règle REJECT ou DROP si l'on veut simplement enregistrer la trace d'un paquet qui doit être refusé) ;
  • ULOG : enregistrer un message de log via ulogd, plus adapté et plus efficace que syslogd pour gérer de grandes quantités de messages (cette action renvoie aussi le fil d'exécution à sa position dans la chaîne appelante) ;
  • nom_de_chaîne : évaluer les règles de la chaîne indiquée ;
  • RETURN : stopper l'évaluation de la chaîne courante et revenir sur la chaîne appelante (si la chaîne courante est une chaîne standard, dépourvue de chaîne appelante, effectuer l'action par défaut — il s'agit d'une action particulière qui se configure avec l'option -P de iptables) ;
  • SNAT (seulement dans la table nat : effectuer du Source NAT (des options précisent les modifications à effectuer) ;
  • DNAT (seulement dans la table nat) : effectuer du Destination NAT (des options précisent les modifications à effectuer) ;
  • MASQUERADE (seulement dans la table nat) : effectuer du masquerading (SNAT particulier) ;
  • REDIRECT (seulement dans la table nat) : rediriger un paquet vers un port particulier du pare-feu lui-même ; action notamment utile pour mettre en place un mandataire (ou proxy) web transparent (il s'agit d'un service pour lequel aucune configuration côté client n'est nécessaire, puisque le client a l'impression de se connecter directement au destinataire alors que ses échanges avec le serveur transitent systématiquement par le mandataire).
D'autres actions, concernant davantage la table mangle, ne sont pas mentionnées ici. Vous en trouverez la liste exhaustive dans les pages de manuel iptables(8) et ip6tables(8).

14.2.2. Syntaxe de iptables et ip6tables

Les commandes iptables et ip6tables permettent de manipuler les tables, les chaînes et les règles. L'option -t table indique la table sur laquelle opérer (par défaut, c'est filter).

14.2.2.1. Les commandes

L'option -N chaîne crée une nouvelle chaîne ; l'option -X chaîne supprime une chaîne vide et inutilisée. L'option -A chaîne règle ajoute une règle à la fin de la chaîne indiquée. L'option -I chaîne numrègle règle insère une règle avant la règle numérotée numrègle. L'option -D chaîne numrègle ou -D chaîne règle supprime une règle dans la chaîne (la première syntaxe l'identifie par son numéro et la seconde par son contenu). L'option -F chaîne supprime toutes les règles de la chaîne (si celle-ci n'est pas mentionnée, elle supprime toutes les règles de la table). L'option -L chaîne affiche le contenu de la chaîne. Enfin, l'option -P chaîne action définit l'action par défaut pour la chaîne donnée (seules les chaînes standards peuvent en avoir une).

14.2.2.2. Les règles

Chaque règle s'exprime sous la forme conditions -j action options_de_l'action. En écrivant bout à bout plusieurs conditions dans la même règle, on en produit la conjonction (elles sont liées par des et logiques), donc une condition plus restrictive.
La condition -p protocole sélectionne selon le champ protocole du paquet IP, dont les valeurs les plus courantes sont tcp, udp, icmp et icmpv6. Préfixer la condition par un point d'exclamation inverse la condition (qui correspond alors à tous les paquets n'ayant pas le protocole indiqué). Cette manipulation est possible pour toutes les autres conditions énoncées ci-dessous.
La condition -s adresse ou -s réseau/masque vérifie l'adresse source du paquet ; -d adresse ou -d réseau/masque en est le pendant pour l'adresse de destination.
La condition -i interface sélectionne les paquets provenant de l'interface réseau indiquée ; -o interface sélectionne les paquets en fonction de leur interface réseau d'émission.
D'autres conditions plus spécifiques existent, qui dépendent des conditions génériques déjà définies. La condition -p tcp peut par exemple être accompagnée de conditions sur les ports TCP avec --source-port port et --destination-port port.
L'option --state état indique le statut du paquet dans une connexion (le module ipt_conntrack, qui implémente le suivi des connexions, lui est nécessaire). L'état NEW désigne un paquet qui débute une nouvelle connexion. L'état ESTABLISHED concerne les paquets d'une connexion existante et l'état RELATED les paquets d'une nouvelle connexion liée à une connexion existante (c'est le cas des connexions ftp-data d'une session ftp en mode "actif").
La section précédente détaille la liste des actions possibles, mais pas les options qui leur sont associées. L'action LOG dispose ainsi de plusieurs options visant à :
  • indiquer le niveau de sévérité du message à syslog (--log-level, dont la valeur par défaut est warning) ;
  • préciser un préfixe textuel pour différencier les messages (--log-prefix) ;
  • indiquer les données à intégrer dans le message (--log-tcp-sequence pour le numéro de séquence TCP, --log-tcp-options pour les options TCP et --log-ip-options pour les options IP).
L'action DNAT dispose de l'option --to-destination adresse:port pour indiquer la nouvelle adresse IP et/ou le nouveau port de destination. De la même manière, l'action SNAT dispose de l'option --to-source adresse:port pour indiquer la nouvelle adresse et/ou le nouveau port source.
L'action REDIRECT (seulement disponible si le NAT est disponible) a une option --to-ports port(s) pour indiquer le port ou l'intervalle de ports vers lesquels rediriger les paquets.

14.2.3. Créer les règles

Il faut invoquer iptables/ip6tables une fois par règle à créer ; c'est pourquoi on consigne habituellement tous les appels à cette commande dans un fichier de script pour mettre en place la même configuration à chaque redémarrage de la machine. On peut écrire ce script à la main mais il est souvent intéressant de le préparer à l'aide d'un outil de plus haut niveau, tel que fwbuilder.
# apt install fwbuilder
Son principe est simple. Dans une première étape, il faut décrire tous les éléments susceptibles d'intervenir dans les différentes règles :
  • le pare-feu et ses interfaces réseau ;
  • les réseaux (et plages d'IP associées) ;
  • les serveurs ;
  • les ports correspondant aux services hébergés sur les différents serveurs.
On crée ensuite les règles par simple glisser/déposer des différents objets, quelques menus contextuels servant à modifier la condition (l'inverser, par exemple). Il ne reste qu'à saisir l'action souhaitée et à la paramétrer.
On peut soit créer 2 jeux de règles différents pour IPv4 et IPv6, soit n'en créer qu'un seul et laisser fwbuilder traduire les règles adéquates en fonction des différentes adresses assignées aux objets manipulés.
Fwbuilder en action

Figure 14.2. Fwbuilder en action

fwbuilder peut alors générer un script de configuration du pare-feu selon les règles saisies. Son architecture modulaire lui permet de générer des scripts pour les pare-feu de différents systèmes (iptables pour Linux, ipf pour FreeBSD et pf pour OpenBSD).

14.2.4. Installer les règles à chaque démarrage

Dans les autres cas, le plus simple est d'inscrire le script de configuration du pare-feu dans une directive up du fichier /etc/network/interfaces. Dans l'exemple ci-dessous, ce script s'appelle /usr/local/etc/arrakis.fw.

Exemple 14.1. Fichier interfaces avec appel du script de pare-feu

auto eth0
iface eth0 inet static
    address 192.168.0.1
    network 192.168.0.0
    netmask 255.255.255.0
    broadcast 192.168.0.255
    up /usr/local/etc/arrakis.fw
Ces exemples supposent que les interfaces réseau sont configurées par ifupdown. Si vous utilisez un autre outil (par exemple NetworkManager ou systemd-networkd), il faudra vous référer à la documentation spécifique de cet outil pour trouver le moyen d'exécuter un script après la mise en marche de l'interface.