Atelier Netfilter : Le firewall Linux en action

Olivier ALLARD-JACQUIN

Version 0.9.1 - 20 avril 2004
Ce document est publié sous la Licence de Libre Diffusion de Documents (LLDD)

Ce document est le support écrit d'un atelier / TP ( Travaux Pratiques) que j'ai présenté le 1er avril 2004 dans le cadre de l'association Linux Guilde. Il s'agit d'une succession d'exercices et de leurs réponses afin d'étudier le comportement et la mise en oeuvre de Netfilter, le firewall de Linux. Vous trouverez les notions théoriques de cet atelier dans cette autre documentation que j'ai écris.

Vous trouverez la dernière version de ce document :

Pour les personnes désirant reproduire cet atelier chez eux, vous aurez besoin :


Plan :

Introduction

Dans cet atelier, nous allons revoir quelques rapides rappels sur Netfilter, et quelles bases des techniques de firewall sous Linux. Puis nous mettrons en oeuvre des techniques simples de filtrages. Dans une 3ème partie, nous aborderons des filtrages plus évolués à usage tant personnels que professionnels. Nous aborderons enfin la mise en oeuvre de protections destinés aux serveurs.

I Rappels sur Netfilter

Le contenu théorique de cet atelier se base sur une documentation que j'ai écris, et que vous pouvez retrouver sur http://olivieraj.free.fr/fr/linux/information/firewall/.

Netfilter est une couche logiciel intégrée dans le kernel de Linux, c'est à dire le coeur même du système d'exploitation Linux. Elle se situe plus particulièrement au niveau des couches réseaux IP (du protocole réseau IP, appelé aussi par abus de langage "TCP/IP"), et se caractérise sous la forme de 5 hooks ("crochets" en Français) placés à 5 endroits stratégiques du système réseau du kernel.

Lorsque qu'un paquet IP arrive à un de ces hook, il va subit un certain nombre de vérifications (règles) que constituent la chaîne associé au hook en question. En fonction du résultat de ces vérifications, une action (appelée "cible" par la suite) sera décidé pour lui : suppression du paquet, acceptation, modification, etc...

Illustration : Vue générale et hooks

I-1 Règles

Comme leur nom l'indiquent, les règles sont des critères sur le contenu des paquets.
Les critères peuvent être multiples :

Suivant si le paquet répond ou non aux critères, le paquet sera dirigé vers une cible ou un autre.
Exemple de cible :

Illustration : Règles

I-2 Chaînes

Les chaînes sont de deux types : pré-définie ou utilisateur. Dans les deux cas, les chaînes sont des empilements de règles, que le paquet IP va parcourir. Une fois que toutes les règles ont été appliquées sur le paquet, et que celui-ci ne correspond à aucune règle, la cible par défaut de la chaîne sera utilisée. En général, il s'agira de DROP ou de ACCEPT.

Les chaînes pré-défines sont au nombre de 5, et sont toutes associées à un hook particulier :

HookChaîneDescription
NF_IP_PRE_ROUTINGPREROUTING A ce stade, le paquet est "brut de forme", c'est à dire qu'il n'a subit aucune modification par rapport à ce que l'interface réseau a reçu.
NF_IP_LOCAL_ININPUT Ce "hook" est très intéressant, car à ce stade, le paquet est prêt à être envoyé aux couches applicatives, c'est à dire aux serveurs et aux clients qui tournent sur la machine. C'est un des points principaux sur lequel nous allons travailler.
NF_IP_FORWARDFORWARD "Forward" ("faire suivre" en français) est assez particulier. Ce "hook" voit passer des paquets IP qui vont transiter d'une interface réseau à une autre, sans passer par la couche applicative. Pourquoi diantre faire suivre un paquet entre 2 interfaces réseaux, comme par exemple entre "eth0" et "ppp0" ? En fait, c'est afin de permettre à Linux de se transformer en passerelle, une sorte de connexion entre diverses interfaces réseaux.
NF_IP_LOCAL_OUTOUPUT Ce "hook" est l'équivalent du "NF_IP_LOCAL_IN", sauf qu'il est exécuté après que les couches applicatives aient traités, ou générés, un paquet IP. Tout comme "NF_IP_LOCAL_IN", c'est un point que nous allons voir en détail.
NF_IP_POSTROUTINGPOSTROUTING C'est l'équivalent du "NF_IP_PRE_ROUTING" pour les paquets IP sortants de la couche IP. A ce stade, les paquets sont prêt à être envoyés sur l'interface réseau.

