![]() |
![]() |
![]() |
Auteur : David Mascle.
Le but de ce TP est de comprendre l'écriture de règles pour les écluses ("Firewall") avec IPChains sous Linux.
Pour ce TP, nous disposions de la configuration suivante :
![]() |
Table de routage du Firewall station nommée "pass" :
Table de routage IP du noyau Destination Passerelle Genmask Indic MSS Fenêtre irtt Iface 192.168.110.1 0.0.0.0 255.255.255.255 UH 0 0 0 eth1 193.55.130.181 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 192.168.110.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 193.55.130.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 193.55.130.1 0.0.0.0 UG 0 0 0 eth |
Table de routage de la station nommée "tp1" :
Table de routage IP du noyau Destination Passerelle Genmask Indic MSS Fenêtre irtt Iface 192.168.110.2 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 192.168.110.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 192.168.110.1 0.0.0.0 UG 0 0 0 eth0 |
Table de routage de la station nommée "tp2" :
Table de routage IP du noyau Destination Passerelle Genmask Indic MSS Fenêtre irtt Iface 192.168.110.3 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 192.168.110.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo 0.0.0.0 192.168.110.1 0.0.0.0 UG 0 0 0 eth0 |
Le premier objectif de ce TP est de réaliser un essai d'écluse entre un réseau privé et un réseau public (Internet). Pour cela, nous allons nous intéresser au fonctionnement des règles d'IPChains pour mettre en place un Firewall. Nous allons aussi nous intéresser aux problèmes posés par l'utilisation du protocole FTP au travers d'un Firewall.
Le deuxième objectif de ce TP est d'auto-sécuriser un Firewall (protection anti-spoofing) et de mettre en place un ensemble de règles permettant l'utilisation de divers services sur le réseau privé au travers de ce Firewall (DNS, ICMP, HTTP, FTP, POP, SMTP...).
Nous allons commencer par voir le principe de fonctionnement d'IPChains. Cette application est un filtre de paquets fonctionnant au niveau du noyau Linux.
Le noyau dispose de trois listes de règles appelées des chaînes. Ces trois chaînes sont des filtres disposant de règles propres et qui fonctionnent en entrée (INPUT), en transmission (FORWARD) et en sortie (OUTPUT). Lorsqu'un paquet arrive, il est filtré à l'aide des règles de la chaîne INPUT. Si ce paquet est accepté, il est routé vers sa destination. Lorsque la destination est différente de la station hébergeant le Firewall, alors le paquet est filtré à l'aide de la chaîne FORWARD (ce qui permet notamment de réaliser du masquage d'adresse : "masquerading"). Et finalement le paquet est filtré par la chaîne OUTPUT.
Chaque chaîne peut fonctionner selon trois politiques différentes :
A l'aide des règles affectables à chaque chaîne, il est possible d'autoriser, de restreindre ou d'interdire l'accès à différents services réseaux. Et ainsi modifier la politique de filtrage des paquets de chaque chaîne. En faite, le filtrage de paquet fonctionne en analysant les entêtes des paquets. Si les données contenues dans l'entête d'un paquet correspondent à une règle alors la règle est appliquée (acceptation ou refus du paquet), sinon nous passons à la règle suivante tout pendant que toutes les règles de la liste affectée à chaque chaîne n'ont pas été testées.
Pour plus de détails sur IPChains vous pouvez consulter :
Vous pouvez retrouver les liens vers la documentation et le HowTo sur IPChains en consultant la page des références.
Notre but est d'autoriser les connexions sortantes HTTP depuis le réseau privé vers le réseau public (Internet). Pour résoudre ce problème, nous commençons par régler le problème inverse : c'est à dire autoriser tout sauf les connexions sortantes HTTP.
La première étape est de supprimer les règles affectées à chaque chaîne :
[root@pass /root]# ipchains -F |
Ensuite nous modifions la politique de chaque chaîne (mise dans l'état ACCEPT) :
[root@pass /root]# ipchains -P input ACCEPT [root@pass /root]# ipchains -P forward ACCEPT [root@pass /root]# ipchains -P output ACCEPT |
Il faut maintenant activer le masquage d'adresse (masquerading) :
[root@pass /root]# ipchains -A forward -s 192.168.110.0/255.255.255.0 -d 0.0.0.0/0.0.0.0 -j MASQ |
Pour vérifier l'état des différentes chaînes, tapez la commande suivante :
[root@pass /root]# ipchains -L |
Le résultat doit être le suivant :
Chain input (policy ACCEPT): Chain forward (policy ACCEPT): target prot opt source destination ports MASQ all ------ 192.168.110.0/24 anywhere n/a Chain output (policy ACCEPT): |
Nous interdisons maintenant en tcp : l'accès du port 80 (port HTTP) vers les ports dynamiques (1024 à 65535) en entrée et l'accès des ports dynamiques vers le port 80 en sortie.
[root@pass /root]# ipchains -A input -p tcp -s any/0 80 -d any/0 1024:65535 -j REJECT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 80 -j REJECT |
Le résultat doit être le suivant :
Chain input (policy ACCEPT): target prot opt source destination ports REJECT tcp ------ anywhere anywhere www -> 1024:65535 Chain forward (policy ACCEPT): target prot opt source destination ports MASQ all ------ 192.168.110.0/24 anywhere n/a Chain output (policy ACCEPT): target prot opt source destination ports REJECT tcp ------ anywhere anywhere 1024:65535 -> www |
A partir de maintenant, il est impossible d'accéder depuis les stations du réseau privé (Firewall inclus) aux pages web (par HTTP) dont le serveur fonctionne sur le port 80.
Pour vérifier le rejet des connexions HTTP sortantes vous pouvez tapez la commande suivante :
[root@pass /root]# lynx http://www.info.unicaen.fr |
La connexion vers http://www.info.unicaen.fr est impossible.
Nous allons maintenant résoudre le problème inverse. C'est à dire interdire toutes les connexions sortantes sauf celles du protocole HTTP.
Attention : il faut ne pas oublier d'autoriser les connexions vers le service de DNS, sinon la résolution de nom sera impossible.
Tout d'abord, nous allons supprimer les règles des chaînes INPUT et OUTPUT. Nous conservons les règles de la chaîne FORWARD pour le masquerading.
[root@pass /root]# ipchains -F input [root@pass /root]# ipchains -F output |
Ensuite nous modifions les politiques pour les chaînes INPUT (DENY), FORWARD (DENY) et OUTPUT (REJECT).
[root@pass /root]# ipchains -P input DENY [root@pass /root]# ipchains -P forward DENY [root@pass /root]# ipchains -P output REJECT |
Nous ajoutons les règles pour accéder au DNS (en UDP et en TCP au cas ou les réponses du serveur DNS dépassent 512 octets) :
[root@pass /root]# ipchains -A input -p udp -s any/0 53 -j ACCEPT [root@pass /root]# ipchains -A output -p udp -d any/0 53 -j ACCEPT [root@pass /root]# ipchains -A input -p tcp -s any/0 53 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -d any/0 53 -j ACCEPT |
Nous autorisons aussi les connexions HTTP :
[root@pass /root]# ipchains -A input -p tcp -s any/0 www -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 www -j ACCEPT |
Listons les règles d'IPChains :
[root@pass /root]# ipchains -L Chain input (policy DENY): target prot opt source destination ports ACCEPT udp ------ anywhere anywhere domain -> any ACCEPT tcp ------ anywhere anywhere domain -> any ACCEPT tcp ------ anywhere anywhere www -> 1024:65535 Chain forward (policy DENY): target prot opt source destination ports MASQ all ------ 192.168.110.0/24 anywhere n/a Chain output (policy REJECT): target prot opt source destination ports ACCEPT udp ------ anywhere anywhere any -> domain ACCEPT tcp ------ anywhere anywhere any -> domain ACCEPT tcp ------ anywhere anywhere 1024:65535 -> www |
Il est maintenant seulement possible à partir du réseau privé :
Ceci est une configuration de base qui ne prend pas en compte certains problèmes : absence de traitement des messages ICMP et absence de protection contre les principales failles de sécurité. Mais nous verrons dans la section 2.2.2 comment régler ces problèmes.
Intéressons nous pour le moment au problème plus complexe des connexions sortantes FTP.
Le FTP peut fonctionner selon deux modes :
Le mode actif pose les problèmes suivants : lorsqu'un serveur FTP souhaite envoyer des données vers un client, il tente d'ouvrir une connexion TCP supplémentaire sur ce client pour y faire transiter les données. Ce qui rend impossible le filtrage de ces connexions sans supprimer la connexion FTP faisant transiter les commandes du protocole.
![]() |
La première solution est de faire fonctionner le FTP en mode passif, c'est à dire que ce n'est plus le serveur FTP qui va décider de l'ouverture et du contrôle d'un canal de données mais le client. Ce qui permet le filtrage de la connexion pour le canal de données sans supprimer la connexion pour le canal de commandes.
Cependant certains serveurs ou certains clients FTP n'accepte pas le mode passif. Dans ce cas, il existe une deuxième solution qui consiste à n'autoriser les connexions que vers les ports dynamiques (1024 à 65535). Tout en n'oubliant pas de rejeter les connexions TCP entre les ports 6000 à 6010 pour empêcher le piratage des ports X11 (pouvant permettre à un pirate de visualiser votre session X11 et de récupérer votre mot de passe par exemple).
Nous verrons dans la section suivante les règles nécessaires à l'utilisation du protocole FTP en mettant en place une auto-écluse.
Pour qu'un Firewall soit efficace, il faut le protéger contre certains problèmes de sécurité. C'est ce que nous allons faire maintenant.
Pour cela, nous allons :
Attention : en préalable à toutes les modifications futures, vous devez videz les différentes chaînes de leurs règles, changer les politiques des différentes chaînes et activer le masquerading pour la chaîne FORWARD comme décrit à la section 2.2.1.
L'ip-spoofing est une attaque qui permet à un hôte d'envoyer des paquets qui prétendent venir d'un autre hôte. Le but de cette attaque est d'abuser les filtres de paquets (car ils se fient aux adresses IP sources des paquets pour traiter les paquets). Cela permet à des pirates de se rendre anonyme et ainsi d'attaquer des serveurs sans être repérer.
Pour se protéger de l'ip-spoofing avec IPChains, il faut interdire l'accès à tous les hôtes se connectant par une autre interface que eth1 (interface du réseau privé sur le Firewall) avec une adresse IP du réseau privé. Cette règle est la suivante :
[root@pass /root]# ipchains -A input -i ! eth1 -s 192.168.0.0/24 -d 0.0.0.0/0 -j DENY |
Attention : cette solution consistant à utiliser IPChains pour se prévenir de l'ip-spoofing fonctionne, mais n'est pas la meilleure. En fait, la lutte contre l'ip-spoofing doit être réalisée au niveau du code de routage (en vérifiant l'adresse source à chaque lancement du serveur hébergeant le Firewall) et non pas par le Firewall. Le document Linux IPChains HowTo fournit un script permettant de le faire.
# This is the best method: turn on Source Address Verification and get # spoof protection on all current and future interfaces. if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then echo -n "Setting up IP spoofing protection..." for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done echo "done." else echo PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED. echo "CONTROL-D will exit from this shell and continue system startup." echo # Start a single user shell on the console /sbin/sulogin $CONSOLE fi |
Nous allons maintenant sécuriser le DNS.
La première étape consiste à éditer le fichier /etc/resolv.conf :
Il faut maintenant relancer le serveur de nom de domaine en tapant la commande suivante :
[root@pass /root]# /etc/rc.d/init.d/named restart |
Ensuite nous ajoutons les règles IPChains suivantes pour autoriser les connexions DNS seulement vers saunet.unicaen.fr :
[root@pass /root]# ipchains -A input -p udp -s 193.55.121.60 53 -d any/0 -j ACCEPT [root@pass /root]# ipchains -A output -p udp -s any/0 -d 193.55.121.60 53 -j ACCEPT |
Note : dans le cas présent nous autorisons que les connexions DNS en UDP comme demandé dans le TP, mais comme précisé à la section 2.2.1., il peut être nécessaire d'autoriser les connexions en TCP pour les réponses du serveur DNS dépassant 512 octets.
Passons au règles pour les messages ICMP. Nous allons autoriser les messages de type 0 (pong), 3 (destination unreachable) et 8 (ping). Attention : il ne faut surtout pas autoriser les messages ICMP de type 5 (redirection) qui peuvent être utilisés par les pirates pour manipuler le routage des paquets. Voici les règles pour ICMP :
[root@pass /root]# ipchains -A input -p icmp --icmp-type 0 -j ACCEPT [root@pass /root]# ipchains -A input -p icmp --icmp-type 3 -j ACCEPT [root@pass /root]# ipchains -A input -p icmp --icmp-type 8 -j ACCEPT [root@pass /root]# ipchains -A output -p icmp --icmp-type 0 -j ACCEPT [root@pass /root]# ipchains -A output -p icmp --icmp-type 3 -j ACCEPT [root@pass /root]# ipchains -A output -p icmp --icmp-type 8 -j ACCEPT |
Note : l'attaque connue sous le nom de "Ping Of Death" consistant à l'envoi de paquets ICMP illégalement grands faisant déborder les buffers de la pile TCP du récepteur et entraînant de gros dégâts est maintenant impossible sous Linux.
Maintenant, nous allons mettre en place les règles permettant l'utilisation des services HTTP, FTP, POP et SMTP.
Nous devons commencer par protéger les ports X11(ports 6000 à 6010) :
[root@pass /root]# ipchains -A input -p tcp -s any/0 6000:6010 -d any/0 1024:65535 -j REJECT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 6000:6010 -j REJECT |
Nous autorisons le service HTTP (port 80) :
[root@pass /root]# ipchains -A input -p tcp -s any/0 www -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 www -j ACCEPT |
Nous autorisons le service FTP en mode actif plus passif (port 21) :
[root@pass /root]# ipchains -A input -p tcp -s any/0 21 -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 21 -j ACCEPT [root@pass /root]# ipchains -A input -p tcp -s any/0 1024:65535 -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 1024:65535 -j ACCEPT |
Nous autorisons le service POP (port 110) :
[root@pass /root]# ipchains -A input -p tcp -s any/0 110 -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -s any/0 110 -j ACCEPT |
Nous autorisons le service SMTP (port 25) :
[root@pass /root]# ipchains -A input -p tcp -s any/0 25 -d any/0 1024:65535 -j ACCEPT [root@pass /root]# ipchains -A output -p tcp -s any/0 1024:65535 -d any/0 25 -j ACCEPT |
Pour ajouter un nouveau service, vous devez :
Consultons l'état des chaînes d'IPChains :
[root@pass /root]# ipchains -L Chain input (policy DENY): target prot opt source destination ports ACCEPT udp ------ saunet.unicaen.fr anywhere domain -> any ACCEPT icmp ------ anywhere anywhere echo-reply ACCEPT icmp ------ anywhere anywhere destination-unreachable ACCEPT icmp ------ anywhere anywhere echo-request REJECT tcp ------ anywhere anywhere 6000:6010 -> 1024:65535 ACCEPT tcp ------ anywhere anywhere www -> 1024:65535 ACCEPT tcp ------ anywhere anywhere ftp -> 1024:65535 ACCEPT tcp ------ anywhere anywhere 1024:65535 -> 1024:65535 ACCEPT tcp ------ anywhere anywhere pop3 -> 1024:65535 ACCEPT tcp ------ anywhere anywhere smtp -> 1024:65535 DENY all ------ 192.168.0.0/24 anywhere n/a Chain forward (policy DENY): target prot opt source destination ports MASQ all ------ 192.168.110.0/24 anywhere n/a Chain output (policy REJECT): target prot opt source destination ports ACCEPT udp ------ anywhere saunet.unicaen.fr any -> domain ACCEPT icmp ------ anywhere anywhere echo-reply ACCEPT icmp ------ anywhere anywhere destination-unreachable ACCEPT icmp ------ anywhere anywhere echo-request REJECT tcp ------ anywhere anywhere 1024:65535 -> 6000:6010 ACCEPT tcp ------ anywhere anywhere 1024:65535 -> www ACCEPT tcp ------ anywhere anywhere 1024:65535 -> ftp ACCEPT tcp ------ anywhere anywhere 1024:65535 -> 1024:65535 ACCEPT tcp ------ anywhere anywhere 1024:65535 -> pop3 ACCEPT tcp ------ anywhere anywhere 1024 -> smtp |
Que permet notre Firewall ?
Attention : si vous souhaitez utiliser un Firewall Linux pour protéger un réseau hétérogène, vous devez vous informer des failles de sécurité inhérentes à ces environnements pour ajouter des règles empêchant ces failles. Il existe des exemples connus sous Windows avec les chevaux de Troie : Netbus (ports 12345-12346) et Back Orifice (port 31337) qui permettent à un pirate de prendre le contrôle de votre station. La première étape avant d'autoriser de nouveaux services sur un Firewall est de s'informer d'éventuelles failles de sécurité en consultant les newsgroups, les listes de diffusions et les sites webs sur la sécurité réseau (quelques références vous sont fournies en annexes).
Journalisation : si vous ajoutez l'option "-l" ou "--log" à une règle IPChains, lorsque celle-ci est activée alors il y a journalisation de l'événement à l'aide du daemon syslogd et affichage d'un message sur la console. Les messages journalisés sont de niveau noyau (stockés la plupart du temps dans le fichier /var/log/kern.log). Bien sûr, il n'est pas utile de journaliser toutes les règles. Il faut plutôt journaliser les règles aboutissant à une interdiction tels que l'ip-spoofing. Ensuite, il suffit de faire un script se chargeant d'analyser les fichiers de logs et qui préviendra l'administrateur système (envoi d'un email par exemple) dans le cas ou une attaque a été journalisée. Cela permettra à l'administrateur système de prendre des mesures en conséquence.
Si vous avez utilisé IPChains, vous avez du vous rendre compte que l'écriture de règles est assez fastidieuse. C'est pourquoi il existe différente application graphique permettant d'écrire ces règles :
Vous trouverez les liens vers ces applications sur la page des références.
Pour vous faciliter le travail il est aussi possible d'enregistrer vos règles dans un fichier à l'aide de la commande :
[root@pass /root]# ipchains-save > rules.txt |
Puis de les recharger dans IPChains à l'aide la commande :
[root@pass /root]# ipchains-restore < rules.txt |
Note : cette commande peut servir aussi à l'activation des règles lors du démarrage du Firewall.
![]() |
![]() |
![]() |