OBSD4* : wiki

Version de traduction basée sur la 6.4 officielle (v1.95 : 29/10/2018)


PF - Filtrage de Paquets

Introduction

Le filtrage de paquets est le passage ou le blocage sélectif de paquets de données quand ils passent au-travers de l'interface réseau. Les critères que pf(4) utilise, quand il inspecte les paquets, sont basés sur les entêtes de la Couche 3 (IPv4 et IPv6) et celles de la Couche 4 (TCP, UDP, ICMP, et ICMPv6). Les critères les plus souvent utilisés sont les adresses de destination et de source, les ports source et de destination, et le protocole.

Les règles de filtrage spécifient le critère auquel un paquet doit correspondre et une action résultante, soit de bloquer ou de laisser passer, qui est prise quand une correspondance est trouvée. Les règles de filtrage sont évaluées dans un ordre séquentiel, de la première à la dernière. À moins que les paquets correspondent à une règle contenant le mot clé quick, les paquets seront évalués dans toutes les règles de filtrage avant que l'action finale soit exécutée. La dernière règle qui correspond est la “gagnante” et obligera quelle action sera prise sur le paquet. Il y a l'implicite pass all au début du jeu de règles de filtrage, ce qui signifie que si le paquet ne trouve pas de correspondances avec aucune règle de filtrage, l'action résultante sera pass.

Syntaxe des règles

La syntaxe générale, hautement simplifiée, pour les règles de filtrage est :

  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
L'action à prendre pour les paquets correspondants, soit pass ou block. L'action pass va laisser passer le paquet vers le noyau pour un traitement ultérieur tandis que l'action block réagira sur la base de l'option 'block-policy'. La réaction par défaut peut être surchargée en spécifiant soit block drop, soit block return.

direction
La direction que le paquet suit dans une interface, soit in ou out.

log
Spécifie que les paquets devront être enregistrés via pflogd(8). Si la règle crée un état alors seul le paquet qui correspond à l'état est enregistré. Pour enregistrer tous les paquets, utilisez log (all).

quick
Si un paquet correspond à une règle spécifiant quick, alors la règle est considérée comme étant la dernière règle correspondante et l'action spécifiée est exécutée.

interface
Le nom ou le groupe d'interfaces réseau au-travers duquel le paquet circule. Les interfaces peuvent être ajoutées à des groupes arbitraires en utilisant la commande ifconfig(8). Plusieurs groupes sont aussi créés automatiquement par le noyau :

  • Le groupe egress, qui contient la ou les interface(s) qui correspondent à la ou aux route(s) par défaut.
  • Le groupe des familles d'interfaces pour les interfaces clonées. Par exemple : ppp ou carp.
    Cette règle aura pour conséquence que tout paquet, qui correspond, traversera toute interface ppp ou carp, respectivement.

af
La famille d'adresse du paquet, soit inet pour IPv4 ou inet6 pour IPv6. PF est généralement capable de déterminer ce paramètre basé sur la ou les adresse(s) source et/ou de destination.

protocol
Le protocole de la Couche 4 du paquet :

  • tcp
  • udp
  • icmp
  • icmpv6
  • un nom de protocole valide depuis le fichier /etc/protocols.
  • un numéro de protocole entre 0 et 255
  • un ensemble de protocoles utilisant une liste.

