« Iptables » : différence entre les versions
Aucun résumé des modifications |
|||
(20 versions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
= iptables par l'exemple = | = iptables par l'exemple = | ||
Ligne 31 : | Ligne 29 : | ||
iptables a besoin au minimum d'un noyau 2.4 compilé avec des options spéciales. Ceci ne pose pas de problèmes avec les noyaux génériques des principales distributions : tout a déjà été fait pour vous. | iptables a besoin au minimum d'un noyau 2.4 compilé avec des options spéciales. Ceci ne pose pas de problèmes avec les noyaux génériques des principales distributions : tout a déjà été fait pour vous. | ||
Bref, sur une distribution récente et standard, passez à la partie 2/. | |||
=== 1.2/ Options de compilation du kernel === | === 1.2/ Options de compilation du kernel === | ||
Ligne 77 : | Ligne 77 : | ||
* '''Table NAT''' (Network Address Translation) : Table utilisée pour la translation d'adresse ou la translation de port. <br />Il a 2 types de chaînes<sup><nowiki>#</nowiki></sup> : ''PREROUTING'' qui permet de spécifier « à l'arrivée du pare-feu » et la chaîne ''POSTROUTING'' qui permet de spécifier « à la sortie du pare-feu ». Il existe 3 targets (ou cibles) : ''DNAT<sup><nowiki>*</nowiki></sup>, SNAT<sup><nowiki>*</nowiki></sup>'' et ''MASQUERADE<sup><nowiki>*</nowiki></sup>''. | * '''Table NAT''' (Network Address Translation) : Table utilisée pour la translation d'adresse ou la translation de port. <br />Il a 2 types de chaînes<sup><nowiki>#</nowiki></sup> : ''PREROUTING'' qui permet de spécifier « à l'arrivée du pare-feu » et la chaîne ''POSTROUTING'' qui permet de spécifier « à la sortie du pare-feu ». Il existe 3 targets (ou cibles) : ''DNAT<sup><nowiki>*</nowiki></sup>, SNAT<sup><nowiki>*</nowiki></sup>'' et ''MASQUERADE<sup><nowiki>*</nowiki></sup>''. | ||
* '''Table FILTER''' : C'est la table par défaut lorsque l'on en spécifie pas. <br />Cette table contient toutes les règles de filtrage, il existe 3 types de chaînes : ''FORWARD'' pour les paquets passant par le | * '''Table FILTER''' : C'est la table par défaut lorsque l'on en spécifie pas. <br />Cette table contient toutes les règles de filtrage, il existe 3 types de chaînes : ''FORWARD'' pour les paquets passant par le pare-feu, ''INPUT'' pour les paquets entrant et ''OUTPUT'' pour les paquets sortants. Les cibles disponibles sont : ''ACCEPT, DENY, DROP, REJECT °''. | ||
* '''Table Mangle''' : C'est la table qui contient les règles pour la modification de paquets. <br />Elle est peu utilisée et ne sera pas décrite dans cet article. | * '''Table Mangle''' : C'est la table qui contient les règles pour la modification de paquets. <br />Elle est peu utilisée et ne sera pas décrite dans cet article. | ||
Ligne 85 : | Ligne 85 : | ||
: 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. | : 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. | ||
; * <u>SNAT</u> | ; * <u>SNAT</u> | ||
: | : Permet de modifier l'adresse source du paquet. | ||
; * <u>DNAT</u> | ; * <u>DNAT</u> | ||
: | : Permet de modifier l'adresse destination du paquet. | ||
; * <u>MASQUERADE</u> | ; * <u>MASQUERADE</u> | ||
: Une passerelle (gateway) transforme les paquets sortants passant par elle pour donner l'illusion qu'ils sortent de la passerelle elle-même par un port alloué dynamiquement ; lorsque la passerelle recoit une réponse sur ce port, elle utilise une table de correspondance entre le port et les machines du réseau privé qu'elle gère pour lui faire suivre le paquet. | : Une passerelle (gateway) transforme les paquets sortants passant par elle pour donner l'illusion qu'ils sortent de la passerelle elle-même par un port alloué dynamiquement ; lorsque la passerelle recoit une réponse sur ce port, elle utilise une table de correspondance entre le port et les machines du réseau privé qu'elle gère pour lui faire suivre le paquet. | ||
; ° <u>policy ACCEPT</u> | ; ° <u>policy ACCEPT</u> | ||
: | : Permet d'accepter un paquet grâce à la règle vérifiée. | ||
; ° <u>policy DROP</u> | ; ° <u>policy DROP</u> | ||
: Rejet d'un paquet sans message d'erreur si la règle est vérifiée ("non ! j'en veux pas mais je dis rien à l'expediteur"). | : Rejet d'un paquet sans message d'erreur si la règle est vérifiée ("non ! j'en veux pas mais je dis rien à l'expediteur"). | ||
Ligne 97 : | Ligne 97 : | ||
: Rejet avec un retour de paquet d'erreur à l'expediteur si la règle est verifiée ("un paquet recommandé de La Poste refusé par son destinataire"). | : Rejet avec un retour de paquet d'erreur à l'expediteur si la règle est verifiée ("un paquet recommandé de La Poste refusé par son destinataire"). | ||
; ° <u>policy LOG</u> | ; ° <u>policy LOG</u> | ||
: Affiche le | : Affiche le résultat vers la sortie standard. | ||
: | : Peut être associé a un préfixe pour une meilleure lisibilité (un préfixe pour les paquets rejetes,un autre pour les paquets forwardés etc...). | ||
:Exemple : -j LOG --log-prefix '[IPTABLES DROP] : ' | :Exemple : -j LOG --log-prefix '[IPTABLES DROP] : ' | ||
=== 2.2/ Les commandes === | === 2.2/ Les commandes === | ||
iptables n'est pas livré avec une interface graphique ; les commandes et les règles sont passées en ligne de commande. Le mieux est d'écrire des scripts (à rajouter dans <tt>/etc/rc.d/init.d</tt>) qui permettent d'appliquer toutes les règles d'un seul coup, dès le démarrage de GNU/Linux. | 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 <tt>/etc/rc.d/init.d</tt>) qui permettent d'appliquer toutes les règles d'un seul coup, dès le démarrage de GNU/Linux. | ||
La plupart des distributions proposent cependant des outils graphiques ou semi-graphiques pour configurer le pare-feu. Ainsi, Red Hat et Fedora proposent <tt>system-config-firewall-tui</tt> et <tt>system-config-firewall </tt>, Mageia utilise <tt>Shorewall</tt>, Ubuntu <tt>UFW</tt>. | |||
==== 2.2.1/ Commandes principales ==== | ==== 2.2.1/ Commandes principales ==== | ||
Ligne 109 : | Ligne 111 : | ||
<tt>-A --append</tt> : Ajoute la règle à la fin de la chaîne spécifiée <br />''<font color="#770000">Exemple :</font>''<br /><tt><font color="#770000"><nowiki># iptables -A INPUT ...</nowiki></font></tt> | <tt>-A --append</tt> : Ajoute la règle à la fin de la chaîne spécifiée <br />''<font color="#770000">Exemple :</font>''<br /><tt><font color="#770000"><nowiki># iptables -A INPUT ...</nowiki></font></tt> | ||
<tt>-D --delete</tt> : Permet de supprimer une chaîne. On peut l'utiliser de 2 manières, soit en spécifiant le | <tt>-D --delete</tt> : 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. <br />''<font color="#770000">Exemples :</font>''<br /><tt><font color="#770000"><nowiki># iptables -D INPUT --dport 80 -j DROP</nowiki></font></tt><br /><tt><font color="#770000"><nowiki># iptables -D INPUT 1</nowiki></font></tt> | ||
<tt>-R --replace</tt> : Permet de remplacer la chaîne spécifiée. <br />''<font color="#770000">Exemple :</font>''<br /><tt><font color="#770000"><nowiki># iptables -R INPUT 1 -s 192.168.0.1 -j DROP</nowiki></font></tt> | <tt>-R --replace</tt> : Permet de remplacer la chaîne spécifiée. <br />''<font color="#770000">Exemple :</font>''<br /><tt><font color="#770000"><nowiki># iptables -R INPUT 1 -s 192.168.0.1 -j DROP</nowiki></font></tt> | ||
Ligne 178 : | Ligne 180 : | ||
Les exemples qui suivent supposent que vous êtes reliés à internet par modem via l'interface ppp0 (mais en remplaçant ppp0 par eth0 - par exemple, on peut adapter les exemples pour d'autres type de liaisons) et que votre réseau local est 192.168.1.0/24 (classe C). | Les exemples qui suivent supposent que vous êtes reliés à internet par modem via l'interface ppp0 (mais en remplaçant ppp0 par eth0 - par exemple, on peut adapter les exemples pour d'autres type de liaisons) et que votre réseau local est 192.168.1.0/24 (classe C). | ||
* 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 (normal, on fait un | * 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 (normal, on fait un pare-feu, oui ou non ?) : <blockquote><tt> iptables -P INPUT DROP<br /> iptables -P OUTPUT DROP<br /> iptables -P FORWARD DROP</tt></blockquote> | ||
* Pour '''logguer''' tout ce qu'on jette : <blockquote><tt> iptables -N LOG_DROP<br /> iptables -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : '<br /> iptables -A LOG_DROP -j DROP</tt></blockquote> | * Pour '''logguer''' tout ce qu'on jette : <blockquote><tt> iptables -N LOG_DROP<br /> iptables -A LOG_DROP -j LOG --log-prefix '[IPTABLES DROP] : '<br /> iptables -A LOG_DROP -j DROP</tt></blockquote> | ||
Les trois dernières règles doivent être : <blockquote><tt> iptables -A FORWARD -j LOG_DROP<br /> iptables -A INPUT -j LOG_DROP<br /> iptables -A OUTPUT -j LOG_DROP </tt></blockquote> | Les trois dernières règles doivent être : <blockquote><tt> iptables -A FORWARD -j LOG_DROP<br /> iptables -A INPUT -j LOG_DROP<br /> iptables -A OUTPUT -j LOG_DROP </tt></blockquote> | ||
Ligne 188 : | Ligne 190 : | ||
Pour autoriser le '''ssh''', il faut préciser le port 22; pour autoriser l''''irc''', le port 6667 (ou celui que vous utilisez pour vous connecter à votre serveur); pour le '''smtp''' (envoi d'emails), le port 25; pour le '''pop3''' (réception d'emails), le port 110; pour le '''imap''' (réception d'emails), les ports 143 et 220 ('''imap3''') ; pour le '''cvs''', le port 2401 ; pour le '''https''', le port 443. De manière générale, le numéros de port se trouvent dans /etc/services. | Pour autoriser le '''ssh''', il faut préciser le port 22; pour autoriser l''''irc''', le port 6667 (ou celui que vous utilisez pour vous connecter à votre serveur); pour le '''smtp''' (envoi d'emails), le port 25; pour le '''pop3''' (réception d'emails), le port 110; pour le '''imap''' (réception d'emails), les ports 143 et 220 ('''imap3''') ; pour le '''cvs''', le port 2401 ; pour le '''https''', le port 443. De manière générale, le numéros de port se trouvent dans /etc/services. | ||
* Pour le '''ftp''' c'est un peu plus complexe. D'abord, il faut charger le module : <tt>ip_conntrack_ftp</tt> (c'est lui qui suit - track en anglais - les connexions ftp) et, si vous ''nat''ez (en utilisant le masquerading par exemple) vos connexions ftp vers d'autres postes le module : <tt>ip_nat_ftp</tt> : <blockquote><tt> modprobe ip_conntrack_ftp</tt><br /> # éventuellement : <tt> modprobe ip_nat_ftp</tt> </blockquote> Ensuite, il faut taper les commandes suivantes : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT </tt></blockquote> Cela pour que la connexion puisse s'établir. Ensuite (et c'est la qu'on a besoin de <tt>ip_conntrack_ftp</tt>) : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT </tt></blockquote> Pour que serveur puisse établir la connexion pour les données (en mode actif). Et enfin : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT </tt></blockquote> Pour que le serveur puisse établir la connexion pour les données (en mode passif). Ici aussi <tt>ip_conntrack_ftp</tt> est nécessaire. | * Pour le '''ftp''' c'est un peu plus complexe. D'abord, il faut charger le module : <tt>ip_conntrack_ftp</tt> (c'est lui qui suit - track en anglais - les connexions ftp) et, si vous ''nat''ez (en utilisant le masquerading par exemple) vos connexions ftp vers d'autres postes le module : <tt>ip_nat_ftp</tt> : <blockquote><tt> modprobe ip_conntrack_ftp</tt><br /> # éventuellement : <tt> modprobe ip_nat_ftp</tt> </blockquote> Ensuite, il faut taper les commandes suivantes : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT </tt></blockquote> Cela pour que la connexion puisse s'établir. Ensuite (et c'est la qu'on a besoin de <tt>ip_conntrack_ftp</tt>) : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT </tt></blockquote> Pour que serveur puisse établir la connexion pour les données (en mode actif). Et enfin : <blockquote><tt> iptables -A INPUT -i ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT<br /> iptables -A OUTPUT -o ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT </tt></blockquote> Pour que le serveur puisse établir la connexion pour les données (en mode passif). Ici aussi <tt>ip_conntrack_ftp</tt> est nécessaire. | ||
* Pour '''partager une connexion''', il faut que le forwarding soit activé dans le noyau (<tt>echo 1 > /proc/sys/net/ipv4/ip_forward</tt>), puis il faut autoriser iptable à faire le forwarding : <blockquote><tt> iptables -F FORWARD<br /> iptables -A FORWARD -j ACCEPT </tt></blockquote> et enfin, cacher les machines | |||
* Pour '''partager une connexion''', il faut que le forwarding soit activé dans le noyau (<tt>echo 1 > /proc/sys/net/ipv4/ip_forward</tt>), puis il faut autoriser iptable à faire le forwarding : <blockquote><tt> iptables -F FORWARD<br /> iptables -A FORWARD -j ACCEPT </tt></blockquote> et enfin, cacher les machines forwardées par le pare-feu : <blockquote><tt> iptables -A POSTROUTING -t nat -o ppp0 -j MASQUERADE </tt></blockquote> 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 : <blockquote><tt> route add default gw 192.168.1.1 </tt></blockquote> 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 : <blockquote><tt>/etc/sysconfig/network</tt></blockquote> et d'ajouter dedans : <blockquote><tt>GATEWAY=192.168.1.1</tt></blockquote> puis de redémarer le réseau :<blockquote><tt>service network restart</tt></blockquote> | |||
== 3/ Application par l'exemple == | == 3/ Application par l'exemple == | ||
Nous allons mettre en place un | Nous allons mettre en place un pare-feu / proxy. | ||
Pour cet exemple, le | Pour cet exemple, le pare-feu aura la connexion à Internet (interface eth2) et disposera de 2 pattes sur des réseaux privés (eth0 et eth1) : | ||
* il fait office de proxy sur le port 3128 pour un réseau qui aura ainsi un accès internet | * il fait office de proxy sur le port 3128 pour un réseau qui aura ainsi un accès internet | ||
Ligne 213 : | Ligne 216 : | ||
; <sup><nowiki>* </nowiki></sup><u>DMZ, ou zone démilitarisée</u> | ; <sup><nowiki>* </nowiki></sup><u>DMZ, ou zone démilitarisée</u> | ||
: Sous-réseau dans lequel des serveurs accessibles depuis internet sont en adressage privé (classe d'adresse IP réservée comme 192.168.x.x) derrière un | : Sous-réseau dans lequel des serveurs accessibles depuis internet sont en adressage privé (classe d'adresse IP réservée comme 192.168.x.x) derrière un pare-feu. | ||
=== 3.1/ Le script init.d === | === 3.1/ Le script init.d === | ||
Nous allons écrire un script qui permettra de charger automatiquement au démarrage de la machine ou sur demande les règles du | Nous allons écrire un script qui permettra de charger automatiquement au démarrage de la machine ou sur demande les règles du pare-feu qui seront stockées dans le fichier <tt>/etc/firewall.sh</tt>. <br />Le script de démarrage sera nommé <tt>/etc/init.d/firewall</tt>. Bien sûr, on n'oubliera pas d'exécuter un <tt>chmod +x</tt> sur les 2 scripts que nous allons créer au long de ce chapitre. | ||
À noter que dans de nombreuses distributions, ce script existe déjà. Ainsi, sous Red Hat et Fedora, il s'appelle <tt>/etc/init.d/iptables</tt>. Le service associé s'appelle <tt>iptables</tt> et lorsqu'il est actif, il utilise les règles définies dans le fichier <tt>/etc/sysconfig/iptables</tt>. | |||
Go ! <br />Fichier de chargement <tt>/etc/init.d/firewall</tt> : <br /> | Go ! <br />Fichier de chargement <tt>/etc/init.d/firewall</tt> : <br /> | ||
Ligne 225 : | Ligne 230 : | ||
{| width="90%" bgcolor="#FFFFCC" | {| width="90%" bgcolor="#FFFFCC" | ||
| | | | ||
<tt><nowiki>#!/bin/bash</nowiki></tt><br /><tt><nowiki>#</nowiki></tt><br /><tt><nowiki># Lancement du script de | <tt><nowiki>#!/bin/bash</nowiki></tt><br /><tt><nowiki>#</nowiki></tt><br /><tt><nowiki># Lancement du script de pare-feu</nowiki></tt><br /><tt><nowiki># Arnaud de Bermingham</nowiki></tt> | ||
<tt>. /etc/init.d/functions</tt> | <tt>. /etc/init.d/functions</tt> | ||
Ligne 231 : | Ligne 236 : | ||
<tt>RETVAL=0</tt> | <tt>RETVAL=0</tt> | ||
<tt><nowiki># Fonction pour le lancement du | <tt><nowiki># Fonction pour le lancement du pare-feu</nowiki></tt><br /><tt>start() {</tt><br /><tt> echo -n "Application des règles IpTables: "</tt><br /><tt> /etc/firewall.sh</tt><br /><tt> RETVAL=0</tt><br /><tt> [ $RETVAL -eq 0 ] && touch /var/lock/subsys/firewall</tt><br /><tt> echo</tt><br /><tt>}</tt> | ||
<tt><nowiki># Fonction pour arrêter le | <tt><nowiki># Fonction pour arrêter le pare-feu (on flush)</nowiki></tt><br /><tt>stop() {</tt><br /><tt> echo -n "Flush des règles IpTables: "</tt><br /><tt> /etc/flush_iptables.sh</tt><br /><tt> RETVAL=0</tt><br /><tt> [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/firewall</tt><br /><tt> echo</tt><br /><tt>}</tt> | ||
<tt>case $1 in</tt><br /><tt> start)</tt><br /><tt> start</tt><br /><tt> ;;</tt><br /><tt> stop)</tt><br /><tt> stop</tt><br /><tt> ;;</tt><br /><tt> restart)</tt><br /><tt> stop</tt><br /><tt> start</tt><br /><tt> ;;</tt><br /><tt> status)</tt><br /><tt> /sbin/iptables -L</tt><br /><tt> /sbin/iptables -t nat -L</tt><br /><tt> RETVAL=0</tt><br /><tt> ;;</tt><br /><tt> *)</tt><br /><tt> echo "Usage: firewall {start|stop|restart|status}"</tt><br /><tt> RETVAL=1</tt><br /><tt>esac</tt> | <tt>case $1 in</tt><br /><tt> start)</tt><br /><tt> start</tt><br /><tt> ;;</tt><br /><tt> stop)</tt><br /><tt> stop</tt><br /><tt> ;;</tt><br /><tt> restart)</tt><br /><tt> stop</tt><br /><tt> start</tt><br /><tt> ;;</tt><br /><tt> status)</tt><br /><tt> /sbin/iptables -L</tt><br /><tt> /sbin/iptables -t nat -L</tt><br /><tt> RETVAL=0</tt><br /><tt> ;;</tt><br /><tt> *)</tt><br /><tt> echo "Usage: firewall {start|stop|restart|status}"</tt><br /><tt> RETVAL=1</tt><br /><tt>esac</tt> | ||
Ligne 269 : | Ligne 274 : | ||
</center> | </center> | ||
Bon, on va enfin commencer les choses sérieuses : le script du | Bon, on va enfin commencer les choses sérieuses : le script du pare-feu :) | ||
=== 3.3/ Les prérequis pour le script du pare-feu et création des tables pour les logs === | === 3.3/ Les prérequis pour le script du pare-feu et création des tables pour les logs === | ||
Ligne 283 : | Ligne 288 : | ||
<tt><nowiki># script </nowiki>'''/etc/firewall.sh'''</tt> | <tt><nowiki># script </nowiki>'''/etc/firewall.sh'''</tt> | ||
<tt><nowiki># | <tt><nowiki># Pare-feu d'exemple a but pédagogique</nowiki></tt><br /><tt><nowiki># Arnaud de Bermingham</nowiki></tt><br /><tt><nowiki># duracell@apinc.org</nowiki></tt> | ||
<tt><nowiki># </nowiki>'''Activation du forwarding'''</tt><br /><tt><font size="-1"><nowiki># C'est pas pour faire joli, on aura des règles</nowiki></font></tt><br /><tt><font size="-1"><nowiki># de forward et il faut bien que les paquets</nowiki></font></tt><br /><tt><font size="-1"><nowiki># traversent la machine, donc on met ce fichier à 1</nowiki></font></tt> | <tt><nowiki># </nowiki>'''Activation du forwarding'''</tt><br /><tt><font size="-1"><nowiki># C'est pas pour faire joli, on aura des règles</nowiki></font></tt><br /><tt><font size="-1"><nowiki># de forward et il faut bien que les paquets</nowiki></font></tt><br /><tt><font size="-1"><nowiki># traversent la machine, donc on met ce fichier à 1</nowiki></font></tt> | ||
Ligne 289 : | Ligne 294 : | ||
<tt>echo 1 > /proc/sys/net/ipv4/ip_forward</tt> | <tt>echo 1 > /proc/sys/net/ipv4/ip_forward</tt> | ||
<tt><nowiki># Alors la, on va appliquer quelques astuces</nowiki></tt><br /><tt><nowiki># pour empêcher les attaques de type </nowiki>''spoofing''</tt><br /><tt><nowiki># et bloquer les réponses ICMP du | <tt><nowiki># Alors la, on va appliquer quelques astuces</nowiki></tt><br /><tt><nowiki># pour empêcher les attaques de type </nowiki>''spoofing''</tt><br /><tt><nowiki># et bloquer les réponses ICMP du pare-feu,</nowiki></tt><br /><tt><nowiki># comme ça c'est très propre. Attention, le</nowiki></tt><br /><tt><nowiki># fait de bloquer le trafic ICMP sur</nowiki></tt><br /><tt><nowiki># le pare-feu bloque les pings.</nowiki></tt> | ||
<tt><nowiki># Je veux </nowiki>'''pas de spoofing'''</tt> | <tt><nowiki># Je veux </nowiki>'''pas de spoofing'''</tt> | ||
Ligne 307 : | Ligne 312 : | ||
<tt>modprobe ip_nat_ftp</tt><br /><tt>modprobe ip_nat_irc</tt><br /><tt>modprobe iptable_filter</tt><br /><tt>modprobe iptable_nat</tt> | <tt>modprobe ip_nat_ftp</tt><br /><tt>modprobe ip_nat_irc</tt><br /><tt>modprobe iptable_filter</tt><br /><tt>modprobe iptable_nat</tt> | ||
<tt><nowiki># Pour faire bien, on va </nowiki>'''vider toutes les règles'''</tt><br /><tt><nowiki># avant d'appliquer les nouvelles règles de | <tt><nowiki># Pour faire bien, on va </nowiki>'''vider toutes les règles'''</tt><br /><tt><nowiki># avant d'appliquer les nouvelles règles de pare-feu</nowiki></tt> | ||
<tt>iptables -F</tt><br /><tt>iptables -X</tt> | <tt>iptables -F</tt><br /><tt>iptables -X</tt> | ||
Ligne 317 : | Ligne 322 : | ||
<tt><nowiki># ici, on logue et on accepte le paquet,</nowiki></tt><br /><tt><nowiki># on rajoute un préfixe pour pouvoir</nowiki></tt><br /><tt><nowiki># s'y retrouver dans les logs</nowiki></tt><br /><tt>iptables -N LOG_ACCEPT</tt><br /><tt>iptables -A LOG_ACCEPT -j LOG \</tt><br /><tt> --log-prefix '[IPTABLES ACCEPT] : '</tt><br /><tt>iptables -A LOG_ACCEPT -j ACCEPT</tt> | <tt><nowiki># ici, on logue et on accepte le paquet,</nowiki></tt><br /><tt><nowiki># on rajoute un préfixe pour pouvoir</nowiki></tt><br /><tt><nowiki># s'y retrouver dans les logs</nowiki></tt><br /><tt>iptables -N LOG_ACCEPT</tt><br /><tt>iptables -A LOG_ACCEPT -j LOG \</tt><br /><tt> --log-prefix '[IPTABLES ACCEPT] : '</tt><br /><tt>iptables -A LOG_ACCEPT -j ACCEPT</tt> | ||
<tt><nowiki># On veut faire un | <tt><nowiki># On veut faire un pare-feu efficace,</nowiki></tt><br /><tt><nowiki># donc la politique a appliquer est de tout</nowiki></tt><br /><tt><nowiki># refuser par défaut et rajouter une a une</nowiki></tt><br /><tt><nowiki># les règles que l'on autorise.</nowiki></tt><br /><tt><nowiki># Bien sur, on a RTFM un peu et on a vu que</nowiki></tt><br /><tt><nowiki># l'option -P permet de définir</nowiki></tt><br /><tt><nowiki># </nowiki>'''la cible par défaut'''</tt> | ||
<tt>iptables -P INPUT DROP</tt><br /><tt>iptables -P OUTPUT DROP</tt><br /><tt>iptables -P FORWARD DROP</tt> | <tt>iptables -P INPUT DROP</tt><br /><tt>iptables -P OUTPUT DROP</tt><br /><tt>iptables -P FORWARD DROP</tt> | ||
Ligne 325 : | Ligne 330 : | ||
<tt>iptables -A INPUT -i lo -j ACCEPT</tt><br /><tt>iptables -A OUTPUT -o lo -j ACCEPT</tt> | <tt>iptables -A INPUT -i lo -j ACCEPT</tt><br /><tt>iptables -A OUTPUT -o lo -j ACCEPT</tt> | ||
<tt><nowiki># Bon, la partie initialisation et préparation est</nowiki></tt><br /><tt><nowiki># terminée, passons aux choses sérieuses</nowiki></tt><br /><br /><tt><nowiki># Comme on l'a dit dans la présentation de</nowiki></tt><br /><tt><nowiki># l'architecture réseau, le | <tt><nowiki># Bon, la partie initialisation et préparation est</nowiki></tt><br /><tt><nowiki># terminée, passons aux choses sérieuses</nowiki></tt><br /><br /><tt><nowiki># Comme on l'a dit dans la présentation de</nowiki></tt><br /><tt><nowiki># l'architecture réseau, le pare-feu fait</nowiki></tt><br /><tt><nowiki># également office de proxy grâce par exemple</nowiki></tt><br /><tt><nowiki># à un squid installé dessus. On va donc</nowiki></tt><br /><tt><nowiki># accepter que le </nowiki>'''proxy''' ait une '''connexion'''</tt><br /><tt><nowiki># </nowiki>'''internet directe'''. Tant qu'à faire, on va</tt><br /><tt><nowiki># mettre des états pour que ça soit bien sécurisé</nowiki></tt> | ||
<tt>iptables -A OUTPUT -o ppp0 -m state \</tt><br /><tt> --state NEW,ESTABLISHED -p tcp --dport 80 -j ACCEPT</tt><br /><tt>iptables -A INPUT -i ppp0 -m state \</tt><br /><tt> --state ESTABLISHED -p tcp --sport 80 -j ACCEPT</tt> | <tt>iptables -A OUTPUT -o ppp0 -m state \</tt><br /><tt> --state NEW,ESTABLISHED -p tcp --dport 80 -j ACCEPT</tt><br /><tt>iptables -A INPUT -i ppp0 -m state \</tt><br /><tt> --state ESTABLISHED -p tcp --sport 80 -j ACCEPT</tt> | ||
<tt><nowiki># Maintenant, on va faire en sorte que le</nowiki></tt><br /><tt><nowiki># </nowiki>'''proxy soit totalement transparent pour le LAN'''</tt><br /><tt><nowiki># bénéficiant de la connexion internet.</nowiki></tt><br /><tt><nowiki># L'astuce consiste a rediriger toutes les</nowiki></tt><br /><tt><nowiki># requêtes ayant un port de destination 80</nowiki></tt><br /><tt><nowiki># vers le port 3128 du proxy, ici c'est le</nowiki></tt><br /><tt><nowiki># | <tt><nowiki># Maintenant, on va faire en sorte que le</nowiki></tt><br /><tt><nowiki># </nowiki>'''proxy soit totalement transparent pour le LAN'''</tt><br /><tt><nowiki># bénéficiant de la connexion internet.</nowiki></tt><br /><tt><nowiki># L'astuce consiste a rediriger toutes les</nowiki></tt><br /><tt><nowiki># requêtes ayant un port de destination 80</nowiki></tt><br /><tt><nowiki># vers le port 3128 du proxy, ici c'est le</nowiki></tt><br /><tt><nowiki># pare-feu (qui est sur le pare-feu et qui</nowiki></tt><br /><tt><nowiki># a l'adresse IP 192.168.2.1 ).</nowiki></tt><br /><tt><nowiki># Une règle de NAT suffira largement pour faire ça.</nowiki></tt> | ||
<tt>iptables -t nat -A PREROUTING -i eth1 -p tcp \</tt><br /><tt> --dport 80 -j DNAT --to-destination 192.168.2.1:3128</tt> | <tt>iptables -t nat -A PREROUTING -i eth1 -p tcp \</tt><br /><tt> --dport 80 -j DNAT --to-destination 192.168.2.1:3128</tt> | ||
Ligne 337 : | Ligne 342 : | ||
<tt>iptables -t nat -A PREROUTING -d 42.42.42.42 \</tt><br /><tt> -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80</tt> | <tt>iptables -t nat -A PREROUTING -d 42.42.42.42 \</tt><br /><tt> -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80</tt> | ||
<tt><nowiki># C'est bien tout ça ! mais le problème c'est</nowiki></tt><br /><tt><nowiki># que les chaînes de la table FILTER sont toutes</nowiki></tt><br /><tt><nowiki># à DENY, donc tout ceci ne fait rien du tout.</nowiki></tt><br /><tt><nowiki># On va donc passer a la </nowiki>'''configuration du'''</tt><br /><tt><nowiki># </nowiki>''' | <tt><nowiki># C'est bien tout ça ! mais le problème c'est</nowiki></tt><br /><tt><nowiki># que les chaînes de la table FILTER sont toutes</nowiki></tt><br /><tt><nowiki># à DENY, donc tout ceci ne fait rien du tout.</nowiki></tt><br /><tt><nowiki># On va donc passer a la </nowiki>'''configuration du'''</tt><br /><tt><nowiki># </nowiki>'''pare-feu''' proprement dit.</tt> | ||
<tt><nowiki># On va quand même </nowiki>'''accepter les connexions ssh'''</tt><br /><tt><nowiki># (port 22) provenant d'une machine (la votre en</nowiki></tt><br /><tt><nowiki># l'occurrence, on va dire 192.168.2.42) vers le</nowiki></tt><br /><tt><nowiki># | <tt><nowiki># On va quand même </nowiki>'''accepter les connexions ssh'''</tt><br /><tt><nowiki># (port 22) provenant d'une machine (la votre en</nowiki></tt><br /><tt><nowiki># l'occurrence, on va dire 192.168.2.42) vers le</nowiki></tt><br /><tt><nowiki># pare-feu pour pouvoir modifier les règles</nowiki></tt><br /><tt><nowiki># facilement pour bien surveiller, on va quand</nowiki></tt><br /><tt><nowiki># même loguer les connexions provenant de mon IP</nowiki></tt><br /><tt><nowiki># et à destination du ssh du pare-feu</nowiki></tt> | ||
<tt>iptables -A INPUT -i eth1 -s 192.168.2.42 -m state \</tt><br /><tt> --state NEW,ESTABLISHED -p tcp --dport 22 -j LOG_ACCEPT</tt><br /><tt>iptables -A OUTPUT -o eth1 -d 192.168.2.42 -m state \</tt><br /><tt> --state ESTABLISHED -p tcp --sport 22 -j LOG_ACCEPT</tt> | <tt>iptables -A INPUT -i eth1 -s 192.168.2.42 -m state \</tt><br /><tt> --state NEW,ESTABLISHED -p tcp --dport 22 -j LOG_ACCEPT</tt><br /><tt>iptables -A OUTPUT -o eth1 -d 192.168.2.42 -m state \</tt><br /><tt> --state ESTABLISHED -p tcp --sport 22 -j LOG_ACCEPT</tt> | ||
Ligne 351 : | Ligne 356 : | ||
<tt>iptables -A FORWARD -i eth1 -o eth0 -p tcp \</tt><br /><tt> --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT</tt><br /><tt>iptables -A FORWARD -i eth0 -o eth1 -p tcp \</tt><br /><tt> --sport 80 -m state --state ESTABLISHED -j ACCEPT</tt> | <tt>iptables -A FORWARD -i eth1 -o eth0 -p tcp \</tt><br /><tt> --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT</tt><br /><tt>iptables -A FORWARD -i eth0 -o eth1 -p tcp \</tt><br /><tt> --sport 80 -m state --state ESTABLISHED -j ACCEPT</tt> | ||
<tt><nowiki># Maintenant il n'y a plus qu'à dire au | <tt><nowiki># Maintenant il n'y a plus qu'à dire au pare-feu</nowiki></tt><br /><tt><nowiki># d'autoriser à transmettre des paquets TCP à</nowiki></tt><br /><tt><nowiki># destination du port 80 provenant de l'adresse</nowiki></tt><br /><tt><nowiki># IP publique (i.e. d'</nowiki>'''internet''') '''vers le serveur'''</tt><br /><tt><nowiki># </nowiki>'''web de la DMZ''' que nous avons naté précédemment.</tt> | ||
<tt>iptables -A FORWARD -i ppp0 -o eth0 -p tcp \</tt><br /><tt> --destination-port 80 -m state --state NEW,ESTABLISHED -j ACCEPT</tt><br /><tt>iptables -A FORWARD -o ppp0 -i eth0 -p tcp \</tt><br /><tt> --source-port 80 -m state --state ESTABLISHED -j ACCEPT</tt> | <tt>iptables -A FORWARD -i ppp0 -o eth0 -p tcp \</tt><br /><tt> --destination-port 80 -m state --state NEW,ESTABLISHED -j ACCEPT</tt><br /><tt>iptables -A FORWARD -o ppp0 -i eth0 -p tcp \</tt><br /><tt> --source-port 80 -m state --state ESTABLISHED -j ACCEPT</tt> | ||
Ligne 357 : | Ligne 362 : | ||
<tt><nowiki># Maintenant il ne reste plus grand chose à faire !</nowiki></tt> | <tt><nowiki># Maintenant il ne reste plus grand chose à faire !</nowiki></tt> | ||
<tt><nowiki># Il faut permettre à l'ensemble du LAN de dialoguer</nowiki></tt><br /><tt><nowiki># sur internet avec la même adresse IP sinon, bien</nowiki></tt><br /><tt><nowiki># évidemment ça ne marchera pas (à moins que vous</nowiki></tt><br /><tt><nowiki># ayez 30 adresses ip !).</nowiki></tt><br /><tt><nowiki># Une petite règle de NAT avec un -j MASQUERADE</nowiki></tt><br /><tt><nowiki># suffira (masquerade = dialoguer avec l'adresse</nowiki></tt><br /><tt><nowiki># IP publique sur | <tt><nowiki># Il faut permettre à l'ensemble du LAN de dialoguer</nowiki></tt><br /><tt><nowiki># sur internet avec la même adresse IP sinon, bien</nowiki></tt><br /><tt><nowiki># évidemment ça ne marchera pas (à moins que vous</nowiki></tt><br /><tt><nowiki># ayez 30 adresses ip !).</nowiki></tt><br /><tt><nowiki># Une petite règle de NAT avec un -j MASQUERADE</nowiki></tt><br /><tt><nowiki># suffira (masquerade = dialoguer avec l'adresse</nowiki></tt><br /><tt><nowiki># IP publique sur pare-feu)</nowiki></tt> | ||
<tt>iptables -t nat -A POSTROUTING \</tt><br /><tt> -s 192.168.2.0/24 -j MASQUERADE</tt> | <tt>iptables -t nat -A POSTROUTING \</tt><br /><tt> -s 192.168.2.0/24 -j MASQUERADE</tt> | ||
Ligne 365 : | Ligne 370 : | ||
<tt>iptables -t nat -A POSTROUTING \</tt><br /><tt> -s 192.168.1.0/24 -j MASQUERADE</tt> | <tt>iptables -t nat -A POSTROUTING \</tt><br /><tt> -s 192.168.1.0/24 -j MASQUERADE</tt> | ||
<tt><nowiki># Toutes les règles qui n'ont pas passé les</nowiki></tt><br /><tt><nowiki># règles du | <tt><nowiki># Toutes les règles qui n'ont pas passé les</nowiki></tt><br /><tt><nowiki># règles du pare-feu seront refusées et loguées...</nowiki></tt><br /><tt><nowiki># facile :</nowiki></tt> | ||
<tt>iptables -A FORWARD -j LOG_DROP</tt><br /><tt>iptables -A INPUT -j LOG_DROP</tt><br /><tt>iptables -A OUTPUT -j LOG_DROP</tt> | <tt>iptables -A FORWARD -j LOG_DROP</tt><br /><tt>iptables -A INPUT -j LOG_DROP</tt><br /><tt>iptables -A OUTPUT -j LOG_DROP</tt> | ||
Ligne 376 : | Ligne 381 : | ||
</center> | </center> | ||
Et voilà ! le | Et voilà ! le pare-feu de compét' est prêt et fonctionnel. | ||
Ceci était bien évidemment un exemple, vous pouvez dès à présent préparer votre propre pare-feu personnalisé ! <br />Vous pouvez l'adapter à vos besoins, votre connexion vers internet (par ADSL par exemple), etc. | Ceci était bien évidemment un exemple, vous pouvez dès à présent préparer votre propre pare-feu personnalisé ! <br />Vous pouvez l'adapter à vos besoins, votre connexion vers internet (par ADSL par exemple), etc. | ||
= | == Sauvegarder, restaurer et rendre permanente la configuration == | ||
Tester votre | Pour voir si iptables est activé comme service au démarrage, tapez (pour <tt>systemd</tt>) : | ||
<div class="code"> | |||
<nowiki>#</nowiki> systemctl list-unit-files |grep iptables | |||
iptables.service disabled | |||
</div> | |||
Si vous voyez ''enable'', c'est que votre pare-feu est bien activé. | |||
Sinon, pour l'activer : | |||
<div class="code"> | |||
<nowiki>#</nowiki> systemctl start iptables | |||
</div> | |||
Si votre distribution n'utilise pas <tt>systemd</tt>, tapez : | |||
<div class="code"> | |||
<nowiki>#</nowiki> chkconfig --list iptables|grep iptables | |||
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off | |||
</div> | |||
Et pour l'activer : | |||
<div class="code"> | |||
<nowiki>#</nowiki> chkconfig iptables on | |||
</div> | |||
<tt>iptables-restore</tt> et <tt>iptables-save</tt> sont deux commandes associées qui permettent de sauvegarder/restaurer la configuration Netfilter, dans un fichier spécifié, par exemple <tt>/etc/sysconfig/iptables</tt> sous Red Hat et Fedora. Généralement, ces commandes peuvent être appelées par le service, typiquement : | |||
<div class="code"> | |||
<nowiki>#</nowiki> service iptables save | |||
</div> | |||
Sous Ubuntu et Debian, c'est la commande <tt>iptables-persistent</tt> qui gère les règles iptables au démarrage, avec comme argument <tt>save</tt> pour sauvegarder les règles, <tt>flush</tt> pour les vider et <tt>reload</tt> pour les recharger, tout cela en se basant sur le fichier <tt>/etc/iptables/rules.v4</tt> (resp. v6 pour IPv6). | |||
== Autres ressources == | |||
Le [[Trucs:Partager une connexion internet|partage de connexion]] facile. | |||
Tester votre pare-feu [http://grc.com/default.htm là]. | |||
Cliquez sur 'ShieldsUP!', puis sur l'un des boutons : 'Test My Shields !" et "Probe My Ports !". Ça vaut pas un bon <tt>nmap</tt> fait par un ami, mais ça permet de voir ou on en est. | Cliquez sur 'ShieldsUP!', puis sur l'un des boutons : 'Test My Shields !" et "Probe My Ports !". Ça vaut pas un bon <tt>nmap</tt> fait par un ami, mais ça permet de voir ou on en est. | ||
Évidemment, si vous êtes derrière une box internet (Freebox, Livebox etc.), ce sera son pare-feu à elle - il s'agit d'ailleurs probablement d'<tt>iptables</tt> également - qui sera testé et non pas celui de votre distribution. | |||
<br/> | <br/> | ||
<br/> | <br/> | ||
'''<b>[[ | '''<b>[[Sécurité et vie privée|@ Retour à la rubrique Sécurité et vie privée]]</b>''' | ||
<br/> | <br/> | ||
Ligne 400 : | Ligne 444 : | ||
{{Copy|12/11/2001|[mailto:duracell_chez_apinc_point_org Arnaud de Bermingham]|DP}} | {{Copy|12/11/2001|[mailto:duracell_chez_apinc_point_org Arnaud de Bermingham]|DP}} | ||
[[Catégorie:Sécurité et vie privée]] |
Dernière version du 19 décembre 2023 à 23:27
iptables par l'exemple
par Arnaud de Bermingham révision par Jice, Fred, Jiel
Introduction
Cet article présente de façon pratique la mise en place d'un pare-feu (en anglais, firewall) ou d'un proxy sur une machine GNU/Linux tournant au minimum avec un noyau 2.4.
Pour des informations plus théoriques sur les pare-feux et les proxys, vous pouvez lire l'article pare-feu.
Présentation d'iptables
iptables est une solution complète de pare-feu pour le système GNU/Linux depuis le noyau 2.4, remplaçant ipchains, le pare-feu du noyau 2.2. iptables permet de faire du firewalling à états (stateful), de la translation de port et d'adresse, du filtrage au niveau 2 et beaucoup d'autres choses que nous n'allons pas aborder comme le « mangle » ou modification des paquets à la volée (atchoum).
iptables est fiable et dispose de très nombreuses options qui permettent de faire du filtrage très fin.
Précisons dès maintenant que le module qui fournit au noyau Linux les fonctions de pare-feu, de partage de connexions internet (NAT) et d'historisation du trafic réseau s'appelle Netfilter. iptables est en fait juste l'outil qui permet à un administrateur de configurer Netfilter en mode utilisateur.
Licence d'iptables
iptables et le framework NetFilter sont sous licence libre GPL.
1/ Installation
1.1/ Prérequis
iptables est installé en standard sur de nombreuses distributions GNU/Linux récentes (kernel 2.4.x. ou supérieur).
iptables a besoin au minimum d'un noyau 2.4 compilé avec des options spéciales. Ceci ne pose pas de problèmes avec les noyaux génériques des principales distributions : tout a déjà été fait pour vous.
Bref, sur une distribution récente et standard, passez à la partie 2/.
1.2/ Options de compilation du kernel
Si vous désirez re-compiler votre kernel, il faut spécifier les options nécessaires au fonctionnement d'iptables.
Les options suivantes doivent êtres activées en module (M) ou dans le kernel (Y) :
CONFIG_PACKET
CONFIG_NETFILTER
CONFIG_IP_NF_CONNTRACK
CONFIG_IP_NF_FTP
CONFIG_IP_NF_IRC
CONFIG_IP_NF_IPTABLES
CONFIG_IP_NF_FILTER
CONFIG_IP_NF_NAT
CONFIG_IP_NF_MATCH_STATE
CONFIG_IP_NF_TARGET_LOG
CONFIG_IP_NF_MATCH_LIMIT
CONFIG_IP_NF_TARGET_MASQUERADE
et éventuellement :
CONFIG_IP_NF_COMPAT_IPCHAINS pour garder la compatibilité avec ipchains.
CONFIG_IP_NF_COMPAT_IPFWADM pour garder la compatibilité avec ipfwadm.
CONFIG_IP_NF_TARGET_REDIRECT indispensable, pour les proxies transparents par exemple.
CONFIG_IP_NF_MATCH_MAC permet de matcher avec les adresses MAC.
Ne pas oublier le support réseau et TCP/IP et compiler le kernel comme d'habitude :
make dep && make clean && make bzImage && make modules && make modules_install
1.3/ Installation
Récupérer le package netfilter et l'installer comme d'habitude avec apt-get, urpmi, emerge...
Notons que sur les versions inférieures a Red Hat 7.1, il faut compiler un noyau 2.4 car iptables ne supporte pas les noyaux 2.2.x. La compilation de iptables est complexe. Le mieux est de lire le fichier INSTALL du package des sources.
1.4/ Chargement des modules
Dans le cas ou les options iptables du noyau ont été compilées en modules, il est nécessaire de charger ces modules avant de pouvoir utiliser iptables :
# modprobe ip_tables
selon les besoins, on peut éventuellement charger les modules suivants :
# modprobe ip_nat_ftp
# modprobe ip_nat_irc
# modprobe iptable_filter
# modprobe iptable_mangle
# modprobe iptable_nat
Si on a besoin de pouvoir rediriger (forward) les paquets IP arrivant sur un interface réseau (connectée par exemple à Internet) vers une autre interface réseau (connectée par exemple au réseau local), il sera nécessaire, dans la plupart des cas, d'exécuter cette commande :
# echo 1 > /proc/sys/net/ipv4/ip_forward
afin de l'indiquer au noyau.
Nota bene : tous les modprobe semblent inutiles car le kernel les charge automatiquement si l'on se sert de l'une des fonctionnalités d'iptables.
2/ Présentation
2.1/ Les tables
- Table NAT (Network Address Translation) : Table utilisée pour la translation d'adresse ou la translation de port.
Il a 2 types de chaînes# : PREROUTING qui permet de spécifier « à l'arrivée du pare-feu » et la chaîne POSTROUTING qui permet de spécifier « à la sortie du pare-feu ». Il existe 3 targets (ou cibles) : DNAT*, SNAT* et MASQUERADE*. - Table FILTER : 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 : FORWARD pour les paquets passant par le pare-feu, INPUT pour les paquets entrant et OUTPUT pour les paquets sortants. Les cibles disponibles sont : ACCEPT, DENY, DROP, REJECT °. - Table Mangle : 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.
A noter : 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.
- # chaîne
- 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.
- * SNAT
- Permet de modifier l'adresse source du paquet.
- * DNAT
- Permet de modifier l'adresse destination du paquet.
- * MASQUERADE
- Une passerelle (gateway) transforme les paquets sortants passant par elle pour donner l'illusion qu'ils sortent de la passerelle elle-même par un port alloué dynamiquement ; lorsque la passerelle recoit une réponse sur ce port, elle utilise une table de correspondance entre le port et les machines du réseau privé qu'elle gère pour lui faire suivre le paquet.
- ° policy ACCEPT
- Permet d'accepter un paquet grâce à la règle vérifiée.
- ° policy DROP
- Rejet d'un paquet sans message d'erreur si la règle est vérifiée ("non ! j'en veux pas mais je dis rien à l'expediteur").
- ° policy REJECT
- Rejet avec un retour de paquet d'erreur à l'expediteur si la règle est verifiée ("un paquet recommandé de La Poste refusé par son destinataire").
- ° policy LOG
- Affiche le résultat vers la sortie standard.
- Peut être associé a un préfixe pour une meilleure lisibilité (un préfixe pour les paquets rejetes,un autre pour les paquets forwardés etc...).
- Exemple : -j LOG --log-prefix '[IPTABLES DROP] : '
2.2/ Les commandes
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.
La plupart des distributions proposent cependant des outils graphiques ou semi-graphiques pour configurer le pare-feu. Ainsi, Red Hat et Fedora proposent system-config-firewall-tui et system-config-firewall , Mageia utilise Shorewall, Ubuntu UFW.
2.2.1/ Commandes principales
-A --append : Ajoute la règle à la fin de la chaîne spécifiée
Exemple :
# 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.
Exemples :
# iptables -D INPUT --dport 80 -j DROP
# iptables -D INPUT 1
-R --replace : Permet de remplacer la chaîne spécifiée.
Exemple :
# 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.
Exemple :
# iptables -I INPUT 1 --dport 80 -j ACCEPT
Si aucun chiffre n'est spécifié à la suite (#iptables -I INPUT --dport 80 -j ACCEPT), la règle est ajoutée au début de la chaîne spécifiée
-L --list : Permet d'afficher les règles.
Exemples :
# 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.
Exemple :
# iptables -F INPUT
-N --new-chain : Permet de créer une nouvelle chaîne.
Exemple :
# iptables -N LOG_DROP
-X --delete-chain : Permet d'effacer une chaîne.
Exemple :
# 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 ...
Exemple :
# iptables -P INPUT DROP
2.2.2/ Commandes pour matcher
Remarques :
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 :
Exemple :
# 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...
Exemple :
# iptables -A INPUT -p icmp -j DROP
-p --protocol : Spécifier un protocole : tcp, udp, icmp, all (tous)
Exemple :
# iptables -A INPUT -p icmp -j DROP
-s --source : Spécifier une adresse source à matcher
Exemple :
# iptables -A INPUT -p tcp -s 192.168.42.42 -j ACCEPT
-d --destination : Spécifier une adresse destination
Exemple :
# iptables -A FORWARD -p tcp -d 10.1.0.1 -j ACCEPT
-i --in-interface : Spécifier une interface d'entrée
Exemple :
# iptables -A INPUT -p icmp -i eth0 -j DROP
-o --out-interface : Spécifier une interface de sortie
Exemple :
# iptables -A OUTPUT -p icmp -o eth0 -j DROP
-f --fragment : Paquet fragmenté
Exemple :
# iptables -A INPUT -p icmp -f -j DROP
--sport --source-port : Spécifier le port source ou une plage de ports, fonctionne aussi en udp, -m multiport permet de
spécifier plusieurs ports à matcher.
Exemples :
# 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écifier le port destination ou une plage de ports, fonctionne aussi en udp, -m multiport
permet de spécifier plusieurs ports a matcher.
Exemples :
# 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
Exemple :
# iptables -A INPUT -p tcp --dport 42 --tcp-flags SYN,ACK -j ACCEPT
--icmp-type : Spécifier un type de paquet icmp à matcher
Exemple :
# iptables -A INPUT -p icmp --icmp-type 8 -j DROP
--mac-source : Spécifier l'adresse MAC à matcher
Exemple :
# iptables -A INPUT --mac-source 42.42.AA.42.42.AA -j DROP
En cas d'erreur, il peut-être nécessaire de spécifier le module mac, exemple :
# 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
Exemples :
# 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
Spécificités NAT :
--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.
Exemples :
# 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.
Spécificités pour les LOGS :
--log-level : Level, niveau de log
Exemple : Cf. chapitre 3
--log-prefix : Permet de spécifier un préfixe pour les logs.
Exemple : Cf. chapitre 3
2.2.3/ Quelques exemples :
Les exemples qui suivent supposent que vous êtes reliés à internet par modem via l'interface ppp0 (mais en remplaçant ppp0 par eth0 - par exemple, on peut adapter les exemples pour d'autres type de liaisons) et que votre réseau local est 192.168.1.0/24 (classe C).
- 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 (normal, on fait un pare-feu, oui ou non ?) :
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
Enfin (pour loguer le trafic autorisé), recommencer en remplaçant -j DROP, par -j ACCEPT et a la place de -j LOG_DROP il faut mettre -j LOG_ACCEPT
- 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 ppp0 --protocol udp --source-port 53 -j ACCEPT
iptables -A OUTPUT -o ppp0 --protocol udp --destination-port 53 -j ACCEPT
iptables -A INPUT -i ppp0 --protocol tcp --source-port 53 -j ACCEPT
iptables -A OUTPUT -o ppp0 --protocol tcp --destination-port 53 -j ACCEPT - Pour accepter le traffic web (on veut surfer!) :
La première ligne pour accepter ce qui entre sur notre interface ppp0 sur le port 80 (le port http) si c'est une connexion déjà établie, la seconde pour accepter ce qui sort sur ppp0 sur le port 80 si c'est une nouvelle connexion ou si c'est une connexion déjà établie.iptables -A INPUT -i ppp0 --protocol tcp --source-port 80 -m state --state ESTABLISHED -j LOG_ACCEPT
iptables -A OUTPUT -o ppp0 --protocol tcp --destination-port 80 -m state --state NEW,ESTABLISHED -j LOG_ACCEPT
Pour autoriser le ssh, il faut préciser le port 22; pour autoriser l'irc, le port 6667 (ou celui que vous utilisez pour vous connecter à votre serveur); pour le smtp (envoi d'emails), le port 25; pour le pop3 (réception d'emails), le port 110; pour le imap (réception d'emails), les ports 143 et 220 (imap3) ; pour le cvs, le port 2401 ; pour le https, le port 443. De manière générale, le numéros de port se trouvent dans /etc/services.
- Pour le ftp c'est un peu plus complexe. D'abord, il faut charger le module : ip_conntrack_ftp (c'est lui qui suit - track en anglais - les connexions ftp) et, si vous natez (en utilisant le masquerading par exemple) vos connexions ftp vers d'autres postes le module : ip_nat_ftp :
Ensuite, il faut taper les commandes suivantes :modprobe ip_conntrack_ftp
# éventuellement : modprobe ip_nat_ftp
Cela pour que la connexion puisse s'établir. Ensuite (et c'est la qu'on a besoin de ip_conntrack_ftp) :iptables -A INPUT -i ppp0 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ppp0 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
Pour que serveur puisse établir la connexion pour les données (en mode actif). Et enfin :iptables -A INPUT -i ppp0 -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -o ppp0 -p tcp --dport 20 -m state --state ESTABLISHED -j ACCEPT
Pour que le serveur puisse établir la connexion pour les données (en mode passif). Ici aussi ip_conntrack_ftp est nécessaire.iptables -A INPUT -i ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o ppp0 -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT
- Pour partager une connexion, il faut que le forwarding soit activé dans le noyau (echo 1 > /proc/sys/net/ipv4/ip_forward), puis il faut autoriser iptable à faire le forwarding :
et enfin, cacher les machines forwardées par le pare-feu :iptables -F FORWARD
iptables -A FORWARD -j ACCEPT
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 :iptables -A POSTROUTING -t nat -o ppp0 -j MASQUERADE
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 :route add default gw 192.168.1.1
et d'ajouter dedans :/etc/sysconfig/network
puis de redémarer le réseau :GATEWAY=192.168.1.1
service network restart
3/ Application par l'exemple
Nous allons mettre en place un pare-feu / proxy.
Pour cet exemple, le pare-feu aura la connexion à Internet (interface eth2) et disposera de 2 pattes sur des réseaux privés (eth0 et eth1) :
- il fait office de proxy sur le port 3128 pour un réseau qui aura ainsi un accès internet
- et une DMZ* ("zone démilitarisée") sur laquelle il y a un ensemble de serveurs disponibles de l'extérieur dont un serveur web qui a pour adresse 192.168.1.2 écoutant sur le port 80 en TCP.
_____ eth1 .-> ---+------+------+--- _/ \_ ____ / [PC1] [PC2] [PC3] ( ) eth2 | |<--' réseau local 198.168.2.0 ( INTERNET )<---->|Fire| (_ _) ppp0 |wall| \______/ |____|<--. DMZ serveurs 198.168.1.0 eth0\ [WEB] [NEWS] [FTP] '-> ---+------+------+--- ASCIIArt (c) Jice
La classe d'adresse IP 192.168.2.0 correspond au réseau interne sur l'interface eth1.
La classe d'adresse IP 192.168.1.0 correspond a la DMZ sur l'interface eth0.
L'interface de la connexion Internet est ppp0 sur l'interface eth2.
- * DMZ, ou zone démilitarisée
- Sous-réseau dans lequel des serveurs accessibles depuis internet sont en adressage privé (classe d'adresse IP réservée comme 192.168.x.x) derrière un pare-feu.
3.1/ Le script init.d
Nous allons écrire un script qui permettra de charger automatiquement au démarrage de la machine ou sur demande les règles du pare-feu qui seront stockées dans le fichier /etc/firewall.sh.
Le script de démarrage sera nommé /etc/init.d/firewall. Bien sûr, on n'oubliera pas d'exécuter un chmod +x sur les 2 scripts que nous allons créer au long de ce chapitre.
À noter que dans de nombreuses distributions, ce script existe déjà. Ainsi, sous Red Hat et Fedora, il s'appelle /etc/init.d/iptables. Le service associé s'appelle iptables et lorsqu'il est actif, il utilise les règles définies dans le fichier /etc/sysconfig/iptables.
Go !
Fichier de chargement /etc/init.d/firewall :
#!/bin/bash . /etc/init.d/functions RETVAL=0 # Fonction pour le lancement du pare-feu # Fonction pour arrêter le pare-feu (on flush) case $1 in exit |
C'est tout simple non ?
3.2/ Le script pour vider (flusher) les règles
Et maintenant : /etc/flush_iptables.sh.
#!/bin/sh # # # # iptables -X # Message de fin |
Bon, on va enfin commencer les choses sérieuses : le script du pare-feu :)
3.3/ Les prérequis pour le script du pare-feu et création des tables pour les logs
Le script sera commenté au fur et à mesure, afin de décrire chaque étape.
#!/bin/sh # script /etc/firewall.sh # Pare-feu d'exemple a but pédagogique # Activation du forwarding echo 1 > /proc/sys/net/ipv4/ip_forward # Alors la, on va appliquer quelques astuces # Je veux pas de spoofing if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ] # pas de icmp echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all # On va utiliser iptables. Si on l'a compilé en module modprobe ip_tables # on va charger quelques modules supplémentaires pour modprobe ip_nat_ftp # Pour faire bien, on va vider toutes les règles iptables -F # On va rajouter 2 nouvelles chaînes. # La on logue et on refuse le paquet, # ici, on logue et on accepte le paquet, # On veut faire un pare-feu efficace, iptables -P INPUT DROP # Pour éviter les problèmes, on va tout accepter sur iptables -A INPUT -i lo -j ACCEPT # Bon, la partie initialisation et préparation est iptables -A OUTPUT -o ppp0 -m state \ # Maintenant, on va faire en sorte que le iptables -t nat -A PREROUTING -i eth1 -p tcp \ # Bon, c'est pas trop compliqué ! Maintenant iptables -t nat -A PREROUTING -d 42.42.42.42 \ # C'est bien tout ça ! mais le problème c'est # On va quand même accepter les connexions ssh iptables -A INPUT -i eth1 -s 192.168.2.42 -m state \ # On veut que le LAN connecté à l'interface iptables -A FORWARD -i eth1 -o ppp0 -j ACCEPT # Maintenant on donne le droit au LAN de iptables -A FORWARD -i eth1 -o eth0 -p tcp \ # Maintenant il n'y a plus qu'à dire au pare-feu iptables -A FORWARD -i ppp0 -o eth0 -p tcp \ # Maintenant il ne reste plus grand chose à faire ! # Il faut permettre à l'ensemble du LAN de dialoguer iptables -t nat -A POSTROUTING \ # Il faut également que le serveur web de la DMZ iptables -t nat -A POSTROUTING \ # Toutes les règles qui n'ont pas passé les iptables -A FORWARD -j LOG_DROP # Pour faire zoli # c'est enfin fini |
Et voilà ! le pare-feu de compét' est prêt et fonctionnel.
Ceci était bien évidemment un exemple, vous pouvez dès à présent préparer votre propre pare-feu personnalisé !
Vous pouvez l'adapter à vos besoins, votre connexion vers internet (par ADSL par exemple), etc.
Sauvegarder, restaurer et rendre permanente la configuration
Pour voir si iptables est activé comme service au démarrage, tapez (pour systemd) :
# systemctl list-unit-files |grep iptables
iptables.service disabled
Si vous voyez enable, c'est que votre pare-feu est bien activé.
Sinon, pour l'activer :
# systemctl start iptables
Si votre distribution n'utilise pas systemd, tapez :
# chkconfig --list iptables|grep iptables
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Et pour l'activer :
# chkconfig iptables on
iptables-restore et iptables-save sont deux commandes associées qui permettent de sauvegarder/restaurer la configuration Netfilter, dans un fichier spécifié, par exemple /etc/sysconfig/iptables sous Red Hat et Fedora. Généralement, ces commandes peuvent être appelées par le service, typiquement :
# service iptables save
Sous Ubuntu et Debian, c'est la commande iptables-persistent qui gère les règles iptables au démarrage, avec comme argument save pour sauvegarder les règles, flush pour les vider et reload pour les recharger, tout cela en se basant sur le fichier /etc/iptables/rules.v4 (resp. v6 pour IPv6).
Autres ressources
Le partage de connexion facile.
Tester votre pare-feu là.
Cliquez sur 'ShieldsUP!', puis sur l'un des boutons : 'Test My Shields !" et "Probe My Ports !". Ça vaut pas un bon nmap fait par un ami, mais ça permet de voir ou on en est.
Évidemment, si vous êtes derrière une box internet (Freebox, Livebox etc.), ce sera son pare-feu à elle - il s'agit d'ailleurs probablement d'iptables également - qui sera testé et non pas celui de votre distribution.
@ Retour à la rubrique Sécurité et vie privée
Cette page est issue de la documentation 'pré-wiki' de Léa a été convertie avec HTML::WikiConverter. Elle fut créée par Arnaud de Bermingham le 12/11/2001. Cette page a été révisée par Jice, puis par Fred en 2005, puis par Jiel en 2006 et 2014.
Copyright
© 12/11/2001 Arnaud de Bermingham
La documentation de cette page est laissée dans le domaine public. |