PROFDINFO.COM

Votre enseignant d'informatique en ligne

Section 4 - iptables

Retour à la page du cours

Nous apprendrons maintenant les bases d'iptables, le mur coupe-feu de Linux. C'est un sujet fort complexe et qui pourrait aisément faire l'objet d'un cours en soi, c'est pourquoi nous ne couvrirons que ce qui est le plus utile dans l'immédiat.

4.1 - Présentation générale

4.2 - Les tables

4.3 - Les chaînes

4.4 - La table filter en détails

4.5 - La commande iptables

4.6 - Sauvegarder les changements

4.7 - Pour aller (beaucoup) plus loin...

4.8 - Exercices pratiques simples

4.1 - Présentation générale

iptables est à la fois un service et une commande. Le service fait office de mur coupe-feu et de filtre IP. La commande permet de consulter et de modifier les tables qui sont derrière le service.

iptables est en effet commandé par des tables, chacune d'elle contenant des chaînes. Chaque chaîne, à son tour, est composée de règles qui seront appliquées l'une après l'autre dans l'ordre, pour chaque paquet IP à traverser le mur coupe-feu.

Il existe à la base 4 tables et ceci est immuable. Il existe à la base 5 chaînes, dont deux sont beaucoup plus utilisées. On pourra toutefois créer d'autres chaînes comme bon nous semblera et les unir en faisant faire des sauts d'une règle à une chaîne.

Retour à la table des matières de la section

4.2 - Les tables

Des quatre tables d'iptables, une seule est couramment utilisée (et c'est la seule que l'on utilisera dans ce cours). Voici tout de même la liste complète:

  • mangle: la table mangle permet de modifier des paquets avant qu'ils atteignent les autres tables ou qu'ils ne sortent de votre serveur. On modifiera généralement les paquets dans un but de routage, pour y appliquer des marques pour SELinux dans un but de sécurité, ou encore pour modifier leur Time To Live (durée de vie).
  • nat (Network Address Translation): elle sert à modifier l'adresse source ou destination d'un paquet afin de faire de la traduction d'adresses sur un réseau. Notez que seul le premier paquet d'un flux traversera cette table - une fois son sort déterminé, tous les autres paquets du flux subiront le même sans relire la table (ce qui est fort logique).
  • raw: le seul usage de cette table est de marquer des paquets afin qu'ils ne soient pas vérifiés par le système de traçage de connexion. Le traçage de connexion permet d'identifier un paquet comme faisant partie d'un flux déjà établi (parce qu'il n'est pas le premier du flux). Cette fonctionnalité est nouvelle dans iptables et n'est que bien rarement utilisée. Lorsqu'elle l'est, elle intervient en tout premier lieu, avant toutes les autres tables.
  • filter: c'est la table qui est utilisée par défaut avec la commande iptables et elle permet de filtrer les paquets entrant et sortant selon différents critères. C'est le coeur du mur coupe-feu.

Retour à la table des matières de la section

4.3 - Les chaînes

Il existe 5 chaînes de base, chacune d'elle se retrouvant (ou non) dans certaines tables:

  • PREROUTING: cette chaîne est présente dans les tables mangle, nat et raw. Elle permet de modifier des paquets avant toute décision de routage (et ne sera donc pas utilisée si votre serveur ne fait pas de routage).
  • POSTROUTING: cette chaîne est présente dans la table mangle et sert à modifier des paquets juste avant qu'ils ne sortent du serveur après le routage, pour être envoyés à une autre plateforme.
  • INPUT: cette chaîne est présente dans les tables mangle et filter et sert à modifier ou à filtrer (selon le cas) les paquets qui ont comme destination le serveur lui-même.
  • OUTPUT: cette chaîne est présente dans les tables filter, nat et raw et sert à filtrer ou à modifier (selon le cas) les paquets qui sont produits par le serveur lui-même.
  • FORWARD: cette chaîne est présente dans les tables filter et mangle et sert à filtrer ou à modifier (selon le cas) les paquets qui sont routés à travers le serveur (qui ne sont donc pas produits par le serveur, ni destinés au serveur). À noter que dans le cas de la table mangle, la chaîne FORWARD est traitée après le PREROUTING et avant le POSTROUTING.

On peut également créer autant de chaînes que désiré dans chacune des tables.

Comme nous n'utiliserons dans ce cours que la table filter, nous travaillerons principalement avec les chaînes INPUT et OUTPUT. La chaîne FORWARD sera couverte uniquement si nous couvrons les serveurs en tant que routeur.

