Introduction au firewall Linux : iptables

To the non-french speaker, note that you can translate the articles using the Google Trad widget situated at the bottom of all pages.


Aujourd’hui nous allons parler de firewall et plus particulièrement du firewall Linux : Iptables. Iptables c’est un outil qui a été codé par un développeur de génie : Rusty Russell en 1998. Son idée à lui, c’était de créer un outil qui permettrait de créer des règles de firewalling facilement. Et il a plutôt bien réussi !

I/ Iptables, la théorie

Pour intercepter les paquets entrants et sortants d’une interface, nous utilisons des règles Iptables. Ces règles respectent un certain format. Elles sont toutes composées d’une table, d’une chaîne, de paramètres et d’une cible. Voici à quoi ressemble une règle Iptables qui autorise les connexions entrantes vers le port 22 (sous entendu l’accès SSH) :

iptablesrules

« Ok mais c’est quoi une table, une chaîne, une cible et comment fonctionnent les paramètres ? » Eh bien nous allons voir ça en détails 😉😉 !

Il existe trois tables majoritaires répondant à trois problématiques bien précises : la table nat (responsable des translations NAT), la table filter, dont on se servira le plus, utilisée pour filtrer des flux et la table mangle (utilisée pour la modification de paquets bits à bits).

Notez bien que si vous ne spécifiez pas de tables lors de l’écriture de votre règle iptables alors la table utilisée par défaut sera la table filter. Autrement dit, les règles suivantes :

iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

et

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

sont équivalentes. A ces tables, il faut ajouter les chaînes qui sont au nombre de cinq. Ces cinq chaînes sont en fait les cinq hooks (accroches) qui permettent d’intercepter un paquet à cinq moments différents sur nos interfaces réseaux :

Ces cinq moments sont :

PREROUTING le hook va être déclenché juste après que le paquet soit arrivé sur notre interface réseau.
INPUT le hook est déclenché par tout trafic dont le destinataire est l’hôte (i.e : l’adresse IP du destinataire est celle de nôtre machine)
FORWARD le paquet est forwardé vers un hôte et déclenche ce hook au moment du routage.
OUTPUT le hook est déclenché par tout trafic émis par notre machine (i.e : l’adresse IP de la source est celle de nôtre machine)
POSTROUTING le hook est déclenché juste avant que le paquet ne quitte notre interface réseau.

Comme toujours je pense qu’un schéma est plus parlant que des mots donc voilà :

iptables.png

OK, maintenant que l’on sait ça, il est important de bien comprendre que les chaînes et les tables sont dépendantes les unes des autres et que l’on ne peut pas utiliser n’importe quelle chaîne avec n’importe quelle table.

Voici donc un tableau récapitulatif des chaînes utilisables en fonction des tables :

Table Chaines utilisables
FILTER INPUT
OUTPUT
FORWARD
NAT PREROUTING
OUTPUT
POSTROUTING
Mangle PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING

« Ok c’est bien beau tout ça mais tu ne nous as toujours pas expliqué ce qu’on pouvait faire avec ces fameuses iptables ? » Eh bien nous pouvons faire énormément de choses : bloquer les accès SSH, bloquer les requêtes sur certains ports, bloquer les communications avec certaines IP’s, bloquer certains protocoles ou encore intercepter des paquets pour en modifier le contenu.

Que vous interceptiez un paquet en PREROUTING, POSTROUTING, FORWARD, INPUT ou OUTPUT, vous pourrez effectuer plusieurs types d’actions dessus :

ACCEPT On laisse le paquet passer par notre interface réseau
DROP On bloque le paquet à l’entrée de notre interface
REJECT On bloque le paquet à l’entrée de notre interface
QUEUE
On place le paquet dans une file d’attente afin d’effectuer des actions dessus (coucou le DNS spoofing 😍😍 )
LOG Nous permettra de logger l’apparition de certains paquets (dans le fichier /var/log/kernel.log)

Attention cependant, les actions DROP et REJECT, même si elles rejettent le paquet, ne fonctionnent pas identiquement. Si vous spécifiez un DROP alors le paquet sera détruit et le l’expéditeur/destinataire ne recevra pas de messages d’erreur. En revanche avec l’action REJECT, il recevra un message d’erreur de ce type :

reject.png

Bueno passons à la partie pratique 😏😏 !

II/ Iptables, la pratique

Bon la première chose à faire, c’est d’afficher la configuration de base de nos Iptables. Pour cela on dispose de la commande suivante :

iptables -L

iptablesconf.png

Ici on voit que seule les chaînes INPUT, FORWARD et OUPUT sont affichées. Mais où sont passées les chaînes PREROUTING et POSTROUTING ?

Eh bien souvenez vous de ce que je vous ai dit plus tôt : par défaut la seule table qui est affichée est la table FILTER. Donc ici on ne voit que la configuration Iptables de la table FILTER. Si on veut afficher la configuration d’une autre table, il faudra la spécifier. Par exemple pour afficher la configuration de la table nat on utilisera cette commande :

iptables -t nat -L

iptablesnattable.png

En observant le rendu des deux commandes précédentes on remarque que la policy est configurée pour accepter tous les paquets (indiqué par la partie  policy ACCEPT). Sur une machine personnelle on peut se permettre de laisser la policy comme telle. En revanche sur un serveur on fera plutôt l’inverse : on bloque tous les flux par défaut et on autorise seulement ceux qui nous intéressent (pour un serveur web on autorisera les ports 80, 443 et 22 ou 3389 (pour l’administrer à distance)).

