c'est un stateful firewall (décisions basées sur l'état d'une connexion logique)
il utilise la notion de macros (variables à expanser), ce qui permet de paramétrer le jeu de règle ; ce qui facilite la maintenance et améliore la portabilité ;
il utilise des tables (de hachage) qui permettent de stocker de large plage d'adresses, tout en assurant un temps d'accès constant ;
il implémente le NAT (ré-écriture des adresses sources en sortie) et la redirection (ré-écriture des adresses destination en entrée) ;
il opère dans le mode de la « dernière correspondance gagnante », mais propose un mode de court-circuit avec le mot clé quick ;
il propose une fonction de normalisation de trafic (scrub) qui annule toutes ambiguïtés dans les paquets reçus et à transmettre aux destinataires (en entrée ou en sortie) ;
il supporte nativement plusieurs méthodes implémentant le contrôle de bande passante (par gestion de files de priorités selon différents algorithmes)
il dispose d'un mécanisme implicite d'ordonnancement des règles ;
il dispose d'un excellent mécanisme de log et de statistiques.
Si PF est disponible directement sous OpenBSD, sa mise en oeuvre sous FreeBSD implique généralement la recompilation du noyau, ou le chargement dynamique du module pf :
Exemple 2. Chargement automatique du module pf sous FreeBSD, fichier /boot/loader.conf
pf_load="YES"
pflog_load="YES"
Exemple 3. Modification du noyau
device pf
device pflog
device pfsync
options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
Dans les deux cas, il est nécessaire d'intervenir sur le fichier /etc/rc.conf pouyr activer PF au démarrage de la machine, et charger les jeux de règles :
Exemple 4. Fichier rc.conf
pf_enable="YES" # Enable PF (load module if required)
pf_rules="/etc/pf.conf" # rules definition file for pf
pf_flags="" # additional flags for pfctl startup
pflog_enable="YES" # start pflogd(8)
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
pflog_flags="" # additional flags for pflogd startup
gateway_enable="YES" # Enable as LAN gateway
PF possède un puissant outil de manipulation des règles, des tables et de collecte de statistiques, pftcl.
pfctl [ [-AdeghmNnOqRrvz] [-a anchor] [-D macro= value] [-F modifier]
[-f file] [-i interface] [-K host | network] [-k host | network]
[-o [level]] [-p device] [-s modifier] [-t table -T command
[address ...]] [-x level]]
Exemple 5. Utilisations de la commande pfctl
# pfctl -d //désactiver pf # pfctl -e //activer pf # pfctl -f /etc/pf.conf -n //tester le fichier de configuration # pfctl -f /etc/pf.conf -v //charger en mode verbeux le fichier de conf # pfctl -sr //afficher le jeux de règles en cours # pfctl -s info //statistiques de filtrage # pfctl -t banned -T show //afficher le contenu de la tablebanned# pfctl -t banned -T add 192.168.0.12/32 //ajouter un hôte à la tablebanned
Lorsque les directives de « log » sont activés, les paquets voulus sont envoyés vers la pseudo interface pflog0. Cette pseudo interface réseau est alors directement atteignable via les classiques outils d'analyse réseau :
Exemple 6. Analyse temps réel de l'activité de PF :
# tcpdump -netvli pflog0
rule 9/(match) [uid 0, pid 2208] block in on em0: 172.17.10.31.1900 > 239.255.255.250.1900: udp 318 (ttl 127, id 51797, len 346)
rule 1/(match) [uid 0, pid 2208] block in on em0: 172.17.8.6.138 > 172.17.8.127.138: udp 201 (ttl 128, id 6662, len 229)
rule 1/(match) [uid 0, pid 2208] block in on em0: 172.17.8.6.138 > 172.17.8.127.138: udp 201 (ttl 128, id 6662, len 229, bad cksum 0!)
....
Cette facilité d'analyse rend PF bien plus agréable à utiliser que Netfilter/Iptables sous Linux ! En effet, par la