Outils pour utilisateurs

Outils du site


Ceci est une ancienne révision du document !


IPtables

Pour manipuler les poignées de Netfilter, les outils «iptables» ont été développés à partir du noyau Linux 2.4, à partir de 1998. Avant ça, il y a eu d'abord «ipfwadm» avec les noyaux 2.0, très rudimentaire, puis «ipchains» avec les noyaux 2.2.

Bien que frappé d'obsolescence au profit de Nftables», cette suite d'outils (au 29/03/2025) a vu sa dernière révision en novembre 2024. À ce jour, de très nombreux firewalls en exploitation sont encore construits avec ces outils ou avec des surcouches de ces outils, si bien qu'il faut encore en parler.

Des règles de base pour IPv4

Pour cette étude, comme d'habitude, une maquette virtuelle fera l'affaire. Reprenons celle utilisée pour l'exposé sur DHCP: Maquette virtuelle La station qui fait office de routeur/DHCP/DNS va en plus devoir assurer la protection du LAN en vert, autant en IPv4 d'abord.

Protection du serveur lui-même

  1. Étant serveur DNS et DHCP pour le LAN 192.168.61.0/24, il doit accepter toutes les requêtes entrant par enp7s0 sur les ports concernés à savoir:
    • port 53 pour DNS;
    • port 67 pour DHCP.
  2. En revanche, ces requêtes ne doivent pas être acceptées venant du LAN 192.168.60.0/24.
  3. l'accès à Telnet ne doit être autorisé qu'à 192.168.61.254, station de l'administrateur
  4. Rien ne doit entrer sur enp1s0 hormis les réponses aux connexions que lui-même a initiées, ce qui inclut le nécessaire pour ses mises à jour et pour le bon fonctionnement du cache DNS.

Nous pouvons faire ceci de suite:

iptables -t filter -A INPUT -i enp7s0  -p udp -m multiport --dports 53,67 -j ACCEPT
  • -t filter indique que l'on charge dans la table «Filter», mais ceci est optionnel parce qu'implicitement, c'est cette table qui est choisie;
  • -A INPUT Ajoute à la chaîne «INPUT» ce qui suit:
    • -i enp7s0 «input» enp7s0
    • -p udp «protocol» UDM
    • -m multiport «match» multiport. C'est pour signaler que l'on a besoin d'un module de test additionnel, ici un module capable de tester si un port dans le paquet se trouve dans la liste (53,67)
    • -j ACCEPT Alors si un paquet entrant par enp7s0 contient un datagramme udp avec un port (source ou destination) égal à 53 ou 67, il faut laisser passer.
iptables -A INPUT -i enp7s0 -p tcp --dport 23 -s 192.168.61.254 -j ACCEPT

Si, en entrant par enp7s0, ça vient de la source 192.168.61.254 (-s 192.168.61.254) à destination du port 23 (–dport 23) On accepte, car c'est le port Telnet ouvert exclusivement pour la station de l'administrateur.

iptables -A INPUT -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Cette fois-ci nous nous occupons de ce qui entre par enp1s0

  • -m conntrack ici nous faisons appel au module conntrack pour vérifier si l'état d'un paquet qui entre est dû à une connexion déjà établie ou en relation avec une connexion déjà établie. Si c'est le cas, le paquet est accepté.

Un exemple: le routeur/DHCP/DNS a envoyé une requête à un DNS «SOA». C'est un paquet sortant autorisé par défaut ici. La réponse à ce paquet est considérée par le module conntrack comme faisant partie d'une connexion déjà établie. C'est facile à faire en TCP, moins en UDP mais il est fort, ce module…

En revanche, quelqu'un de l'extérieur enverrait une requête DNS sur enp1s0, elle serait considérée comme «NEW» et donc rejetée par cette règle.

Nous allons tout de même accepter ICMP sur les deux interfaces:

iptables -A INPUT -p ICMP -j ACCEPT

Pour finir, la règle par défaut qu'il vaut mieux définir en dernier, de manière à ce que l'administrateur ait déjà l'autorisation d'accéder à la machine depuis sa station de travail:

iptables -P INPUT DROP