src_addr, dst_addr
L'adresse source ou de destination dans l'entête IP. Les adresses peuvent être spécifiées, telles que :

  • Une simple adresse IPv4 ou IPv6.
  • Un bloc réseau CIDR.
  • Un nom de domaine pleinement qualifié qui sera résolu via DNS quand le jeu de règles sera chargé. Toutes les adresses IP résultantes seront substituées dans la règle.
  • Le nom de l'interface réseau ou du groupe. Toute adresse IP assignée à l'interface sera substituée dans la règle.
  • Le nom de l'interface réseau suivi du masque réseau /netmask (càd, /24). Chaque adresse IP sur l'interface est combinée avec le masque réseau pour former un bloc réseau CIDR qui est substitué dans la règle.
  • Le nom de l'interface réseau ou du groupe entre parenthèses ( ). Ceci dit à PF de mettre à jour la règle si la ou les adresse(s) IP de l'interface concernée change(nt). Ceci est pratique sur une interface qui obtient son adresse IP via DHCP ou par connexion commutée, ainsi le jeu de règles n'a pas à être rechargé chaque fois que l'adresse change.
  • Le nom de l'interface réseau suivi d'un de ces modificateurs :
    • :network - remplace le bloc réseau CIDR (ex., 192.168.0.0/24)
    • :broadcast - remplace le bloc d'adresses de diffusion réseau (ex., 192.168.0.255)
    • :peer - remplace les adresses IP d'un pair sur un lien point-à-point
      De plus, le modificateur :0 peut être ajouté soit à un nom d'interface soit à tout modificateur ci-dessus, pour indiquer à PF qu'il ne devrait pas inclure les alias d'adresses IP dans la substitution. Ces modificateurs peuvent aussi être utilisés quand l'interface est contenue entre parenthèses. Exemple : fxp0:network:0
  • Une table.
  • Le mot-clé urpf-failed peut être utilisé pour l'adresse source afin d'indiquer qu'il doit être exécuté au-travers de la vérification d'uRPF.
  • Tout ce qui précède mais utilisé en négation avec le modificateur ! (“not”).
  • Un ensemble d'adresses utilisant une liste.
  • Le mot-clé any signifiant toutes les adresses.
  • Le mot-clé all qui est un raccourci de from any to any.

src_port, dst_port
Le port source ou de destination dans l'entête de paquet de la Couche 4. Les ports peuvent être spécifiés, tels que :

  • Un numéro entre 1 et 65535
  • Un nom de service valide depuis le fichier /etc/services.
  • Un ensemble de ports utilisant une liste.
  • Une plage :
    • != (non égal)
    • < (plus petit que)
    • > (plus grand que)
    • ''<='' (inférieur ou égal)
    • >= (supérieur ou égal)
    • >< (plage)
    • <> (plage inverse)
      Ces deux derniers sont des opérateurs binaires (ils prennent deux arguments) et n'incluent pas les arguments dans la plage.
    • : (qui inclus)
      L'opérateur inclusif est aussi un opérateur binaire et inclut les arguments dans la plage.

tcp_flags
Spécifie que les drapeaux doivent être paramétrés dans les entêtes TCP quand est utilisé proto tcp. Les drapeaux sont spécifiés comme flags check/mask. Par exemple : l'instruction flags S/SA demande que PF regarde seulement les drapeaux S et A (SYN et ACK) et correspond si seulement le drapeau SYN est sur “on” (et est appliqué à toutes les règles TCP par défaut). L'instruction flags any demande à PF de ne pas suivre les drapeaux.

state
Spécifie quelles informations d'état sont gardées sur les paquets correspondants à cette règle.

  • no state - fonctionne avec TCP, UDP, et ICMP. PF ne suivra pas cette connexion avec état. Pour les connexions TCP, flags any est habituellement aussi requise.
  • keep state - fonctionne avec TCP, UDP, et ICMP. Cette option est celle par défaut pour toutes les règles de filtrage.
  • modulate state - fonctionne seulement avec TCP. PF générera de solides numéros de séquence initiale (ISN - Initial Sequence Numbers) pour les paquets correspondants à cette règle.
  • synproxy state - des mandataires pour les connexions TCP entrantes afin d'aider à protéger les serveurs des bombardements de TCP SYN usurpés. Cette option inclus les fonctionnalités keep state et modulate state.

Refus par défaut

