Iptables est un programme qui permet de configurer les tables fournies par le pare-feu du noyau Linux (implémenté en tant que différents modules Netfilter) et les chaînes et règles qu'il stocke. En d'autres termes, iptables est un outil utilisé pour gérer les règles du pare-feu Linux.
Table utilisée pour la translation d'adresse ou la translation de port.
Il a 2 types de chaînes:
C'est la table par défaut lorsque l'on en spécifie pas.
Cette table contient toutes les règles de filtrage, il existe 3 types de chaînes :
C'est la table qui contient les règles pour la modification de paquets.
Elle est peu utilisée et ne sera pas décrite dans cet article.
Les règles sont évaluées dans l'ordre, par défaut la table FILTER est vide et donc accepte tout. Aucune règle de translation d'adresse n'est présente par défaut.
une chaîne est une suite de règles, qui sont prises dans l'ordre ; dès qu'une règle s'applique à un paquet, elle est déclenchée, et la suite de la chaîne est ignorée.
Il existe 3 targets (ou cibles) :
Les policy disponibles sont :
-j LOG --log-prefix '[IPTABLES DROP] : '
iptables n'est pas livré avec une interface graphique par défaut ; les commandes et les règles sont généralement passées en ligne de commande. Le mieux est d'écrire des scripts (à rajouter dans /etc/rc.d/init.d) qui permettent d'appliquer toutes les règles d'un seul coup, dès le démarrage de GNU/Linux.
-A –append | Ajoute la règle à la fin de la chaîne spécifiée | iptables -A INPUT ... |
---|---|---|
-D –delete | Permet de supprimer une chaîne. On peut l'utiliser de 2 manières, soit en spécifiant le numéro de la chaîne a supprimer, soit en spécifiant la règle à retirer. | iptables -D INPUT --dport 80 -j DROP iptables -D INPUT 1 |
-R –replace | Permet de remplacer la chaîne spécifiée. | iptables -R INPUT 1 -s 192.168.0.1 -j DROP |
-I –insert | Permet d'ajouter une chaîne dans un endroit spécifié de la chaîne. | iptables -I INPUT 1 --dport 80 -j ACCEPT 1) |
-L –list | Permet d'afficher les règles. | iptables -L # Affiche toutes les règles des chaînes de FILTER iptables -L INPUT # Affiche toutes les règles de INPUT (FILTER) |
-F –flush | Permet de vider toutes les règles d'une chaîne. | iptables -F INPUT |
-N –new-chain | Permet de créer une nouvelle chaîne. | iptables -N LOG_DROP |
-X –delete-chain | Permet d'effacer une chaîne. | iptables -X LOG_DROP |
-P –policy | Permet de spécifier au noyau la politique par défaut d'une chaîne DENY, ACCEPT, REJECT, DROP … | iptables -P INPUT DROP |
Le “!” peut être utilisé pour certaines commandes afin de spécifier le contraire (on peut le traduire par “sauf”). Par exemple une commande qui doit refuser tout trafic TCP sauf ce qui provient de l'adresse IP 10.42.42.42 sera traduite par la commande suivante :
iptables -A INPUT -p tcp --source ! 10.42.42.42 -j DROP
Les adresses IP peuvent optionnellement être spécifiées avec le masque associé sous la forme [adresse ip]/[masque].
-j (jump) | Défini l'action à prendre si un paquet répond aux critères de cette règle: ACCEPT, LOG, DROP… | iptables -A INPUT -p icmp -j DROP |
---|---|---|
-p –protocol | Spécifie un protocole : tcp, udp, icmp, all (tous) | iptables -A INPUT -p icmp -j DROP |
-s –source | Spécifie une adresse source à matcher | iptables -A INPUT -p tcp -s 192.168.42.42 -j ACCEPT |
-d –destination | Spécifie une adresse destination | iptables -A FORWARD -p tcp -d 10.1.0.1 -j ACCEPT |
-i –in-interface | Spécifie une interface d'entrée | iptables -A INPUT -p icmp -i eth0 -j DROP |
-o –out-interface | Spécifie une interface de sortie | iptables -A OUTPUT -p icmp -o eth0 -j DROP |
-f –fragment | Paquet fragmenté | iptables -A INPUT -p icmp -f -j DROP |
–sport –source-port | Spécifie le port source ou une plage de ports, fonctionne aussi en udp, -m multiport permet de spécifier plusieurs ports à matcher. | iptables -A INPUT -p tcp --sport 80 -j ACCEPT iptables -A INPUT -p udp --sport 80 -j DROP iptables -A OUTPUT -p tcp -m multiport --sport 3128,21,1000 -j DROP iptables -A OUTPUT -p tcp --sport 1024:2042 -j ACCEPT |
–dport –destination-port | Spécifie le port destination ou une plage de ports, fonctionne aussi en udp, -m multiport permet de spécifier plusieurs ports a matcher. | iptables -A INPUT -p tcp --dport 110 -j DROP iptables -A INPUT -p udp --dport 110 -j DROP iptables -A INPUT -p tcp -m multiport --dport 110,4242,119 -j DROP iptables -A INPUT -p tcp --sport 4925:4633 -j ACCEPT |
–tcp-flags | Spécifier un flag tcp à matcher : SYN ACK FIN RST URG PSH ALL NONE | iptables -A INPUT -p tcp --dport 42 --tcp-flags SYN,ACK -j ACCEPT |
–icmp-type | Spécifie un type de paquet icmp à matcher | iptables -A INPUT -p icmp --icmp-type 8 -j DROP |
–mac-source | Spécifier l'adresse MAC à matcher | iptables -A INPUT --mac-source 42.42.AA.42.42.AA -j DROP n cas d'erreur, il peut-être nécessaire de spécifier le module mac : iptables -A INPUT -m mac --mac-source 42.42.AA.42.42.AA -j DROP |
–state | Permet de spécifier l'état du paquet à matcher parmi les états suivants : * ESTABLISHED: paquet associé à une connexion déjà établie * NEW: paquet demandant une nouvelle connexion * INVALID : paquet associé à une connexion inconnue * RELATED : Nouvelle connexion mais liée, idéal pour les connexions FTP | iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT |
–to-destination | Utilisé en target pour le DNAT, permet de spécifier l'adresse de destination de la translation, on peut également spécifier un port s'il est différent du port source. | iptables -t nat -A PREROUTING -d 42.12.42.12 -p tcp --dport 110 -j DNAT --to-destination 192.168.1.2:6110 iptables -t nat -A PREROUTING -d ! 42.12.42.12 -p tcp --dport 80 -j DNAT --to-destination 192.168.2.1:3128 |
---|---|---|
–to-source | Utilisé pour en target pour le SNAT, permet de spécifier l'adresse source de la translation. |
–log-level | Level, niveau de log |
---|---|
–log-prefix | Permet de spécifier un préfixe pour les logs. |
Par défaut, la stratégie IPv4 dans les noyaux Red Hat Enterprise Linux désactive la prise en charge du transfert IP, ce qui empêche les serveurs exécutant Red Hat Enterprise Linux de fonctionner en tant que routeurs dédiés. Pour activer le transfert IP, exécuter la commande suivante:
$ sysctl -w net.ipv4.ip_forward = 1
Si cette commande est exécutée via l'invite du shell, le paramètre n'est pas mémorisé après un redémarrage. On peut définir définitivement le transfert en remplaçant 0 par 1 sur la ligne net.ipv4.ip_forward dans le fichier /etc/sysctl.conf:
$ sed -i 's/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/' /etc/sysctl.conf
Exécuter la commande suivante pour activer la modification dans le fichier sysctl.conf:
$ sysctl -p /etc/sysctl.conf
Pour partager une connexion, il faut que le forwarding soit activé dans le noyau, puis il faut autoriser iptable à faire le forwarding :
$ iptables -F FORWARD $ iptables -A FORWARD -j ACCEPT
Vérifier les noms des modules avec la commande suivante
$ ls -l /lib/modules/$(uname -r)/kernel/net/ipv4/netfilter/
Vérifier la présence des modules nécessaires (comme nf_nat_ftp, nf_conntrack_ftp) avec la commande lsmod pour afficher le contenu du fichier /proc/modules.
$ lsmod | grep nf
nf_nat_ftp 3443 0 nf_conntrack_ftp 11953 1 nf_nat_ftp nf_nat 22676 3 nf_nat_ftp,ipt_MASQUERADE,iptable_nat nf_conntrack_ipv4 9154 4 iptable_nat,nf_nat nf_defrag_ipv4 1483 1 nf_conntrack_ipv4 nf_conntrack 79206 7 nf_nat_ftp,nf_conntrack_ftp,ipt_MASQUERADE,iptable_nat,nf_nat,nf_conntrack_ipv4,xt_state
Si les modules ne sont pas chargés utiliser la commande modprobe pour les activer
Le serveur dispose de 2 cartes réseau configurées comme ci-dessous:
Le réseau 10.10.1.0/24 est ensuite naturellement NATé via le routeur de la maison pour avoir accès à Internet.
On souhaite obtenir la configuration suivante
La table de routage ressemble à ceci:
$ ip ro
10.10.1.0/24 dev eth0 proto kernel scope link src 10.10.1.20 10.8.8.0/24 dev eth1 proto kernel scope link src 10.8.8.2 default via 10.10.1.1 dev eth0
La passerelle par défaut est sur un interface eth0 “publique”.
Pour que les machines du réseau interne (eth1) puissent envoyer une requête ping aux serveurs publics, il faut autoriser tout nouveau trafic ICMP, provenant de eth1, à quitter via eth0:
$ iptables -A FORWARD -i eth1 -o eth0 -p icmp -m state --state NEW -j ACCEPT
Pour que les serveurs du réseau interne (eth1) puissent établir des connexions aux serveurs Web publics sur les ports HTTP et HTTPS:
$ iptables -A FORWARD -s 10.8.8.0/24 -i eth1 -o eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT
La définition de l'adresse réseau source n'est pas obligatoire ici.
Pour pouvoir contacter les serveurs web privés depuis le réseau public (eth0) , :
$ iptables -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT
Pour pouvoir se connecter au réseau privé (eth1) via SSH:
$ iptables -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 22 -m state --state NEW -j ACCEPT
Pour autoriser toutes les connexions déjà établies ou connexes, dans les deux sens:
$ iptables -A FORWARD -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
Enfin, pour logger tout le reste à des fins de dépannage avant de le jetter:
$ iptables -A FORWARD -p tcp -j LOG --log-prefix "iptables_forward " $ iptables -A FORWARD -p tcp -j DROP
Voici la configuration finale d'iptables pour la chaîne de transfert de table de filtres:
$ iptables -S FORWARD -P FORWARD ACCEPT -A FORWARD -i eth1 -o eth0 -p icmp -m state --state NEW -j ACCEPT -A FORWARD -s 10.8.8.0/24 -i eth1 -o eth0 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 80,443 -m state --state NEW -j ACCEPT -A FORWARD -d 10.8.8.0/24 -i eth0 -o eth1 -p tcp -m multiport --dports 22 -m state --state NEW -j ACCEPT -A FORWARD -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -p tcp -j LOG --log-prefix "iptables_forward " -A FORWARD -p tcp -j DROP
La chaîne de pré-acheminement (Prerouting) aide à traduire l'adresse IP de destination des paquets en quelque chose qui correspond au routage sur le serveur local. Ceci est utilisé pour le NAT de destination (DNAT).
Dans l'exemple suivant, on souhaite transférer tout le trafic SSH sur le port local 22 du port 22043 à 10.8.8.43:
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22043 -m comment --comment "DNAT SSH for .43" -j DNAT --to-destination 10.8.8.43:22
Lorsqu'on initialise une connexion SSH depuis le réseau extérieur (eth0) vers 10.10.1.20:22043, on accédera à la machine 10.8.8.43 sur le port 22.
Plus de règles DNAT, similaires à celles ci-dessus, peuvent être ajoutées, par exemple, pour atteindre un serveur web HTTP sur le port 8080 qui est hébergé sur 10.8.8.44:80:
$ ptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.8.44:80
Chaîne de post-routage (Postrouting) aide à traduire l'adresse IP source des paquets à quelque chose qui pourrait correspondre au routage sur le serveur de destination. Ceci est utilisé pour le NAT source (SNAT).
Pour permettre aux nœuds privés (eth1) avec des adresses IP privées de communiquer avec des réseaux publics externes, configurer le pare-feu pour le masquage IP, qui masque les requêtes des nœuds LAN avec l'adresse IP du périphérique externe du pare-feu (dans ce cas , eth0):
$ iptables -t nat -A POSTROUTING -o eth0 -p icmp -j MASQUERADE $ iptables -t nat -A POSTROUTING -o eth0 -p tcp -m multiport --dports 80,443 -j MASQUERADE
Voici la dernière configuration d'iptables pour la table NAT (toutes les chaînes):
$ iptables -t nat -S -P PREROUTING ACCEPT -P POSTROUTING ACCEPT -P OUTPUT ACCEPT -A PREROUTING -i eth0 -p tcp -m tcp --dport 22043 -m comment --comment "DNAT SSH for .43" -j DNAT --to-destination 10.8.8.43:22 -A POSTROUTING -o eth0 -p icmp -j MASQUERADE -A POSTROUTING -o eth0 -p tcp -m multiport --dports 80,443 -j MASQUERADE
Ne pas oublier de sauvegarder les règles iptables:
$ service iptables save
Pour fixer les politiques par défaut (cad: ce qui se passe quand aucune règle ne correspond - ne matche pas), ici, on refuse tout
$ iptables -P INPUT DROP $ iptables -P OUTPUT DROP $ iptables -P FORWARD DROP
Pour logguer tout ce qu'on jette :
$ iptables -N LOG_DROP $ iptables -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : ' $ iptables -A LOG_DROP -j DROP
Les trois dernières règles doivent être :
$ iptables -A FORWARD -j LOG_DROP $ iptables -A INPUT -j LOG_DROP $ iptables -A OUTPUT -j LOG_DROP
Recommencer en remplaçant -j DROP, par -j ACCEPT et a la place de -j LOGDROP il faut mettre -j LOGACCEPT
Pour accepter tout ce qui se passe sur l'interface lo (sinon ce n'est pas la peine d'activer le réseau !) :
$ iptables -A INPUT -i lo -j ACCEPT $ iptables -A OUTPUT -o lo -j ACCEPT
Pour accepter tout ce qui se passe sur le réseau local 192.168.1.0 :
$ iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT $ iptables -A OUTPUT -d 192.168.1.0/24 -j ACCEPT $ iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
Pour accepter les résolutions de nom (ie: le dns) :
$ iptables -A INPUT -i eth0 --protocol udp --source-port 53 -j ACCEPT $ iptables -A OUTPUT -o eth0 --protocol udp --destination-port 53 -j ACCEPT $ iptables -A INPUT -i eth0 --protocol tcp --source-port 53 -j ACCEPT $ iptables -A OUTPUT -o eth0 --protocol tcp --destination-port 53 -j ACCEPT
Pour accepter le traffic web (on veut surfer!) :
$ iptables -A INPUT -i eth0 --protocol tcp --source-port 80 -m state --state ESTABLISHED -j LOG_ACCEPT $ iptables -A OUTPUT -o eth0 --protocol tcp --destination-port 80 -m state --state NEW,ESTABLISHED -j LOG_ACCEPT
La première ligne pour accepter ce qui entre sur notre interface eth0 sur le port 80 (le port http) si c'est une connexion déjà établie, la seconde pour accepter ce qui sort sur eth0 sur le port 80 si c'est une nouvelle connexion ou si c'est une connexion déjà établie.
De manière générale, le numéros de port se trouvent dans /etc/services.
Sur chaque machine devant être cachée par le pare-feu (ou devant partager la connexion avec la machine qui est connectée à internet), il faut ajouter une route par defaut :
$ route add default gw 192.168.1.1
Si la machine connectée à internet a comme ip : 192.168.1.1. Par exemple, il suffit avec une Red Hat ou Mageia d'éditer :
$ vi /etc/sysconfig/network
et d'ajouter dedans :
GATEWAY=192.168.1.1
puis de redémarer le réseau :
$ service network restart
Le pare-feu dispose d'un port eth0 paramétré dans le réseau 172.31.0.0/24.
Un serveur HTTP dédié est connecté sur un réseau isolé à l'adresse 10.0.4.2 (dans un sous réseau en dehors de la plage 172.31.0.0/24 du réseau local).
Pour définir une règle d'acheminement des requêtes HTTP entrantes vers l'adresse 10.0.4.2 NAT appelle une table PREROUTING pour transférer les paquets à leur destination correcte
La stratégie FORWARD permet de contrôler où les paquets peuvent être routés dans un réseau local. Par exemple, pour autoriser le transfert pour l'intégralité du réseau local, les règles suivantes peuvent être définies:
iptables -A FORWARD -i eth0 -j ACCEPT iptables -A FORWARD -o eth0 -j ACCEPT
Avec cette règle la passerelle achemine les paquets d'un noeud LAN vers son noeud cible, en passant tous les paquets via son périphérique eth0.
L'acceptation des paquets transférés via le périphérique IP interne du pare-feu permet aux nœuds LAN de communiquer entre eux; Cependant, ils ne sont toujours pas autorisés à communiquer en externe sur Internet. Pour permettre aux nœuds LAN avec des adresses IP privées de communiquer avec des réseaux publics externes, configurer le pare-feu pour le masquage IP, qui masque les requêtes des nœuds LAN avec l'adresse IP du périphérique externe du pare-feu (dans ce cas, eth0):
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
La règle utilise la table de correspondance de paquets NAT (-t nat) et spécifie la chaîne POSTROUTING intégrée pour NAT (-A POSTROUTING) sur le périphérique de réseau externe du pare-feu (-o eth0). POSTROUTING permet de modifier les paquets lorsqu'ils quittent le périphérique externe du pare-feu. La cible -j MASQUERADE est spécifiée pour masquer l'adresse IP privée d'un noeud avec l'adresse IP externe du pare-feu / passerelle.
Les règles iptables peuvent être configurées pour acheminer le trafic vers certaines machines, telles qu'un serveur HTTP ou FTP dédié, dans une zone démilitarisée (DMZ) - un sous-réseau local spécial dédié à la fourniture de services sur un opérateur public tel qu'Internet
Pour rendre le serveur interne disponible en externe, il faut utiliser la cible -j DNAT de la chaîne PREROUTING dans NAT pour spécifier une adresse IP de destination et un port où les paquets entrants demandant une connexion à votre service interne peuvent être transmis. Par exemple, pour transférer les demandes HTTP entrantes vers le serveur Apache HTTP Server dédié à l'adresse 10.0.4.2, exécuter la commande suivante:
$ iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --destination 10.0.4.2:80
Cette règle spécifie que la table NAT utilise la chaîne PREROUTING intégrée pour transférer les demandes HTTP entrantes exclusivement vers l'adresse IP de destination répertoriée 10.0.4.2.
Si la politique par défaut de DROP est définie, il faut ajouter une règle dans la chaîne FORWARD pour autoriser le transfert des demandes HTTP entrantes afin que le routage NAT de destination puisse être possible. Pour ce faire, exécuter la commande suivante:
iptables -A FORWARD -i eth0 -p tcp --dport 80 -d 10.0.4.2 -j ACCEPT
Cette règle permet de transférer les demandes HTTP entrantes du pare-feu à la destination prévue du serveur Apache HTTP Server derrière le pare-feu.
L'une des principales raisons pour l'utilisation du mode FTP passif est qu'il permet de passer plus facilement à travers les pare-feux. Cependant, certains utilisateurs peuvent ne pas savoir comment activer le mode FTP passif ou avoir des clients incompatibles.
Pour permettre aux requètes FTP de passer correctement les pare-feu, iptables devant être capable de marquer et suivre ces connexions, il faut activer le module du noyau nf_conntrack_ftp (c'est lui qui suit - track en anglais - les connexions ftp).
Pour nater (en utilisant le masquerading par exemple) les connexions ftp, il faut activer le module du noyau nf_nat_ftp.
Pour les noyaux 2.6.19 ou antérieurs, les noms des modules sont ip_nat_ftp et ip_conntrack_ftp et ils sont normalement chargés à partir de /lib/modules/<version du noyau>/kernel/net/ipv4/netfilter/
.
$ modprobe nf_conntrack_ftp $ modprobe nf_nat_ftp
Ajouter dans /etc/sysconfig/iptables-config les modules:
IPTABLES_MODULES="nf_conntrack_ftp nf_nat_ftp"
Autoriser le tafic NEW ESTABLISHED etRELATED sur le port 21
$ iptables -A INPUT -p tcp --dport 21 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $ iptables -A OUTPUT -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
Autoriser le trafic ESTABLISHED et RELATED sur le port 20 (on a besoin de nf_conntrack_ftp)
$ iptables -A INPUT -p tcp --dport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT $ iptables -A OUTPUT -p tcp --sport 20 -m state --state ESTABLISHED -j ACCEPT
Autoriser le trafic ESTABLISHED et RELATED sur les port 1024 à 65535 (on a besoin de nf_conntrack_ftp)
$ iptables -A INPUT -p tcp --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT $ iptables -A OUTPUT -p tcp --sport 1024:65535 -m state --state ESTABLISHED -j ACCEPT