Sachez par exemple que sur le Cloud AWS, les security groups (les règles de firewall) sont configurées par défaut pour rejeter tout trafic. Voici les règles que l’on utiliserait avec iptables pour faire ce genre de manipulations :

iptables --policy INPUT DROP && iptables --policy OUTPUT DROP

En faisant ça, nous venons d’indiquer à la table FILTER qu’elle devait rejeter tout trafic entrant ou sortant de notre machine. Fini donc Internet, l’accès SSH, le FTP etc…

droppolicies

La seule façon de rétablir le trafic à son état normal sera d’entrer les commandes inverses :

iptables --policy INPUT ACCEPT && iptables --policy OUTPUT ACCEPT

Avant d’aller plus loin je vais créer une règle bidon pour vous montrer comment la supprimer (ça vous servira croyez moi 🤣🤣) :

iptables -t filter -A INPUT -p tcp --dport 92 -j DROP

Ici je rejette tout le trafic en direction du port 92 TCP. Pour supprimer cette règle, il faudra d’abord lister numériquement les règles présentes dans la table FILTER. Pour cela on utilise cette commande :

iptables -L --line-numbers

linenumbers.png

Ici on voit que la règle précédemment créée a comme numéro identificateur, le numéro 1 dans la chaîne INPUT de la table FILTER. Pour la supprimer il faudra donc utiliser cette commande :

iptables -t filter -D INPUT 1

deletingrules.png

Notre règle n’existe plus 😁 ! Ah et si jamais vous voulez supprimer toutes vos règles d’un seul coup vous pourrez utiliser ces commandes :

iptables -F && iptables -X

Avec ces commandes en tête on va pouvoir commencer à jouer avec les règles iptables ! Première chose à bien avoir en tête, c’est qu’Iptables peut catcher plusieurs protocoles de couche 4 et 3. La liste est décrite dans le man d’iptables :

protocolmaniptables.png

Dans le cadre de cet article, on s’arrêtera aux protocoles TCP, UDP et ICMP (les variantes IPv6 n’ajoutant pas de réelles difficultés).

Pour indiquer que l’on souhaite bloquer un protocole en particulier en sortie, il faut spécifier l’option  -p suivie du nom du protocole et le port de destination ou de source. Par exemple on pourra très facilement bloquer les connexions SSH en utilisant ces règles iptables :

iptables -t filter -I OUTPUT -p tcp --dport 22 -j REJECT
iptables -t filter -I INPUT -p tcp --dport 22 -j REJECT

Ici on bloque les connexions sortantes et entrantes vers le port 22. Du coup, si on essaye de se connecter à une machine distante on aura ce message :

sshblocked

Si vous voulez bloquer un flux UDP (comme le protocole DNS) alors il faudra entrer ce genre de commande :

iptables -t filter -I INPUT -p udp --dport 53 -j REJECT

dnsiptables.png

Pour finir si vous voulez bloquer le ping (donc l’ICMP) il faudra utiliser ce type de commandes :

iptables -t filter -I INPUT -p icmp -j REJECT

pingiptables

Et le ping ne fonctionnera plus !

Notez qu’il est possible de spécifier une adresse IP source et destinataire dans les paramètres de notre règle. Ainsi si vous voulez bloquer tous les pings en direction du serveur DNS de Google (8.8.8.8) vous pourrez utiliser cette règle :

 iptables -t filter -I OUTPUT -p icmp -d 8.8.8.8 -j REJECT

ping8.8.8.8vsfacebook.png

Dernière petite chose à noter, vous pouvez spécifier sur quelle interface vous voulez que votre règle s’applique. Ainsi on peut très facilement spécifier que l’on interdit tout trafic Peer-To-Peer sur une interface Wi-Fi en jouant avec l’option -i.

Nous allons nous arrêter là pour le moment. Il y a encore beaucoup de choses à voir avec Iptables mais je ne me suis pas suffisamment servi des fonctionnalités avancées pour pouvoir vous en parler. En revanche je ferai probablement un article complémentaire en cours d’année 😉😉 !

Pour les plus impatients je vous invite à lire cet article 😎.

III/ Iptables-apply

La dernière partie de cet article sera consacrée à une seule commande : iptables-apply. Avant que ne soit développée la commande iptables-apply, il existait deux commandes : iptables-save et iptables-restore. Les deux combinées permettaient de sauvegarder/restaurer des règles Iptables à partir d’un script de configuration.

Cependant il arrivait (très souvent) que les administrateurs systèmes et réseaux se coupent l’herbe sous le pied en implémentant une règle Iptables qui fermait leurs connexions SSH/Telnet ou autres… Du coup il fallait shutdown le serveur et le remonter (ou pousser un snapshot si vous en aviez un). Problématique n’est ce pas ?

Avec iptables-apply ce genre de problématique ne se pose plus puisqu’elle va justement appliquer les nouvelles règles Iptables (à partir d’un fichier) et ensuite demander confirmation auprès du client après les avoir appliquées. Si la connexion à distance a été fermée alors le client ne pourra pas répondre et iptables-apply remettra en place les anciennes règles iptables.

Voilà, je voulais juste vous faire part de l’existence de cet outil puisqu’il pourrait vous être d’une très grande utilité 😁😁 !


Plus tard dans l’année je ferai donc une deuxième partie à cet article concernant les fonctionnalités avancées d’Iptables. En attendant je vous link la documentation dont je me suis servi pour l’écriture de cet article et que vous pourrez retrouver sur le Drive du site !

2 commentaires

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s