I) Introduction :
Dans cette article, nous verrons la mise en place d’un firewall sous Linux (kernel 2.4) au travers de trois exemples. Le premier correspondra à une machine isolée ayant accès à Internet, le deuxième sera celui d’une machine faisant office de routeur/firewall pour un petit réseau domestique, enfin nous verrons la configuration de netfilter dans un réseau comprenant une zone démilitarisée (DMZ) en ajoutant une troisième patte à notre routeur.
Petit rappel, un firewall est un dispositif relié à au moins deux réseaux (exemple : un réseau local et internet) et permettant de filter les paquets le traversant en autorisant certains ou en refusant d’autres suivant certaines règles. Le firewall sous Linux s’appelle Netfilter. Il est composé de deux parties. La première est à compiler directement dans le kernel, j’ai ainsi pour préférence de ne rien compiler en modules à ce niveau car si un module venait à ne pas pouvoir être chargé, le firewall serait inopérant. La deuxième est constituée par la commande iptables. Cette commande permet d’indiquer les directives de filtrage. Pour terminer, une question de bon sens, il faut fermer tous les accès à un firewall puis ensuite authoriser l’accès aux services réseau désirés et non pas interdire uniquement les paquets jugés dangereux. Dans le premier cas, un oubli vous coutera le disfonctionnement d’un service tandis que dans l’autre cas, vous trainerez à vos pieds un risque potentiel pour votre sécurité si vous omettez une règle de filtrage particulière
II) Les commandes d’iptables :
Iptables possède trois tables :
- filter, la table par défaut qui possède les règles INPUT, OUTPUT, FORWARD.
- nat, la table de translation d’adresse réseau avec les règles PREROUTING (à l’arrivée du firewall) et POSTROUTING (à la sortie du firewall).
- mangle, que je connais trop peu pour en parler mais qui est rarement utilisée sert à la modification à la volée des en-tête des paquets.
Dans le firewall, le cheminement des paquets se fait comme suit :
INPUT : chaîne par laquelle passent tous les paquets arrivant par une interfaçe.
OUTPUT : chaîne par laquelle passent tous les paquets sortant sur une interfaçe.
FORWARD : passent ici les paquets qui doivent aller d’une interfaçe à une autre.
Comportements associés a ces chaines :
ACCEPT : Le paquet est autorisé.
REJECT : Le paquet est rejecté et on envoi un message d’erreur à l’emetteur.
DROP : On ignore le paquet.
LOG : Le paquet est loggé.
Options pour manipuler les chaînes :
N : Créé une nouvelle chaîne.
X : Supprime une chaîne vide.
P : Politique par défaut.
L : Liste les règles.
A : Ajoute une règle à une chaîne.
I : Insère une règle à une position donnée dans une chaîne.
R : Remplace une chaîne donnée par une autre.
D : Effaçe une règle d’une chaîne.
III) Exemple 1 : Machine isolée
#!/bin/bash
# Créer une chaine qui bloque les nouvelles connections à part celles qui viennent de l’intérieur.
iptables -A block -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state –state NEW -i ! ppp0 -j ACCEPT
iptables -A block -j DROP
# Sauter sur cette chaine à partir des chaines INPUT et FORWARD.
iptables -A INPUT -j block
iptables -A FORWARD -j block
IV) Exemple 2 : Routeur/Firewall
Notez que certains ports supplémentaires sont ouverts car le routeur fait aussi office de serveur web, ftp et mail.
#!/bin/bash #efface les regles existantes des trois tables iptables -F iptables -t nat -F iptables -t mangle -F #Effacement des chaines définies iptables -X #Politique par defaut (tout rejeter) iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP iptables -N lan-web iptables -N lan-fw iptables -N web-lan iptables -N web-fw iptables -N icmp-acc iptables -N fw-lan # la loopback du firewall peut émetre dans tous les sens : iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # les connections invalides sont refusées : iptables -A INPUT -m state --state INVALID -j DROP iptables -A FORWARD -m state --state INVALID -j DROP # les connections etablies ou assimilables sont acceptées en entrée comme en forward : iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -o eth0 -j ACCEPT # Protection TCP Syn Flood : iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT iptables -A INPUT -p tcp --syn -m limit --limit 1/second -j ACCEPT # Protection UDP Flood : iptables -A FORWARD -p udp -m limit --limit 1/second -j ACCEPT iptables -A INPUT -p udp -m limit --limit 1/second -j ACCEPT # on trie les paquets suivant les interfaces : iptables -A INPUT -i ppp0 -j web-fw iptables -A INPUT -i eth0 -j lan-fw iptables -A INPUT -j DROP # on trie les paquets en fonction de leur cheminement dans nos chaines iptables -A FORWARD -i eth0 -o ppp0 -j lan-web iptables -A FORWARD -i ppp0 -o eth0 -j web-lan # le firewall peut emettre comme il veut iptables -A OUTPUT -j ACCEPT # On autorise les paquets ICMP iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT iptables -A icmp-acc -j DROP # Du web vers le lan : iptables -A web-lan -j REJECT # Du reseau local vers le web : on donne droit à tout iptables -A lan-web -p icmp -j icmp-acc iptables -A lan-web -j ACCEPT ## # Règles pour les connections sur le firewall provenant du LAN: ## iptables -A lan-fw -p tcp --dport ssh -j ACCEPT iptables -A lan-fw -p tcp --dport domain -j ACCEPT iptables -A lan-fw -p udp --dport domain -j ACCEPT iptables -A lan-fw -p tcp --dport smtp -j ACCEPT iptables -A lan-fw -p tcp --dport pop3 -j ACCEPT iptables -A lan-fw -p udp --dport pop3 -j ACCEPT iptables -A lan-fw -p tcp --dport 143 -j ACCEPT iptables -A lan-fw -p udp --dport 143 -j ACCEPT iptables -A lan-fw -p tcp --dport www -j ACCEPT iptables -A lan-fw -p tcp --dport ftp -j ACCEPT iptables -A lan-fw -p tcp --dport ftp-data -j ACCEPT iptables -A lan-fw -p icmp -j icmp-acc iptables -A lan-fw -j DROP ## # Règles pour les connections sur le firewall de l'extérieur : ## iptables -A web-fw -p tcp --dport ssh -j ACCEPT iptables -A web-fw -p tcp --dport domain -j ACCEPT iptables -A web-fw -p udp --dport domain -j ACCEPT iptables -A web-fw -p tcp --dport smtp -j ACCEPT iptables -A web-fw -p tcp --dport pop3 -j ACCEPT iptables -A web-fw -p udp --dport pop3 -j ACCEPT iptables -A web-fw -p tcp --dport 143 -j ACCEPT iptables -A web-fw -p udp --dport 143 -j ACCEPT iptables -A web-fw -p tcp --dport www -j ACCEPT iptables -A web-fw -p tcp --dport ftp -j ACCEPT iptables -A web-fw -p tcp --dport ftp-data -j ACCEPT iptables -A web-fw -p icmp -j icmp-acc iptables -A web-fw -j DROP # Activation du NAT IPV4 : iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 0.0.0.0/0 -o ppp0 -j MASQUERADE # On active le routage : echo "1" > /proc/sys/net/ipv4/ip_forward
V) Exemple 3 : Cas d’une DMZ
Dans cet exemple, la machine sur laquelle se trouve le firewall jouera le rôle de passerelle vers internet, fera de la translation d’adresses, sera serveur pop3 et smtp et enfin serveur DNS. Dans la DMZ se trouve un serveur HTTP et FTP. De plus on veut permettre au réseau local de se connecter au firewall et au serveur web via le protocole ssh.
Le firewall possède les interfaçes réseau suivantes :
ppp0 : reliée temporairement à internet.
eth0 : reliée au réseau local (192.168.0.0/24).
eth1 : reliée à la DMZ (192.168.1.0/24).
#! /bin/sh # /etc/firewall.sh # # Firewall # # ppp0 : interface reliee a internet # eth0 : lan (ip : 192.168.0.1) # eth1 : dmz (ip : 192.168.1.1 # ip du serveur http de la dmz : 192.168.1.2 #efface les regles existantes des trois tables iptables -F iptables -t nat -F iptables -t mangle -F #Effacement des chaines définies iptables -X #Politique par defaut (tout rejeter) iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Chaines définies pour trier les paquets : # dmz designe la dmz # lan mon reseau local # web le web # fw le firewall iptables -N lan-web iptables -N lan-dmz iptables -N lan-fw iptables -N dmz-lan iptables -N dmz-web iptables -N dmz-fw iptables -N web-dmz iptables -N web-fw iptables -N web-lan iptables -N icmp-acc # la loopback du firewall peut émetre dans tous les sens : iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # les connections invalides sont refusées : iptables -A INPUT -m state --state INVALID -j DROP iptables -A FORWARD -m state --state INVALID -j DROP # les connections etablies ou assimilables sont acceptées en entrees comme en forward : iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # on trie les paquets suivant les interfaces : iptables -A INPUT -i ppp0 -j web-fw iptables -A INPUT -i eth0 -j lan-fw iptables -A INPUT -i eth1 -j dmz-fw iptables -A INPUT -j DROP # on trie les paquets en fonction de leur cheminement dans nos chaines iptables -A FORWARD -i eth0 -o ppp0 -j lan-web iptables -A FORWARD -i eth0 -o eth1 -j lan-dmz iptables -A FORWARD -i eth1 -o ppp0 -j dmz-web iptables -A FORWARD -i eth1 -o eth0 -j dmz-lan iptables -A FORWARD -i ppp0 -o eth1 -j web-dmz iptables -A FORWARD -i ppp0 -o eth0 -j web-lan # Le firewall peut emettre comme il veut : iptables -A OUTPUT -j ACCEPT # On authorise les paquets ICMP iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-request -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT iptables -A icmp-acc -j DROP # Reseau interne vers la dmz iptables -A lan-dmz -p tcp --dport smtp -j ACCEPT iptables -A lan-dmz -p tcp --dport pop3 -j ACCEPT iptables -A lan-dmz -p udp --dport domain -j ACCEPT iptables -A lan-dmz -p tcp --dport domain -j ACCEPT iptables -A lan-dmz -p tcp --dport www -j ACCEPT iptables -A lan-dmz -p tcp --dport https -j ACCEPT iptables -A lan-dmz -p tcp --dport ssh -j ACCEPT iptables -A lan-dmz -p tcp --dport auth -j ACCEPT iptables -A lan-dmz -p tcp --dport ftp -j ACCEPT iptables -A lan-dmz -p icmp -j icmp-acc iptables -A lan-dmz -j DROP # Du web vers la dmz : iptables -A web-dmz -p tcp --dport www -j ACCEPT iptables -A web-dmz -p tcp --dport https -j ACCEPT iptables -A web-dmz -p tcp --dport ftp -j ACCEPT iptables -A web-dmz -p icmp -j icmp-acc iptables -A web-dmz -j DROP # Du reseau local vers le web : on donne droit à tout iptables -A lan-web -j ACCEPT iptables -A lan-web -p icmp -j icmp-acc # De la dmz vers le reseau local : tous les droits : iptables -A dmz-lan -j ACCEPT iptables -A dmz-lan -p icmp -j icmp-acc # De la dmz vers le web, tous les droits également : iptables -A dmz-web -j ACCEPT iptables -A dmz-web -p icmp -j icmp-acc # Du web vers le lan : iptables -A web-lan -j REJECT # Règles pour les connections sur le firewall : iptables -A web-fw -p icmp -j icmp-acc iptables -A web-fw -j ACCEPT iptables -A web-fw -p icmp -j icmp-acc iptables -A dmz-fw -j ACCEPT iptables -A lan-fw -p tcp --dport ssh -j ACCEPT iptables -A lan-fw -p tcp --dport domain -j ACCEPT iptables -A lan-fw -p udp --dport domain -j ACCEPT iptables -A lan-fw -p tcp --dport smtp -j ACCEPT iptables -A lan-fw -p tcp --dport pop3 -j ACCEPT iptables -A lan-fw -p ICMP --icmp-type ping -j ACCEPT iptables -A lan-fw -p ICMP --icmp-type pong -j ACCEPT iptables -A lan-fw -j icmp-acc iptables -A lan-fw -j DROP # On active le routage : echo "1" > /proc/sys/net/ipv4/ip_forward # Enfin on termine par les règles de nat entrant comme sortant : iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE iptables -t nat -A PREROUTING -j DNAT -i ppp0 -p TCP --dport ftp --to-destination 192.168.1.2 iptables -t nat -A PREROUTING -j DNAT -i ppp0 -p TCP --dport www --to-destination 192.168.1.2 iptables -t nat -A PREROUTING -j DNAT -i ppp0 -p TCP --dport https --to-destination 192.168.1.2
VI) Gestion de la QOS avec iptables :
La gestion de la QOS sous iptables se fait en manipulant le champs TOS de l’en tête TCP. Sachez que bien que ça améliore la gestion de la bande passante, ce n’est pas aussi efficace qu’une vrai gestion de la QOS telle que celle offerte par le kernel. Les options que l’on donne au champs TOS sont les suivantes :
Minimize-Delay : Améliore la réactivité des connexions en réduisant le délai (ssh, telnet, ftp contrôle, tftp, flux DNS)
Maximize-Throughput : Améliore le débit au prix d’une possible détérioration de l’interactivité de la session. Les temps de latence ne sont pas importants (ftp-data,www, transfert de zone DNS)
Maximum-Reliability : Certitude que les données arrivent sans perte – Améliore la fiabilité (snmp, smtp)
Minimize monetary cost : minimise le délai, meilleure rentabilité (nntp, icmp)
Exemple :
iptables -A PREROUTING -t mangle -p tcp --sport ssh -j TOS --set-tos Minimize-Delay iptables -A PREROUTING -t mangle -p tcp --sport ftp -j TOS --set-tos Minimize-Delay iptables -A PREROUTING -t mangle -p tcp --sport www -j TOS --set-tos Minimize-Delay iptables -A PREROUTING -t mangle -p tcp --sport ircd -j TOS --set-tos Minimize-Delay # On donne un maximum de débit aux transferts ftp, peu importe la latence iptables -A PREROUTING -t mangle -p tcp --sport ftp-data -j TOS --set-tos Maximize-Throughput iptables -A PREROUTING -t mangle -p tcp --sport 53 -j TOS --set-tos Maximize-Throughput
VII) Arrêt du Firewall :
Script pour réinitialiser le firewall :
#!/bin/bash # Script pour désactiver le firewall : # On efface les règles définies : iptables -t filter -F iptables -t nat -F iptables -t mangle -F # Efface les chaines définies : iptables -X # Politique par défaut : iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT