Depuis le noyau 2.4, Linux s'est doté d'une nouvelle architecture de firewalling conceptuellement très différente des solutions précédentes (ipfwadm avec le noyau 2.0 et ipchains avec le noyau 2.2).
Alors que pour les versions du noyau antérieures, le code source correspondant au filtrage des paquets étaient disséminés un peu partout à travers l'implémentation de la pile TCP/IP, avec l'arrivée du noyau 2.4, les développeurs (dont Paul Russel, qui travaillait déjà sur ipchains à l'époque) ont choisi de mettre en place des hooks à des endroits spécifiques du code. Cela permettait d'avoir un code à la fois plus clair et plus souple, surtout pour les contributeurs qui avait désormais un point précis pour ajouter des fonctionnalité de filtrage.
Lorsque l'on parle de filtrage sous Linux, ont emploi généralement Netfilter et Iptables indifféremment. Pour information, Netfilter est l'ensemble du code interne au noyau qui s'occupe de réaliser les opérations de firewalling. Iptables est pour sa part, l'utilitaire en espace utilisateur, permettant de piloter le comportement du filtrage à travers les couches réseaux.
A travers cette présentation, nous verrons quelles sont les possibilités offertes par Netfilter pour ne pas authoriser certains type de trafic ou logger certaines attaques. Nous évoquerons d'une part la protection d'une machine simple puis nous aborderons le cas plus délicat de machines officiant comme passerelle ou routeur.
Netfilter est livré avec le noyau 2.4, ce qui signifie qu'il est présent dans n'importe quelle machine utilisant ce noyau (ou ultérieur). Il n'y a donc pas de différentiation entre un simple poste de travail et un serveur de production. Vous ne paierez pas plus cher si vous acheter une version « Home » ou « Super Advanced Server »:)
Comme nous le verrons plus loin dans ce document, Netfilter possède des fonctionnalités de filtrage très avancées, même souvent plus avancées que certains matériels dédiés.
Actuellement, il n'existe pas de moyen simple pour permettre la tolérance de panne ou la répartition de charge de firewall sous Linux. Netfilter n'offre aucun moyen de mettre en place un cluster dédié au filtrage (Le redondance IP ne serait pas un problème avec des systèmes tels que LVS, le problème venant essentiellement de l'echange des tables d'état).
Pour plus d'informations, se reporter à la mailing list des développeurs de Netfilter.c (A confirmer: La mise en place d'une telle configuration est possible avec DRBD, le module block distribué?)
Par ailleurs, un autre cas d'utilisation peut poser problème lorsque l'on manipule les règles utilisants les tables d'état. Il n'est pas possible de changer l'état de ces tables dynamiquement. Par exemple, si l'on ne souhaite plus accepter le protocole H323 en entrée, même quand le trafic a été initié depuis notre réseau de confiance, nous serons obligés d'attendre que la communication se termine pour que la modification soit prise en compte.
A priori, il n'y a pas besoin d'installer Netfilter sur une machine sous Linux, celui-ci étant fourni sur les distributions les plus connues. Néanmoins, une précaution est à prendre si vous désirez efféctuer des mises à jour. Gardez en mémoire que la version d'Iptables doit être compatible avec votre version de Netfilter.
Par ailleurs, je recommende fortement de se procurer dans un premier temps des outils graphiques de configuration de vos règles de filtrage. Cela vous permettra de vous familiariser avec la syntaxe verbeuse d'Iptable.
Avant d'entrer dans les détails du fonctionnement de netfilter, il faut savoir qu'il n'est pas seulement un dispositif de filtrage de paquets. Il permet (et c'est ce qui le rend très souple) de faire à peu près tout ce que l'on souhaite sur les paquets qui traversent la pile TCP/IP de Linux.
Pour cela, le traitements sont divisés par catégories. Ces catégories sont matérialisées par des tables, au nombre de 3
Dans le cadre de ce document, nous ne détaillerons que la table filter. Nous pourrons, dans certains cas, évoquer l'utilisation des tables nat et mangle.
Pour ce qui est des fonctionnalité disponibles de Netfilter, elles sont fonction des modules chargés par votre noyau (elles peuvent également être compilées avec le noyau). Comme nous l'avons vu précédemment, Netfilter fait partie intégrante du noyau. Les fonctionnalites sont disponibles sous forme de modules que l'on charge avant d'effectuer le filtrage. On peut également laisser le noyau le faire à notre place si l'option <REMPLIR> a été validée.
Pour connaître les modules disponibles avec votre distribution de Netfilter :
[root@localhost modules]# ls /lib/module/2.4.<version>
/kernel/net/ipv4/netfilter/
arptable_filter.o ip_nat_ftp.o ip_tables.o ipt_esp.o
ipt_MARK.o ipt_REJECT.o ipt_ULOG.o arp_tables.o ip_
nat_irc.o ipt_ah.o ipt_helper.o ipt_MASQUERADE.o
ipt_state.o ipt_unclean.o ipchains.o ip_nat_snmp_basic.o
ipt_conntrack.o ipt_length.o ipt_MIRROR.o ipt_tcpmss.o
ip_conntrack_ftp.o ip_queue.o ipt_dscp.o ipt_limit.o ipt_multiport.o
ipt_TCPMSS.o ip_conntrack_irc.o iptable_filter.o ipt_DSCP.o ipt_LOG.o
ipt_owner.o ipt_tos.o ip_conntrack.o iptable_mangle.o ipt_ecn.o
ipt_mac.o ipt_pkttype.o ipt_TOS.o ipfwadm.o iptable_nat.o ipt_ECN.o
ipt_mark.o ipt_REDIRECT.o ipt_ttl.o
Lorsque l'on souhaite filtrer un trafic réseau, il faut savoir, dans le périmètre de notre machine, d'où il vient et par où il passe. Par exemple, il est clair qu'un paquet que l'on émet depuis un processus local (issue d'une communication ssh par exemple), ne subira pas le même traitement qu'un paquet qui traverse notre machine passerelle. N savons donc quel « chemin » les paquet emprunte dans notre machien, c'est à dire d'où il viennent et où il vont. Ces chemins sont les suivants :
Ce que nous venons d'évoquer représente la notion de chaine. Cette notion, très pratique avec Iptables, permet de définir un filtrage commun à tout les paquets qui les traverse. Les 3 chaines que nous vennons de voir sont déjà créées nativement (builtin), vous ne pourrez donc pas les effacer.
Notez qu'il est possible de créer ses propres chaines, généralement dans l'optique de simplifier le traitement (visuellement et fonctionnellement, iptable n'ayant pas à « lire » toutes les règles d'une même chaine). Pour exemple, si l'on souhaite créer un filtrage détaillé pour le protocole ICMP, nous pouvons créer une chaine ICMP dans laquel nous ajouterons toutes les règles sur le filtrage que l'on souhaite appliquer. Depuis une autre chaine telle que FORWARD ou INPUT, nous ajouterons alors une règle informant que si le protocole est de type ICMP, iptable devra se réferer à la chaine ICMP.
Pour mieux appréhender les notions vues précédemment, nous allons mettre en oeuvre un exemple simple défini par le scénario suivant :
Ce que l'on ne souhaite pas :
Ce que l'on souhaite :
La première chose à faire est de définir la politique de traitement par défaut des règles natives. Cela signifie que si aucune règle que nous allons écrire ne correspond au type du paquet à traiter lorsque celui-ci arrive en bout de chaine, iptables appliquera la politique par défaut.
Iptables -P INPUT DROP
Iptables -P FORWARD DROP
Iptables -P OUTPUT ACCEPT // A
priori, nous ne filtrons pas en détail les paquets que nous
émmetons
A ce stade, il serait intéressant de ne pas avoir de connexion en cours au risque de voir les données arrivant tout simplement être laissées tombé par iptables.
Pour en illustrer l'intérêt, nous allons créer notre propre chaîne utilisateur :
iptables -N ICMP
Ensuite, nous allons lui définir une pseudo politique par défaut (la fonctionnalité n'existe pas réellement pour les chaînes utilisateur) en ajoutant la règle suivante à la fin:
iptables -A ICMP -j DROP // Si aucune règle ne convient, envoie les paquet vers la cible DROP
A ce stade, toujours aucun traitement n'est réellement fait. Nous allons donc définir un traitement particulier pour les paquets de ICMP de type echo-reply (ping). Nous travaillons donc sur la chaîne que nous venons de créer :
iptables -A ICMP -p icmp –icmp-type echo-request -j DROP
Puis on indique à la chaine INPUT que les paquets de type ICMP sont traités par notre chaîne :
iptables -I INPUT 1 -p icmp -j ICMP
Notre machine ne peut plus recevoir de demande de type echo-reply. Cet exemple est didactique, car en modifiant les paramêtres réseaux du noyau, il était possible d'en faire tout autant. Nous allons donc essayer d'améliorer la chose. Notre machine doit pouvoir recevoir des demandes de type echo-reply seulement depuis notre LAN :
# On vide
la chaine
iptables -F ICMP
# On
accepte les paquets de type icmp
depuis notre réseau
iptables -A ICMP
-p icmp -s
192.168.10.0/24 -j ACCEPT
# On laisse tomber tout les autres paquets de type icmp
iptables -A ICMP -j DROP
Maintenant, nous allons empecher qu'un machine puisse initier une connexion vers notre machine. Du point de vue protocole, nous refusons les segments TCP avec les drapeaux SYN ou ACK :
# On va créer une nouvelle chaîne pour le protocole TCP
iptable -N TCP
# On accepte tout les paquets ayant une concordance dans les tables d'état :
iptables -A TCP -p tcp --tcp-flags SYN,RST,ACK SYN -j DROP
Ce que l'on ne souhaite pas :
Ce que l'on souhaite
Encore une fois, les exemples fournis n'ont qu'un intérêt didactiques et ne sont en aucun cas à utiliser tels quels. Ils représentent des points précis de ce que l'on peut faire d'intéressant avec netfilter.
Pour se protéger du scan de port, il existe plusieurs moyens. En premiers lieu, il convient d'empecher simplement les connexions initiée depuis l'exterieur.
[seb@localhost ]$ nmap localhost
Starting nmap V.3.00 (www.insecure.org/nmap/ )
Interesting ports on localhost.localdomain (127.0.0.1):
(The 1597 ports scanned but not shown below are in state: closed)
Port State Service
25/tcp open smtp
505/tcp open mailbox-lm
631/tcp open ipp
6000/tcp open X11
Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds
[root@localhost ]# iptables -A INPUT -p tcp -SYN -j DROP
[seb@localhost ]$ nmap localhost
Avec la règle que l'on vient d'introduire, on spécifie à Netfilter que tout les segments tcp venant de l'exterieur et initiant une connexion ou tentant d'envoyer des segments avec entètes non conformes (utilisation des flags RST, SYN et ACK/SYN) seront refusés. Un second appel à nmap démontre que l'on a obtenu ce que l'on souhaitait.
Cependant, l'exemple ci-dessus est évocateur des problèmes liés aux filtres de paquets sans états. En effet, nous n'utilisons pas les fonctionnalités de comparaison d'état d'un paquet (abscence de -m state). Les réels problèmes apparaitrons alors avec les protocoles « particulier » comme FTP ou H323 où l'utilisation de plusieurs flux d'informations séparés peuvent engendrer une demande de connexion depuis un serveur vers notre machine (Se référer notamment à la RFC XXX, qui détail les principes de connexion active/passive en FTP).
Si l'on souhaite encore pouvoir utiliser ces protocoles, nous ne pouvons donc pas utiliser la règle précédente. A la limite du proxying applicatif, nous devons utiliser les modules de netfilter gérant ces cas particuliers.
[root@localhost kernel]# iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@localhost kernel]# iptables -A INPUT -j DROP
La première règle va donc intercepter tout le trafic de type tcp qui arrive sur notre machine. L'utilisation de l'argument -m state permet d'indiquer à Netfilter qu'il doit utiliser des tables d'état pour accepter ou non les segments qu'il filtre.
On précise également deux type d'état à accepter :
ESTABLISHED : Cet état correspond aux segments TCP arrivant après que le 3WayHandshake ait eu lieu. Netfilter est capable de reconnaître, en inspectant les numéros de séquence TCP et les informations de l'entête (source, destination, ports...) si le paquet correspond à un flux légitime et décide alors de l'accepter ou pas. Dans notre cas, si le paquet correspond à un flux authorisé, on accepte qu'il traverse le hook INPUT.
RELATED : Cet état est particulier aux protocoles de type FTP ou H323, où une demande de connexion depuis une machine distante vers notre machine peut arriver. Dans ce cas, Netfilter vérifie dans sa table de correspondance si à l'origine d'une telle demande, il existe bien un flux sortant pour ce type de protocole. On accepte ce genre de paquet.
En dernier lieu, on empeche tout autre trafic vers notre machine, y compris les scans de ports.
Lorsque l'on écrit ce genre de règle, on fait confiance au module de suivit applicatif associé au protocole accepté. Si vous souhaitez redoublez la sécurité de votre machine, il convient de spécifier vous même les règles à définir. Ce qui nous ammenerai à écrire :
[root@localhost]# iptables -A INPUT -m state –state ESTABLISHED -j ACCEPT
[root@localhost]# iptables -A INPUT -p tcp -m state –state NEW –sport 1024: --dport 21 -j ACCEPT
[root@localhost]# iptables -A INPUT -p tcp -m state –state RELATED –sport 20 --dport 1024: -j ACCEPT // ACTIF
[root@localhost]# iptables -A INPUT -p tcp -m state –state RELATED –sport 1024: --dport 1024: -j ACCEPT // PASSIF
Une telle mise en oeuvre demande de connaître les fonctionnements de tous les protocoles que l'on souhaite filtrer.
A ce stade, nous empechons donc tout le trafic venant de l'exterieur, ce qui peut poser problème lorsque l'on offre un service (ici http et ftp). Pour permettre aux clients d'accéder à ces ports :
[root@localhost]# iptables -I INPUT 2 -p tcp -m state --state NEW --dport 80 -j ACCEPT
Pour pouvoir loguer tout les paquets suspect, iptables met à la disposition de l'administrateur la cible ULOG. Celle-ci doit être utilisée avant les règles utilisant les règles DROP. Par ailleurs, un autre paramêtre à prendre en compte lorsque l'on souhaite garder une trace des flux suspects, concerne la fréquence avec laquelle nous allons relever l'information. En effet, si pas erreur, vous loguez tout le flux interdit et qu'un pirate s'en rend compte, il pourra tenter d'exploser la taille de vos logs et donc de remplir complètement le disque concerné. Au passage, on notera ici l'avantage de spécifier une partition différente pour /var ou /var/log.
Pour éviter ce genre de problème, il existe une concordance appelée limit. Elle défini simplement les limites maximums allouée pour la règle correspondante.
Netfilter est un système de filtrage à état très fiable et robuste. Quelque soit le rôle de la machine, son utilisation devrait être systématique. D'une part, disposer nativement d'un tel outil et ne pas l'utiliser serait une grave erreur. D'autre part, que l'on soit un serveur critique ou un simple poste de travail, la vérification et la proscription de certains flux devrait être faite, lorsque l'on connait les outils disponibles sur Internet pour mettre à mal le comportement d'une pile TCP/IP ou simplement utiliser une application mal développée et susceptible de présenter des trous de sécurité. On regrettera cependant la difficulté de mise en oeuvre d'une redondance de firewall Netfilter et le peu de frontend graphiques de qualités. Pour terminer sur cette courte présentation de Netfilter, n'hésitez pas, comme pour toute application Unix, à utiliser la puissance de la ligne de commande et des fichiers de configuration. En effet, rien ne vous empeche de mettre en place 3 ou 4 scripts différents de filtrage, que l'on appliquera automatiquement via cron à certaines periode de l'année ou de la journée (pourquoi laisser un serveur extranet disponible à 2h du matin par exemple... heure où certains pirates boivent du café et se « baladent sur Internet).
![]() |
![]() |
![]() |
![]() |
![]() |
First | Previous | Post comment | Next | Last |