[Section précédente : Tables]
[Index]
[Section suivante : Traduction des Adresses IP ("NAT")]
PF : Le Filtrage de Paquets
Table des Matières
Introduction
Le filtrage de paquets à l'aide de
pf(4)
consiste à autoriser ou bloquer le trafic réseau en fonction des
propriétés des protocoles des couches 3
(IPv4 et
IPv6) et 4
(TCP,
UDP,
ICMP, et
ICMPv6).
Les adresses et ports source et destination ainsi que les protocoles
utilisés sont des critères fréquemment employés.
Les règles de filtrage énumèrent les critères auxquels doivent se
conformer les paquets et spécifient les actions qui y sont associées :
bloquer ou laisser passer. Ces règles sont évaluées de façon
séquentielle de la première à la dernière (du haut vers le bas dans les
fichiers de règles utilisés).
Sauf utilisation du mot-clef quick dans l'une d'entre elles,
chaque paquet est évalué à l'aide de toutes les règles avant
qu'une décision finale ne soit prise.
L'action (block ou pass) associée à la dernière règle dont les critères
se rapportent au paquet traité est appliquée. La première règle est un
tout laisser passer implicite de sorte que si aucune règle
n'est applicable à un paquet, celui-ci est accepté (pass).
Syntaxe
L'écriture des règles obéit à la syntaxe très simplifiée suivante
:
action [direction] [log] [quick] [on interface]
[af] [proto protocol] \
[from src_addr [port src_port]] [to
dst_addr [port dst_port]] \
[flags tcp_flags] [state]
- action
- Ce mot-clef indique le type d'action associé à tout paquet
correspondant aux critères contenus dans la règle. Les deux valeurs
possibles sont pass et block.
pass signifie que le paquet sera transféré au noyau pour être
traité. Le blocage du paquet (block) sera fonction de la
politique définie par les options
block-policy. L'action
associée par défaut peut être modifiée en spécifiant
block drop ou block return.
- direction
- Ce mot-clef spécifie le sens du trafic vu depuis l'interface réseau
: celui-ci peut être entrant (in) ou sortant
(out).
- log
- La présence de ce mot-clef dans une règle déclenche la
journalisation des paquets correspondants à la règle grâce à
l'utilitaire
pflogd(8).
Si les options keep state, modulate state, ou
synproxy state sont également renseignées, seul le paquet
correspondant à l'ouverture de la session est conservé. Pour
conserver tous les paquets d'une session, il faut utiliser le
mot-clef log (all).
- quick
- Si le mot-clef quick est utilisé dans une règle, celle-ci est
considérée comme étant la dernière à prendre en compte et
l'action spécifiée est prise.
- interface
- Ce mot-clef désigne l'interface sur laquelle le trafic est à
analyser. Il est possible de grouper plusieurs interfaces. Dans ce
cas, le groupe est désigné par le nom générique de l'interface non
suivi d'un numéro. Par exemple : ppp ou fxp. La
règle s'appliquera aux paquets traversant toute interface de type
ppp ou fxp respectivement.
- af
- Il est possible de spécifier la famille d'adresses IP à laquelle
appliquer une règle à l'aide de ce mot-clef. Les deux valeurs
possibles sont inet pour les adresses IPv4 ou
inet6 pour IPv6. PF peut généralement déterminer à quelle
famille appartient un paquet à partir de ses adresses source et
destination.
- protocol
- Ce mot-clef identifie les protocoles de couche 4 utilisés. Il peut
prendre les valeurs suivantes :
- tcp
- udp
- icmp
- icmp6
- tout protocole spécifié dans le fichier
/etc/protocols
- le numéro d'un protocole compris entre 0 et 255
- un ensemble de protocoles passé dans une
liste.
- src_addr, dst_addr
- Ces mots-clefs identifient respectivement les adresses source et
destination du paquet telles que contenues dans son en-tête IP. Ces
adresses peuvent être spécifiées :
- sous la forme d'adresse IPv4 ou IPv6.
- sous la forme d'un bloc d'adresses
CIDR.
- sous la forme d'un domaine. Ce dernier fera l'objet d'une résolution
DNS lors du chargement des règles par PF. La règle s'appliquera
alors à tous les adresses du domaine.
- par l'intermédiaire du nom d'une interface réseau. Toute adresse IP
affectée à cette interface sera valide pour la règle.
- par l'intermédiaire du nom d'une interface réseau suivi d'un /netmask
(par exemple, /24). Toutes les adresses IP
correspondant au bloc CIDR formé par l'adresse IP de l'interface et le
masque de sous réseau seront valides pour cette règle.
- sous la forme du nom d'une interface réseau mis entre parenthèses
( ). Cette mise en forme indique à PF qu'il doit mettre ses
règles à jour en cas de changement de l'adresse IP affectée à
l'interface en question. Cette technique est très utile dans le cas
de liaisons PPP ou d'utilisation du protocole DHCP pour
l'attribution d'adresses IP. Elle évite d'avoir à recharger les
règles à chaque nouvelle affectation.
- grâce au nom d'une interface suivi d'un des paramètres suivants :
- :network - identifie un bloc CIDR (par exemple :
192.168.0.0/24)
- :broadcast - identifie une adresse de multi-diffusion
(par exemple : 192.168.0.255)
- :peer - identifie l'adresse d'un pair sur un lien point à
point.
- De plus, le paramètre :0 peut être ajouté aussi bien au
nom d'une interface qu'à chacun des paramètres présentés
ci-dessus. PF ne prend alors pas en compte les éventuels alias
d'adresses IP affectés à l'interface. Ces paramètres peuvent
aussi être utilisés dans le cas d'une interface entre parenthèses.
Par exemple: fxp0:network:0
- à l'aide d'une table.
- sous toutes les formes décrites ci-dessus précédées du paramètre
d'inversion ! ("not").
- à l'aide d'une liste d'adresses.
- grâce au mot-clef any qui identifie n'importe quelle
adresse.
- grâce au mot-clef all qui est un raccourci pour
l'expression from any to any (n'importe quelle source vers
n'importe quelle destination).
- src_port, dst_port
- Ces mots-clefs identifient respectivement les ports source et
destination qui apparaissent dans les en-têtes des protocoles de
couche 4. Ces ports peuvent être spécifiés :
- sous forme numérique par un nombre compris entre 1 et 65535.
- par le nom d'un service tel qu'identifié dans le fichier
/etc/services.
- sous la forme d'une liste.
- sous la forme d'un intervalle de ports construit à l'aide des
opérateurs suivants :
- != (différent)
- < (inférieur à)
- > (supérieur à)
- <= (inférieur ou égal à)
- >= (supérieur ou égal à)
- >< (intervalle)
- <> (intervalle inverse)
- Les deux derniers opérateurs demandent deux arguments pour
former un intervalle qui n'inclue pas ces arguments.
- : (intervalle complet)
- L'opérateur d'intervalle complet est également un opérateur binaire
incluant les arguments dans l'intervalle.
- tcp_flags
- Spécifie les drapeaux qui doivent être activés dans l'en-tête TCP lors de
l'utilisation de proto tcp. Cette valeur est spécifiée ainsi :
flags check/mask. Par exemple : flags S/SA.
Dans ce cas, PF teste la valeur des drapeaux S et A (SYN et ACK) pour savoir
s'ils sont positionnés. Si le drapeau SYN est positionné, et uniquement ce
drapeau, alors la règle est applicable.
- state
- Ce mot-clef indique dans quel état doit être le paquet pour
satisfaire à une règle.
- keep state - s'applique aux protocoles TCP, UDP, et ICMP.
- modulate state - ne s'applique qu'au protocole TCP. PF
renforcera le caractère aléatoire des numéros de séquence initiaux
(ISN) générés pour ces paquets.
- synproxy state - PF agit comme mandataire pour les
connexions TCP entrantes. Cela renforce la protection contre les
attaques par inondation de paquets SYN en provenance d'adresses
usurpées. Cette option active implicitement les fonctionnalités
keep state et modulate state.
Blocage par défaut
Il est recommandé d'adopter une approche de blocage par défaut lors de
la configuration d'un pare-feu. Cela signifie que tout est
interdit et que l'on autorise le trafic au cas par cas. Cette approche
est assimilable à l'application d'un principe de précaution et simplifie
l'écriture des règles.
Cette politique de blocage par défaut repose sur deux règles :
block in all
block out all
Cela suffit à interdire tout trafic dans un sens comme dans l'autre et
ce sur toutes les interfaces de la machine.
Laisser passer le trafic
Une fois notre politique restrictive mise en place, il faut spécifier
quelles sont les connexions autorisées. C'est là qu'entrent en jeu les
critères décrits précédemment : adresse et port source et destination,
protocole, etc. Chaque fois qu'un paquet est autorisé à franchir les
murs du pare-feu, les règles correspondantes devront être les plus
restrictives possible : il s'agit de n'autoriser que le trafic voulu et
lui seul.
Quelques exemples:
# Autoriser le trafic entrant sur l'interface dc0
# en provenance du réseau local 192.168.0.0/24,
# à destination de la machine dont l'adresse IP est 192.168.0.1.
# Dans le même temps, autoriser le trafic sortant par l'interface dc0.
pass in on dc0 from 192.168.0.0/24 to 192.168.0.1
pass out on dc0 from 192.168.0.1 to 192.168.0.0/24
# Autoriser le trafic TCP entrant sur l'interface fxp0
# à destination d'un serveur HTTP.
# Le nom de l'interface - fxp0 - est utilisé comme adresse de destination
# pour les paquets autorisés.
pass in on fxp0 proto tcp from any to fxp0 port www
L'option quick
Comme nous l'avons vu, chaque paquet est testé au regard de toutes les
règles de filtrage, de la première à la dernière. Par défaut, un paquet
est marqué à chaque test. Le résultat final peut ainsi changer d'une
règle à l'autre jusqu'à ce que toutes aient été parcourues. Rappelons
que c'est la dernière règle à laquelle correspond un paquet qui
l'emporte sur les autres. Il y a cependant une exception : si l'option
quick est présente dans une règle et qu'un paquet correspond
aux critères de cette règle, il n'y a plus de tests : la règle en
question est alors considérée par PF comme étant la dernière. Les
exemples suivants illustrent ce cas de figure :
Mauvais :
block in on fxp0 proto tcp from any to any port ssh
pass in all
La ligne block n'aura aucun effet. Les paquets seront bien
évalués suivant ses critères, mais la ligne suivante annulera tout effet
de cette première règle.
Mieux :
block in quick on fxp0 proto tcp from any to any port ssh
pass in all
A première vue c'est la même chose. Si la ligne block correspond,
l'option quick provoque l'arrêt des tests pour chaque paquet qui
correspond aux critères de la première règle. Les paquets qui n'y
satisfont pas seront quant à eux testés au regard des critères de la
règle suivante.
Conserver l'état
Une des fonctionnalités les plus importantes de PF est sa capacité à
conserver l'état des connexions. PF est capable d'évaluer un paquet non
plus unitairement mais dans le contexte de la connexion à laquelle il
appartient. PF utilise pour cela une table d'état grâce à laquelle PF
peut rapidement déterminer si un paquet fait partie d'une connexion déjà
établie et autorisée. Si tel est le cas, le paquet est transféré sans
test complémentaire.
Conserver l'état des connexions a pour avantage de simplifier les règles
de filtrage et d'améliorer les performances. PF évalue les paquets
quel que soit leur sens : il n'est alors plus nécessaire d'écrire
les règles pour les paquets des flux retour. PF consacre ainsi beaucoup
moins de temps à inspecter les paquets.
Quand l'option keep state est utilisée dans une règle, le
premier paquet qui déclenche l'activation de celle-ci provoque la
création d'un enregistrement dans la table d'état des connexions en
cours. Par la suite, non seulement les paquets allant de l'expéditeur au
destinataire sont rattachés à cette table et donc autorisés à passer,
mais également les paquets qui appartiennent aux réponses du
destinataire. Par exemple :
pass out on fxp0 proto tcp from any to any keep state
Cette règle autorise les connexions TCP sortantes sur l'interface
fxp0 mais aussi les paquets retour. L'option keep state permet donc
d'augmenter les performances du pare-feu car la recherche dans la table d'état
est beaucoup plus rapide que l'opération consistant à évaluer un paquet au
regard de toutes les règles de filtrage.
L'option modulate state fonctionne de la même façon que
l'option keep state à ceci près qu'elle ne s'applique qu'aux
paquets TCP sortants. L'option modulate state renforce le caractère
aléatoire de leurs numéros de séquence initiaux (ISN). Cette option permet de
renforcer la sécurité de certains systèmes d'exploitation ne sachant pas générer
des ISN suffisamment aléatoires. A partir de la version 3.5 d'OpenBSD, l'option
modulate state peut être utilisée pour les autres protocoles que TCP.
Pour conserver l'état des connexions TCP, UDP et ICMP tout en renforçant
la sécurité des ISN :
pass out on fxp0 proto { tcp, udp, icmp } from any \
to any modulate state
Un des avantages de conserver l'état des connexions tient à ce que les
messages ICMP relatifs à celles-ci seront traités comme faisant partie
de la connexion. Si des messages ICMP sont émis par une machine pour
signaler une congestion par exemple, et que l'option keep state
est activée, les messages seront pris en compte et acceptés par le
pare-feu. Sans cela, ils auraient été bloqués ou ignorés.
La portée d'une entrée dans la table d'état dépend des options
state-policy d'une manière
globale ou bien des options if-bound, group-bound et
floating-state. Les valeurs appliquées règle par règle on la même
signification que lorsqu'elles sont utilisées avec l'option
state-policy. Par exemple :
pass out on fxp0 proto { tcp, udp, icmp } from any \
to any modulate state (if-bound)
Selon cette règle, les paquets ne trouveront une correspondance dans la
table d'état que s'ils transitent par l'interface fxp0.
Il faut noter que les règles nat, binat et rdr créent implicitement des entrées dans la table d'état.
Conserver l'état des connexions UDP
On entend souvent dire qu'il est impossible d'utiliser la table d'état
avec UDP car c'est un protocole sans état. S'il est vrai qu'une
connexion UDP n'utilise pas stricto sensu le concept d'état tel que le
fait une connexion TCP (à savoir une ouverture et une terminaison
explicites de la connexion), cela n'a aucune conséquence sur la capacité
qu'a PF de créer et gérer des états pour les connexions UDP. Pour ce
type de protocole sans début ou fin de connexion explicites, PF
conserve simplement une trace de la durée d'une session. S'il s'écoule
un certain laps de temps sans échange de paquets entre les deux parties,
l'entrée associée à la session dans la table d'état est supprimée.
Ce laps de temps peut être configuré dans la section
options du fichier pf.conf.
Options de Suivi Stateful
Quand une règle de filtrage crée une entrée dans la table d'états suite
à l'utilisation des mots clé keep state, modulate
state ou synproxy state, certaines options peuvent être
spécifiées afin de contrôler le comportement de ces créations d'états.
Les options suivantes sont disponibles :
- max number
- Limite le nombre maximum d'entrées d'états que la règle peut créer à
number.
Si le maximum est atteint, les paquets qui devraient normalement créer
un état sont rejetés jusqu'à ce que le nombre d'états existants diminue.
- source-track
- Cette option active le suivi du nombre d'états créés par adresse IP
source.
Cette option a deux formats :
- source-track rule - Le nombre maximum d'états créés
par cette règle est limité par les options max-src-nodes
et max-src-states de la règle. Seules les
entrées d'états crées par cette règle particulière comptent
pour la limite des règles.
- source-track global - Le nombre d'états créés par
toutes les règles qui utilisent cette option est limité.
Chaque règle peut spécifier différentes options max-src-nodes
et max-src-states, cependant, les entrées
d'états crées par toute règle participante comptent en vue
d'une limite individuelle éventuelle.
Le nombre total d'adresses IP source suivies globalement peut être
contrôlé via l'option
src-nodes runtime.
- max-src-nodes nombre
- Lorsque l'option source-track est utilisée,
max-src-nodes limitera le nombre d'adresses IP source pouvant
créer simultanément une entrée.
Cette option peut seulement être utilisée avec une règle source-track.
- max-src-states nombre
- Lorsque l'option source-track est utilisée,
max-src-states limitera le nombre d'entrées d'états
simultanées pouvant être crées par adresse IP source.
La portée de cette limite (les états créés par cette règle uniquement ou
les états créés par toutes les règles utilisant source-track)
est dépendante de l'option source-track spécifiée.
Une règle d'exemple :
pass in on $ext_if proto tcp to $web_server \
port www flags S/SA keep state \
(max 200, source-track rule, max-src-nodes 100,
max-src-states 3)
La règle ci-dessus définit le comportement suivant :
- Limiter le nombre maximum absolu d'états pouvant être créés par
cette règle à 200
- Activer le suivi de la source; limiter la création d'états pour
cette règle uniquement
- Limiter le nombre maximum de noeuds pouvant simultanément créer des
états à 100
- Limiter le nombre maximum d'états simultanés par adresse IP source à
3
Un jeu séparé de restrictions peut être placé sur les connexions TCP
stateful qui ont une poignée de main "3-way handshake" complète.
- max-src-conn nombre
- Limiter le nombre maximum de connexions TCP simultanées ayant
réalisé la poignée de main qu'un hôte peut initier.
- max-src-conn-rate nombre / intervalle
- Limiter le taux de nouvelles connexions à un certaine fréquence.
Ces deux options font appel à l'option source-track rule et
sont incompatibles avec source-track global.
Ces limites étant placées sur les connexions TCP ayant réalisé la
poignée de main TCP, des connexions plus agressives pourront toujours
avoir lieu depuis les adresses IP concernées.
- overload <table>
- Mettre l'adresse d'un hôte concerné dans la table désignée.
- flush [global]
- Tue toutes les autres connexions qui correspondent à cette règle et
qui ont été créées par cette adresse IP source.
Quand global est spécifié, cela tue tous les états
correspondant à cette adresse IP source, sans discernement de la règle
qui a créé cet état.
Un exemple :
table <abusive_hosts> persist
block in quick from <abusive_hosts>
pass in on $ext_if proto tcp to $web_server \
port www flags S/SA keep state \
(max-src-conn 100, max-src-conn-rate 15/5,
overload <abusive_hosts> flush)
Ceci permet de :
- Limiter le nombre maximum de connexions par source à 100
- Limiter le taux du nombre de connexions à 15 dans une durée de 5
secondes
- Mettre l'adresse IP de tout hôte qui dépasse ces limites dans la
table <abusive_hosts>
- Pour des adresses IP concernées, supprimer tous les états créés par
cette règle.
Les drapeaux TCP
On utilise souvent les drapeaux TCP dans des règles pour traiter les
ouvertures de sessions. Ces drapeaux et leur signification sont
présentés dans la liste suivante :
- F : FIN - Fin de session
- S : SYN - Synchronize ; correspond à une ouverture de session
- R : RST - Reset ; met fin à une session
- P : PUSH - Push ; le paquet est envoyé immédiatement
- A : ACK - Acknowledgement ; atteste de l'acquittement d'une
des parties
- U : URG - Urgent
- E : ECE - Explicit Congestion Notification Echo ; avis de congestion
- W : CWR - Congestion Window Reduced ; avis de réduction de la
fenêtre TCP
Le mot-clef flags doit apparaître dans une règle si l'on
souhaite que PF prenne en compte la valeur des drapeaux TCP d'un paquet.
La syntaxe est la suivante :
flags check/mask
La partie mask de la règle indique la liste des drapeaux
que PF doit inspecter. La partie check quant à elle
spécifie les drapeaux qui doivent être positionnés pour que la règle
s'applique au paquet traité.
pass in on fxp0 proto tcp from any to any port ssh flags S/SA
Cette règle s'applique aux paquets TCP dont le drapeau SYN est
positionné. PF limite son inspection aux drapeaux SYN et ACK. La règle
s'applique donc à un paquet dont les drapeaux SYN et ECE sont
positionnés mais pas à un paquet dont les drapeaux SYN et ACK ou dont
seul le drapeau ACK sont positionnés.
Notez que les précédentes versions d'OpenBSD acceptaient cette syntaxe :
. . . flags S
Ce qui n'est plus vrai : le masque doit maintenant toujours être
renseigné.
Les drapeaux sont souvent utilisés avec l'option keep state
pour mieux contrôler la création des entrées dans la table d'état :
pass out on fxp0 proto tcp all flags S/SA keep state
Une entrée est créée pour tous les paquets TCP sortants dont le drapeau
SYN est positionné.
Il faut manipuler les drapeaux avec prudence et se méfier des mauvais
conseils. Certaines personnes suggèrent de ne créer des entrées que pour
les paquets dont le drapeau SYN est positionné. Ce qui peut aboutir à
cette règle :
. . . flags S/FSRPAUEW mauvaise pioche !!
En théorie, une session TCP commence par un paquet dont le drapeau SYN
est positionné. Toujours en théorie, il ne faut créer une entrée dans la
table d'état que pour ce genre de paquets. Mais certains systèmes
utilisent le drapeau ECN en début de session. Ces paquets sont rejetés
par la règle précédente. Une meilleure solution est :
. . . flags S/SAFR
Si le trafic est normalisé, il peut être
pratique et sûr de ne pas tester la valeur des drapeaux FIN et RST. Dans
ce cas, PF rejette tout paquet entrant dont les drapeaux TCP sont
positionnés de manière illicite (par exemple SYN et RST) et les
combinaisons potentiellement ambiguës (telles que SYN et FIN) seront
normalisées. Il est fortement recommandé de toujours normaliser
(scrub) le trafic entrant :
scrub in on fxp0
.
.
.
pass in on fxp0 proto tcp from any to any port ssh flags S/SA \
keep state
Mandataire TCP SYN
Normalement, quand un client ouvre une connexion TCP vers un serveur, PF
relaie les paquets d'ouverture
(handshake) au fur et à mesure qu'ils arrivent.
PF peut agir en tant que mandataire (proxy). Dans ce cas, PF va traiter
la demande en lieu et place du serveur et ne transfèrera qu'ensuite les
paquets à ce dernier. Aucun paquet n'est transmis au serveur avant que
le client n'ait terminé l'échange initial (handshake). L'avantage de
cette méthode est de protéger le serveur des attaques par inondation de
paquets SYN lancées à l'aide de paquets falsifiés.
Le mandataire TCP SYN est activé à l'aide de l'option synproxy
state :
pass in on $ext_if proto tcp from any to $web_server port www \
flags S/SA synproxy state
Toutes les connexions à destination du serveur HTTP seront mandatées par
PF.
L'option synproxy state apporte les mêmes avantages que les
options keep state et modulate state.
Par contre, l'option synproxy ne fonctionne pas quand PF est installé en
passerelle transparente
(bridge(4)).
Bloquer les paquets usurpés
On parle d'usurpation quand un utilisateur mal intentionné maquille son
adresse IP dans le but d'anonymiser ou de cacher son identité afin de
lancer des attaques sans que leur origine soit détectable. Il peut
également essayer et parfois réussir à avoir accès à des services
réservés à certaines adresses.
PF permet de se prémunir de ce type d'attaques grâce à l'option
antispoof :
antispoof [log] [quick] for interface [af]
- log
- Journalise les paquets via
pflogd(8).
- quick
- Si un paquet correspond à la règle, celle-ci est appliquée
immédiatement.
- interface
- Désigne l'interface sur laquelle s'applique la protection. Il est
possible de passer une liste
d'interfaces en paramètre.
- af
- Spécifie le type d'adresse : inet pour IPv4 ou
inet6 pour IPv6.
Exemple:
antispoof for fxp0 inet
Quand les règles sont chargées, toutes les occurrences du mot
antispoof sont décodées dans deux filtres. Si l'interface
fxp0 dont l'adresse IP est 10.0.0.1 pour un masque de sous-
réseau de 255.255.255.0 (soit /24) est protégée, l'option
antispoof sera décodée ainsi :
block in on ! fxp0 inet from 10.0.0.0/24 to any
block in inet from 10.0.0.1 to any
Cette règle déclenche deux actions :
- elle bloque tout le trafic en provenance du réseau 10.0.0.0/24 s'il
ne passe pas par l'interface fxp0. Puisque le réseau
10.0.0.0/24 est branché sur l'interface fxp0, aucun paquet en
provenance de celui-ci ne devrait arriver ailleurs.
- elle bloque tout le trafic entrant dont l'adresse source est
10.0.0.1, à savoir celle de l'interface fxp0. Cette machine
ne devrait en effet jamais émettre de paquets à travers une
interface externe et par conséquent ne doit pas recevoir de paquets
ayant son adresse IP comme adresse source.
REMARQUE : le filtrage activé par l'option antispoof
d'une règle s'applique également aux paquets envoyés sur l'adresse de
bouclage interne (loopback).
Le filtrage est communément désactivé sur ces interfaces, et cela
devient primordial lors de l'utilisation de règles antispoof :
set skip on lo0
antispoof for fxp0 inet
L'utilisation de l'option antispoof est réservée aux interfaces
qui possèdent une adresse IP. Utiliser antispoof sur une interface sans
adresse IP aboutit au filtrage suivant :
block drop in on ! fxp0 inet all
block drop in inet all
Avec ce genre de règles, le risque est réel de bloquer tout le
trafic entrant sur toutes les interfaces.
Reconnaissance passive d'OS par leurs empreintes
La reconnaissance passive d'OS par leurs empreintes ("OS
Fingerprinting" ou OSFP) est une méthode qui permet de reconnaître
à distance quel système d'exploitation tourne sur une machine. Cette
reconnaissance se base sur les caractéristiques des paquets TCP SYN
renvoyés par une machine. Ces informations peuvent être utilisées comme
critères dans des règles de filtrage.
PF utilise le fichier
d'empreintes
/etc/pf.os
pour reconnaître les systèmes d'exploitation auxquels il a affaire.
Lorsque PF s'exécute, la liste des empreintes reconnues peut être
consultée grâce à la commande suivante :
# pfctl -s osfp
Dans une règle, une empreinte peut être désignée sous la forme d'une
classe, d'une version ou d'un sous-type d'OS. La liste de ces éléments
est affichée à l'aide de la commande pfctl. Pour désigner une
empreinte dans une règle, il faut utiliser le mot-clef os :
pass in on $ext_if from any os OpenBSD keep state
block in on $ext_if from any os "Windows 2000"
block in on $ext_if from any os "Linux 2.4 ts"
block in on $ext_if from any os unknown
unknown est une classe spéciale désignant les systèmes
d'exploitation dont l'empreinte n'est pas connue.
Notez bien que :
- La reconnaissance peut échouer face à des paquets spécifiquement
construits pour tromper la détection d'empreintes.
- L'application de correctifs peut modifier le comportement de la
pile TCP/IP d'un système d'exploitation et faire également échouer
ou tromper la reconnaissance de l'OS.
- L'option OSFP n'est applicable qu'aux paquets TCP SYN. Elle est
inefficace avec d'autres protocoles et pour les sessions déjà
établies.
Les options IP
PF bloque par défaut tous les paquets qui utilisent les options IP. Cela
rend moins aisé le travail des outils de reconnaissance d'empreintes
tels que nmap. Si une application utilise ces options (par exemple IGMP
ou les diffusions multicast) il est possible d'utiliser l'option
allow-opts :
pass in quick on fxp0 all allow-opts
Exemple de règles de filtrage
Vous trouverez ci-dessous un exemple de règles de filtrage pour un
pare-feu PF destiné à protéger un petit réseau connecté à Internet. Seules
les règles de filtrage sont mentionnées ;
queueing,
nat,
rdr, etc.
ont été volontairement laissées de côté.
ext_if = "fxp0"
int_if = "dc0"
lan_net = "192.168.0.0/24"
# Déclaration du tableau référençant toutes les adresses IP affectées au
# pare-feu.
table <firewall> const { self }
# Ne pas filtrer sur l'interface de bouclage
set skip on lo0
# Normalisation de tous les paquets entrants.
scrub in all
# Mise en place d'une politique d'interdiction par défaut.
block all
# Activation de la protection contre l'usurpation sur l'interface
# externe.
antispoof quick for $int_if inet
# Les connexions ssh ne sont autorisées qu'en provenance du réseau local
# et de la machine 192.168.0.15. "block return" provoque l'émission d'un
# paquet TCP RST pour mettre fin aux connexions illicites. "quick"
# assure que cette règle n'est pas contredite par les règles "pass".
block return in quick on $int_if proto tcp from ! 192.168.0.15 \
to $int_if port ssh flags S/SA
# Autoriser le trafic sortant et entrant sur le réseau local.
pass in on $int_if from $lan_net to any
pass out on $int_if from any to $lan_net
# Autoriser les connexions sortantes tcp, udp et icmp sur l'interface
# externe.
# Activer le suivi des états pour les protocoles udp et icmp.
# Activer l'option modulate state sur les paquets tcp.
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto { udp, icmp } all keep state
# Autoriser les connexions ssh sur l'interface externe du moment
# qu'elles ne sont pas destinées au pare-feu lui-même. Journaliser le
# paquet qui initie la session afin de pouvoir déterminer qui s'est
# connecté. Activer un service mandataire SYN.
pass in log on $ext_if proto tcp from any to ! <firewall> \
port ssh flags S/SA synproxy state
|
[Section précédente : Tables]
[Index]
[Section suivante : Traduction des Adresses IP ("NAT")]
www@openbsd.org
$OpenBSD: filter.html,v 1.23 2006/05/14 09:54:41 saad Exp $