Il est toutefois toujours bon de connaître les autres tables et chaînes, pour culture personnelle (ou pour répondre à des questions d'examen).

Retour à la table des matières de la section

4.4 - La table filter en détails

Au départ, voici ce que les chaînes contiennent:

Chain INPUT (policy ACCEPT)
target     prot opt source      destination
ACCEPT     all  --  anywhere    anywhere       state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere    anywhere

ACCEPT     tcp  --  anywhere    anywhere       state NEW tcp dpt:ssh

REJECT     all  --  anywhere    anywhere       reject-with icmp-host-prohibited


Chain FORWARD (policy ACCEPT)
target     prot opt source      destination
REJECT     all  --  anywhere    anywhere       reject-with icmp-host-prohibited


Chain OUTPUT (policy ACCEPT)
target     prot opt source      destination
      

(vous pouvez voir la même chose sur votre ordinateur, en faisant iptables -L, iptables --list ou même service iptables status, qui équivaut en fait à iptables -L -n --line-numbers).

Chacune des trois chaînes (INPUT, FORWARD et OUTPUT) possède une stratégie de base (policy) qui est ici ACCEPT. Ensuite, elles peuvent contenir des règles (dans le cas par défaut, INPUT contient 5 règles, FORWARD une seule et OUTPUT n'en contient aucune).

Lorsqu'un paquet IP est amené à la table filter, il passera à travers toutes les règles de la chaîne appropriée (selon qu'il est un paquet entrant à destination du serveur, sortant créé par le serveur ou destiné à être routé). L'ordre des règles est donc très important.

Chaque règle applique son filtre et si le paquet est arrêté par le filtre, une décision sera prise pour lui et on arrêtera de lire des règles. Si le filtre laisse passer le paquet, celui-ci se rendra à la règle suivante. Si toutes les règles ont laissé passé le paquet, c'est la stratégie par défaut de la chaîne qui s'appliquera.

Retour à la table des matières de la section

4.4.1 - Les différentes colonnes

 

target indique l'action à prendre pour un paquet arrêté par le filtre. Les choix populaires sont ACCEPT (le paquet est envoyé au service approprié), REJECT (le paquet est rejeté et un paquet de rejet est envoyé à l'expéditeur), DROP (le paquet est ignoré et rien n'est envoyé à l'expéditeur), LOG (le paquet est ignoré comme pour DROP mais des informations qu'il contient seront loguées - à noter que cette pratique peut être illégale!) et REDIRECT (le paquet est redirigé vers un autre port de la machine locale). On peut également spécifier le nom d'une chaîne vers laquelle faire traverser le paquet. L'option RETURN est également disponible (elle permet de faire revenir le paquet vers la chaîne précédente s'il y en a une - si ce n'est pas le cas, la stratégie par défaut de la chaîne sera appliquée immédiatement).
protocol Permet de filtrer un paquet selon son protocole: tcp, udp ou icmp.
options Options de filtrage - rarement utilisées
source Filtrage par l'adresse source du paquet
destination Filtrage par l'adresse de destination du paquet
colonne finale sans nom Filtres supplémentaires. On verra souvent: l'état de la connexion duquel provient le paquet (NEW, ESTABLISHED, RELATED), les ports reliés au protocole et le type de message de rejet à envoyer à l'expéditeur (dans le cas d'un REJECT, bien entendu).

Retour à la table des matières de la section

4.5 - La commande iptables

La commande iptables permet évidemment de modifier le contenu des tables, en plus de l'afficher à l'écran. Les différentes options communes sont:

-A: ajouter une règle à la fin de la chaîne. On devra spécifier quelle chaîne, puis énoncer la règle elle-même. Par exemple:

iptables -A INPUT -p tcp --dport 5900 -s 192.168.0.0/24 -j ACCEPT

Dans cet exemple, une fois qu'on a défini qu'on voulait ajouter une règle à la chaîne INPUT, tout le reste permet de définir le filtre et l'action à prendre lorsque le paquet est retenu par ce filtre:

  • -p tcp: protocole tcp (on aurait aussi pu mettre udp ou icmp)
  • --dport 5900: port de destination. On aurait pu en énumérer plusieurs, séparés par des virgules (comme 5900,5910,6000) ou encore définir une plage (5900:5920). On peut même faire les deux d'un seul coup: 5900,5910,6000:6100. On peut également utiliser les noms des ports tels que définis dans /etc/services.
  • -s 192.168.0.0/24: adresse source, sous forme addr/masque binaire.
  • -j ACCEPT: le résultat final. j est pour "jump" puisqu'on pourrait alors faire sauter le paquet vers une autre chaîne. On utilisera souvent les "sauts" vers les actions standard comme ACCEPT, DROP ou REJECT.

On aurait également pu utiliser:

  • --sport: ports de la source (fonctionne exactement comme --dport)
  • -d: adresse de destination (utile dans la chaîne FORWARD ou OUTPUT)
  • -i: interface réseau (eth0 par exemple)

De la même façon, l'option -I permet d'insérer une règle dans la chaîne spécifiée à la ligne spécifiée (plutôt que de l'insérer à la fin avec -A). La règle qui se trouvait à cette ligne sera décalée d'une ligne, comme toutes les suivantes:

iptables -I INPUT 5 -p tcp --dport 5900 -s 192.168.0.0/24 -j ACCEPT

On peut aussi effacer une ligne avec l'option -D:

iptables -D INPUT 5

Finalement, on peut remplacer une ligne avec l'option -R:

iptables -R INPUT 5 -p tcp --dport 5900 -s 192.168.0.0/24 -j ACCEPT

La cinquième ligne serait ici remplacée par ce qui est spécifié. Notez que cela ne modifie pas la ligne, cela la remplace toujours au complet.

Pour modifier la stratégie de base d'une chaîne, on fait:

iptables -P INPUT ACCEPT

(on peut également utiliser DROP au lieu d'ACCEPT - ce sont les deux seuls choix valides.)

Si on est intéressé à créer ses propres chaînes, on peut faire simplement:

iptables -N ma_chaine

pour la créer. Après coup, on pourra utiliser son nom pour un "saut" avec -j dans une règle. On fera aussi:

iptables -X ma_chaine

pour la détruire. Notez qu'il faut que la chaîne soit vide et qu'aucune référence n'y soit faite (via un "saut") pour qu'elle puisse être détruite. Il est possible de la renommer avec:

iptables -E ma_chaine nouveau_nom

Finalement, l'option -L permet de lister le contenu des chaînes. Si on ajoute -n, des valeurs numériques seront utilisées pour les adresses et les ports. Si on ajoute --line-numbers, on verra des numéros de lignes au début des lignes (ce qui est franchement utile quand notre table grossit).

Retour à la table des matières de la section

4.5.1 - Les types de rejet

Lorsque l'on utilise le "saut" REJECT, on indique à iptables de rejeter le paquet ainsi filtré tout en envoyant un paquet d'information à l'expéditeur (contrairement à DROP, qui n'envoie rien du tout). On pourra spécifier quel type de message envoyer en faisant quelque chose comme:

iptables -A INPUT -j REJECT --reject-with icmp-host-prohibited

L'option --reject-with doit suivre un saut vers REJECT et peut prendre les valeurs suivantes:

  • icmp-net-prohibited (ou icmp-net-unreachable): envoie "Network unreachable"
  • icmp-host-prohibited (ou icmp-host-unreachable): envoie "No route to host"
  • icmp-port-unreachable: envoie "Connection refused"

Retour à la table des matières de la section

4.6 - Sauvegarder les changements

Lorsque vous modifiez iptables, ces changements resteront en vigueur jusqu'au prochain redémarrage du service (ou du serveur!). Pour sauvegarder vos modifications, il suffit de faire:

service iptables save

Retour à la table des matières de la section

4.7 - Pour aller (beaucoup) plus loin...

Je vous recommande l'excellent guide d'Oskar Andreasson. Il est très exhaustif et très dense. Certains chapitres sont plutôt obscurs mais l'information y est présentée de façon claire et précise. Je vous recommande particulièrement les chapitres 9, 10 et 11, avec une lecture rapide de 6, 7 et 8. Le reste est beaucoup plus avancé mais est fort intéressant pour ceux qui veulent aller plus loin avec iptables - ses possibilités sont étonnantes.

4.8 - Exercices pratiques simples

Modifiez votre mur coupe-feu afin de:

  • Permettre aux gens de la classe de faire un ftp sur votre serveur. Les autres devront recevoir un message de type "Connection refused".
  • Permettre à tout le monde de faire un telnet sur votre serveur.
  • Ignorer les ping afin d'être invisible sur le réseau.

Retour à la table des matières de la section