netfilter

3. Nouveaux matches de netfilter.

Dans cette section, on essayera d'expliquer l'utilisation de ces nouveaux matches de netfilter. Les patches seront abordés par ordre alphabétique. Aussi, nous n'expliquerons pas les patches qui cassent les autres patches. Mais ça pourra venir ensuite.

De manière générale, pour les matches, vous pouvez voir le petit synopsis de chacun d'eux en tapant :

# iptables -m le_match_que_vous_voulez --help

Cela va afficher le texte d'aide normal d'iptables, et le petit synopsis spécifique à ``le_match_que_vous_voulez'' à la fin.
3.1 Le patch ah-esp

Ce patch par Yon Uriarteajoute 2 nouveaux matches :

* ``ah'' : vous permet de matcher un paquet IPSEC basé sur son Security Parameter Index (SPI)
* ``esp'' : vous permet de matcher un paquet IPSEC basé sur son SPI.

Ce patch peut être très utile pour ceux d'entre vous qui utilisent IPSEC et qui voudraient discriminer les connexions basées sur leur SPI.

Par exemple, on va DROPper tous les paquets AH qui ont un SPI égal à 500 :

# iptables -A INPUT -p 51 -m ah --ahspi 500 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP ipv6-auth-- anywhere anywhere ah spi:500

Les options supportées pour le match ah sont :

--ahspi [!] spi[:spi]

-> match le spi (intervalle)

Le match esp marche exactement pareil :

# iptables -A INPUT -p 50 -m esp --espspi 500 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP ipv6-crypt-- anywhere anywhere esp spi:500

Les options supportées pour le match esp sont :

--espspi [!] spi[:spi]

-> match le spi (intervalle)

N'oubliez pas de spécifier le bon protocole en utilisant l'option ``-p 50'' ou ``-p 51'' (pour esp & ah respectivement) quand vous utilisez le match ah ou esp, sinon la règle de filtrage ne s'insèrera pas, pour une raison triviale...
3.2 Le patch condition

Ce patch par Stephane Ouelletteajoute un nouveau match qui vous permet d'autoriser ou de neutraliser un jeu de règles en utilisant les variables de condition stockées dans des fichiers `/proc'.

Notes:

* Les variables de condition sont stockées dans le répertoire `/proc/net/ipt_condition/'.
* Une variable de condition peut être seulement mise à ``0'' (VRAI) ou à ``1'' (FAUX).
* Une ou plusieurs règles peuvent êtres affectées par l'état d'une seule variable de condition.
* Un fichier proc de condition est crée automatiquement quand une nouvelle condition est référencée pour la premiere fois.
* Un fichier proc de condition est effacé automatiquement quand la dernière référence vers cette condition est effacée.

Les options supportées pour le match condition match sont :

--condition [!] conditionfile

-> match la condition booléenne.

Par exemple, si vous voulez interdire l'accès à votre serveur web pendant que vous faites de la maintenance, vous pouvez utiliser ce qui suit :

# iptables -A FORWARD -p tcp -d 192.168.1.10 --dport http -m condition --condition webdown -j REJECT --reject-with tcp-reset

# echo 1 > /proc/net/ipt_condition/webdown

La règle suivant va matcher seulement si la condition ``webdown'' est mise à ``1''.
3.3 Le patch conntrack

Ce patch par Marc Boucherajoute un nouveau match (un superset du match `state') qui permet de matcher sur plus de critères en relation avec le suivi de connexions.

Par exemple, si vous voulez ACCEPTer toutes les connexions `RELATED' mais seulement pour le protocole TCP, vous pouvez faire comme suit :

# iptables -A FORWARD -m conntrack --ctstate RELATED --ctproto tcp -j ACCEPT

# iptables --list
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere ctstate RELATED

Les options supportées pour le match conntrack sont :

[!] --ctstate [INVALID|ESTABLISHED|NEW|RELATED|SNAT|DNAT][,...]

-> L(es) 'état(s) à matcher. Les "nouveaux" états `SNAT' et `DNAT' sont virtuels, et matchent si l'adresse source originale diffère de la destination réponse, ou si la destination originale diffère de la réponse source.
[!] --ctproto proto