Les chaînes utilisateurs sont une particularité intéressante de Netfilter. Elles peuvent être appelées en temps que cible d'une règle (d'une chaîne dite "appelante"), et contenant elles-mêmes des règles. A la fin de la chaîne utilisateur, si aucun traitement n'a été effectué sur le paquet IP, celui-ci continuera son traitement dans la chaîne appelante.

Illustration : Chaînes

I-3 Tables

Comme son nom ne l'indique pas, Netfilter ne s'occupe pas qu'uniquement du filtrage des paquets IP. C'est une de ses tache, mais ce n'est pas la seule. Ainsi, Netfilter est conçue pour gérer 3 taches. Et à chaque tache, une table a été définie. Les 3 taches sont :

Une table est composée d'un ensemble de chaînes pré-défines, et d'un comportement particulier. Ainsi :

Illustration : Tables

I-4 Iptables

Lorsque l'on parle de firewall sous Linux, iptables est LA commande à connaître. Ce programme est la 2nd partie principale de Netfilter. Contrairement au code de Netfilter inclus dans le noyau Linux, "iptables" est un programme "classique" (i.e : il fonctionne dans l'espace utilisateur) que l'on lance manuellement. Bien entendu, seul le root a les droits suffisant pour l'utiliser.

Iptables permet au root de configurer Netfilter, en lui indiquant quelles sont les règles à utiliser pour les différentes tables et chaînes. Il se lance plusieurs fois de suite, chaque lancement permettant de créer/supprimer/visualiser une règles de Netfilter.

Un descriptif complet des paramètres d'iptables serait inutile. La commande "man iptables" étant LA référence de toute documentation sur cette commande. Cependant, en voici un bref résumé des principaux paramètres :

iptables [table] [action] [critères] [cible]

Pour plus d'informations sur ces paramètres ou pour avoir plus d'explications sur les exemples, vous pouvez consulter ce chapitre de ma documentation de Netfilter.

Illustration : Iptables

II Filtrages de base

Dans cette partie, nous verrons comment mettre en oeuvre des filtrages assez simples.

II-1 Principes généraux du filtrage

La technique de firewall la plus efficace se résume en 3 phrases:

Sous Linux, la configuration du firewall va consister à lancer la commande "iptables" autant de fois que nécessaire pour construire une à une les différentes règles dont nous aurons besoin. Voyons maintenant comment construire un tel script.

Illustration : Principes généraux de filtrage

Exercice : Les opérations à faire ci-dessous sont nécessaires à la bonne poursuite de l'atelier. A partir de maintenant, vous devrez lancer tous les scripts de configuration de Netfilter que nous allons créer avec ce shell possédant les droits root. Attention de ne pas faire d'erreurs de manipulation !

II-2 Initialisation des chaînes

La première chose à faire pour construite notre script de firewall sera d'initialiser le firewall. Comme le script que nous allons écrire ne sait à priori pas dans quel état se trouve Netfilter (si des règles n'ont pas été déjà définies par exemple), il nous faudra commencer par supprimer toutes les précédentes règles (pré-définies et utilisateur). Et ce, pour toutes les tables de Netfilter.

Illustration : Initialisation des chaînes

Exercice : Écrire un script d'initialisation de Netfilter. On appellera ce script "initialisation1.sh"

Solution : La solution est téléchargeable ici.

L'ordre d'initialisation des tables n'a pas d'importance ici.

II-3 Cibles/politique de filtrage par défaut

Comme vu précédemment, il est nécessaire de configurer Netfilter afin de tout interdire par défaut.

La logique voudrait donc que l'on place à "DROP" la cible par défaut (ou politique par défaut) de chaque chaîne. Et ce, quelque soit la table. Cependant, comme nous désirons avant tout filtrer nos connexions, seul les cibles par défaut de la table FILTER sont à restreindre. Pour les tables NAT et MANGLE, il n'est donc pas nécessaire de mettre à DROP les cibles par défaut. Même si c'est techniquement faisable de restreindre les cibles par défaut des autres tables, cela alourdit considérablement le script de firewall, et entraîne une chute des performances réseau.

Illustration : Cibles/politique de filtrage par défaut

Exercice : Re-écrire le script d'initialisation vu ci-dessus, mais en rajoutant maintenant les politiques de filtrage par défaut. On appellera ce script "initialisation2.sh".

Améliorations : Penser à optimiser au mieux la sécurité, en plaçant les restrictions dans l'ordre de priorité décroissante.


Solution : La solution est téléchargeable ici.

A partir de maintenant, nous pourrons utiliser ce script comme base de travail pour nos autres scripts.

