IPF(5)						Formats de fichiers de FreeBSD

 

NOM

ipf, ipf.conf - Syntaxe des règles de filtrage de paquets IP

 

DESCRIPTION

Un fichier de règles ipf peut avoir n'importe quel nom et même être l'entrée standard. Comme ipfstat produit, lors sortie de la liste des filtres internes, des règles analysables, il est tout à fait possible de rediriger sa sortie vers l'entrée de ipf. Ainsi, pour annuler tous les filtres sur les paquets en entrée, il est possible de taper :

# ipfstat -i | ipf -rf -

 

GRAMMAIRE

Voici, en BNF, le format que suivent les fichiers utilisés par ipf pour construire les règles de filtrage :

 
       règle     = [ insert ] action entrée-sortie [ options ] [ tos ] [ ttl ]
		  [ proto ] [ ip ] [ groupe ].
 
       insert    = "@" nombredec .
       action    = bloque | "pass" | enreg | "count" | saute | aut | appel .
       entrée-sortie = "in" | "out" .
       options   = [ enreg ] [ "quick" ] [ "on" nom-interface [ dup ] [ froute ] ] .
       tos       = "tos" nombredec | "tos" nombrehex .
       ttl       = "ttl" nombredec .
       proto     = "proto" protocole .
       ip        = srcdst [ drapeaux ] [ avec avecopt ] [ icmp ] [ garde ] .
       groupe    = [ "head" nombredec ] [ "group" nombredec ] .
 
       bloque    = "block" [ icmp[coderetour] | "return-rst" ] .
       aut       = "auth" | "preauth" .
       enreg     = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" niv-enreg ] .
       appel     = "call" [ "now" ] fonction .
       saute     = "skip" nombredec .
       dup       = "dup-to" nom-interface[":"adr-ip] .
       froute    = "fastroute" | "to" nom-interface .
       protocole = "tcp/udp" | "udp" | "tcp" | "icmp" | nombredec .
       srcdst    = "all" | depuisvers .
       depuisvers = "from" [ "!" ] objet "to" [ "!" ] objet .
 
       icmp      = "return-icmp" | "return-icmp-as-dest" .
       objet     = adr [ port-comp | intervalle ] .
       adr       = "any" | nommasque | nom-hôte [ "mask" adr-ip | "mask" nombrehexa ] .
       port-comp = "port" compare num-port .
       intervalle = "port" num-port inégal num-port .
       drapeaux  = "flags" opt { opt } [ "/" opt { opt } ] .
       avec      = "with" | "and" .
       icmp      = "icmp-type" type-icmp [ "code" nombredec ] .
       coderetour = "("code-icmp")" .
       garde     = "keep" "state" | "keep" "flags" .
       niv-enreg = niveau"."priorité | priorité .
 
       nommasque = nom-hôte [ "/" nombredec ] .
       nom-hôte  = adr-ip | nom-hôte | "any" .
       adr-ip    = num-hôte "." num-hôte "." num-hôte "." num-hôte .
       num-hôte  = chiffre [ chiffre [ chiffre ] ] .
       num-port  = nom-de-service | nombredec .
 
       avecopt   = [ "not" | "no" ] typeopt [ avecopt ] .
       typeopt   = "ipopts" | "short" | "frag" | "opt" optsip  .
       nomopt    = optsip [ "," nomopt ] .
       optsip    = listeopt | "sec-class" [ nom-sec ] .
       nom-sec   = niv-sec [ "," nom-sec ] .
       niv-sec   = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" |
	      "reserv-4" | "secret" | "topsecret" .
       type-icmp = "unreach" | "echo" | "echorep" | "squench" | "redir" |
		"timex" | "paramprob" | "timest" | "timestrep" | "inforeq" |
		"inforep" | "maskreq" | "maskrep"  | nombredec .
       code-icmp = nombredec | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
		"needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
		"net-prohib" | "host-prohib" | "net-tos" | "host-tos" |
		"filter-prohib" | "host-preced" | "cutoff-preced" .
       listeopt  = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
	      "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" |
	      "addext" | "visa" | "imitd" | "eip" | "finn" .
       niveau    = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" |
	       "lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" |
	       "audit" | "logalert" | "local0" | "local1" | "local2" |
	       "local3" | "local4" | "local5" | "local6" | "local7" .
       priorité  = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" |
	       "info" | "debug" .
 
       nombrehexa = "0" "x" chainehexa .
       chainehexa = chiffrehexa [ chainehexa ] .
       nombredec  = chiffre [ nombredec ] .
 
       compare    = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" |
	      "gt" | "le" | "ge" .
       inégal     = "<>" | "><" .
       chiffrehexa = chiffre | "a" | "b" | "c" | "d" | "e" | "f" .
       chiffre    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
       opt        = "F" | "S" | "R" | "P" | "A" | "U" .
 

