Publié le: 2011-08-27

IPTables

Iptables est le paquet Linux permettant d’interfacer netfilter avec l’utilisateur. Il permet de gérer les flux réseau, donc de faire votre firewall par vous même. Par défaut, tout est ouvert, il est nécessaire d’utiliser Iptables afin de filtrer sur votre machine.

Plus encore, Iptables permet de faire du NAT, et ainsi de créer votre propre passerelle réseau !

Notion d’entrée, sortie, passage

3 notion principales sont à maîtriser avec Iptables, les entrées, les sorties et les passages.

Entrée (INPUT): tout flux venant d'une machine distante vers soi
Sortie (OUTPUT): tout flux partant de soi vers une autre machine
Passage (FORWARD): tout flux passant par soi (pour les passerelles notamment) mais qui n'est pas pour la machine

Refus, Blocage, Acceptation

Lorsque vous filtrez des flux, vous avez 3 possibilités de gestion :

Refus (REJECT): rejette le flux et envoie un packet qui notifie ce refus au client (__fortement déconseillé__)
Blocage (DROP): bloque le flux et ne notifie pas, ce qui permet de ne pas savoir qu'il y a une écoute sur ce port.
Acceptation (ACCEPT): accepte le flux.

Notion de politique par défaut

Bloquer des ports c’est bien, mais le mieux est d’avoir une politique qui n’autorise que les flux précisés et non l’inverse.

Afin de modifier une politique par défaut, il suffit de taper iptables -P -j <règle>. Exemple de bonne politique par défaut :

iptables -P INPUT -j DROP

Bloquer/Autoriser un port

Maintenant que vous savez comment appliquer la politique par défaut, nous pouvons voir comment déroger à celle-ci.

Pour pouvoir interagir sur un port, il suffit de taper iptables -A -p <tcp/udp/icmp> –dport -j <règle>. Ouvrons par exemple le port SSH avec l’option –dport (port de destination):

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

Vous pouvez aussi taper le nom du port (visible dans /etc/services) :

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

Lorsque vous avez plusieurs interfaces réseau, il est judicieux de préciser sur quelle interface vous voulez opérer avec l’option -i

iptables -A INPUT -i eth0 -p tcp --dport ssh -j ACCEPT

Note: l’option -I et -A ont quasiment la même signification. -A va ajouter en fin de liste de règles et -I insérer.

Bloquer/Autoriser une destination/source

On peut aussi filtrer du trafic provenant ou allant vers une destination précise. Ceci permet notamment de gérer des blacklists d’hôtes infectés qui attaqueraient vos machines. L’option -d permet de spécifier un hôte de destination et l’option -s un hôte source. Si par exemple vous voulez interdire la communication d’un hôte vers vous :

iptables -A INPUT -s host.distant -j DROP

Vous pouvez interdire vos communications vers un hôte distant en inversant source par destination et INPUT par OUTPUT.

iptables -A OUTPUT -d host.distant -j DROP

La chaîne host.distant peut aussi bien être un nom DNS qu’une adresse IP. Pensez bien en revanche à ouvrir les ports DNS (ports 67 en UDP et TCP) en trée et sortie sinon votre pare-feu ne pourra pas ajouter les règles de filtrage de vos noms DNS ! Vous pouvez également autoriser une classe d’adresses IP en entrant la combinaison réseau/masque. Si par exemple on souhaite autoriser en entrée tous le réseau 10.1.1.0 de masque 255.255.255.0 :

iptables -A INPUT -s 10.1.1.0/24 -j ACCEPT

Plus puissant encore vous pouvez combiner un hôte/réseau et un port spécifique. Si vous voulez par exemple, dans une politique de blocage par défaut, autoriser SSH que depuis la source 10.1.1.1 :

iptables -A INPUT -s 10.1.1.1 -p tcp --dport ssh -j ACCEPT

Nettoyer les règles iptables

Une fois vos règles iptables entrées, elles sont stockées en mémoire. Il convient parfois lors d’une erreur de nettoyer vos règles.

Pour un nettoyage global de votre firewall, utilisez le bash suivant :

#!/bin/bash
iptables -X
iptables -F

Pour nettoyer uniquement une règle, tapez la règle en question mais remplacez le -A par -D. Par exemple pour

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

vous aurez la règle d’annulation suivante :

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

Vous savez désormais tout ce qu’il faut pour développer votre firewall classique pour Linux. Voyons maintenant comment oeuvrer pour développer une passerelle efficace.

Notion de NAT

iptables est, comme dit précedemment une interface de netfilter. Il permet de filter les paquets, pour les autoriser et les bloquer, mais il peut également servir à faire du NAT (translation d’adresses). Ceci est utile si vous avez 2 interfaces réseau sur votre serveur et que vous souhaitez en faire une passerelle. Celle-ci permettra d’accéder à des serveurs distant en vous faisant passer pour la passerelle et vous permettra, dans le cas d’un réseau privé, de router les adresses locales en adresses internet.

Iptables est composés de 3 tables, filter, nat et mangle. Ci-dessus vous avez manipulé la table filter sans le savoir. Pour spécifier la table NAT, il faudra rajouter l’option -t nat en début de commande.

