%
Puffy image/svg+xml Puffy 2019-06-14 Stéphane HUC OpenBSD Team Inkscape Puffy OpenBSD https://www.openbsd.org/art4.html English "Puffy", it's a symbol of OpenBSD

PF : Packet Filter

Article publié, le et modifié le
21 minutes de lecture

Cet article contient 4418 mots.
Source brute de l'article :
Commit version : 698e16e

PF : Packet Filter

Cette documentation traitera de l’usage du gestionnaire de filtrage “pare-feu” nommé PF

L’outil pfctl permet de contrôler l’état du parefeu.

Le fichier /etc/pf.conf permet de gérer la configuration

Installation

Par défaut, rien à installer par soi-même… il est inclus de base.

Depuis la version 4.6 d’OpenBSD, il n’est plus nécessaire de l’activer, puisqu’il l’est par défaut.

Utilisation

Cette section traite de l’usage de l’outil pfctl :

Note : L’usage de l’outil pfctl nécessite des droits administrateur… pensez-y !

Quelques informations à-propos des options de pfctl :

  • l’option -d : arrête le parefeu
  • l’option -e : activer, vérifier l’état de pf
  • l’option -ef : activer le parefeu tout en ciblant le fichier de configuration, tel que : -ef /etc/pf.conf
  • l’option -f : permet de recharger les nouvelles règles à partir du fichier.
  • l’option -F : permet de vider toutes les règles et autres tables du parefeu
  • l’option -nf : permet de vérifier les règles écrites dans un fichier, sans les charger.
  • l’option -r : permet de faire du reverse dns
  • l’option -s : afficher les informations d’état… voir plus bas, pour plus d’infos.
  • l’option -t : spécifie une action précise sur une table particulière, tel que : -t <table_nom> -T command adr_ip
  • l’option -v : est le mode verbeux

De plus amples informations dans le manpage correspondant !

Configuration

Le fichier de configuration principal du pare-feu PF se nomme : /etc/pf.conf

Il est possible de créer des sous-fichiers de configuration qui seront appelés par la directive : include /etc/pf/filename.conf

Le fichier de configuration est décomposé en plusieurs sections :

  • déclarations de listes, macros, tables - de préférence - absolument en premier
  • gestion de la bande passante - au besoin, en suivant
  • déclaration des règles bloquantes, et/ou filtrantes - absolument en dernier

De plus amples informations dans le manpage correspondant !

Gestion des listes

Les listes définissent des critères multiples similaires, tels que les noms de ports, des numéros de protocoles, plusieurs adresses IP, etc.

Les listes sont définies en spécifiant les items par l’usage des crochets { }, chaque item pouvant être séparé soit par un espace, soit par une virgule.

block out on fxp0 from { 192.168.0.1, 10.5.32.6 } to any

Une liste peut contenir une autre liste imbriquée.

Là où les listes se trouvent limiter en usage, les macros prennent facilement le relais

Gestion des macros

Les macros sont l’équivalent de variables dans les langages informatiques.

Elles définissent une valeur ou un ensemble de valeurs… celles-ci peuvent être une ou plusieurs interfaces réseaux, une ou plusieurs adresses ip, un ou plusieurs numéros de ports, etc… voire une partie d’écriture de règles.

Les macros peuvent contenir des listes, d’autres macros.

⇒ Définition :

  • Les noms de ces macros doivent ABSOLUMENT commencer par une lettre, un chiffre ou le symbole _.
  • Il est interdit d’utiliser des mots réservés, tels que : pass, in, out

Ces macros, une fois définies, sont utilisées dans le contexte des règles.

⇒ Exemple :

iface = "em0"
http_ports = "{ 80 443 }"
  
pre = "pass in quick on ep0 inet proto tcp from "
post = "to any port { 80, 6667 }"

Pour plus d’informations, lire : https://www.openbsd.org/faq/pf/shortcuts.html#macros

Gestion des tables

Les tables sont une collection d’adresses et/ou de réseaux.

C’est une manière très efficace et puissante de gérer un ensemble d’informations, consommant moins de ressources processeur et mémoire.

À privilégier, plutôt qu’une liste de macros, dès que vous voulez gérer un ensemble d’adresses ip !

⇒ Définition :

  • Tout comme pour les macros, les noms réservés ne DOIVENT pas être utilisés !
  • Une table initialisée avec une liste vide { } sera purgée, lors du chargement…
  • Elles peuvent être définies en étant suivies d’un de ces trois attributs : const, counters, ou persist