Cette syntaxe est quelque peu simplifiée pour être plus lisible. Certaines combinaisons grammaticalement correstes sont cependant interdites sous peine de créer des non-sens (par exemple des flags tcp sur des paquets non-tcp).

 

RÈGLES DE FILTRAGE

Les règles les plus simples sont (actuellement) no-ops et sont sous la forme :

block in all
pass in all
log out all
count in all

Les règles de filtrage sont passées en revue dans l'ordre, la dernière règle appliquée déterminant la destinée du paquet (mais voyez quand même l'option quick plus loin).

Les filtres sont positionnés, par défaut, à la fin des listes du noyau. Toutefois, si celle-ci commence par @n, elle sera insérée à la n-ième place de la liste courante. Cela est spécialement utile lors de modifications et de tests de filtres actifs. Reportez-vous à ipf(1) pour plus d'informations.

 

ACTIONS

L'action indique quoi faire d'un paquet si celui-ci satisfait le reste de la règle de filtrage. Chaque règle DOIT avoir une action. Celles reconnues sont :

block

Le paquet est bloqué. En réponse à ce blocage, le filtre peut avoir comme instruction de renvoyer comme réponse, soit un paquet ICMP (return-icmp), soit paquet ICMP déguisé comme s'il provenait du destinataire (return-icmp-as-dest), soit une "réinitialisation" TCP (return-rst). Un paquet ICMP peut être généré en réponse à n'importe quel paquet IP (son type peut éventuellement être spécifié) mais une réinitialisation TCP ne peut répondre qu'à une règle impliquant un paquet TCP. Dans le cas d'une réponse return-icmp ou return-icmp-as-dest, il tout de même possible de spécifier le réel "type" de refus d'accès : un réseau ou un port inaccessible ou même une décision administrative limitant les connexions. Le paramètrage se fait en indiquant le code ICMP voulu, entre parenthèses, directement après return-icmp ou return-icmp-as-dest, comme ceci :

block return-icmp(11) ...

qui renvoie l'erreur Type-Of-Service (TOS) ICMP unreachable.

 

pass

Le paquet passe à travers le filtre.

log

Le paquet est écrit sur le disque (voir la description de LOGGING plus loin) sans intervenir sur le fait que le paquet passe ou non à travers le filtre.

count

Le paquet est compté pour les statistiques établies par le filtre sans intervenir sur le fait qu'il passe ou non à travers le filtre. Ces statistiques sont visualisées par ipfstat(8).

call

Cette action est utilisée pour lancer la fonction voulue du noyau en se conformant aux spécifications d'appel. Des actions et une sémantique personnalisés peuvent ainsi être ajoutées à celles existantes. Cette caractéristique est pour l'utilisation des hackers avertis et n'est pas encore documentée.

skip <n>

Demande au filtre de sauter à la n-ième règle suivante.Si une règle de la zone sautée est insérée ou enlevée, la valeur de n est correctement ajustée.

auth

Permet à l'autentification d'être effectuée par un programme utilisateur qui valide lui-même les paquets. Ceux-ci sont gardés pendant un certain temps dans un tampon interne jusqu'à ce que le programme détermine s'ils sont autorisés à passer ou non. Un tel programme doit pouvoir regarder l'adresse source et demander une autentification (un mot de passe, par exemple) avant de laisser passer le paque ou de demander au noyau de l'abandonner pour cause d'expéditeur inconnu.

preauth

Demande au filtre, pour des paquets de telle classe, de regarder dans la liste de pré-autentification quelles sont les autres tests à passer. Si aucune autre règle n'est trouvée, le paquet est abandonné (le FR_PREAUTH est différent de FR_PASS). Si une autre règle est trouvée, son résultat est utilisé. Cette action est surtout utilisée dans la situation où une personne se connecte au pare-feu pour mettre en place des règles temporaires définissant l'accès de cette personne.

Le mot suivant doit être, soit in, soit out. Tout paquet se déplaçant dans le noyau est, soit entrant (il vient d'être reçu par une interface et se dirige vers l'analyseur de protocoles), soit sortant (transmis ou redirigé par la pile et partant vers une interface). Les règles de filtrage doivent obligatoirement indiquer l'état d'entrée-sortie sur lequel elles s'appliquent.

 

OPTIONS

