Netfilter

De Wiki info-lab.fr
Aller à : Navigation, rechercher

Sommaire

Présentation

NETFILTER est le parefeu intégré au noyau Linux depuis la version 2.4. Il agit principalement au niveau des couches 3 (réseau) et 4 (transport) du modèle OSI avec quelques possibilités d'action sur la sous couche MAC de la couche 2 (liaison de données). NETFILTER est en général déjà pré-compilé sur toute distribution récente, sans aucune règle appliquée.
Les commandes de l'utilitaire IPTABLES permettent de positionner les règles que NETFILTER doit appliquer sur les paquets. Au niveau de chaque chaîne (INPUT, OUTPUT, FORWARD) les règles IPTABLES qui s'y appliquent sont interprétées séquentiellement.
La commande IPTABLES est représentée par le fichier /sbin/iptables lien symbolique pointant vers le fichier exécutable /sbin/xtables-multi cumulant les fonctionnalités de iptables et ip6tables.

Commandes utiles

Voici quelques commandes utiles avant d'aborder NETFILTER. Pour info sysctl est une commande permettant d'appliquer des directives au noyau, lui indiquant par exemple comment il doit traiter le trafic réseau. Le fichier /etc/sysctl.conf est interprété au démarrage pour modifier le comportement du noyau, et en cours de fonctionnement on peut modifier ce comportement en utilisant la commande sysctl. Une commande sysctl est volatile et ne survit pas à un redémarrage sauf si elle est définie dans le fichier /etc/sysctl.conf.

Routage

Activation du routage nécessaire sur un équipement en coupure ayant plusieurs interfaces. Non nécessaire sur un équipement terminal :

# cat /etc/sysctl.conf
   net.ipv4.ip_forward=1

Vérification :

# echo /proc/sys/net/ipv4/ip_forward
   1                 (1=routage activé, 0=routage désactivé)

Ajout de routes statiques (volatile) :

# route add -net 10.0.0.0 netmask 255.128.0.0 gw 125.32.8.108

Ajout de routes statiques (permanent) :

# cat /etc/sysconfig/static-routes
   any net 10.0.0.0 netmask 255.128.0.0 gw 125.32.8.108

NOTA : Le fichier /etc/sysconfig/static-routes peut ne pas exister sur tous les systèmes Gnu-Linux.

Traitement particulier affecté à certains trafics au niveau du noyau

Si /proc/sys/net/ipv4/ip_forward permet d'activer le routage IPv4 entre les interfaces, /proc/sys/net/ipv4/conf/all/rp_filter permet de lutter contre l'usurpation d'adresse IP en vérifiant que l'association adresse IP/interface est cohérente. Peut aussi servir à empêcher le routage des adresses RFC 1918 vers Internet si elles n'ont pas été préalablement "traduites" (NAT).
/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts permet de définir le comportement face aux messages ICMP echo de type broadcasts ou multicasts.
Le fichier /etc/sysctl.conf s'il existe permet ainsi d'activer certaines protections contre des trafics particuliers ; il est recommandé d'activer ces protections sur un serveur et un parefeu.

# vim /etc/sysctl.conf
net/ipv4/conf/all/rp_filter=1     (protection contre l'usurpation d'adresse IP)
net/ipv4/conf/all/log_martians=1     (journaliser les paquets ayant une adresse IP mal formée)
net/ipv4/conf/all/send_redirects=0    (interdire les redirections)
net/ipv4/conf/all/accept_source_route=0      (interdire les paquets dont la source a été routée)
net/ipv4/conf/all/accept_redirects=0    (interdire les redirections ICMP)
net/ipv4/tcp_syncookies=1    (activer la protection contre certains dénis de service)
net/ipv4/icmp_echo_ignore_broadcasts=1     (interdire les réponses au ping broadcast)
net/ipv4/ip_forward=1          ( active le routage IPv4)

Le même fichier permet de fixer les délais de connexion TCP ; ainsi une connexion TCP établie reste par défaut 5 jours dans la table de suivi des connexions avant d'être effacée, il est préférable de limiter cette durée à une heure ou moins en ajoutant la ligne :

net/netfilter/nf_conntrack_tcp_timeout_established=3600