-> Le protocole à matcher; Indiqué par son numéro (ex: 6) ou son nom (ex: `tcp').
--ctorigsrc [!] address[/mask]

-> Spécifie l'adresse source originale.
--ctorigdst [!] address[/mask]

-> Spécifie l'adresse destination originale.
--ctreplsrc [!] address[/mask]

-> Spécifie l'adresse source de réponse.
--ctrepldst [!] address[/mask]

-> Spécifie l'adresse destination de réponse.
[!] --ctstatus [NONE|EXPECTED|SEEN_REPLY|ASSURED][,...]

-> Le(s) status à matcher.
[!] --ctexpire time[:time]

-> Match le temps restant (intervalle inclusif).

3.4 Le patch fuzzy

Ce patch par Hime Aguiar e Oliveira Jr.ajoute un nouveau module qui vous permet de matcher un paquet d'après un profile dynamique implémenté par voie d'un simple contrôleur de logique floue (Fuzzy Logic Controller, FLC).

Ce match implémente un TSK FLC (Takagi-Sugeno-Kang Fuzzy Logic Controller). L'idée de base est que l'on donne au match deux paramètres pour décrire l'intervalle de filtrage.

* Quand le débit des paquets est en dessous de `lower-limit' la règle ne matchera jamais.
* Entre `lower-limit' et `upper-limit', plus le débit des paquets s'approche de `upper-limit' et plus le module matchera.
* Finalement, quand le débit des paquets atteint `upper-limit', le module atteint son maximum, et matche les paquets à 99%.

En prenant en compte que l'échantillonnage du débit est variable et qu'il est approximativement de 100ms (sur une machine très occupée), l'auteur du module pense que ce module présente une bonne réponse, qui s'adapte rapidement aux changement de trafic.

Par exemple, si vous voulez éviter les Denials Of Service, vous pourriez utiliser la règle suivante :

iptables -A INPUT -m fuzzy --lower-limit 100 --upper-limit 1000 -j REJECT

* En dessous du débit de 100 pps (paquets par seconde), le filtre est inactif.
* Entre 100 et 1000 pps, l'acceptance moyenne tombe de 100% (quand on est à 100pps) à 1% (quand on est a 1000pps).
* Au dessus de 1000pps, l'acceptance moyenne reste constante, à 1%.

Les options supportées pour le match fuzzy sont :

--upper-limit n

-> La limite supérieure.
--lower-limit n

-> La limite inférieure.

3.5 Le patch iplimit

Ce patch par Gerd Knorrajoute un match qui vous permet de restreindre le nombre de connexions TCP parallèles à partir d'une machine en particulier ou d'un réseau particulier.

Par exemple, on va limiter le nombre de connexions HTTP parallèles faites par une seule adresse IP à 4 :

# iptables -A INPUT -p tcp --syn --dport http -m iplimit --iplimit-above 4 -j REJECT

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- anywhere anywhere tcp dpt:http flags:SYN,RST,ACK/SYN #conn/32 > 4 reject-with icmp-port-unreachable

Ou vous voudriez peut être limiter à 5 le nombre de connexions parallèles faites à partir d'un réseau de classe A par exemple :

# iptables -A INPUT -p tcp --syn --dport http -m iplimit --iplimit-mask 8 --iplimit-above 5 -j REJECT

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT tcp -- anywhere anywhere tcp dpt:http flags:SYN,RST,ACK/SYN #conn/8 > 5 reject-with icmp-port-unreachable

Les options supportées par le match iplimit sont :

[!] --iplimit-above n

-> match si le nombre de connexions TCP existantes (n') est (pas) au dessus de n.
--iplimit-mask n

-> netmask si vous voulez un réseau à la place d'une seule machine.

3.6 Le patch ipv4options

Ce patch par Fabrice MARIEajoute un nouveau match qui vous permet de matcher un paquet basé sur les options IP qui ont été mises.

Par exemple, nous allons DROPper tous les paquets qui ont l'option record-route et l'option timestamp mise :

# iptables -A INPUT -m ipv4options --rr -j DROP
# iptables -A INPUT -m ipv4options --ts -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere IPV4OPTS RR
DROP all -- anywhere anywhere IPV4OPTS TS

Les options supportées pour le match ipv4options sont :

--ssrr

-> match l'option strict source routing.
--lsrr

-> match l'option loose source routing.
--no-srr

-> match les paquets sans source-routing du tout.
[!] --rr

-> match l'option record-route.
[!] --ts

-> match l'option timestamp.
[!] --ra

-> match l'option router-alert.
[!] --any-opt

-> match un paquet qui a au moins une option de mise (ou pas d'option du tout si ! est spécifié).

3.7 Le patch length

Ce patch par James Morrisvous permet de matcher un paquet basé sur sa taille.

Par exemple, nous allons DROPper tous les pings qui ont une taille de paquet plus grande que 85 octets :

# iptables -A INPUT -p icmp --icmp-type echo-request -m length --length 86:0xffff -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere icmp echo-request length 86:65535

Les options supportées pour le match length sont :

[!] --length length[:length]

-> match la taille du paquet (bornes inclues)

Les valeurs non présentes seront mises d'office à leur défaut. La valeur par défaut du minimum est 0, alors que la valeur par défaut du maximum est 65535.
3.8 Le patch mport

Ce patch par Andreas Ferberajoute un nouveau match qui vous permet de spécifier des ports avec un mélange entre des intervalles de ports, et des ports en eux même, aussi bien pour TCP que pour UDP.

Par exemple, si vous voulez bloquer ftp, ssh, telnet et HTTP en une ligne, faites comme suit :

# iptables -A INPUT -p tcp -m mport --ports 20:23,80 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP tcp -- anywhere anywhere mport ports ftp-data:telnet,http

Les options supportées pour l'option mport sont :

--source-ports port[,port:port,port...]

->
--sports port[,port:port,port...]

-> match le(s) port(s) source.
--destination-ports port[,port:port,port...]

-> match le(s) port(s) de destination.
--dports port[,port:port,port...]

-> match le(s) port(s) de destination.
--ports port[,port:port,port]

-> match le(s) port(s) source ou destination.

3.9 Le patch nth

Ce patch par Fabrice MARIEajoute un nouveau match qui vous permet de matcher le Nième paquet revu par la règle.

Par exemple, si vous voulez DROPper un paquet sur deux, faites comme suit :

# iptables -A INPUT -p icmp --icmp-type echo-request -m nth --every 2 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere icmp echo-request every 2th

Des extensions écrites par Richard Wagnervous permettent de créer une méthode simple et rapide pour faire du load-balancing :

Par exemple, si vous voulez balancer la charge entre les 3 adresses IP 10.0.0.5, 10.0.0.6 et 10.0.0.7, alors vous pouvez faire comme suit :

# iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 --every 3 --packet 0 -j SNAT --to-source 10.0.0.5
# iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 --every 3 --packet 1 -j SNAT --to-source 10.0.0.6
# iptables -t nat -A POSTROUTING -o eth0 -m nth --counter 7 --every 3 --packet 2 -j SNAT --to-source 10.0.0.7

# iptables -t nat --list
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- anywhere anywhere every 3th packet #0 to:10.0.0.5
SNAT all -- anywhere anywhere every 3th packet #1 to:10.0.0.6
SNAT all -- anywhere anywhere every 3th packet #2 to:10.0.0.7

Les options supportées par le match nth sont :

--every Nth

-> match chaque Nième paquet.
[--counter] num

-> utiliser le compteur numéro (0-15, défaut 0).
[--start] num

-> Initialise le compteur à la valeur `num' à la place de 0. `num' doit être entre 0 et (Nth-1).
[--packet] num

-> Match sur le paquet numéro `num'. `num' doit être entre 0 et (Nth-1). Si cette option est utilisée, alors il doit y avoir autant de règles avec cette option, qu'il y a de valeurs entre 0 et (Nth-1), de manière à couvrir l'intervalle.

3.10 Le patch pkttype.

Ce patch par Michal Ludvigajoute un nouveau match qui vous permet de matcher un paquet basé sur son type : host/broadcast/multicast.

Si par exemple vous voulez DROPper silencieusement tous les paquets broadcastés :

# iptables -A INPUT -m pkttype --pkt-type broadcast -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere PKTTYPE = broadcast

Les options supportées par le match pkttype sont :

--pkt-type [!] packettype

-> Match le type de paquet, où le type de paquet est l'un des suivants :

host

-> dirige vers une machine en particulier.
broadcast

-> dirige vers tout le monde.
multicast

-> dirige vers un groupe de machines.

3.11 Le patch pool

Ce patch a été écrit par Patrick Schaaf . Joakim Axelsson et Patrick sont en train de réécrire ce match, et donc ils vont remplacer cette section dès que le travail sera fini.
3.12 Le match psd

Ce match par Dennis Koslowskiajoute un nouveau match qui essaie de détecter les port-scans.

Dans sa forme la plus simple, le match psd peut être utilisé comme suit :

# iptables -A INPUT -m psd -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere psd weight-threshold: 21 delay-threshold: 300 lo-ports-weight: 3 hi-ports-weight: 1

Les options supportées pour le match psd sont :

[--psd-weight-threshold threshold]

-> Le poids limite de détection.
[--psd-delay-threshold delay]

-> Le délai limite de détection.
[--psd-lo-ports-weight lo]

-> Poids des ports privilégiés.
[--psd-hi-ports-weight hi]

-> Poids des ports non privilégiés.

3.13 Le patch quota

Ce patch par Sam Johnstonajoute un nouveau match qui vous permet de mettre en place des quotas. Une fois que le quota a été atteint, la règle ne matche plus.

Par exemple, si vous voulez mettre un quota de 50Megs sur les données HTTP entrantes, faites comme suit :

# iptables -A INPUT -p tcp --dport 80 -m quota --quota 52428800 -j ACCEPT
# iptables -A INPUT -p tcp --dport 80 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:http quota: 52428800 bytes
DROP tcp -- anywhere anywhere tcp dpt:http

Les options supportées par le match quota sont :

--quota quota

-> Le quota que vous voulez mettre en place.

3.14 Le patch random

Ce patch par Fabrice MARIEajoute un nouveau match qui vous permet de matcher un paquet de manière aléatoire, basé sur une probabilité.

Par exemple, si vous voulez DROPper 50% des pings de manière aléatoire, faites comme suit :

# iptables -A INPUT -p icmp --icmp-type echo-request -m random --average 50 -j DROP

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP icmp -- anywhere anywhere icmp echo-request random 50%

Les options supportées par le match random sont :

[--average percent]

-> La probabilité de match exprimée sous forme de pourcentage. Si omise, cette probabilité sera de 50% par défaut. Le pourcentage doit être entre 1 et 99 compris.

3.15 Le patch realm

Ce patch par Sampsa Rantaajoute un nouveau match qui vous permet d'utiliser une clé realm (venant du code de routing) comme match similaire à ceux trouvés dans le packet classifier.

Par exemple, pour LOGguer tous les paquets sortants qui ont un realm égal à 10, faites comme suit :

# iptables -A OUTPUT -m realm --realm 10 -j LOG

# iptables --list
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere REALM match 0xa LOG level warning

Les options supportées pour le match realm sont :

--realm [!] value[/mask]

-> Match le realm

3.16 Le patch recent

Ce patch par Stephen Frostajoute un nouveau match qui vous permet de créer dynamiquement une liste d'adresses IP et ensuite de matcher des paquets par rapport à cette liste de différentes manières.

Par exemple, si vous voulez créer une liste `lesmechants' contenant l'adresse IP des gens qui essayent de se connecter au port 139 sur votre firewall, pour pouvoir ensuite les bloquer pendant 60 secondes, faites comme suit :

# iptables -A FORWARD -m recent --name lesmechants --rcheck --seconds 60 -j DROP
# iptables -A FORWARD -p tcp -i eth0 --dport 139 -m recent --name lesmechants --set -j DROP

# iptables --list
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere recent: CHECK seconds: 60
DROP tcp -- anywhere anywhere tcp dpt:netbios-ssn recent: SET

Les options supportées pour le match recent sont :

--name name

-> Spécifie le nom de la liste sur laquelle il faut exécuter les commandes. si aucun nom n'est donné, alors le nom `DEFAULT' sera utilisé.
[!] --set

-> Ceci va ajouter l'adresse source du paquet à la liste. Si l'adresse source est déjà dans la liste, alors ça va mettre à jour l'entrée existante. Ça va toujours matcher; ou ne matchera jamais si la négation `!' a été spécifiée.
[!] --rcheck

-> Ceci va vérifier si l'adresse source du paquet est pour le moment dans la liste, et va matcher si l'adresse y est, et ne matchera pas si l'adresse n'y est pas. L'effet inverse est obtenu en spécifiant la négation `!'.
[!] --update

-> Ceci va vérifier si l'adresse source du paquet est pour le moment dans la liste. Si elle y est, alors l'entrée va être mise à jour, et la règle va matcher. Si l'adresse n'est pas dans la liste pour le moment, alors la règle ne matchera pas. L'effet inverse est obtenu si la négation `!' est spécifiée.
[!] --remove

-> Cela va vérifier si l'adresse source du paquet est pour le moment dans la liste. Si elle y est, alors l'entrée sera retirée et la règle va matcher. Si l'adresse n'est pas trouvée dans la liste, la règle ne matchera pas. L'effet inverse est obtenu si la négation `!' est spécifiée.
[!] --seconds seconds

-> Cette option doit être utilisée avec `rcheck' ou `update'. Quand cette option est utilisée, ça va faire en sorte que la règle ne matche que si l'adresse est pour le moment dans la liste et que l'adresse a été vue dans l'intervalle donné (en secondes). L'effet inverse est obtenu en spécifiant la négation `!'.
[!] --hitcount hits

-> Cette option doit être utilisée avec `rcheck' ou `update'. Quand cette option est utilisée, cela va faire en sorte que la règle ne matche que si l'adresse est pour le moment dans la liste et qu'on a reçu un nombre de paquets supérieur ou égal a `hits'. Cette option peut être utilisée en même temps que `seconds' pour obtenir un match très précis qui requiert qu'un certain nombre de paquets soient vus dans une certaine limite de temps. L'effet inverse est obtenu si la négation `!' est spécifiée..
--rttl

-> Cette option doit être utilisée avec `rcheck' ou `update'. Quand elle est utilisée, ça va faire en sorte que la règle ne matche que si l'adresse est dans la liste et que le TTL du paquet que l'on inspecte maintenant est le même que celui du paquet qui a créé l'entrée initialement dans la règle avec `--set'. Ça peut être utile si vous avez des problèmes avec des gens qui ``spoof''ent leur adresse source pour parvenir a un DoS au travers de ce module.

3.17 Le patch record-rpc

Ce patch par Marcelo Barbosa Limaajoute un nouveau match qui vous permet de matcher un paquet si l'adresse source de ce paquet fait une requête avant sur le portmapper, ou si c'est une nouvelle requête GET vers le portmapper, permettant un filtrage précis du protocole RPC.

Pour matcher les informations de suivi de connexions RPC, faites comme suit :

# iptables -A INPUT -m record_rpc -j ACCEPT

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere

Le match record_rpc n'a aucune option pour le moment.

Ne vous en faites pas pour les informations de match qui ne s'affichent pas quand vous listez la règle, c'est juste que la fonction print() est vide :

/* Prints out the union ipt_matchinfo. */
static void
print(const struct ipt_ip *ip,
const struct ipt_entry_match *match,
int numeric)
{
}

3.18 Le patch string

Ce patch par Emmanuel Rogerajoute un nouveau match qui vous permet de matcher une chaîne de caractères n'importe où dans le paquet.

Par exemple, si vous voulez matcher tous les paquets contenant la chaîne ``cmd.exe'' n'importe où dans le paquet et rediriger le paquet vers la queue en userland pour qu'il soit analysé ensuite par un IDS, faites comme suit :

# iptables -A INPUT -m string --string 'cmd.exe' -j QUEUE

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
QUEUE all -- anywhere anywhere STRING match cmd.exe

Utilisez ce match avec précautions ! Beaucoup de gens veulent utiliser ce match pour arrêter les worms (en DROPpant le paquet louche). C'est une erreur classique. Ça ne marche pas, et puis quand ça marche, ça peut être battu sans problème en utilisant n'importe quelle méthode d'évasion d'IDS.

Dans le même genre, beaucoup de gens veulent utiliser ce match comme moyen de filtrer des fonctions en particulier dans le protocole HTTP par exemple comme POST ou GET en DROPpant n'importe quel paquet qui contient la dite chaîne de caractères. Il faut que vous compreniez que ce travail est mieux effectué par un proxy filtrant en userland. De plus, n'importe quelle page HTML contenant le mot POST serait DROPpé avec cette méthode. Gardez à l'esprit que ce match a été crée dans l'intention de rediriger vers le userland les paquets louches afin d'avoir une meilleure analyse, c'est tout. DROPper un paquet en se basant uniquement sur ce match est une erreur.

Les options supportées pour le match string sont :

--string [!] string

-> Match une string *n'importe ou* dans le paquet.

3.19 Le patch time

Ce patch par Fabrice MARIEajoute un nouveau match qui vous permet de matcher un paquet basé sur son temps d'arrivée ou de départ (pour les paquets localement générés).

Par exemple, si vous voulez ACCEPTer tous les paquets qui arrivent entre 8H00 et 18H00 du lundi au vendredi, faites comme suit :

# iptables -A INPUT -m time --timestart 8:00 --timestop 18:00 --days Mon,Tue,Wed,Thu,Fri -j ACCEPT

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere TIME from 8:0 to 18:0 on Mon,Tue,Wed,Thu,Fri

Les options supportées par le match time sont :

--timestart value

-> minimum HH:MM
--timestop value

-> maximum HH:MM
--days listofdays

-> une liste de jour, à partir de la liste suivante (attention à la casse)

* Mon -> lundi
* Tue -> mardi
* Wed -> mercredi
* Thu -> jeudi
* Fri -> vendredi
* Sat -> samedi
* Sun -> dimanche

3.20 Le patch ttl

Ce patch par Harald Welteajoute un nouveau match qui vous permet de matcher un paquet basé sur son TTL.

Par exemple, si vous voulez LOGguer tous les paquets qui ont un TTL inférieur à 5, faites comme suit :

# iptables -A INPUT -m ttl --ttl-lt 5 -j LOG

# iptables --list
Chain INPUT (policy ACCEPT)
target prot opt source destination
LOG all -- anywhere anywhere TTL match TTL < 5 LOG level warning Les options supportées par le match ttl sont : --ttl-eq value -> Match le TTL exact
--ttl-lt value<