Le NAT comporte 2 facettes, le prerouting et le postrouting.

Notion de prerouting

Le prerouting consiste à encapsuler un paquet forwardé entrant. Il permet de rediriger un paquet vers une destination notamment. Prenons la règle suivante :

iptables -t nat -A PREROUTING -p tcp --dport smtp -j DNAT --to-destination 4.2.6.8

Chaque paquet SMTP, peut importe sa destination (on aurait pu mettre -d pour rediriger une destiantion spécifique) sera encapsulé et redirigé sur le serveur en 4.2.6.8. L’option -j DNAT permet d’utiliser –to-destination. Le soucis désormais est que le serveur 4.2.6.8 va répondre à la passerelle elle-même. De ce fait elle ne pourra rien faire de la réponse. Il convient donc d’appliquer une règle de postrouting

Notion de postrouting

Le postrouting est en quelque sorte l’inverse du prerouting. Il va permettre de désencapsuler un paquet forwardé envoyé via une règle de prerouting.

Voici la règle permettant d’inverser le prerouting de l’exemple ci-dessus :

iptables -t nat -A POSTROUTING -d 4.2.6.8 -p tcp --dport smtp -j SNAT --to myself.host

myself.host correspond à l’IP de l’interface de sortie de la passerelle. Ceci permettra de renvoyer les paquets sur la passerelle qui se chargera de retranslater en IP localee.

Notion de Mascarade

Plus puissant que le prerouting et postrouting, et bien plus efficace pour globaliser la translation, la mascarade (masquerade en anglais), permet de translater l’adresse et aussi de remplacer l’adresse locale par l’adresse de sortie de la passerelle. En général on applique la mascarade en postrouting.

Prenons de nouveau l’exemple du SMTP. On autorise plusieurs SMTP distants à être interrogés, soit on décide de laisser les gens utiliser les SMTP qu’ils souhaitent, dans ce cas on complexifiera la règle, soit on va translater pour tous les SMTP. Voici la règle globale :

iptables -t nat -A POSTROUTING -p tcp --destination-port smtp -j MASQUERADE

On peut également faire de la mascarade vers un hôte pour tous les ports, et combiner les 2 !

iptables -t nat -A POSTROUTING -d machin.distant -j MASQUERADE
iptables -t nat -A POSTROUTING -d machin.distant -p udp --dport domain -j MASQUERADE

Voilà ! vous savez désormais translater les adresses.

N’oubliez pas dans le cas ou votre politique par défaut est de refuser tout d’autoriser le port naté !

iptables -A FORWARD -d machin.distant -p udp --dport domain -j ACCEPT
iptables -A FORWARD -s machin.distant -p udp --sport domain -j ACCEPT

Redirection de ports

Grâce au NAT, vous pouvez également rediriger des ports vers d’autres (utile pour l’utilisation de proxy transparents). Je vais prendre l’exemple de redirection des flux HTTP du port 80 vers le proxy Squid (port 3128 par défaut) :

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3128
#pour Windows lors de la recherche automatique de proxy
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 3128

Nettoyer les règles de NAT

Voici le bash de nettoyage :

#/bin/bash
iptables -t nat -X
iptables -t nat -F

Limitation du nombre de connexions (Anti DDoS)

Iptables permet depuis le noyau 2.6.22 de limiter le nombre de connexions par seconde et ainsi d’éviter de faire tomber un service sous la charge réseau. Pour ce faire, il faut utiliser le module connlimit (-m connlimit). Dans l’exemple suivant nous limiterons à 5 demandes de connexion pour une IP sur le protocole SSH :

iptables -A INPUT -p tcp --syn --dport ssh -m connlimit --connlimit-above 5 -j DROP

On peut également limiter non pas sur une IP mais sur une classe d’adresse précise en utilisant le paramètre connlimit-mask (ici une classe C)

iptables -A INPUT -p tcp --syn --dport ssh -m connlimit --connlimit-above 5 --connlimit-mask 24 -j DROP

Afin de ne pas pénaliser définitivement un utilisateur en le blacklistant, on peut limiter le nombre de connexions sur un intervalle de temps précis avec les directives suivantes :

iptables -A INPUT -p tcp --dport ssh -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport ssh -m state --state NEW -m recent --update --seconds 60 --hitcount 10 -j DROP

Dans cet exemple nous autorisons uniquement 10 connexions en SSH sur un intervalle de 60 secondes.

Laisser passer le TFTP sur le routeur

Le TFTP est un protocole particulier basé sur le port 69 UDP et un port aléatoire. Le soucis vient du fait, que les réponses sont envoyées depuis et sur un port aléatoire. De ce fait vos firewall ne peuvent pas laisser passer tous ces flux, ce serait extrêmement dangeureux.

Afin d’activer le TFTP, il faut ajouter des règles de NAT et d’autorisation :

iptables -I FORWARD -p udp --dport tftp -j ACCEPT
iptables -t nat -A POSTROUTING -p udp --destination-port tftp -j MASQUERADE

et ensuite activer le module noyau de netfilter permettant de nater correctement les réponses TFTP:

modprobe nf_nat_tftp

Vous savez désormais quasiment tout afin de protéger efficacement votre Linux et constituer votre propre routeur filtrant.