NOTAS : 3600 = valeur en secondes. Attention  : Pour plus de lisibilité la commande sysctl peut afficher un espace avant et après le signe = mais cet espace est fictif et il doit être absent dans le fichier sysctl.conf sous peine de générer une erreur de syntaxe.

NMAP

Outil permettant en particulier de vérifier l'état (fermé, ouvert, caché) des ports TCP ou UDP d'un système local ou distant, mais plus généralement de détecter des machines sur un réseau et de les identifier.

$ man nmap
$ nmap -sP 82.66.233.254      # simple ICMP ping
$ nmap -sT 82.66.233.254      # envoi de TCP Connect
$ nmap -Pn 82.66.233.254      # scan même si ICMP ne répond pas
$ nmap -p 1-1023 82.66.233.254    # choix explicites des ports scannés

LSOF

LiSt Open Files : identifier les fichiers utilisés par des processus actifs. Le terme "fichiers" peut désigner des fichiers exécutables, des fichiers texte, fichiers spéciaux blocs, des bibliothèques, répertoires, flux réseaux ou sockets.

$ lsof -Pi

( -P désactive la résolution DNS et -i spécifie tous les fichiers associés à x25 ou Internet, c'est à dire TCP/IP)

Suivi des connexions actives

cat /proc/net/ip_conntrack

NetStat

$ netstat -a | less
$ netstat -an | less
$ netstat -lataupe | less

Les informations récoltées seront plus complètes si NETSTAT est exécuté avec des droits ROOT.

NETFILTER

Interprète un certain nombre de règles, définies par la syntaxe IPTABLES, à appliquer sur les paquets entrants d'une interface, sortants d'une interface et traversants (entrant par une interface puis ressortant par une autre). Chaque paquet est évalué par le noyau et comparé aux différentes règles qui s'appliquent au niveau des points de contrôle INPUT, OUTPOUT et FORWARD. A chaque point de contrôle si aucune règle ne concorde avec le paquet évalué, la règle par défaut (si elle existe) est appliquée.

  • Les actions sont ACCEPT, DROP, REJECT, QUEUE ou LOG. DROP détruit un paquet silencieusement, REJECT détruit un paquet mais en avertit l'émetteur par défaut au moyen d'un message ICMP type 3 code 3 "port unreachable" mais d'autres erreurs peuvent être définies grâce à l'option :
-J REJECT --reject-with message 

ou message peut prendre les valeurs indiquées dans la partie "Syntaxe IPTABLES". QUEUE transfère le paquet en espace utilisateur (si le noyau le permet).

  • Il existe 3 tables IPTABLES ayant un rôle distinct :
    • FILTER (la table par défaut) composée des chaînes INPUT, FORWARD et OUTPUT, chargée de filtrer/détruire les paquets.
    • NAT composée des chaînes POSTROUTING et OUTPUT, charger de la redirection des paquets.
    • MANGLE composée des chaînes PREROUTING et OUTPUT, chargée de la modification des paquets, comme par exemple les champs TOS/DSCP nécessaires à la QoS.

Iptables-simple.png

Schéma simple des points de contrôle d'un paquet entrant par l'interface ethx et sortant par l'interface ethy


PacketFlow9.png

Schéma complet des points de contrôle des paquets par Netfilter


Exemple de règles de filtrage standard

Exemple de règles de filtrage à positionner sur un équipement terminal, comme un serveur : Ces règles ont vocation à filtrer le trafic entrant et sortant du serveur.
Pour toutes les règles suivantes, l'écriture de la table -t filter est optionnelle puisque sans précisions c'est celle-ci qui sera prise en compte ; néanmoins écrire systématiquement la table même quand il s'agit de "filter" supprime toute ambiguïté et ne nuit pas à la compréhension des règles.
NOTA : la commande iptables nécessite les droits root.

Une règle IPTABLES suit cette structure d'instructions successives :

iptables Table et chaîne La règle qui doit concorder et le résultat de la règle
par exemple :
iptables -t filter -A OUTPUT -s 192.168.1.100 -d 192.168.1.50 -p udp --sport 1024:65535 --dport 514 -j ACCEPT

  • Vider les règles générales et personnelles existantes :
iptables -t filter -F
iptables -t filter -X
  • Restriction par défaut de tout le trafic entrant, sortant et traversant (-P = politique par défaut) :
iptables -t filter -P INPUT DROP
iptables -t filter -P OUTPUT DROP
iptables -t filter -P FORWARD DROP
  • Journaliser (log) et jeter les paquets entrant invalides : (-A = ajouter une nouvelle règle)
iptables -t filter -A INPUT -m state --state INVALID -j LOG --log-prefix "INVALIDE :"
iptables -t filter -A INPUT -m state --state INVALID -j DROP

log-préfix permet de positionner une chaîne de caractères (par exemple INVALIDE) : cela servira à identifier clairement cet évènement dans les journaux, et simplifiera sa détection (grep) ou sa colorisation (par lwatch ou ccze). Une autre option --log-level permet d'attribuer un niveau de sévérité.
Les règles de chaque chaîne étant lues et comparées séquentiellement, leur ordre est primordial : dès qu'une règle concorde, la lecture s'interrompt, les autres ne sont pas interprétées. Il faut donc toujours positionner une règle de type LOG avant la règle DROP ou REJECT concernant le même trafic sous peine de ne jamais avoir d'évènements dans les journaux concernant ce trafic.

  • Bloquer en entrée les paquets de diffusion générale
iptables -t filter -A INPUT -m pkttype --pkt-type broadcast -j DROP
  • Autoriser le trafic sur la loopback  :
iptables -t filter -I INPUT -i lo -j ACCEPT
  • Maintenir les connexions déjà établies (empêche par exemple le déconnexion de votre session SSh en appliquant ces règles sur un équipement distant) et permettre le suivi de sessions :
iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  • Journaliser toutes les nouvelles connexions TCP entrantes :
iptables -t filter -A INPUT -p tcp -m state --state NEW -j LOG --log-prefix "Nouvelle Connexion TCP :"
  • Autoriser le trafic entrant SYSLOG pour enregistrer les journaux de serveurs distants (@IPlocale = adresse IP de la machine sur laquelle ces règles sont positionnées ; a.b.c.d = exemple de sous-réseau ; e.f.g.h = autre exemple de sous-réseau) :
iptables -t filter -A INPUT -s a.b.c.d/26 -d @IPlocale -p udp --sport 1024:65535 --dport 514 -j ACCEPT
iptables -t filter -A INPUT -s e.f.g.h/28 -d @IPlocale -p udp --sport 1024:65535 --dport 514 -j ACCEPT
  • Autoriser l'envoi de messages SYSLOG vers un autre serveur ; Le serveur enverra les messages reçus grâce à la règle ci-dessus + ses propres messages (@IPdistante = adresse du serveur en question) :
iptables -t filter -A OUTPUT -s @IPlocale -d @IPdistante -p udp --sport 1024:65535 --dport 514 -j ACCEPT
  • Autoriser la mise à l'heure vers un serveur NTP public (@IPntp) : NTP est un protocole atypique, client et serveur utilisent le même port UDP.
iptables -t filter -A OUTPUT -s @IPlocale -d @IPntp -p udp --sport 123 --dport 123 -m state --state NEW -j ACCEPT
  • Autoriser les connexions SSh vers le serveur local (les clients potentiels sont limités aux sous-réseaux a.b.c.d/26 et i.j.k.l/29) :
iptables -t filter -A INPUT -s a.b.c.d/26 -d @IPlocale -p tcp --sport 1024:65535 --dport 22 -m state --state NEW --syn -j ACCEPT
iptables -t filter -A INPUT -s i.j.k.l/29 -d @IPlocale -p tcp --sport 1024:65535 --dport 22 -m state --state NEW --syn -j ACCEPT
  • Autoriser les connexions sortantes du client SSh (ce serveur peut par exemple télécharger des fichiers distants par SCP ou SFTP vers la machine dont l'adresse IP est m.n.o.p) :
iptables -t filter -A OUTPUT -s @IPlocale -d m.n.o.p/32 -p tcp --sport 1024:65535 --dport 22 -m state --state NEW --syn -j ACCEPT
  •  Protection contre les scans XMAS et NULL
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  • Si l'ICMP est autorisé ou certains de ses messages "tolérés" il peut être filtré en fonction de critère tels que réseaux ou hôtes source ou destination, interface d'arrivée et on peut en limiter le nombre pour éviter des dénis de service au moyen d'ICMP :
iptables -t filter -A INPUT -p icmp --icmp-type echo-request -m limit --limit 3/s -i eth0 -j ACCEPT
iptables -t filter -A OUTPUT -p icmp --icmp-type echo-reply -o eth0 -j ACCEPT

Les messages icmp-request sont autorisés à destination du parefeu, à concurrence de 3 par secondes et à travers l'interface eth0, les réponse icmp-reply sont aussi autorisées à partir de la même interface. Les autres messages ICMP sont interdits.

Une machine dédiée au rôle de pare-feu filtrant et non pas terminal se verra attribuer des règles très différentes, essentiellement sur le trafic de type FORWARD. De plus cet équipement devra mettre en oeuvre du routage et éventuellement appliquer des règles de NAT si ce pare-feu fait le lien entre des réseaux privés type RFC 1918 et Internet.

Les ports TCP/UDP source et destination peuvent être désignés par leur valeur numérique (par exemple --dport 53) ou leur équivalent texte (ici --dport domain) dont la correspondance se trouve dans le fichier /etc/services.

Syntaxe IPTABLES

  • -A (append) permet de créer une règle dans un ordre précis par défaut en queue de liste, -D (delete) permet d'en effacer une, -L (list) les affiche, -I (insert) en insère une dans un ordre précis par défaut en tête de liste, -N (new-chain) crée une chaîne personnalisée et -X (delete-chain) la supprime, -P (policy) permet d'appliquer une politique par défaut.
  • La chaîne où doit s'appliquer une règle (ex -A FORWARD) et le résultat d'une règle (-J LOG) sont toujours écrits au moyen de lettres majuscules.
  • L'option --log-prefix permet de saisir jusqu'à 29 caractères.
  • L'option --log-level accepte les arguments debug, info, notice, warning, err, crit, alert et emerg.
  • Si iptables -t filter -F permet d'effacer toutes les règles de la chaîne filter, iptables -t filter -F INPUT permet de n'effacer que celles qui s'appliquent en entrée.
  • -p (ou --protocol) : type de protocole, accepte les arguments tcp, udp, icmp ou all et permet de désigner des ports source/destination particuliers ou des types de messages ICMP.
  • -i (--in-interface) eth1 permet de désigner une interface d'entrée.
  • -o (--out-interface) eth3 permet de désigner une interface de sortie.
  •  ! désigne tout sauf. Exemple -p tcp --dport !21 désigne tous les ports TCP en destination sauf le 21.
  • --sport (ou --source-port) : un port source ou une plage de ports (jusqu'à 15) avec l'option -m multiport
  • --dport (ou --destination-port) : un port de destination ou une plage de ports (jusqu'à 15) avec l'option -m multiport
  • --icmp-type : permet de préciser quels type de messages ICMP seront traités par la règle.
  • -m module : permet de charger le module désigné.
    • -m --mac-source pour désigner une adresse MAC source spécifique, au format AA-AA-AA-AA-AA-AA
    • -m --state pour spécifier l'état d'un paquet qui peut être NEW (paquet TCP de type SYN, demande de nouvelle connexion), ESTABLISHED (paquet TCP lié à une connexion déjà établie ACK), RELATED (nouvelle connexion mais directement liée à une connexion précédente comme cela est prévu par FTP, H323, SIP ou les messages d'erreur envoyés par ICMP), et enfin INVALID (connexion inconnue ou protocole non respecté, par exemple un SYN ACK est envoyé avant le SYN).
    • -m --limit pour limiter une fréquence (/second, /minute, /hour, /day). Par exemple iptables -A INPUT -p tcp --dport 22 -m --limit 2/minute -J ACCEPT n'autorisera que 2 connexions SSH dans la même minute.
    • -m --multiport plage de ports appliquée à --sport ou --dport.
    • -m --owner pour contrôler au niveau de la chaîne OUTPUT uniquement le trafic concernant une application locale au moyen des options --uid-owner userid, gid-owner groupid, pid-owner pid ou sid-owner sid.
  • Sans précisions particulières, le résultat -J REJECT détruit un paquet concordant avec la règle correspondante tout en envoyant un message ICMP à l’émetteur de type "port unreachable". L'option --reject-with message permet de communiquer un autre message ICMP, il faut alors remplacer message par :
    • icmp-net-unreachable
    • icmp-host-unreachable
    • icmp-proto-unreachable
    • icmp-net-prohibited
    • icmp-host-prohibited
    • tcp-reset
    • echo-reply

Création de chaînes

Pour réutiliser un résultat de règle complexe facilement il est possible de céer une nouvelle chaîne et ensuite de l'appliquer en la nommant. (-N = créer une nouvelle chaîne).

iptables -N MAUV_CONNEX_SSH       
iptables -A MAUV_CONNEX_SSH -j LOG --log-prefix 'TENTATIVE ILLICITE DE CONNEXION SSH :'
iptables -A MAUV_CONNEX_SSH -j DROP

La nouvelle chaîne est créée (-N) elle s'appelle MAUV_CONNEX_SSH, et elle a pour effet de créer un évenement dans les journaux (évènement marqué du commentaire explicite TENTATIVE ILLICITE DE CONNEXION SSH :) et enfin de détruire silencieusement des paquets. Maintenant cette chaîne pourra être utilisée dans une règle :

iptables -t filter -A INPUT -s w.x.y.z/26 -d @IPserveur -p tcp --sport 1024:65535 --dport 22 -m state --state NEW --syn -j MAUV_CONNEX_SSH

w.x.y.z/26 est par exemple le réseau des élèves qui tenteront immanquablement une connexion SSh à destination du serveur de fichiers qui héberge leurs ressources.
Ajouter un commentaire explicite tel que "TENTATIVE ILLICITE DE CONNEXION SSH :" apparaissant dans le corps du message SYSLOG permet de rechercher et coloriser (LWATCH ou CCZE) facilement cet événement.

 iptables -X MAUV_CONNEX_SSH

Suppression de la chaîne précédemment créée.

Protocoles particuliers

Si la plupart des protocoles fonctionnent selon un schéma classique (port serveur inférieur à 1024, port client supérieur à 1023) certains ont un comportement atypique :

  • NTP utilise par défaut le même port serveur et client, à savoir UDP 123 par défaut.
  • BootP/DHCPv4 utilise les ports UDP 67 pour le serveur et 68 pour le client, client qui au départ n'a pas d'adresse IP et n'émet que des Broadcast à destination de l'adresse MAC ffff-ffff-ffff et de l'adresse IPv4 255.255.255.255 . Par contre les demandes de renouvellement de bail à demi durée de vie sont des trafics unicast dirigés vers le serveur DHCP dont la station a accepté le bail.
  • FTP utilise les ports serveur TCP 20 et 21 (commande et échange de données) et nécessite le module de suivi de connexion ip_conntrack_ftp.
  • TFTP (voir l'article correspondant) utilise le port serveur UDP 69 puis un port serveur au delà de 1024 et nécessite le module de suivi de connexion ip_conntrack_tftp.
  • De nombreux protocoles de ToIP/VoIP tels que H323, SIP ... négociant une session sur un port puis échangeant les données sur d'autres réclament des règles particulières et nécessitent aussi leur module spécifique de suivi de connexion.

Automatisation des règles de pare-feu

  • Inscrire les règles au sein d'un fichier nommé par exemple iptables-regles01.sh, commençant par le shebang classique #!/bin/bash et rendre ce fichier exécutable (chmod).
  • Copier ce fichier dans init.d :
# cp iptables-regles01.sh /etc/init.d/

Ajouter ce script à la liste des services lancés au démarrage afin qu'il soit automatiquement interprété :

# update-rc.d iptables-regles01.sh defaults

Le lancer immédiatement :

# service iptables-regles01.sh reload

NOTA : Pour être sûr de l'interprétation correcte et intégrale de ce script, écrire exit 0 en dernière ligne du script. De suite après l'application du script (par les commandes bash iptables-regles01.sh ou service iptables-regles01.sh reload) saisir dans le même terminal echo $?, le résultat 0 indiquant qu'il a été correctement et intégralement interprété. Tout autre résultat que 0 signale une erreur.
Pour vérifier sa prise en compte, et lister les règles actives, avec ou sans la numérotation des règles :

# iptables -nvL
# iptables -nvL --line-numbers

Pour ne lire que les règles de la table de filtrage :

# iptables -L

Pour ne lire que les règles de la table de filtrage appliquées en sortie :

# iptables -L OUTPUT

Autres ressources et schémas

Autre schéma Netfilter couches 2 et 3

Autre schéma Netfilter

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Outils