La pratique recommandée lors du paramétrage du pare-feu est de prendre l'approche « refus par défault ». Ceci interdit tout trafic, et alors d'allouer sélectivement certain trafic au-travers du pare-feu. Cette approche est recommandée par excès de prudence et rend l'écriture des jeux de règles plus facile.

Pour créer une politique de filtrage de refus par défaut, la première règle devrait être :

  block all

Ceci bloquera tout trafic sur toutes les interfaces dans n'importe quelle direction depuis n'importe où, vers n'importe où.

Laissez passer le trafic

Le trafic doit maintenant passer explicitement au-travers du pare-feu ou il sera supprimé par la politique de refus par défaut. C'est là où les critères de paquets tels que le port source ou de destination, l'adresse source ou de destination et le protocole entrent en jeu. Quand le trafic est autorisé à passer le pare-feu, la (les) règle(s) devrai(en)t être écrite(s) de manière aussi restrictive(s) que possible. Ceci afin de s'assurer que le trafic attendu, et seul le trafic prévu, soit autoriser à passer.

Quelques exemples :

  # Pass traffic in on dc0 from the local network, 192.168.0.0/24, to the OpenBSD
  # machine's IP address 192.168.0.1. Also, pass the return traffic out on 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
  
  # Pass TCP traffic in to the web server running on the OpenBSD machine.
  pass in on egress proto tcp from any to egress port www

Le mot-clé « quick »

Comme indiqué précédemment, chaque paquet est évalué par le jeu de règles de filtrage du début à la fin. Par défaut, le paquet est marqué pour le passage, ce qui peut être changé par toute règle, et pourrait être changé d'avant en arrière, plusieurs fois avant la fin des règles de filtrage. La dernière correspondance de règle gagne. Il y a une exception à cela : l'option quick sur une règle de filtrage a pour effet d'annuler tout autre traitement ultérieur, et provoque l'action spécifiée. Regardons un couple d'exemples :

Incorrect :

  block in on egress proto tcp to port ssh
  pass  in all

Dans ce cas, la ligne block peut être évaluée, mais n'aura jamais d'effet, car elle est suivie par une ligne qui autorise tout.

Correct :

  block in quick on egress proto tcp to port ssh
  pass  in all

Ces règles sont évaluées un peu différemment. Si la ligne block correspond, de par l'option quick, le paquet sera bloqué, et le reste du jeu de règles sera ignoré.

Suivi d'état

Une des plus importantes capacités de PF est « keeping state » ou « stateful inspection ». L'inspection d'état se réfère à la capacité de PF de traquer l'état, ou le progrès, d'une connexion réseau. En enregistrant l'information de chaque connexion dans une table d'état, PF est capable de déterminer rapidement si un paquet doit passer au-travers du pare-feu parce qu'il appartient à une connexion déjà établie. Si c'est le cas, il passe au-travers du pare-feu sans être à nouveau évalué.

Suivre l'état a plusieurs avantages, incluant la simplicité du jeu de règles et de meilleures performances de filtrage des paquets. PF est capable de faire correspondre les paquets allant dans n'importe quelle direction dans les entrées de la table d'état, ce qui signifie que les règles de filtrage qui laissent passer le retour du trafic n'ont pas besoin d'être écrites. Puisque les paquets correspondants à ces états de connexion ne sont plus évalués, le temps de traitement de PF sur ces paquets est grandement diminué.

Quand une règle crée un état, le premier paquet correspondant crée un « état » entre l'envoyeur et le receveur. Maintenant, non seulement les paquets venant de l'envoyeur vers le receveur correspondent à l'entrée d'état et contourneront les règles d'évaluation, mais enverront les paquets de réponses du receveur vers l'envoyeur.

Toutes les règles pass créeront automatiquement une entrée d'état quand un paquet correspond à la règle. Cela peut être explicitement désactivé en utilisant l'option no state.

  pass out on egress proto tcp from any to any