⇒ Drapeaux :

  • const : empêche que la table soit ultérieurement altérée, une fois chargée.
  • counter : active le compte des bits et autres paquets par adresse ip.
  • persist : force le noyau à garder la table, même si aucune règle se réfère à elle. Ce drapeau permet l’ajout ultérieur d’informations…

⇒ Exemple :

iface = "axe0"
  
table <private> const { 10/8, 172.16/12, 192.168/16 }
table <badips> persist
  
block on $iface from { <private>, <badips> } to any

# pfctl -t badips -T add 204.92.77.111

Note : Une table peut être gérée par un ou plusieurs fichiers, qui seront une liste d’adresses ip ou de noms de machines. Une ligne commençant par le symbole dièse ‘#’ est considérée comme un commentaire et sera ignorée.

table <spam> persist file "/dir/filename1" 
  
block on fxp0 from <spam> to any

Gestion des ancres

Les ancres sont un ensemble de règles, qui peuvent être manipulées de manière dynamique.

Elles sont au jeu de règles, ce que les tables sont à la gestion dynamique des adresses ip ou réseaux.

Une ancre est une collection de règles… de tables… voire même d’ancres.

Attention : Pour nommer une ancre, veillez à ne pas utiliser un nom déjà défini auparavant, même s’il définit une table. L’outil pfctl vous avertira, sinon, d’une collision de noms dans l’espace global de noms… à juste titre !

⇒ Utilisation :

anchor nom_ancre {
    jeu de règles
}

L’ajout dynamique à la main peut se faire ainsi :

# echo "pass in proto tcp from 192.0.2.3 to any port 22" | pfctl -a nom_ancre -f -

Elles peuvent aussi être écrite dans un fichier, qui aura soit un jeu de règles définies, et/ou pourra être géré dynamiquement, tel que :

ancre nom_ancre
load nom_ancre from "/etc/pf/fichier_ancre"

Pour de plus amples informations, lire : https://www.openbsd.org/faq/pf/anchors.html

Gestion de la bande passante

Les paquets peuvent être assignés à une ou plusieurs queues, afin de gérer la bande passante.

Il faut définir au moins une queue pour la configurer, et ensuite créer des règles qui feront référence à la queue par son nom. Si une queue appelée n’existe pas pour une interface réseau, c’est la queue par défaut qui sera utilisée.

Il DOIT y avoir une queue maître, qui fait référence spécifiquement à une interface réseau. Les autres queues, appelées enfants, sont créées relativement à la queue maître.

⇒ Exemple :

iface = "em0"
  
queue rq on $iface bandwidth 100M 
queue ssh parent rq bandwidth 10M
queue http parent rq bandwidth 80M
queue std parent rq bandwidth 10M default 
  
block return out on $iface inet all set queue std 

⇒ Définition des mots clés réservés :

  • default : spécifie la queue par défaut
  • on : spécifie une interface réseau
  • parent : attache une queue à une queue maître
  • qlimit : définit le nombre maximum de paquets capturés dans une queue. Par défault : 50

⇒ Définition de valeurs de bande passante :

Les valeurs de bande passante DOIVENT absolument être des entiers ; ces valeurs peuvent être suffixées des lettres suivantes K, M, ou G, qui respectivement représentent le nombre de bits par secondes gérés, tels que Kilobits, Megabits, ou Gigabits.

Ces valeurs ne doivent pas dépasser la taille de la bande passante allouée à une interface réseau !

⇒ Attributs possibles :

  • max : spécifie la limite maximale de bande passante allouée à une queue
  • min : cible la taille minimale, réservée, de bande passante à une queue donnée
  • burst : est un attribut qui permet à une bande passante d’être outrepassée dans un laps de temps donnée, pour une queue précise

⇒ Exemples :

queue ssh parent std bandwidth 10M, min 5M, max 25M
  
queue ssh parent std bandwidth 10M burst 90M for 100ms

Gestion des règles

La première des règles la plus basique, et sécuritaire est celle de tout bloquer :

block

Règles de syntaxe

Il existe des règles de grammaire et de simplifications d’écriture des règles PF.

Règles “block”

⇒ Cela ne sert à rien d’écrire ce qui suit :

  block in all
  block out all

