Tutoriel iptables

5.0
01

iptables est un logiciel libre qui permet de configurer le pare-feu Linux (netfilter).
iptables fonctionne sous la forme de chaînes et de règles que l’on y applique.
iptables est en général inclut dans toutes les distributions Linux et par défaut.

Voici un tutoriel iptables et toutes les explications sur ce dernier.


Tutoriel iptables

Introduction

Iptables est donc un utilitaire inclus dans votre distribution linux qui permet de piloter netfilter.
Cela inclut le filtrage de paquets ou effectuer du NAT.
En clair, iptables permet de créer des règles de pare-feu pour filtrer les paquets entrant/sortant en direction des services réseaux et processus d’une machine.
Iptables permet aussi de jouer des règles NAT dans le cas où la machine linux sert de routeur.
Le processus iptables est en général, /sbin/iptables et doit être exécuté avec les droits root.

iptables fonctionne avec des règles que l’on applique à des tables content des chaînes.
Voici un exemple de deux tables.
La première table est la table filter avec une chaîne INPUT, OUTPUT et FORWARD.
La seconde table est la table NAT avec une chaîne PREROUTING, INPUT, OUTPUT, POSTROUTING.

Pour chacune des chaînes de chaque table, on trouve les règles.
Ici toutes les chaînes de la table NAT sont vides (aucun règle).
Seule les chaînes INPUT et OUTPUT de la table filter contiennent des règles.
Celles-ci sont en listes avec des source/destination et la règle (ici masquées).

Les règles sont jouées dans l’ordre des chaînes de haut en bas.

Les tables

Les tables sont jouées dans un certains ordre et selon certains critères.
On trouve les tables suivantes avec leurs chaînes :

L’accès au table se fait à travers le paramètre -t
Par exemple pour lister le contenu d’une table (chaînes et règles d’une chaîne) :
iptables -t nat -L

Tables filter

Filter est la table par défaut.
C’est la table utilisée pour définir les règles de pare-feu de la machine.
En effet, cette table filter permet en autre de bloquer ou autoriser les paquets qui entrent et sortent.

On y trouve les tables :

  • INPUT : Les paquets à destination de la machine et concernant. En général, à destination des processus locaux.
  • OUTPUT : Les paquets sortant de la machine, en général, provenant des processus locaux.
  • FORWARD : Les paquets qui passent à travers le serveur, par exemple, d’une interface réseau à l’autre ou à destinations d’une autre machine sur le réseau. Cette table est utilisée lorsque la machine joue le rôle de routeur.

Comme il s’agit de la chaîne par défaut, vous n’avez pas besoin d’utiliser le paramètre -t, ainsi pour lister les chaînes et leurs contenus :
iptables -L
ou en détails :
iptables -L -n -v

Tables NAT

La table NAT contient les chaînes suivantes :

  • PREROUTING  : Modifier les paquets AVANT leurs routages. En clair cela, vous permet de rediriger un paquets vers une autre destination en modifiant l’IP de destination par exemple (DNAT – Destination NAT)
  • POSTROUTING : Modifier les paquets APRES le routage. Cela permet de modifier par exemple l’IP source, SNAT (Source NAT).
  • OUTPUT : NAT pour les paquets générés par le pare-feu.

Pour lister le contenu des tables :
iptables -t nat -L

Table Mangle

La tables Mangle permet de modifier les paquets, elle est surtout utile pour effectuer de la QoS.
Cette table ne doit pas être utilisé pour modifier les IPs source/destination pour effectuer du NAT.
Cette table est surtout utilisée pour modifier les composants suivants :

  • TOS : Type of service – Ceci est utilisé pour la QoS.
  • TTL : (Time To Live) – durée de vie d’un paquet
  • MARK : Permet de marquer un paquet, toujours utile pour de la QoS.
  • SECMARK
  • CONNSECMARK

Les chaînes de la table Mangle. On retrouve les mêmes que précédemment, avec les mêmes conditions.

  • PREROUTING
  • OUTPUT
  • FORWARD
  • INPUT
  • POSTROUTING

Lister le contenu de la table mangle :
iptables -t mangle -L

Comprendre les tables

Maintenant que l’on a présenté les trois tables.
Il faut comprendre quand celle-ci rentre en jeu.

Le schéma suivant montre comment un serveur peut arriver, traverser (ou être interdit) par une machine.

  • Le paquet arrive et les deux chaînes PREROUTING des tables NAT/MANGLE sont jouées
  • puis la décision de routage
    • Si le paquet est à destination de la machine, la chaîne INPUT de la table filter est jouée
    • Si le paquet est à destination d’une autre machine sur le réseau, c’est la chaîne FORWARD qui est jouée.
  • Si le processus qui reçoit le paquet, en émet un nouveau en réponse, soit donc un paquet sortant, la chaîne OUTPUT est jouée.
  • A ce paquet sortant, les chaînes POSTROUTING des tables NAT/MANGLE sont enfin jouées.

