Le noyau 2.4 de Linux vient avec un nouveau code de filtrage très puissant. Celui-ci apporte plusieurs nouveautés dont
Netfilter est composé de trois tables
Pour commencer, nous effaçons les règles de firewall existantes des trois tables.
iptables -F iptables -t nat -F iptables -t mangle -FPar défaut, la table
filter
est utilisée.
Netfilter permet de définir ses propres règles, effaçons celles présentes sur le système.
iptables -XLe ménage est fait.
Le plus sûr lorsque l'on conçoit un firewall est de tout interdire par défaut et d'autoriser explicitement.
iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROPL'instruction
DROP
va ignorer le paquet, tandis que REJECT
va signaler à la machine à l'origine du paquet que la communication est impossible.
Afin de présenter un exemple complet, notre firewall a trois interfaces:
eth0
, l'interface externe connectée à Internet,eth1
, l'interface de la DMZ, la zone où se trouve les serveurs accessibles depuis Internet,
eth2
reliant le firewall au réseau interne.good
va désigner le réseau interne, dmz
la DMZ, bad
Internet et me
le firewall. Définissons les chaînes utilisateurs correspondant aux différentes communications possibles. Par exemple, good-bad
désigne les paquets provenant du réseau interne à destination d'Internet.
iptables -N good-bad iptables -N good-dmz iptables -N good-me iptables -N dmz-good iptables -N dmz-bad iptables -N dmz-me iptables -N bad-dmz iptables -N bad-me
On accepte les connexions venant de l'interface lo
(loopback).
Si l'état de la connexion est invalide INVALID
, on ignore le
paquet. Si la connexion est établie ESTABLISHED
ou assimilable à
une connexion établie RELATED
(cas, par exemple, du canal de
donnée dans une communication FTP). Toute communication TCP doit commencer par
un paquet comportant le flag SYN
et uniquement celui-ci,
si ce n'est pas le cas, on rejette la connexion.
Enfin, on trie les connexions entrantes selon les interfaces.
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state INVALID -j DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -m state --state NEW -p TCP --tcp-flags ! ALL SYN -j DROP iptables -A INPUT -i eth0 -j bad-me iptables -A INPUT -i eth1 -j dmz-me iptables -A INPUT -i eth2 -j good-me iptables -A INPUT -j DROPLes scanners de ports comme nmap ne fonctionneront pas en mode furtif, seuls les TCP scans et les SYN scans sont possibles.
Il peut être intéressant d'enregistrer les tentatives de connexion à votre machine, les scans de ports. Mais attention, si tous les ports scannés sont enregistrés, le serveur risque de saturer aussi bien en performance CPU aussi bien qu'en espace disque.
Pour enregistrer les scans de ports TCP furtifs avec un maximum de trois par secondes, il suffit d'ajouter la ligne suivante avant la règle rejetant le paquet.
iptables -A INPUT --state NEW -p TCP --tcp-flags ! ALL SYN -m limit --limit 3/s -j LOG --log-prefix "BAD INPUT "Chaque ligne sera préfixée par
BAD INPUT
, le préfixe pouvant faire
jusqu'à 29 caractères.
En généralisant l'enregistrement des logs aux trois chaînes de filtrage, on obtient:
iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m state --state INVALID -m limit --limit 3/s -j LOG --log-prefix "INVALID INPUT: " iptables -A INPUT -m state --state INVALID -j DROP iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p TCP --tcp-flags ! ALL SYN -m state --state NEW -m limit --limit 3/s -j LOG --log-prefix "INPUT TCP sans SYN: " iptables -A INPUT -p TCP --tcp-flags ! ALL SYN -m state --state NEW -j DROP iptables -A INPUT -i eth0 -j bad-me iptables -A INPUT -i eth1 -j dmz-me iptables -A INPUT -i eth2 -j good-me iptables -A INPUT -m limit --limit 3/s -j LOG --log-prefix "Bad INPUT: " iptables -A INPUT -j DROP
iptables -A FORWARD -m state --state INVALID -m limit --limit 3/s -j LOG --log-prefix "INVALID FORWARD: " iptables -A FORWARD -m state --state INVALID -j DROP iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -m limit --limit 3/s -j LOG --log-prefix "FORWARD TCP sans SYN: " iptables -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -j DROP iptables -A FORWARD -i eth2 -o eth0 -j good-bad iptables -A FORWARD -i eth2 -o eth1 -j good-dmz iptables -A FORWARD -i eth1 -o eth0 -j dmz-bad iptables -A FORWARD -i eth1 -o eth2 -j dmz-good iptables -A FORWARD -i eth0 -o eth1 -j bad-dmz iptables -A FORWARD -j LOG -m limit --limit 3/s --log-prefix "BAD FORWARD " iptables -A FORWARD -j DROPFaisant confiance au firewall, on l'autorise à émettre sans restriction.
iptables -A OUTPUT -j ACCEPT
Pour l'exemple, je vais considérer que la DMZ contient un relais de messagerie en 192.168.1.1, un serveur web 192.168.1.2 et un cache Internet 192.168.1.3 sur le port 3128. Le serveur de messagerie interne est en 10.0.0.1. Depuis Internet, seuls les serveurs de messagerie et le serveur web sont joignables.
iptables -A bad-dmz -p TCP -d 192.168.1.1 --dport smtp -j ACCEPT iptables -A bad-dmz -p TCP -d 192.168.1.2 --dport http -j ACCEPTLimitons aussi les connexions du réseau interne à la DMZ mais tolérons le ping.
iptables -A good-dmz -p TCP -d 192.168.1.1 --dport smtp -j ACCEPT iptables -A good-dmz -p TCP -d 192.168.1.2 --dport http -j ACCEPT iptables -A good-dmz -p TCP -d 192.168.1.3 --dport squid -j ACCEPT iptables -A good-dmz -p ICMP --icmp-type echo-request -m limit --limit 3/s -j ACCEPTLa passerelle de messagerie peut communiquer avec le serveur de mail interne.
iptables -A dmz-good -p TCP -s 192.168.1.1 -d 10.0.0.1 --dport smtp -j ACCEPTMaintenant autorisons la DMZ à communiquer raisonnablement avec Internet. La passerelle de mail peut envoyer des messages, le proxy Internet peut surfer sur des sites sur les ports http(80) et https(443). Toutes les machines de la DMZ peuvent faire des requêtes DNS (domain=53).
iptables -A dmz-bad -p TCP -s 192.168.1.1 --dport smtp -j ACCEPT iptables -A dmz-bad -p TCP -s 192.168.1.3 --dport http -j ACCEPT iptables -A dmz-bad -p TCP -s 192.168.1.3 --dport https -j ACCEPT iptables -A dmz-bad -p TCP --dport domain -j ACCEPT iptables -A dmz-bad -p UDP --dport domain -j ACCEPTJe vous laisse le soin d'ajouter des règles de logs et de spécifier les règles pour
good-bad
.
Votre réseau interne et la DMZ ne peuvent communiquer directement avec Internet. Les serveurs sur lesquels vous vous connectez ne pourront vous répondre que si la source des paquets est une adresse publique. C'est là que le masquerading
intervient, chaque paquet émis vers Internet va utiliser l'adresse de votre interface de sortie.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Il pourrait y avoir un hic. Vous n'avez qu'une seule adresse IP et deux serveurs doivent être accessible: le serveur web et la passerelle Internet. La translation d'adresse va venir à vous rescousse, on va rediriger les ports concernés vers les bonnes destinations.
iptables -t nat -A PREROUTING -j DNAT -i eth0 -p TCP --dport smtp --to-destination 192.168.1.1 iptables -t nat -A PREROUTING -j DNAT -i eth0 -p TCP --dport http --to-destination 192.168.1.2
Si vous souhaitez que tous les surfeurs passent par votre cache Internet et que tout les mails circulent via la passerelle de messagerie, ce n'est pas un problème. Il n'y aura même pas à configurer les clients. Cela est particulièrement utilisé pour des entreprises ayant un antivirus sur le relais de messagerie.
iptables -t nat -A PREROUTING -j DNAT -i eth2 -p TCP --dport http --to-destination 192.168.1.3:3128 iptables -t nat -A PREROUTING -j DNAT -i eth2 -p TCP --dport smtp --to-destination 192.168.1.1NB: Pensez à configurer Squid en proxy transparent avec en particulier
httpd_accel_uses_host_header on
Selon vos besoins, vous allez avoir besoin de charger les modules suivants (ou d'autres), placez ces lignes au début de votre script de firewall.
modprobe ip_conntrack_ftp modprobe iptable_nat modprobe iptable_filterPar exemple, le module
ip_conntrack_ftp
vous permettra de faire du FTP passif aussi bien que du FTP actif.
Le programme sysctl
permet de modifier des paramétrages du
noyau. Ces mêmes paramétrages sont aussi accessibles par l'arborescence
/proc
. Voici les trois paramètres principaux pour un firewall
net.ipv4.ip_forward = 1
active le routage,net.ipv4.conf.all.rp_filter = 1
vérifie la source des paquets,
utile en conséquence contre le spoofing.SYN-flood
(Demande de
connexion répétée), il suffit d'utiliser net.ipv4.tcp_syncookies =
1
, les services de votre serveur resteront accessibles.
Vous trouverez de nombreux paramètres supplémentaire pour optimiser votre
Linux dans Documentation/networking/ip-sysctl.cfg
.
Netfilter est un firewall très puissant capable de rivaliser en performance et en efficacité avec de nombreux firewalls commerciaux. La seule lacune est une absence de fail-over, d'un dispositif de redondance permettant à un second firewall d'assurer la continuité du service en cas de panne du premier. C'est, je crois, l'un des derniers freins à son utilisation en entreprise.
La première version de cet article est parue dans Linux Mag France de mai 2002.
Dernière version: 23 décembre 2002