La liste des options est assez brève. Où qu'elles se trouvent, elles doivent apparaitre dans l'ordre indiqué ci-dessous. Voici celles qui sont actuellement supportées :

log

Si la règle est la dernière à correspondre, indique que l'entête du paquet doit être écrit dans le fichier ipl (comme le décrit la section LOGGED, plus loin).

quick

Permet d'abréger les règles afin d'accélérer le filtre ou de remplacer les règles qui suivent. Si un paquet est concerné par une règle "quick", celle-ci sera la dernière qu'il passera, empruntant un chemin "abrégé" lui évitant de voir les règles suivantes. L'état du paquet, après être passé par la règle, déterminera si celui-ci doit passer ou être bloqué.

Si cette option n'est pas présente, la règle est alors "intermédiaire", c'est à dire que l'état du paquet (passe ou bloque) est sauvegardé et le processus suit son cours en examinant les règles qui suivent.

on

Permet à un nom d'interface d'être inclus dans le processus de vérification. Il apparait sous la forme donnée par "netstat -i". Si cette option est utilisée, la règle ne pourra correspondre que si le paquet passe par cette interface dans le sens indiqué (in/out). Si cette option n'est pas utilisée, la règle s'appliquera à tout paquet quelque soit l'interface par laquelle il passe. Les règles sont communes à toutes les interfaces plutôt que d'avoir une liste pour chacune.

dup-to

Cette option est surtout utile pour se protéger des parodies IP (IP-spoofing) : un paquet n'est autorisé à entrer que par l'interface sur laquelle il peut être attendu d'après son adresse source sinon il est enregistré et/ou abandonné.

Les paquets acceptés sont copiés et envoyés vers l'interface spécifiée, éventuellement après que leur adresse IP de destination ait été changée. Ceci est utile

 
       dup-to causes the packet to be copied, and  the	duplicate
	      packet  to be sent outbound on the specified inter‚
	      face, optionally with the  destination  IP  address
	      changed  to that specified. This is useful for off-
	      host logging, using a network sniffer.
 

to

Déplace le paquet vers la queue sortante de l'interface spécifiée. Cela permet de détourner les décisions de routage du noyau et même d'interrompre le reste du traitement (dans le cas de règles sur les paquets entrants). Il est ainsi possible de mettre en place un pare-feu complètement transparent comme un concentrateur (hub) ou un commutateur (switch) plutôt que comme un routeur. Le mot clé fastroute est équivalent à cette option.

 

PARAMÈTRES DE COMPARAISON

Les mots-clé de cette section sont utilisés pour décrire les attributs des paquets qui déterminent si une règle s'applique ou ne s'applique pas. Les attributs suivants sont à utiliser pour correspondre et doivent être utilisés dans ce sens.

tos

Les paquets avec différentes valeurs de Type de Services (Type-Of-Service) peuvent être filtrés par un type unique ou plusieurs combinés. La valeur du masque TOS peut être un nombre hexadécimal ou décimal.

ttl

Les paquet peuvent aussi être sélectionnés en fonction de leur durée de vie (Time-To-Live). La valeur du paquet doit alors être exactement la même que celle paramètrée dans le filtre. Elle ne peut être donnée que sous la forme d'un entier décimal.

proto

Permet d'effectuer un test sur le protocole. Tous les noms de protocoles du fichier /etc/protocols sont reconnus et peuvent être utilisés cependant, il doit aussi être donné sous forme d'un nombre décimal pour que les règles s'appliquent sur vos propres protocoles mais aussi sur ceux à venir.

Le protocol spécial tcp/udp pour tester un paquet soit TCP, soit UDP. Il existe par comodité afin de ne pas multiplier les règles identiques.

Les mots clef from et to sont utilisés dans les règles concernant les adresses IP (voire le numéro de port). Ces règles doivent indiquer A LA FOIS les paramètres source et destination.

Les adresses IP peuvent être écrites de manière numérique : adresse/masque, ou alphanumérique : nom mask masque. Le nom peut être celui connu par le fichier hosts ou le DNS (suivant votre configuration et vos bibliothèques) ou bien la forme numérique avec des points. Il n'existe pas de désignation spécifique pour les réseaux mais leurs noms sont reconnus. Notez que faire dépendre une règle de filtrage d'une requète DNS ouvre une large avenue aux attaques.

Le nom d'hôte spécifique any, qui vaut 0.0.0.0/0 (voir plus loin pour la syntaxe du masque), veut dire «toute adresse IP». Seul ce mot clef a un masque implicite. Dans toutes les autres situations, le nom d'hôte DOIT être accompagné de son masque. Il est possible de donner «any» pour celui-ci mais, dans ce contexte linguistique, cela ne veut rien dire.