II-4 Filtrage de ports

Où en sommes nous ? Nous avons actuellement verrouillé notre Linux, en filtrant systématiquement ses communications réseaux.

Illustration : Filtrage de ports 1/2

Exercice :

Bien, notre machine étant complètement verrouillée, nous allons voir maintenant comment lui laisser un peu communiquer avec les autres machines mises en réseau.

Illustration : Filtrage de ports 2/2

Exercice :

Améliorations : Recopier le script "filter1.sh" en "filter1a.sh". Dans ce nouveau script, restreindre encore plus le firewall en rajoutant au filtrage du serveur HTTP du présentateur, le filtrage par votre propre adresses IP.


Solution : La solution est téléchargeable ici.

II-5 Log

Maintenant nous allons travailler un peu avec les logs. Netfilter peut stocker ("logger" ou plus français "noter") des informations sur l'état du firewall, via le démon "syslogd". Ceci est particulièrement intéressant afin de rechercher une activité réseau suspecte (tentative d'intrusion), ou de rechercher la cause d'un mauvais fonctionnement du firewall

Illustration : Log

Exercice :.

Améliorations : Recopier le script "log1.sh" en "log1a.sh". Rajouter un préfixe afin de différencier les logs entrants et sortants.


Solution : La solution est téléchargeable ici.

Lancer un xterm en pleine largeur d'écran, avec si possible une police assez petite. Puis taper, en temps que root, la commande "tail -f /var/log/messages".

Ou si possible (présence du paquetage "rxvt" sur la machine), télécharger rxvt_log depuis la machine du présentateur et en temps que root, taper "rxvt_log messages".

III Filtrages plus évolues

Dans cette partie, nous allons étudier les défauts du filtrage part ports vu précédemment. Puis, nous mettrons en pratiques des techniques de filtrages plus fines et plus efficaces.

III-1 Insuffisances du filtrage par ports

Nous allons utiliser "nmap", le scanneur de ports, afin de montrer les lacunes du filtrage par port.

Illustration : Insuffisances du filtrage par ports

Exercice :

III-2 Suivi de connexion

La technique du suivi de connexion ("conntrack") rend inefficace la précédente astuce de port scanning. Elle permet aussi une sécurité très largement accrue, en restreignant au maximum les flux de connexions.

Le suivi de connexion se résume par les points suivants :

Illustration : Suivi de connexion

Exercice : On reprend la philosophie du 1er exercice de filtrage, mais on va rendre notre firewall plus restrictif. Plus particulièrement, on utilisera la technique du suivit de connexion vu ici.

Améliorations : Recopier le script "filter2.sh" en "filter2a.sh". Dans ce nouveau script, rajouter les règles nécessaires afin que vous puissiez accéder aux serveurs FTP (port 21) de n'importe quelle autre machine. Attention, il y a un gros piège...


Solution : La solution est téléchargeable ici.

III-3 ULog

Les logs du firewall sont intéressants (voir même essentiels), mais il est dommage que l'on ne puisse pas les séparer des autres logs kernel. En effet, il arrive que le flots de logs de firewall soit très importants en volume, ce qui rend moins évident la lecture des autres logs du kernel (qui sont tout aussi important, si ce n'est plus).

ULOG est une solution très intéressante à ce problème. Il se décompose en :

Illustration : ULOG

Exercice : Mise en oeuvre de ULOG sur notre machine.

Améliorations : Recopier le script "log2.sh" en "log2a.sh". Rajouter un préfixe afin de différencier les logs entrants et sortants.


Solution : La solution est téléchargeable ici.

Lancer un xterm en pleine largeur d'écran, avec si possible une police assez petite. Puis taper, en temps que root, la commande "tail -f /var/log/ulogd.syslogemu".

Ou si possible (présence du paquetage "rxvt" sur la machine), télécharger rxvt_log depuis la machine du présentateur et en temps que root, taper "rxvt_log netfilter".

III-4 Chaînes utilisateurs

Les chaînes utilisateurs ont le même rôle que les chaînes pré-défines, à savoir : Un conteneur à règles. L'intérêt des chaînes utilisateur n'est pas évident aux premiers abords, mais au final, elles sont très utiles.

Illustration : Chaînes utilisateurs 1/2

Exercice : Mise en oeuvre d'une simple chaîne utilisateur.

Solution : La solution est téléchargeable ici.

Le petit exercice précédent n'est pas très spectaculaire. Mais il est nécessaire afin de bien comprendre l'exercice suivant, qui sera bien plus intéressant.

Dans ce qui va suivre, nous allons considérer que nous voulons avoir des liens privilégiés avec :