Comme, je l’avais spécifiée dans l’introduction, des policy (politiques) sont appliquées à ces règles.
Par exemple, vous pouvez appliquer les règles : ACCEPT/DROP
En clair, si aucun règle n’est vraie pour un paquet arrivant sur la chaîne, la politique est appliquée.
ACCEPT, le paquet sera acceptée, DROP, le paquet sera supprimée.

Les règles

Maintenant que nous avons vu comment fonctionnent les tables et chaînes, nous allons pouvoir créer des règles.
Il faut déjà utiliser le paramètre -t pour choisir la table que l’on vise.

  • Le paramètre -A (append) permet de modifier une chaîne, la règle sera créée à la fin à la chaîne.
  • Le paramètre -I (insert) permet d’ajouter une règle en début de chaîne.
  • Le paramètre -D (delete) permet de supprimer une règle.

Règles pare-feu

Les règles contiennent ensuite des sources, destinations, ports, protocoles auxquelles ont y appliquent une cible (target) à travers le paramètre -j (jump).
Les cibles possibles :

  • ACCEPT : le paquet ciblé est autorisé.
  • DROP/DENY : Le firewall abandonne le paquet. Aucune réponse n’est faite à la cible.
  • REJECT : Le paquet est rejeté, un paquet ICMP destination-unreachable est envoyé en retour à la source pour le notifier.
  • QUEUE : ajoute la règle dans une liste d’attente consultable par des programmes de l’environnement utilisateur, comme des applications réseaux.
  • RETURN : permet de revenir à la chaine principale dans le cas où la cible RETURN est utilisée dans une sous-chaîne (oui il est possible d’utiliser des sous-chaînes).

Ainsi, si l’on veut ajouter une règle en début de la chaîne INPUT, on obtient :
iptables -I INPUT -s 8.8.8.8 -j DROP
La chaîne ci-dessus bloque tous les paquets ayant pour source l’adresse IP 8.8.8.8.

Vous l’aurez compris pour bloquer le traffic local sortant vers l’adresse IP 8.8.8.8, on doit saisir la règle :
iptables -I OUTPUT -s 8.8.8.8 -j DROP

Pour aller plus loin dans les paramètres :

  • -i interface réseau entrant
  • -o interface réseau sortante
  • -s IP source – on peut aussi utiliser des masques de sous-réseau – 1.2.3.0/24
  • -o IP sortante – là aussi on peut utiliser des masques de sous-réseau
  • –sport : port source (attention, il faut deux -)
  • –dport : port de destination (attention, il faut deux -)
  • -p permet enfin de spécifier le protocole : TCP, ICMP, UDP

Ainsi pour bloquer le port 80 en sortant sur le protocole TCP, sur l’interface eth0 et à destination de l’adresse IP de Google, on obtient :
 iptables -I OUTPUT -o eth0 -d 216.58.208.195 -p tcp --dport 80 -j DROP

Une remarque entre les cibles DROP et REJECT évoqués plus haut, dans le message précédent, l’application nc retourne un timeout (qui prend un peu de temps), en clair l’application attend la réponse du serveur qu’elle n’aura pas car iptables a fait passer le paquet sous la table.
Avec la cible REJECT, l’application retourne un « connection refused », car on obtient cette fois-ci une réponse d’iptables :

On peut spécifier plusieurs adresses en source ou destination séparées par des virgules :
 iptables -A INPUT -s 192.168.1.1,2.2.2.2,10.10.10.10 -p tcp --dport 80 -j DROP
Car iptables permet beaucoup de choses et vraiment beaucoup de choses.
En autre, iptables est aussi un pare-feu d’état qui peut donc suivre les états d’une connexions, notamment à travers le paramètre -m state
On trouve alors les états suivants :

  • NEW : Le paquet établit une nouvelle connexion
  • ESTABLISHED : la connexion a déjà été établie par un précédent paquet.
  • RELATED : le paquet établie une nouvelle connexion mais est liée à une connexion précédente. Par exemple, lors de une connexion FTP, ce dernier se connecte au port FTP mais une seconde connexion liée à la première est crée sur un nouveau port.
  • INVALID : le paquet n’est lié à aucune connexion existante, les en-tête erronées de paquet sont acceptés.

Ainsi, si l’on poursuit notre exemple, pour bloquer toute nouvelle connexion vers Google, il faut utiliser la state NEW.
On voit bien ci-dessous qu’en utilisant ETABLISHED (connexion déjà établie), il est encore possible de se connecter au port 80 de Google.

Le paramètre ne s’arrête pas là, puisqu’il accepte bien d’autres paramètres, si vous souhaitez spécifier plusieurs ports (dport devient dports et sport devient sports) :
iptables -A INPUT -i et0 -p tcp -m multiport --dports 80,443 -j DROPl

Pour les classe d’IP, on peut aussi utiliser -m iprange :

iptables -A INPUT -p tcp -m iprange --src-range 192.168.1.13-192.168.2.19

iptables prend aussi du conditionnel. La règle suivant n’est appliquée que si webdown est à 1 :
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport http -m condition --condition webdown -j REJECT --reject-with tcp-reset
# echo 1 > /proc/net/ipt_condition/webdown