Ni :

block all

Écrire block suffit !


⇒ De même, il ne sert à rien de spécifier :

block drop

ou :

block return

⇒ Sauf à utiliser ces mots-clés, dans le contexte de certaines règles PF, spécifier la politique de rejet, puis utiliser juste le mot clé block, tel que :

set block-policy return
  
block

Autres règles

L’usage du mot clé reservé all ou de l’expression réservé from any to any ne servent à rien non plus. Ce sont des règles implicites, par défaut !

Pour plus d’informations, lire : https://www.openbsd.org/faq/pf/shortcuts.html#grammar

Recommandations

Suivi de connexions

Le mot clé keep state permet de gérer le suivi de connexion des flux sur les protocoles TCP, UDP et/ou ICMP. Ce mot clé permet de gérer les messages ICMP relatifs à la régulation du trafic, tel que les messages “source quench”, de fait il n’y a pas besoin de créer de règles spécifiques.

TCP

Pour s’assurer de n’autoriser QUE les nouvelles connexions, ou plutôt l’initiation de nouvelles connexions, on utilisera seulement les drapeaux S/SA - SYN sans ACK -… le suivi de connexion gérera le reste correctement.

⇒ Exemple :

pass in on em0 proto tcp flags S/SA keep state

Note : c’est une bonne habitude à prendre de gérer l’état de connexion à partir de nouvelles initialisation !

Veuillez lire la page de la FAQ Filter pour mieux comprendre ce qu’est la notion de suivi d’états, la syntaxe des règles PF à-propos des états, les différentes options possibles, etc…

Informations d’états

Ainsi que vu plus haut, en début de page, c’est l’option -s qui permet d’obtenir différentes informations relatives aux états du pare-feu. Cette option utilise des drapeaux pour afficher différemment les informations.

# pfctl -s flag

⇒ Définition des drapeaux :

  • Voir toutes les informations : -sa

    • ne pas confondre avec l’option pour voir les ancres !
  • info : affiche les statistiques globales

    • version abrégée : -si
  • nat : affiche les informations de traduction d’adresses réseaux, de type nat, et rdr.

  • rules : affiche les règles de filtrage chargées en mémoire - un peu, l’équivalent des options ‘-Lnv’ à iptables

    • version abrégée : -sr
  • state : affiche l’état des connexions ouvertes.

    • version abrégée : -ss
  • Anchor : option -s Anchor, avec ou sans un ’s’ final, permet de connaître le nom des tables utilisées. Les ancres peuvent aussi être gérées en utilisant directement l’option -sa, ainsi que l’ajout d’un de ses drapeaux -f, -F, ou -s

  • Label : option -s label, avec ou sans un ’s’ final, permet d’obtenir les informations liées à des labels.

    • version abrégée : -sl
  • Queue : option -s queue

    • version abrégée : -sA - avec un A majuscule ;
    • à ne pas confondre avec les ancres !
  • Table : option -s Tables, avec ou sans un ’s’ final, permet de connaître le nom des tables utilisées. Si une table est gérée par une ancre, il est possible de la contrôler en appelant d’abord l’ancre puis la table, telle que : pfctl -a ancre -t table -T command

    • version abrégée : -sT

Note : Pensez à utiliser l’option -vs, voire -vvs qui permet d’avoir un état plus complet de l’information recherchée, si celui est possible.

Pour de plus amples informations, veuillez lire le manpage correspondant à l’outil ‘pfctl’

PF : Nombre maximum d’états

Par défaut, PF gère un nombre maximal d’entrées dans sa table d’états qui est de 10 000.

Pour connaître le nombre d’entrées dans la table d’états, en cours : # pfctl -ss | wc -l

Si et seulement si vous êtes proche de cette limite, vous pouvez agrandir le nombre d’entrées dans la table, en paramétrant votre fichier /etc/pf.conf, tel que : set limit states 20000

Exemples

Ci-dessous, retrouvez un exemple basique de règles PF qui sont donnés pour le flux sur ipv4. Il faudra faire les modifications nécessaires pour ipv6 ;)

PF pour station

Version minimale

block
pass out all keep state

Ces deux règles “disent” :

  • refusent tout le trafic entrant
  • accepte le trafic sortant et relatif aux connexions.

Version améliorée

#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

table <t_bogons> persist file "/etc/pf_table_bogons"