Cette règle permet tout trafic TCP sortant sur l'interface egress et permet aussi au trafic de réponse à passer au-travers le pare-feu. Suivre l'état améliore significativement les performances du pare-feu car les consultations d'états sont beaucoup plus rapides que faire passer un paquet au-travers des règles de filtrage.

L'option modulate state fonctionne de manière identique à keep state, excepté que cela s'applique seulement aux paquets TCP. Avec modulate state, le numéro de séquence initiale (ISN - Initial Sequence Number) des connexions sortantes est aléatoire. C'est pratique pour protéger les connexions initiées par certains systèmes d'exploitation qui font un mauvais travail dans le choix d'ISN. Pour permettre des jeux de règles plus simples, l'option modulate state peut être utilisée dans les règles qui spécifient les protocoles autres que TCP. Dans ces cas, elle est traitée comme keep state.

Suivre l'état sur les paquets TCP, UDP et ICMP sortants et moduler les ISN TCP :

  pass out on egress proto { tcp, udp, icmp } from any to any modulate state

Un autre avantage de suivre l'état est la correspondance du trafic ICMP qui sera passé au-travers du pare-feu. Par exemple, si une connexion TCP qui passe au-travers du pare-feu a été suivie avec état et que le message ICMP source-quench, se rapportant à cette connexion TCP, arrive, il correspondra à l'entrée d'état appropriée et passera au-travers du pare-feu.

La portée d'une entrée d'état est globalement contrôlée par l'option d'exécution state-policy, et par une règle basée sur les options if-bound et floating state. Ces mots-clés de règle ont la même signification que lorsqu'ils sont utilisés avec l'option state-policy. Par exemple :

  pass out on egress proto { tcp, udp, icmp } from any to any modulate state (if-bound)

Cette règle devrait dicter l'ordre par lequel les paquets, qui correspondent à l'entrée d'état, doivent transiter par l'interface egress.

Suivi d'état pour UDP

Parfois, on entend quelqu'un dire qu' « il n'est pas possible de créer un état avec UDP, car UDP est un protocole sans état ! ». Bien qu'il soit vrai qu'une session de communication UDP n'ait aucun concept d'état (un explicite démarrage et arrêt des communications), cela n'a pas aucun impact sur la capacité de PF à créer un état pour une session UDP. Dans le cas des protocoles sans paquets “start” et “end”, PF simplifie le suivi en gardant une trace depuis combien de temps le paquet correspondant est passé. Si le délai est atteint, l'état est nettoyé. La valeur timeout peut être paramétrée dans la section des options du fichier pf.conf.

Options de suivi d'état

Les règles de filtrage qui créent des entrées d'état peuvent spécifier différentes options pour contrôler le comportement résultant de l'entrée d'état. Les options suivantes sont disponibles :

max number
Limite le nombre maximum d'entrées d'état que la règle peut créer. Si le maximum est atteint, les paquets qui devraient normalement créer un état échouent à faire correspondre cette règle jusqu'à ce que le nombre d'états existants diminue sous la limite.

no state
Empêche la règle de créer automatiquement une entrée d'état.

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 de règles max-src-nodes et max-src-states. Seules les entrées d'états créées par cette règle particulière comptent pour les limites de règles.
  • source-track global - Le nombre des états créés par toutes les règles, que cette option utilise, est limité. Chaque règle peut spécifier les différentes options max-src-nodes et max-src-states, autrement les entrées d'état créées par toute règle participante compte pour limite de chaque règle individuelle.
    Le nombre total d'adresses IP sources suivies globalement peut être contrôlées via l'option d'exécution ''src-nodes''.

max-src-nodes number
Quand l'option source-track est utilisée, max-src-nodes limitera le nombre d'adresses IP sources qui peuvent créer simultanément un état. Cette option peut seulement être utilisée avec un source-track rule.