Nous ne désirons communiquer qu'avec ces trois machines, toutes les paquets IP a destination ou partant vers les autres machines devront être détruits.

Illustration : Chaînes utilisateurs 2/2

Exercice : Télécharger ce script utilisant la méthode classique de filtrage. A partir de ce script, il faudra :

Solution : La solution est téléchargeable ici.

III-5 Contraintes de l'état NEW

Le problème de l'état NEW du suivi de connexion vient dans son mode de détection de ce qu'il considère comme étant une nouvelle connexion. Contrairement à ce que l'on peut penser, il ne se base tout simplement pas sur une handshake, ce qui peut l'amener à laisser des paquets se faisant passer pour une nouvelle connexion.

Illustration : Contraintes de l'état NEW 1/2

Si on ne veut pas utiliser l'état NEW, la technique de filtrage (pour des connexions initiées par notre machine) à utiliser peut être ceci :

Illustration : Contraintes de l'état NEW 2/2

Exercice :

Solution : La solution est téléchargeable ici.

Ce script peut vous servir d'exemple pour votre propre firewall. On notera qu'il utilise un nombre de règles minimales. Et que nous contrôlons parfaitement les protocoles que nous voulons laisser sortir.

IV Firewall et serveurs

Mettre en place un démon (logiciel de type "serveur") n'est pas en soit très compliqué. Mais le configurer de telle manière à ce qu'il ne soit pas piraté n'est pas aisé. Le firewall peut assurer une partie de sa sécurité, mais la plus grande partie sera la responsabilité du démon lui même, comme par exemple "Apache" dans le cas d'un serveur HTTP.

Un firewall ne peut pas assurer à lui seul la sécurité d'un démon / serveur publique ! La configuration du démon est l'élément le plus important !

IV-1 Serveur HTTP

Nous n'allons pas nous intéresser ici à la configuration du démon HTTP lui-même. Cela ferait l'objet d'un atelier complet... Mais seulement de ce que peut faire Netfilter afin de protéger un tel démon.

Illustration : Serveur HTTP (web)

Exercice :

Améliorations : Recopier le script "serveur1.sh" en "serveur1a.sh". Dans ce nouveau script, autoriser les autres machines du réseau à "pinger" notre machine, mais en limitant ce flux à 1 ping/s (module "limit").


Solution : La solution est téléchargeable ici.

IV-2 Serveur FTP

Maintenant nous allons voir comment transcrire le travail précédent afin de protéger un serveur FTP.

Illustration : Serveur FTP (fichier)

Exercice :

Solution : La solution est téléchargeable ici.

Écouter les explications sur l'intérêt du module "ip_conntrack_ftp".

Conclusion

Dans cet atelier, nous avons abordé les principales techniques de Netfilter en terme de filtrage. Cependant, cet atelier ne peut résumer qu'une partie seulement des fonctionnalités de Netfilter. Aussi, vous êtes encouragé à fouiller Français la documentation que j'ai précédemment rédigé, Français les guides officiels de netfilter, le Français "man iptables", et bien évidement Français Anglais Google ou tout autre moteur de recherche, afin d'approfondir ce sujet.

Si vous devez retenir qu'une seul chose de cet atelier, c'est le principe général du filtrage : Initialisation du firewall / tout interdire par défaut / autoriser le strict minimum.

J'espère que cet atelier vous a intéressé, et que vous pourrez utiliser les notions abordées afin de configurer efficacement votre propre firewall Linux.

Si vous avez des remarques à faire sur cet atelier, des corrections à proposer ou des points à éclaircir, n'hésitez pas à me contacter ().

Remerciements

Je remercie le CUEFA (Grenoble, Isère / 38) et en particulière Romain KOBYLANSKI pour nous avoir fournit la salle et le matériel de cet atelier. Merci aussi à l'association Guilde pour l'organisation de l'atelier , et notamment (par ordre alphabétique) Edgar BONET, Christophe FIXOT et Jérôme KIEFFER.

License

Ce document peut être librement lu, stocké, reproduit, diffusé, traduit et cité par tous moyens et sur tous supports aux conditions suivantes:

Toute incompatibilité des clauses ci-dessus avec des dispositions ou contraintes légales, contractuelles ou judiciaires implique une limitation correspondante du droit de lecture, utilisation ou redistribution verbatim ou modifiée du document.

Nombre de visiteurs: Compteur

Valid XHTML 1.0! Valid CSS!
Site de référence : http://olivieraj.free.fr/ Last modified: Tue Apr 20 23:08:00 CEST 2004