On peut aussi appliquer des limites :
Limiter le nombre de connexion sortante vers le port 80 à 4 IP :
iptables -A INPUT -p tcp --syn --dport http -m iplimit --iplimit-above 4 -j REJECT
Voir aussi du côté de –hashlimit et –limit
lenght lui permet de jouer sur la taille des paquets, pour limiter les paquets ICMP supérieur à 1000 octets :
iptables -A INPUT -p icmp --icmp-type echo-request -m length --length 1000:0xffff -j DROP
string permet de bloquer des paquets ayant certaines string, on peut donc bloquer des shells cmd.exe etc.
Exemple :
iptables -I OUTPUT -m string --algo bm --string 'kikoo' -p tcp --dport 80 -j REJECT

iptables -I OUTPUT -p udp -m udp --dport 53 -m string --algo bm --icase --hex-string \|676f6f676c6503636f6d\| -j LOG

il existe de multiples autres paramètres -m, je vous laisse chercher 🙂

NAT

Comme expliqué précédement, la table NAT permet de modifier les paquets pour effectuer du NAT.
Le but étant de pouvoir remplacer les IPs sources et destinations afin que la machine puisse faire office de routeur.
Il est aussi possible d’effectuer des redirections de ports.
iptables permet de faire du nat source (snat) et du nat de destination( dnat).

Exemple ci-dessous pour redirige le port 80 vers le port 8080 :
iptables -t nat -I PREROUTING -i eth0 -p tcp -d 192.168.1.4 --dport 6666 -j DNAT --to 192.168.1.4:8080
On créé un serveur en écoute sur le port 8080 :

Si on se connecte sur le port 6666, la connexion s’effectue bien.

et on récupère bien notre blabla de test du côté serveur :

ou encore redirigé le traffic google vers malekal.com :

iptables -t nat -I PREROUTING -i eth0 -p tcp -d 216.58.208.195 --dport 80 -j DNAT --to 94.23.44.69:80

Ceci peut être utilisé pour créer un proxy transparent, afin par exemple de rediriger tout le traffic HTTP sortant vers le port 3128 :
iptables -t nat -A PREROUTING -s 192.168.1.100 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.12:3128
iptables -t nat -A PREROUTING -s 192.168.1.100 -p tcp --dport 443 -j DNAT --to-destination 192.168.1.12:3128

le SNAT fonctionne de la même manière

LOG / Journal

Il est possible de logguer les paquets acceptés ou droppés dans les journaux de Linux : /var/log/syslog par exemple.
Le principe est simple, on créé des chaînes LOG, avec un debug.

Créé la chaîne LOG_ACCEPT avec un log-level de 6.
Cette chaîne accepte les tous paquets.
iptables -N LOG_ACCEPT
iptables -A LOG_ACCEPT -j LOG --log-prefix "INPUT:ACCEPT:" --log-level 6
iptables -A LOG_ACCEPT -j ACCEPT

Même chose avec la chaîne LOG_DROP.
Cette chaîne DROP tous paquets.

iptables -N LOG_DROP
iptables -A LOG_DROP -j LOG --log-prefix "INPUT:DROP: " --log-level 6
iptables -A LOG_DROP -j DROP

puis on applique cette chaîne à la chaîne souhaitée.
Par exemple, si l’on veut logguer toutes les connexions entrantes :

iptables -A INPUT -j LOG_ACCEPT

Si l’on veut logguer que les connexions sortantes qui seront droppés :

iptables -A OUTPUT -j LOG_DROP

Comprenez que cela ne va pas faire que logguer mais aussi appliquer la chaîne.
Ainsi, toutes les paquets des connexions sortantes seront droppées sauf si une règle autorise le paquet avant le -J LOG_DROP

IPset

Le gros problème d’iptables est qu’il joue les règles de manière séquentielle.
Si vous avez beaucoup de règles, cela peut être lent, surtout durant des attaques.
Si vous devez aussi bloquer beaucoup d’IPs, cela peut poser problème.

Ipset arrive à la rescousse.
Le principe est relativement simple, on créé une ou plusieurs tables sur ipset, qui peut contenir des milliers d’entrées.
On applique une règle iptables à cette table ipset.

Je donne un exemple d’un blocage d’IPs TOR (plus de 6000) avec ipset, sur la page suivante : DoS : Attaque type Slowloris (http flood)

Script iptables

Une fois que vous avez compris le fonctionnement, vous allez pouvoir commencer à écrire votre propre script iptables.
Ce script sera à jouer au démarrage de votre linux.

Ici plusieurs méthodes sont possibles.
Soit vous créez un script que vous chargez en mode daemon.
Il faut placer votre script dans /etc/init.d

mv /emplacement/du/script/iptables /etc/init.d
chmod +x /etc/init.d/monIptables
Pour indiquer à votre ordinateur de l'utiliser au démarrage:
update-rc.d monIptables defaults

 

image_pdfimage_print
(Visité 12 364 fois, 15 visites ce jour)
5.0
01

Add Comment