max-src-states number
Quand l'option source-track est utilisée, max-src-states limitera le nombre simultané d'entrées d'état qui peuvent être créées par adresse IP source. La portée de cette limite (càd, les états créés par cette règle seule, ou les états créés par toutes les règles qui utilisent source-track) est dépendante de l'option source-track spécifiée.

Les options sont spécifiées entre parenthèses immédiatement après un mot-clé d'état (keep state, module state, ou synproxy state). Les options multiples sont séparées par des virgules. L'option keep state est le comportement implicite par défaut pour toutes les règles de filtrage. Malgré cela, quand il est spécifié les options d'état, un des mots-clé d'état doit être encore utilisé devant les options.

Une règle d'exemple :

  pass in on egress proto tcp to $web_server port www 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 :

  • Limite le nombre maximum absolu d'état, que cette règle peut créer, à 200.
  • Active le suivi de source : limite la création d'état basé sur les états créés par cette règle seulement.
  • Limite le nombre maximum de nœuds, qui peuvent créer simultanément un état, à 100.
  • Limite le nombre maximum d'états simultanés par IP source à 3.

Un ensemble séparé de restrictions peut être placé sur des connexions TCP suivies qui ont complété le 3-way handshake (connexion TCP en 3 étapes).

max-src-conn number
Limite le nombre maximum de connexions TCP simultanées qui ont complété la connexion en 3 étapes qu'un unique hôte peut faire.

max-src-conn-rate number / interval
Limite le taux de nouvelles connexions à un certain nombre par intervalle de temps.

Ces deux options invoquent automatiquement l'option source-track rule et sont incompatibles avec l'option source-track global.

Puisque ces limites ont seulement été placées sur les connexions TCP qui ont complété la poignée à 3 mains, des actions plus agressives peuvent être prises sur les adresses IP incriminées.

overload <table>
Mettre l'adresse IP d'un hôte fautif dans la table nommée.

flush [global]
Tuer les autres états qui correspondent à cette règle et qui ont été créés par l'IP source. Quand global est spécifié, tuer tous les états correspondant à l'IP source, quelque soit la règle ayant créé l'état.

Un exemple :

  table <abusive_hosts> persist
  block in quick from <abusive_hosts>
  
  pass in on egress 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 fait ce qui suit :

  • Limite le nombre maximum de connexions par source à 100.
  • Limite le taux du nombre de connexions à 15 dans un espace de 5 secondes.
  • Met l'adresse IP de tout hôte qui atteint ces limites dans la table <abusive_hosts>.
  • Concernant les adresses IP attaquantes, vide les états créés par cette règle.

Drapeaux TCP

La correspondance des paquets TCP basés sur les drapeaux est le plus souvent utilisée pour filtrer les paquets TCP qui tentent d'ouvrir une nouvelle connexion. Les drapeaux TCP et leurs significations sont listés ici :

  • F : FIN - Terminé ; fin de session
  • S : SYN - Synchronise ; requête qui indique le début de session
  • R : RST - Réinitialise ; abandonne une connexion
  • P : PUSH - Pousse ; le paquet est envoyé immédiatement
  • A : ACK - Reconnaissance
  • U : URG - Urgent
  • E : ECE - Écho de Notification Explicite de Congestion
  • W : CWR - Fenêtre de Congestion Réduite

Pour que PF inspecte les drapeaux TCP durant l'évaluation d'une règle, le mot-clé flags est utilisé avec la syntaxe suivante :

  flags //check/mask//
  flags any

La partie mask indique à PF d'inspecter uniquement les drapeaux spécifiés et la partie check spécifie quel(s) drapeau(x) doi(ven)t être sur “on” dans l'entête pour qu'une correspondance se produise. L'utilisation du mot-clé any permet n'importe quelle combinaison de drapeaux dans l'entête.

  pass in on egress proto tcp from any to any port ssh flags S/SA
  pass in on egress proto tcp from any to any port ssh