set block-policy return
set optimization normal
set reassemble yes
set ruleset-optimization none
set skip on lo

antispoof for egress

match in all scrub (max-mss 1440 no-df random-id reassemble tcp)

block drop in quick on egress from { <t_bogons> } to any
block drop out quick on egress from any to { <t_bogons> }

# By default, do not permit remote connections to X11
block in on ! lo0 proto tcp to port 6000:6010
# Prevent dns leaks : best to use with unbound, dnscrypt-proxy
block in log on egress inet proto { tcp udp } from any to ! egress port 53

block           # block stateless traffic
pass            # establish keep-state

⇒ Quelques petites explications :

  • egress est un nom définissant toute(s) le(s) interface(s) réseau(x) correspondant à la ou le(s) route(s) par défaut, vers la ou le(s) passerelles. La règle antispoof est une mesure de protection dite ’no spoofing’, afin que ne soit possible de lui “piquer” son ou ses adresses réseau(x).
  • on charge une table contenant les segments réseaux appelés BOGON ne devant pas se trouver sur le net. Est supprimé tout trafic correspondant, sans aucun état d’âme, en entrée et en sortie. Le fichier /etc/pf_table_bogons est donné en exemple ci-dessous !

PF pour serveur

Les deux versions basiques de règles PF sont exactement les mêmes - la deuxième utilise plus profondément les listes et macros pour ne pas avoir à réécrire certaines portions !

Version normale

#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

# lists, macros
auth_tcp_ports ="{ http ftp whois }" # ajouter imap, smtp, rsync ou autres flux TCP nécessaires en sortie
auth_tcps_ports = "{ https }" # ajouter imaps, smtps ou autres flux TCP "secure" nécessaires en sortie
auth_udp_ports = "{ domain }" # ajouter tout flux UDP nécessaire en sortie

web_ports = "{ http https }" # modifier entrée services web

table <t_bogons> persist file "/etc/pf_table_bogons"
table <t_abuse_ssh> persist
table <t_abuse_web> persist

set block-policy return
set optimization normal
set reassemble yes
set ruleset-optimization none
set skip on lo

antispoof for lo
antispoof for egress

#scrub in all fragment reassemble no-df max-mss 1440 <= old version; do not using-it!
match in all scrub (max-mss 1440 no-df random-id reassemble tcp)

# Prevent dns leaks : best to use with unbound, dnscrypt-proxy
block in log on egress inet proto { tcp udp } from any to ! egress port 53

block drop in quick on egress from { <t_bogons> } to any
block drop out quick on egress from any to { <t_bogons> }

# block abuses
block in log quick proto tcp from <t_abuse_ssh> to any port ssh
block in log quick proto tcp from <t_abuse_web> to any port $web_ports

block           # block stateless traffic

# pass few udp ports
pass quick inet proto icmp all icmp-type { echoreq, unreach }
pass proto udp from any to egress port mdns allow-opts

# pass in
pass in on egress proto tcp to any port ssh flags S/SA modulate state (max-src-conn-rate 3/60, overload <t_abuse_ssh> flush global)
pass in on egress proto tcp to any port $web_ports flags S/SA modulate state (max-src-conn 100, max-src-conn-rate 40/5, overload <t_abuse_web> flush global)

# pass out
pass out log on egress proto tcp to any port $auth_tcp_ports modulate state
pass out log on egress proto tcp to any port $auth_tcps_ports modulate state
pass out on egress proto udp to any port $auth_udp_ports allow-opts keep state

Version améliorée

#       $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

# lists, macros
auth_tcp_ports ="{ http ftp whois }" # ajouter imap, smtp, rsync ou autres flux TCP nécessaires en sortie
auth_tcps_ports = "{ https }" # ajouter imaps, smtps ou autres flux TCP "secure" nécessaires en sortie
auth_udp_ports = "{ domain ntp mdns }" # ajouter tout flux UDP nécessaire en sortie

# ports
web_ports = "{ http https }" # modifier entrée services web

# statefull tracking options - sto
ssh_sto = "(max-src-conn-rate 3/60, overload <t_abuse_ssh> flush global)"
web_sto = "(max-src-conn 100, max-src-conn-rate 40/5, overload <t_abuse_web> flush global)"

# state
flag_syn = "flags S/SA modulate state"

