Une table est une structure utilisée pour regrouper un ensemble
d'adresses IPv4 et/ou IPv6. Chercher une adresse IP dans une table est
une opération très rapide qui consomme moins de mémoire et de temps
processeur qu'une recherche dans une
liste. C'est pourquoi une table est
idéale pour contenir un grand nombre d'adresses IP vu que la
consultation d'une table de 50 000 adresses ne prend qu'un tout petit
peu plus de temps que celle d'une table de 50 adresses. Les tables
peuvent être utilisées de l'une des manières suivantes :
adresse de redirection dans les règles de
redirection.
adresse de destination dans les options des règles de filtrage
route-to, reply-to, et dup-to.
Une table peut être créée dans
pf.conf
ou en utilisant
pfctl(8).
Configuration
Dans pf.conf, les tables sont créées en utilisant la directive
table. Les attributs suivants peuvent être spécifiés pour
chaque table :
const - le contenu de la table ne peut être modifié une
fois la table créée. Lorsque cet attribut n'est pas spécifié,
pfctl(8)
peut être utilisé pour ajouter ou supprimer des adresses de la table
à n'importe quel moment, même lorsque le système utilise un
securelevel(7)
supérieur ou égal à 2.
persist - conduit le noyau à garder la table en mémoire
même lorsqu'aucune règle ne s'y réfère. Sans cet attribut, le noyau
supprimera automatiquement la table lorsque la dernière règle s'y
référant aura été supprimée.
block in on fxp0 from { <rfc1918>, <spammers> } to any
pass in on fxp0 from <goodguys> to any
Les adresses peuvent aussi être spécifiées en utilisant l'opérateur de
négation (ou "not"). Voici un exemple :
table <goodguys> { 192.0.2.0/24, !192.0.2.5 }
La table goodguys contient alors toutes les adresses dans le
réseau 192.0.2.0/24 excepté 192.0.2.5.
Notez que les noms de tables sont toujours entourés des chevrons < et
>.
Les tables peuvent aussi être peuplées à partir de fichiers texte
contenant une liste d'adresses et de réseaux IP :
table <spammers> persist file "/etc/spammers"
block in on fxp0 from <spammers> to any
Le fichier /etc/spammers doit contenir une liste d'adresses IP
et/ou des blocs réseau en notation
CIDR, une
entrée par ligne. Toute ligne commençant par # est traitée
comme un commentaire. Elle est donc ignorée.
Manipulation des Tables avec pfctl
Les tables peuvent être manipulées à la volée en utilisant
pfctl(8).
Par exemple, pour ajouter des entrées à la table <spammers>
précédemment créée :
# pfctl -t spammers -T add 218.70.0.0/16
Ceci aura aussi pour effet de créer la table <spammers> si elle
n'existe pas encore. Pour afficher le contenu d'une table :
# pfctl -t spammers -T show
L'argument -v peut aussi être utilisé avec -T show
pour afficher des statistiques pour chaque entrée de la table. Pour
supprimer des adresses de la table :
# pfctl -t spammers -T delete 218.70.0.0/16
Pour plus d'informations concernant la manipulation des tables avec
pfctl, veuillez consulter la page de manuel
pfctl(8).
Spécification des Adresses
Les hôtes peuvent être spécifiés par adresse IP ou par nom. Lorsque le
nom est résolu en adresse IP, toutes les adresses IPv6 et IPv4
résultantes sont placées dans la table. Les adresses IP peuvent aussi
être saisies dans la table en spécifiant le nom d'une interface valide
ou le mot-clé self.
La table contiendra alors toutes les adresses IP affectées à cette
interface ou à la machine (y compris les adresses de loopback),
respectivement.
Il existe une restriction : lorsque des adresses sont spécifiées, les
adresses 0.0.0.0/0 et 0/0 ne peuvent être utilisées
avec des tables. L'alternative consiste à coder en dur ces adresses ou
à utiliser une macro.
Recherche des Adresses Correspondantes
La recherche d'une adresse dans une table retournera l'entrée la plus
proche de cette adresse. Ceci permet la création de tables telles que :
block in on dc0 all
pass in on dc0 from <goodguys> to any
Tout paquet arrivant par dc0 verra son adresse source
recherchée dans la table <goodguys>:
172.16.50.5 - l'entrée la plus proche est 172.16.0.0/16; le paquet a
une entrée correspondante dans la table donc il passe
172.16.1.25 - l'entrée la plus proche est !172.16.1.0/24; le
paquet a une entrée correspondante mais celle-ci est en négation
(l'opérateur "!" est utilisé); le paquet n'a donc aucune entrée
correspondante et sera bloqué
172.16.1.100 - l'entrée la plus proche est 172.16.1.100; le
paquet a une entrée correspondante dans la table donc il passe
10.1.4.55 - n'a aucune adresse correspondante dans la table. Il sera
bloqué