Comme flags S/SA est définie par défaut, les règles ci-dessus sont équivalentes. Chacune de ces règles transmet le trafic TCP avec le drapeau SYN paramétré tout en regardant uniquement les drapeaux SYN et ACK. Un paquet avec les drapeaux SYN et ECE correspondrait aux règles ci-dessus, alors qu'un packet avec SYN et ACK, ou juste ACK, ne le serait pas.

Les drapeaux par défaut peuvent être surchargés en utilisant l'option flags comme indiqué ci-dessus.

Il faut être prudent dans l'utilisation des drapeaux : comprendre ce que vous faites et pourquoi, et faire attention aux conseils donnés par des personnes car beaucoup sont mauvais. Certaines personnes ont suggérés de créer un état « seulement si le drapeau SYN est paramétré et aucun autre ». Une telle règle se terminerait ainsi :

  [...] flags S/FSRPAUEW  //mauvaise idée// !!

La théorie est de créer un état uniquement sur le début d'une session TCP, la session devrait démarrer avec un drapeau SYN, et aucun autre. Le problème est que certains sites commencent à utiliser le drapeau ECN et tout site utilisant ECN qui essaie de se connecter sera rejeté par une telle règle. Une meilleure recommandation est de ne spécifier aucun drapeau et de laisser PF appliquer les drapeaux par défaut à vos règles. Si vous avez vraiment besoin de spécifier vous-même des drapeaux, alors cette combinaison de drapeaux devrait être saine :

  [...] flags S/SAFR

Bien que ce soit pratique et sûr, il est aussi inutile de vérifier les drapeaux FIN et RST si le trafic est aussi effacé. Le processus de nettoyage demandera à PF de supprimer tous les paquets entrants avec des combinaisons illégales de drapeaux TCP (tel que SYN et RST) et de normaliser des combinaisons potentiellement ambiguës (tel que SYN et FIN).

Mandataire TCP SYN

Normalement quand un client initie une connexion TCP à un serveur, PF relaie les paquets de négociation entre les deux points tels qu'ils arrivent. PF a la capacité, toutefois, de mandater la négociation. Ayant la poignée de main mandatée, PF lui-même complétera la poignée de main avec le client, initiera la négociation avec le serveur, et alors laissera passer les paquets entre les deux. Dans le cas d'une attaque par bombardement TCP SYN, l'attaquant ne terminera jamais la connexion en 3 étapes, ainsi les paquets de l'attaquant n'atteindront jamais le serveur protégé, mais légitimeront les clients qui ont accompli la négociation et qui sont passés. Cela minimise l'impact d'un bombardement TCP SYN sur le service protégé, géré par PF en lieu-et-place. L'utilisation systématique de cette option n'est pas recommandée, toutefois, car elle casse le comportement attendu du protocole TCP quand le serveur ne peut pas procéder à la requête ou quand les serveurs équilibrant la charge sont impliqués.

Le mandataire TCP SYN est activé en utilisant le mot-clé synproxy state dans les règles de filtrage. Par exemple :

  pass in on egress proto tcp to $web_server port www synproxy state

Ici, les connexions au serveur web seront mandatés, sur le protocole TCP, par PF.

À cause de la manière dont synproxy state fonctionne, il inclut aussi la même fonctionnalité que keep state et modulate state.

Le mandataire SYN ne travaillera pas si PF fonctionne sur un bridge(4).

Bloquer les paquets usurpés

Une adresse est “usurpée” quand un utilisateur malveillant falsifie l'adresse IP source dans les paquets qu'il transmet pour cacher leur adresse réelle ou se faire passer pour un autre nœud dans le réseau. Une fois que l'utilisateur a usurpé une adresse, il peut lancer une attaque réseau sans révéler la véritable source de l'attaque ou essayer d’accéder aux services du réseau qui sont restreints à certaines adresses IP.

PF offre une certaine protection contre l'usurpation d'adresse au-travers de l'usage du mot clé antispoof :

  antispoof [log] [quick] for interface [af]