# others
edropin = "block drop in quick on egress from"
edropout = "block drop out quick on egress from"
epassout = "pass out log on egress proto tcp to any port"
inblocktcp = "block in log quick proto tcp from"
inpasstcp = "pass in on egress proto tcp to any port"

table <t_bogons> persist file "/etc/pf_table_bogons"
table <t_abuse_ssh> persist
table <t_abuse_web> persist

set block-policy return
set optimization normal
set reassemble yes
set ruleset-optimization none
set skip on lo

antispoof for { lo, egress }

#scrub in all fragment reassemble no-df max-mss 1440 <= old version; do not using-it!
match in all scrub (max-mss 1440 no-df random-id reassemble tcp)

# Prevent dns leaks : best to use with unbound, dnscrypt-proxy
block in log on egress inet proto { tcp udp } from any to ! egress port 53

$edropin { <t_bogons> } to any
$edropout any to { <t_bogons> }

# block abuses
$inblocktcp <t_abuse_ssh> to any port ssh
$inblocktcp <t_abuse_web> to any port $web_ports

block           # block stateless traffic

# pass few udp ports
pass quick inet proto icmp all icmp-type { echoreq, unreach }
pass proto udp from any to egress port mdns allow-opts

# pass in
$inpasstcp ssh $flag_syn $ssh_sto
$inpasstcp $web_ports $flag_syn $web_sto

# pass out
$epassout $auth_tcp_ports $flag_syn
$epassout $auth_tcps_ports $flag_syn
pass out on egress proto udp to any port $auth_udp_ports allow-opts

table bogons

Ces adresses ne doivent en aucun cas se retrouver sur Internet - malheureusement de petits malins les utilisent, d’où la raison de les filtrer !

Le fichier /etc/pf_table_bogons doit contenir des adresses CIDR, telles que :

0.0.0.0
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
128.0.0.0/16
169.254.0.0/16
172.16.0.0/12
191.255.0.0/16
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
#192.168.0.0/16
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
223.255.255.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255

⇒ Pour information :

  • 10.0.0.0/8 # private network ( RFC 1918 )
  • 100.64.0.0/10 # cf RFC 6598
  • 127.0.0.0/8, 128.0.0.0/16 # Loopback ( RFC 1122 ), IANA reservations ( RFC 3330 )
  • 169.254.0.0/16, 172.16.0.0/12 # Link Local Block ( RFC 3927 ), private network ( RFC 1918 )
  • 191.255.0.0/16, 192.0.0.0/24, 192.0.2.0/24, 192.88.99.0/24 # ?, IETF Protocol 5 ( RFC 5736 ), Test-Net 1 ( RFC 1166 ), 6to4 Relay Anycast ( RFC 3068 )
  • 192.168.0.0/16 # privates classes networks ( RFC 1918 ) <= à commenter pour pouvoir “contacter” stations/serveurs locaux
  • 198.18.0.0/15, 198.51.100.0/24 # Network Interconnect Device Benchmark Testing ( RFC 2544 ), Test-Net 2 ( RFC 5737 )
  • 203.0.113.0/24, 223.255.255.0/24, 224.0.0.0/4, 240.0.0.0/4 # Test-Net 3 ( RFC 5737 ), ?, Class D Reserved ( RFC 3171 ), Class E Reserved ( RFC 1112 ),…
  • 255.255.255.255 # limited broadcast destination address

Note : Le site Team Cymru met à jour une liste + ou - régulière des adresses dites “bogons”…

Table badips

De même que la table gérant les réseaux bogons, il est possible d’utiliser des listes sur internet pour filtrer des adresses IP et/ou des segments entiers de réseaux, qui sont reconnus par plusieurs entités, elles-mêmes reconnues officiellement ou non, pour aider à lutter contre.

table <t_badips> persist file "/dir/badips_ipv4" counters
table <t_badips6> persist file "/dir/badips_ipv6" counters

block drop in quick on egress from { <t_badips> } to any
block drop out quick on egress from any to { <t_badips> }

block drop in quick on egress inet6 from { <t_badips6> } to any
block drop out quick on egress inet6 from any to { <t_badips6> }

Astuces

Les astuces concernant ICMP, ICMPv6, et Traceroute sont tirées du livre “The Book of PF” !

Retrouvez une “cheat sheet"…

Info

ICMP, ICMPv6

