Le noyau 2.4 de Linux vient avec un nouveau code de filtrage très puissant. Celui-ci apporte plusieurs nouveautés dont :
Les tables
Netfilter est composé de trois tables :
INPUT
OUTPUT
FORWARD
PREROUTING et OUTPUT permettant de modifier la destination des paquets avant que le paquet soit filtré.
POSTROUTING pour modifier la source apparente des paquets mangle pour altérer les paquets sortants.
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éfault, la table filter est utilisée.
iptables -XLe ménage est fait.
Politique par défaut
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.
Déclaration des chaînes utilisateurs
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
Redirection vers les chaînes utilisateurs
Les états
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ées dans une communication FTP). Toute communication TCP doit commencer par un paquet comportant le flag SYN; 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 -p TCP --state NEW ! --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.
Enregistrement : les logs
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 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 -p TCP --state NEW ! --syn -j DROP -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.
Généralisation
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 INPUT -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 --state NEW ! --syn -j DROP -m limit --limit 3/s -j LOG --log-prefix "INPUT TCP sans SYN: " iptables -A INPUT -p TCP --state NEW ! --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 -m limit --limit 3/s -j LOG --log-prefix "BAD INPUT: " iptables -A INPUT -j DROP iptables -A FORWARD -m state --state INPUT -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 --state NEW ! --syn -j DROP -m limit --limit 3/s -j LOG --log-prefix "FORWARD TCP sans SYN: " iptables -A FORWARD -p TCP --state NEW ! --syn -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
Règles de filtrage
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 -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.
Règles de NAT
Masquerading
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
NAT
Il pourrait y avoir un hic. Vous n'avez qu'une seule adresse IP et deux serveurs doivent être accessibles : le serveur Web et la passerelle Internet. La translation d'adresse va venir à votre 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.2Si vous souhaitez que tous les surfeurs passent par votre cache Internet et que tous 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.1N.B. : pensez à configurer Squid en proxy transparent avec en particulier httpd_accel_uses_host_header_on.
Les modules
Selon vos besoins, vous allez devoir charger les modules suivants (ou d'autres). Placez ces lignes au début de votre script de firewall (sous Debian, /etc/init.d/iptables ).
insmod ip_conntrack_ftp insmod iptable_nat insmod iptable_filterPar exemple, le module ip_conntrack_ftp vous permettra de faire du FTP passif aussi bien que du FTP actif.
Configuration du kernel avec sysctl
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 :
Pour protéger vos serveurs contre les 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émentaires pour optimiser votre Linux dans Documentation/networking/ip-sysctl.cfg, présent dans les sources de votre kernel.
Conclusion
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.