Firewall avec Netfilter

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

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.