Concernant le LAN 192.168.61.0/24

Il ne faut permettre dans le sens enp1s0 → enp7s0 que les connexions établies ou relatives à des connexions établies. On sait déjà faire, il suffit de l'appliquer ici à la chaîne FORWARD. C'est toujours sous-entendu du filtrage. Donc:

iptables -A FORWARD -i enp1s0 -o enp7s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

-i comme «input» et -o comme «output». Ce qui entre pas enp7s0 pour ressortie par enp1s0 n'a à priori aucune raison d'être filtré ici. Mais nous avons appris dans l'exercice de routage qu'il fallait faire du masquage d'adresses dans ce sens pour assurer le chemin de retour depuis l'internet vers 192.168.61.0/24 en passant par 192.168.60.0/24:

iptables -t nat -A POSTROUTING  -o enp1s0 -j MASQUERADE

Dans la table «nat», il faut ici le spécifier, dans la chaîne POSTROUTING , ce qui sort par enp1s0

Et maintenant pour IPv6

Toujours la même maquette, mais avec les adresses IPv6 suivantes pour le serveur:

  • enp1s0 dans le LAN orange:
    • 2a01:e0a:875:b1d0:5054:ff:fe74:45f2 lien global
    • fe80::5054:ff:fe74:45f2 lien local
  • enp7s0 dans le LAN vert:
    • 2a01:e0a:875:b1d2::1 lien global
    • fe80::5054:ff:fe78:2d7e lien local

Protection du serveur:

Depuis l'extérieur, l'idée reste la même que pour IPv4:

ip6tables -A INPUT -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Cependant, il faut ajouter icmp pour les annonces et découvertes des voisins, aussi bien du côté orange que du côté vert:

ip6tables -A INPUT -p icmp -j ACCEPT

En ce qui concerne les adresses de lien local, nous n'allons pas être paranoïaques au point de suspecter l'entourage immédiat du serveur:

ip6tables -A INPUT -s fe80::/64 -j ACCEPT

Avant d'appliquer la règle par défaut sur les entrées, il faut autoriser les membres du LAN vert à interroger le serveur DNS:

ip6tables -A INPUT -p udp --dport 53 -j ACCEPT

Et enfin:

ip6tables -P INPUT DROP

Concernant la délégation 2a01:e0a:875:b1d2::/64

Ici plusieurs options sont possibles. Avec IPv4, les nouvelles connexions depuis l'internet vers le LAN vert sont naturellement impossibles puisque les IP 192.168.61.0/24 ne sont pas routables, mais avec des adresses lien-global routables, le problème est différent.

Le plus simple est juste d'interdire aux nouvelles connexions entrant pas enp1s0 de traverser le routeur

ip6tables -A FORWARD -i enp1s0 -m conntrack --ctstate NEW -j REJECT
ip6tables -A FORWARD -i enp1s0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Ainsi comme pour IPv4 seules les connexions initiées depuis l'intérieur de la délégation ouvriront le pare-feu pour laisser passer les réponses, mais il faut également penser à bloquer les nouvelles explicitement

Ici en revanche, il n'est pas nécessaire de faire du marquage d'adresse puisque les adresses lien-global IPv6 dans la délégation sont routables et que le routeur de la Freebox sait y accéder.

Il n'y a à priori plus rien à faire en fonction du cahier des charges initial

Synthèse

Nous venons de voir les règles les plus souvent utilisées. Nous en verrons d'autres exemples plus loin. Reste à savoir si ça fonctionne bien comme prévu.

Un client d'adresse 192.168.61.101 fait un ping sur 194.177.211.216 (www.debian.org)

ping -c1 194.177.211.216

PING 194.177.211.216 (194.177.211.216) 56(84) bytes of data.
64 bytes from 194.177.211.216: icmp_seq=1 ttl=57 time=65.6 ms

--- 194.177.211.216 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 65.622/65.622/65.622/0.000 ms
Donc le routage masqué fonctionne et les clients verts (192.168.61.0/24) accèdent bien à l'internet.

IPtables: Dernière modification le: 31/03/2025 à 12:43 par prof