# macros
icmp_types="{ echoreq unreach }"
icmp6_types="{ unreach toobig timex paramprob echoreq routeradv neighbrsol neighbradv }"
(…)
# icmp (pass in+out)
pass quick inet proto icmp icmp-type $icmp_types
pass quick inet6 proto icmp6 icmp6-type $icmp6_types

Note : N’hésitez pas à lire les manpages icmp(4) et icmp6(4)

Avahi (mDNS, SSDP)

Voici des règles IPv4 et IPv6 pour le trafic multicast et SSDP liés à la bibliothèque Avahi !

⇒ pour le trafic mDNS :

pass proto udp from any to 224.0.0.251 port mdns allow-opts
pass inet6 proto udp from any to ff02::fb port mdns allow-opts 

⇒ pour le trafic SSDP :

  • pour IPv6 :
    • ‘‘ff02::c’’ est l’adresse multicast de lien local
    • ‘‘ff05::c’’ est l’adresse multicast de site local
    • ‘‘ff08::c’’ est l’adresse multicast d’organisation local
    • il existe aussi ‘‘ff0e::c’’ pour l’adresse multicast global - que nous n’utiliserons pas dans le contexte local !
pass proto udp from any to 239.255.255.250 port ssdp allow-opts
pass inet6 proto udp from any to { ff02::c, ff05::c, ff08::c } port ssdp allow-opts 

multiports

Exemple pour du flux torrent : 6881:6891

pass in quick on egress inet proto tcp from any to 192.168.0.3 port 6881:6891 flags S/SA

samba

smb_ports_tcp = "{ 135 137 139 445 }"
smb_ports_udp = "{ 135 137 138 445 }"

# samba in
pass in quick on egress proto tcp from egress:network to egress port $smb_ports_tcp flags S/SA modulate state
pass in quick on egress proto udp from egress:network to egress port $smb_ports_udp allow-opts keep state

# samba out
pass out on egress proto tcp from egress to egress:network port $smb_ports_tcp flags S/SA modulate state
pass out on egress proto udp from egress to egress:network port $smb_ports_udp allow-opts keep state

syncthing

# syncthing in
pass in quick on egress inet proto tcp from { 192.168.1.0/24 } to egress port 22000 flags S/SA modulate state
pass in quick on egress inet proto udp from { 192.168.1.0/24 } to egress port 21027

# syncthing out
pass out quick on egress inet proto tcp from egress to { 192.168.1.0/24 } port 22000 flags S/SA modulate state
pass out quick on egress inet proto udp from egress to { 192.168.1.0/24 } port 21027

Traceroute

Il n’est pas forcément nécessaire de créer des règles pour utiliser l’outil traceroute, en effet l’option -I permet de l’utiliser en ciblant UDP. Néanmoins, si vous souhaitez obtenir le comportement par défaut, il faut utiliser les règles suivantes :

pass out on egress inet proto udp to port 33433:33626 # For IPv4
pass out on egress inet6 proto udp to port 33433:33626 # For IPv6

Note : N’hésitez pas à lire le manpage traceroute(8)

Personnalisation Shell

Rajoutez dans votre fichier ~/.kshrc, les alias suivants :

alias pf_clean_all="doas pfctl -F all"
alias pf_clean_counters="doas pfctl -z"
alias pf_clean_info="doas pfctl -F info"
alias pf_clean_queue="doas pfctl -F queue"
alias pf_clean_rules="doas pfctl -F rules"
alias pf_edit="doas nano /etc/pf.conf"
alias pf_info="doas pfctl -si"
alias pf_info_tables="doas pfctl -vvsT"
alias pf_less="doas pfctl -vf /etc/pf.conf"
alias pf_load_table="doas pfctl -T load -f /etc/pf.conf"
alias pf_reload="doas pfctl -f /etc/pf.conf"
alias pf_restart="doas pfctl -d && doas pfctl -ef /etc/pf.conf"
alias pf_start="doas pfctl -ef /etc/pf.conf"
alias pf_stop="doas pfctl -d"
alias pf_test="doas pfctl -nf /etc/pf.conf"
alias pf_view="doas pfctl -sr"
alias pf_view_tables="doas pfctl -sT"
alias pf_watch="doas tcpdump -n -e -ttt -i pflog0"

Exécutez à nouveau : . .kshrc

Maintenant, vous pourrez vous faciliter la vie, en exécutant un des alias, commençant par pf_* ;-)


Informations avancées

ICMP, ICMPv6