log
Spécifie que les paquets correspondants doivent être enregistrés via pflogd(8).

quick
Si un paquet correspond à cette règle alors elle sera considérée comme règle « gagnante » et l'évaluation du jeu de règles sera arrêtée.

interface
L'interface réseau sur laquelle activer la protection. Ceci peut également être une liste d'interfaces.

af
La famille d'adresses réseaux sur laquelle activer la protection, soit inet pour IPv4, ou inet6 pour IPv6.

Exemple :

  antispoof for fxp0 inet

Lorsqu'un jeu de règles est chargé, toutes les occurrences du mot-clé antispoof seront étendues dans les deux règles de filtrage suivantes. En supposant que l'interface egress a l'adresse IP 10.0.0.1 et un masque réseau 255.255.255.0 (c.-à-d. : un /24), la règle antispoof ci-dessous sera étendue ainsi :

  block in on ! fxp0 inet from 10.0.0.0/24 to any
  block in inet from 10.0.0.1 to any

Ces règles accomplissent deux choses :

  • Bloque tout le trafic venant du réseau 10.0.0.0/24, qui ne passe pas au-travers de l'interface fxp0. Puisque l'interface fxp0 fait partie du réseau 10.0.0.0/24, les paquets avec une adresse source dans ce bloc réseau ne devraient jamais être vus sur toute autre interface.
  • Bloque tout le trafic entrant depuis l'adresse IP 10.0.0.1 sur fxp0. La machine hôte ne devrait jamais s'envoyer des paquets à elle-même au-travers de l'interface externe, ainsi tout paquet arrivant avec une adresse source appartenant à la machine doit être considéré comme malveillant.

NOTE : Les règles de filtrage, telle que la règle antispoof, bloqueront tous les paquets envoyés au-travers de l'interface de bouclage vers les adresses locales. Ceci est la meilleure pratique pour sauter le filtrage sur l'interface de bouclage, mais devient une nécessité lors de l'utilisation de règles anti-usurpation :

  set skip on lo0
  antispoof for fxp0 inet

L'utilisation de la règle antispoof devrait être restreinte aux interfaces qui ont une adresse IP assignée. Utiliser antispoof sur une interface sans adresse IP aura pour résultat de telles règles :

  block drop in on ! fxp0 inet all
  block drop in inet all

Avec de telles règles, il y a un risque de bloquer tout le trafic entrant sur toutes les interfaces.

Unicast Reverse Path Forwarding

PF offre la fonctionnalité de Transmission Mono-diffusée de la Route Inverse (uRPF - Unicast Reverse Path Forwarding). Quand un paquet est passé dans la vérification d'uRPF, l'adresse IP source du paquet est recherchée dans la table de routage. Si l'interface de sortie est trouvée dans les entrées de la table de routage comme étant la même que l'interface par laquelle le paquet arrive, alors elle passe la vérification uRPF. Si les interfaces ne correspondent pas, alors il est possible que l'adresse IP source soit usurpée.

La vérification d'uRPF peut être effectuée sur les paquets en utilisant le mot-clé urpf-failed dans les règles de filtrage :

  block in quick from urpf-failed label uRPF

Notez que la vérification uRPF n'a de sens que dans un environnement où le routage est symétrique.

uRPF fournit les mêmes fonctionnalités que les règles anti-usurpation.

Prise d'empreinte passive du système d'exploitation

La prise d'empreinte passive du système d'exploitation (OSFP - Passive OS fingerprinting) est une méthode pour détecter passivement le système d'exploitation d'une machine hôte distante basée sur certaines caractéristiques des paquets TCP SYN envoyés par cet hôte. Cette information peut ensuite être utilisée comme critère dans les règles de filtrage.

PF détermine le système d'exploitation distant par comparaison des caractéristiques du paquet TCP SYN avec le fichier d'empreintes, qui par défaut est pf.os(5). Une fois que PF est activé, la liste courante d'empreintes peut être vue avec la commande :

  # pfctl -s osfp