Le format numérique "x/y" indique un masque de y 1 consécutifs. Ainsi, pour un y de 16, le masque vaut 0xffff0000. La notation "x mask y", elle, indique un masque y sous la forme d'adresse IP avec des points ou bien sous la forme d'un nombre hexadécimal comme 0x12345678. Notez que, de cette façon, pour un paquet, l'adresse IP donnée par le masque doit exactement correspondre. Il n'existe encore aucun moyen pour inverser le test ou pour facilement tester un intervalle d'adresses à partir d'un masque "générique".

Si un port est donné à tester, soit source, soit destination, soit les deux, il ne s'applique qu'aux paquets TCP et UDP. S'il n'y a aucune indication de proto, les paquets des deux protocoles sont testés (ceci équivaut à «proto tcp/udp»). Pour indiquer un port à comparer, le nom du service ou un numéro de port peut être utilisé. Il existe de nombreuses façons d'inscrire la comparaison à effectuer à l'aide de divers opérateurs et d'intervalles de ports. Lorsque l'instruction from est utilisée, c'est le port source qui est regardé et lorsque l'instruction to est utilisée, c'est le port de destination qui est regardé. Reportez-vous aux exemples pour d'autres informations.

Le mot clé all (tout) équivaut à «toute source vers toute destination» sans avoir besoin d'autres paramètres.

Suivants les paramètres concernant la source ou la destination, les paramètres aditionnels suivants peuvent être utilisés :

with

est utilisé pour tester des attributs inhabituel que peuvent avoir certains paquets. Pour tester la présence d'options IP en général, utilisez with ipopts. Pour trouver les paquets trop petits pour contenir un en-tête complet, utilisez with short. Pour trouver les paquets fragmentés, utilisez with frag. Pour poser des filtrer plus précis sur les options IP, des options individuelles peuvent être listées.

Avant tout paramètre utilisé avec with, le mot not ou no peut être inséré afin de tester si la ou les options n'est pas présente.

Plusieurs clauses with peuvent se suivre. Autrement, le mot clé and peut être utilisé à la place de with afin de rendre les règles plus lisibles («with ... and ...»). Pour qu'un paquet corresponde à la règle, toutes les clauses with doivent être satisfaites.

flags

Ne fonctionne que pour le filtrage de paquets TCP. Chaque lettre représente une option présente dans l'en-tête TCP. Elles sont :

F - FIN

S - SYN

R - RST

P - PUSH

A - ACK

U - URG

Les lettres peuvent être combinées. Ainsi, par exemple, «SA» permet de tester la présence de SYN-ACK dans le paquet. Rien n'empêche de tester n'importe quelle combinaisons même celles du genre «SFR» qui ne seront générées par aucune implémentation TCP développée dans les règles. Cependant, pour éviter ces abérrations, nous vous conseillons de commenter les filtres que vous posez. Pour cela, il est possible d'indiquer un masque contenant les options TCP que vous voulez comparer (celles qui vous semblent importantes). Il suffit d'ajouter «/<options>» aux options TCP à filtrer. Par exemple :

... flags S

# devient «flags S/AUPRFS» et retiendra les paquet contenant

# UNIQUEMENT l'option SYN.

... flags SA

# devient «flags S/AUPRFS» et retiendra tout paquet ne contenant

# que les options SYN et ACK.

... flags S/SA

# permet de retenir les paquets ayant l'option SYN sauf ceux

# ayant la paire SYN-ACK. Les paquet ayant à la fois les deux options

# positionnées ne seront pas retenus, en revanche, ceux ayant

# «SFP» le seront.

icmp-type

n'est effective qu'associé à proto icmp mais JAMAIS avec flags. Il existe de nombreux types, référencés par une abréviation reconnue ou par le numéro qui leur est associé. Le plus important, du point de vue sécurité, est la redirection ICMP.

 

TRAÇABILITÉ

Le second dernier paramètre à fixer dans une règle de filtrage indique s'il faut ou non garder un historique des paquets concernés et ce qu'il faut garder. Les informations suivantes peuvent être enregistrées :

state

garde les informations sur le flot de la session de communication. Ne sont concernés que les paquets TCP, UDP et ICMP.

flags

garde des informations sur les paquets fragmentés, à appliquer aux paquets associés qui suivent.

permettant aux paquets concernés de continuer tout droit plutôt que d'emprunter la liste de contrôles d'accès.

 

GROUPES