ATTENTION : les recommandations de l’IETF - Internet Engineering Task Force -, voire de l’IANA - Internet Assigned Numbers Authority - sont de supprimer : drop - impérativement les codes suivants :

⇒ ICMP :

  • 3/6 - Destination Network Unknown
  • 3/8 - Source Host Isolated
  • 4/0 - Source Quench <= voire de journaliser !
  • 15/0 - Information Request Message
  • 16/0 - Information Reply Message

⇒ ICMP v6 :

  • le code 137 - Redirect Message
  • le code 138 - Router Renumbering
  • le code 139 - ICMP Node Information Query
  • le code 140 - ICMP Node Information Response
  • le code 144 - Home Agent Address Discovery Request Message
  • le code 145 - Home Agent Address Discovery Reply Message
  • le code 146 - Mobile Prefix Solicitation
  • le code 147 - Mobile Prefix Advertisement

Note : Il semble, selon le manpage icmp6(4), que les codes 144 à 147 ne soient pas gérés… par OpenBSD !

L’IANA recommande aussi de filtrer - soit drop, soit reject - à la discrétion de l’administrateur - tous les codes suivants :

⇒ ICMP :

  • code 6/0 - Alternate Host Address
  • code 15 - Information Request
  • code 16 - Information Reply
  • code 17 - Address Mask Request
  • code 18 - Address Mask Reply
  • code 30 - Traceroute
  • code 31 - Datagram Conversion Error
  • code 32 - Mobile Host Redirect
  • code 33 - IPv6 Where-Are-You
  • code 34 - IPv6 I-Am-Here
  • code 35 - Mobile Registration Request
  • code 36 - Mobile Registration Reply
  • code 37 - Domain Name Request
  • code 38 - Domain Name Reply
  • code 38 - SKIP

Les autres codes, icmp et icmp6, sont à “limiter” en entrée et/ou en sortie… Pour en savoir plus, veuillez ABSOLUMENT vous informer - cf, la documentation dans la note finale !

Ce qui donne pour le propos les règles suivantes :

# macros
blockicmp = "block drop quick on egress inet proto icmp icmp-type"
blockicmplog = "block drop quick log on egress inet proto icmp icmp-type"
blockicmp6 = "block drop quick on egress inet6 proto icmp6 icmp6-type"

inpassicmplan = "pass in quick on egress inet proto icmp from egress:network to egress icmp-type"
inpassicmpwan = "pass in quick on egress inet proto icmp from any to egress icmp-type"

outpassicmplan = "pass out quick on egress inet proto icmp from egress to egress:network icmp-type"
outpassicmpwan = "pass out quick on egress inet proto icmp from egress to any icmp-type"

icmp6_types="{ echoreq unreach timex paramprob }"

# statefull tracking options
icmp_sto = "keep state (max-src-conn-rate 3/1)"

(…) # autres macros

set block-policy return

(…) # autres set

# block icmp
$blockicmp 3 code 6
$blockicmp 3 code 8
$blockicmplog 4
$blockicmp 6
$blockicmp 15
$blockicmp 16

$blockicmp6 137
$blockicmp6 138
$blockicmp6 139
$blockicmp6 140
$blockicmp6 144
$blockicmp6 145
$blockicmp6 146
$blockicmp6 147

(…) # autres block si nécessaires

block

(…) 

# icmp in
$inpassicmplan 0 $icmp_sto
$inpassicmplan 3 code 0 $icmp_sto
$inpassicmplan 3 code 1 $icmp_sto
$inpassicmpwan 3 code 3 $icmp_sto
$inpassicmpwan 8 $icmp_sto
$inpassicmpwan 11 $icmp_sto
$inpassicmplan 12 $icmp_sto
# icmp out
$outpassicmplan 0 $icmp_sto
$outpassicmplan 3 code 0 $icmp_sto
$outpassicmplan 3 code 1 $icmp_sto
$outpassicmpwan 3 code 3 $icmp_sto
$outpassicmpwan 8 $icmp_sto
$outpassicmpwan 11 $icmp_sto
$outpassicmplan 12 $icmp_sto
# icmpv6 (in+out)
pass quick inet6 proto icmp6 icmp6-type $icmp6_types $icmp_sto

Documentation


Historique

J’ai écrit historiquement cette documentation sur le wiki de la communauté “OpenBSD Pour Tous”.