Dans une règle de filtrage, une empreinte peut être spécifiée par une classe d'OS, une version, ou un niveau de sous-type ou de correctifs. Chacun de ces éléments est listé dans la sortie de la commande pfctl vue ci-dessous. Pour spécifier une empreinte dans une règle de filtrage, le mot-clé os est utilisé :

  pass  in on egress proto tcp from any os OpenBSD
  block in on egress proto tcp from any os "Windows 2000"
  block in on egress proto tcp from any os "Linux 2.4 ts"
  block in on egress proto tcp from any os unknown

La classe spéciale du système d'exploitation unknown permet la correspondance des paquets lorsque l'empreinte du système d'exploitation n'est pas connue.

PRENEZ NOTE de ce qui suit :

  • La prise d'empreintes de système d'exploitation est occasionnellement faussée en raison de paquets usurpés ou fabriqués donnant l'impression qu'ils proviennent d'un système d'exploitation spécifique.
  • Certaines révisions ou niveaux de correctifs d'un système d'exploitation peuvent changer la signature comportementale et causer une non-correspondance avec le fichier d'empreintes ou la correspondance avec une autre entrée.
  • OSFP fonctionne seulement sur les paquets TCP SYN ; il ne fonctionnera pas sur les autres protocoles, ou sur des connexions déjà établies.

Options IP

Par défaut, PF bloque les paquets avec des options IP définies. Cela peut rendre le travail de prise d'empreintes plus difficile pour des utilitaires tel que nmap. Si vous avez une application qui requiert que ces paquets passent, telle que multicast ou IGMP, vous pouvez utiliser la directive allow-opts :

  pass in quick on fxp0 all allow-opts

Exemple de règles de filtrage

Ci-dessous un exemple d'un jeu de règles de filtrage. La machine qui fait fonctionner PF agit comme un pare-feu entre un petit réseau interne et Internet. Seules les règles de filtrage sont vues ; les règles de queueing, nat, rdr, etc, ont été sorties de cet exemple.

  int_if  = "dc0"
  lan_net = "192.168.0.0/24"
  
  # table containing all IP addresses assigned to the firewall
  table <firewall> const { self }
  
  # don't filter on the loopback interface
  set skip on lo0
  
  # scrub incoming packets
  match in all scrub (no-df)
  
  # set up a default deny policy
  block all
  
  # activate spoofing protection for all interfaces
  block in quick from urpf-failed
  
  # only allow ssh connections from the local network if it's from the
  # trusted computer, 192.168.0.15. use "block return" so that a TCP RST is
  # sent to close blocked connections right away. use "quick" so that this
  # rule is not overridden by the "pass" rules below.
  block return in quick on $int_if proto tcp from ! 192.168.0.15 to $int_if port ssh
  
  # pass all traffic to and from the local network.
  # these rules will create state entries due to the default
  # "keep state" option which will automatically be applied.
  pass in  on $int_if from $lan_net
  pass out on $int_if to   $lan_net
  
  # pass tcp, udp, and icmp out on the external (Internet) interface.
  # tcp connections will be modulated, udp/icmp will be tracked statefully.
  pass out on egress proto { tcp udp icmp } all modulate state
  
  # allow ssh connections in on the external interface as long as they're
  # NOT destined for the firewall (i.e., they're destined for a machine on
  # the local network). log the initial packet so that we can later tell
  # who is trying to connect.
  # Uncomment last part to use the tcp syn proxy to proxy the connection.
  pass in log on egress proto tcp to ! <firewall> port ssh # synproxy state

Cette page est la traduction officieuse de la page « Packet filtering » de la FAQ officielle d'OpenBSD.
En cas de doute, merci de vous y référer !

Si vous voulez participer à l'effort de traduction, merci de lire ce topic.