La dernière paire de paramètres de filtrage contrôle les «groupements». Par défaut, toutes les règles de filtrages sont placées dans le groupe 0 si aucun autre groupe n'existe. Pour qu'une règle puisse appartenir à un autre groupe que celui par défaut, il faut en débuter un en créant un groupe head. Si un paquet correspond à une règle «head» du groupe, le traitement se poursuit vers ce groupe, utilisant cette règle comme celle par défaut. Si quick est utilisé avec une règle head, le traitement n'est pas interrompu tant qu'il n'est pas sorti du groupe.

Une règle peut être, à la fois le début (head) d'un nouveau groupe et une partie d'un groupe autre que par défaut (head et group peuvent être utilisés sur la même règle).

head <n>

indique qu'un nouveau groupe (numéro n) doit être créé.

group <n>

indique que la règle fait partie du groupe n et non du groupe 0.

 

ENREGISTREMENT

Lorsqu'un paquet est enregistré, avec l'action ou l'option log, les en-têtes du paquet sont inscrits sur le pseudo-périférique ipl. Immédiatement après le mot clef log, les qualificateurs suivant peuvent être utilisés (dans l'ordre) :

body

indique que les 128 premiers octets du paquet seront enregistrés après les en-têtes.

first

Si vous utilisez une l'option «keep», il est recommandé de la combiner avec first afin que seul le paquet significatif soit enregistré et non tous ceux qui suivent.

or-block

si, pour quelque raison, le filtre ne peut plus écrire (par exemple la lecture du fichier est trop lente), la règle doit être interprétée comme étant l'action block pour ce paquet.

level <niveau d'enregistrement>

indique les options et priorité d'enregistrement ou simplement la priorité et l'option par défaut à utiliser pour ce paquet lors de l'utilisation de -s avec ipmon.

Voir ipl(4) pour le format d'enregistrement sur ce périférique. Le programme ipmon(8) peut être utilisé pour lire et formater cet enregistrement.

 

EXEMPLES

L'option quick est adaptée aux règles telles que :

block in quick from any to any with ipopts

qui, pour les paquets dont l'en-tête a une longueur non-standard (présence d'options IP), demande d'abandonner le traitement des règles suivantes, enregistre les informations et bloque le paquet.

Le traitement pas à pas permet d'écrire ceci :

block in from any to any port < 6000

pass in from any to any port >= 6000

block in from any to any port > 6003

qui permet l'accès à la fourchette 6000-6003 uniquement. Notez que l'effet de la première règle est modifié par les suivantes. Une autre façon plus facile d'écrire la même chose :

block in from any to any port 6000 <> 6003

pass in from any to any port 5999 >< 6004

Notez que «block» et «pass» doivent être présent à la fois car le résultat négatif pour une directive «block» n'implique pas «pass» mais implique que la règle n'a pas d'effet. Ainsi, pour permettre l'accès aux ports inférieurs à 1024, une règle comme :

pass in quick from any to any port < 1024

doit apparaitre avant la directive de blocage. Pour établir un groupe qui traite tous les paquets entrants sur le0/le1/lo0 et dont le comportement par défaut est tous les bloquer, la règle peut être écrite de cette façon :

block in all

block in quick on le0 all head 100

block in quick on le1 all head 200

block in quick on lo0 all head 300

puis, pour permettre l'accès aux paquets ICMP arrivant sur le0 :

pass in proto icmp all group 100

Notez qu'il n'y a pas besoin de spécifier une deuxième fois le nom de l'interface puisque le groupe 100 ne traite que celle-là. De la même manière, nous pouvons scinder le traitement de TCP, etc... de cette façon :

block in proto tcp all head 110 group 100

pass in from any to any port = 23 group 110

et ainsi de suite. Sans groupe, la dernière ligne peut être écrite comme :

pass in on le0 proto tcp from any to any port = telnet

Notez que pour pouvoir dire «port = telnet», «proto tcp» doit être spécifié car l'interpréteur prend chaque règle dans son ensemble et associe chaque service et port au protocole spécifié.

 

FICHIERS

 

/dev/ipauth

/dev/ipl

/dev/ipstate

/etc/hosts

/etc/services

 

VOIR AUSSI

ipftest(1), iptest(1), mkfilters(1), ipf(4), ipnat(5), ipf(8), ipfstat(8)

 

 

Version française le 11 octobre 2000 par Guillain SEUILLOT <Guillain@lycosmail.com>


NOM | DESCRIPTION | GRAMMAIRE | RÈGLES DE FILTRAGE | ACTIONS | OPTIONS | PARAMÈTRES DE COMPARAISON | TRAÇABILITÉ | GROUPES | ENREGISTREMENT | EXEMPLES | FICHIERS | VOIR AUSSI