wiki/HowtoOpenBSD/PacketFilter.md

7.9 KiB

categories title
openbsd network firewall Howto PacketFilter

Tips & Astuces

Général

Activer PacketFilter :

Note : Attention, comme les règles qui seront activées n'auront pas d'état, pf va couper toutes les connexions.

# pfctl -e

Désactiver PacketFilter :

# pfctl -d

Vérifier la configuration sans la charger :

# pfctl -nf /etc/pf.conf

Recharger la configuration :

# pfctl -f /etc/pf.conf

Utilisation détaillée

Observation

Voir la QoS en temps réel :

# systat queue
# pfctl -s queue -vv

Voir toutes les règles actuellement en place :

# pfctl -sr

Voir toutes les règles actuellement en place, avec les statistiques :

# pfctl -vsr

Obtenir la règle numéro 42 :

# pfctl -sr -R42

Liste des états :

# pfctl -s states | less

Liste des états avec statistiques, notamment l'âge et l'expiration de l'état :

# pfctl -vs states | less

Obtenir le nombre d'états :

# pfctl -si | grep curr

Toutes les infos sur PF :

# pfctl -sa | less

Action

Flush des états :

# pfctl -F states

Gestion des tables :

# pfctl -t <table> -T show/flush/kill/add/delete

Logs

Voir les logs :

# tcpdump -n -e -ttt -r /var/log/pflog

Voir les vieux logs :

# zcat /var/log/pflog.0.gz |tcpdump -ne -ttt -r -

Voir les logs en temps réel :

# tcpdump -n -e -ttt -i pflog0

Cas d'utilisation

Limite d'état spécifique à une règle

Si une machine est souvent la cible d'attaques pouvant remplir la table d'états, une limite spécifique à une règle peut être mise en place afin de ne pas atteindre la limite globale qui bloquerait la création de nouveaux états.

pass in quick on $if proto tcp from any to 192.0.2.10 port { 80, 443 } keep state (max 50000)

Ainsi, au maximum 50 000 états pourront être créés pour 192.0.2.10:80 et 192.0.2.10:443, soit un total de 100 000 états pour l'ensemble.

Attention, les 2 limites (la globale et celle spécifique à la règle) ne sont pas séparées. Si la limite globale est configuré à 150 000 (set limit states 150000) et que 50 000 états sont atteints pour 192.0.2.10:80, alors il ne restera que 100 000 états possible globalement.

Routage particulier (avec route-to)

Pour avoir un routage spécifique, i.e. différent de celui donné par la table de routage, on peut agir avec le mot-clé route-to.

Généralement c'est sous la forme

pass in on $lan_if ... to ! <lan> route-to ($otherext_if 192.0.2.254)

Cela ne matche que pour le lan et non pas pour le routeur lui-même. Dans ce cas, on peut utiliser une règle du type

pass out from $egress:0 ... route-to 192.0.2.254@$otherext_if nat-to 192.0.2.253

La partie nat-to est nécessaire car sinon les paquets vont partir avec l'IP de l'interface principale et l'opérateur réseau en face va voir cela comme une usurpation et va refuser le paquet

Options nat-to vs rdr-to vs binat-to

L'option nat-to permet de traduire l'adresse IP d'une machine depuis un réseau local vers l'extérieur. Utile par exemple pour qu'une machine ayant une IP privée puisse joindre Internet en utilisant une IP publique.

match out on $ext_if from 10.0.2.1 nat-to 192.0.2.1

L'option rdr-to permet de rediriger le trafic arrivant depuis Internet sur une IP et un port particulier du pare-feu vers une autre IP et un autre port d'une machine interne à un réseau. Utile par exemple pour qu'une machine ayant une IP privée puisse être joignable depuis Internet avec une IP publique.

pass in proto tcp from 192.0.2.1 to self rdr-to 10.0.2.1

L'option binat-to combine les effets de nat-to et rdr-to en une seule règle. Une machine ayant une IP privée dans un réseau local peut alors sortir avec une IP publique et être joignable depuis l'extérieur par cette même IP publique, qui n'est pourtant pas attribuée directement à la machine.

match on $ext_if from 10.0.2.1 binat-to 192.0.2.1

Répondre par la même interface par laquelle une requête arrive

Si un routeur a deux sorties et qu'on le joint par la connexion secondaire, la réponse se fera par la principale en suivant la route par défaut.

On peut modifier ce comportement, pour que la réponse sorte forcément par là où elle est arrivée :

pass in quick on $wan1 from … to self reply-to {($wan1 $wan1_gw)}
pass in quick on $wan2 from … to self reply-to {($wan2 $wan2_gw)}

Note : Attention, l'IP autorisée par cette règle aura un accès complet au routeur.

Tuer un état selon son ID

On peut voir l'ensemble des états d'un firewall et leur ID :

# pfctl -vvss
all udp 2001:db8:1::1[48110] -> 2001:db8:2::1[53]       MULTIPLE:SINGLE
   age 00:00:00, expires in 00:00:30, 1:1 pkts, 88:231 bytes, rule 15
   id: 57dbc2163a63f98b creatorid: 3a22c108

Puis tuer l'état en spécifiant son ID :

# pfctl -k id -k 57dbc2163a63f98b

On peut ainsi tuer par exemple tous les états UDP :

for _ID in $(pfctl -vvss | grep -A2 'all udp' | grep id | awk '{print $2}') ; do echo "${_ID}" ; pfctl -k id -k "${_ID}" ; done

FAQ

pfctl: warning: namespace collision with <table> global table.

Il faut a priori effacer la table avec

# pfctl -t <table> -T kill

Valeurs des timeout

D'après le man :

     set optimization environment
             Optimize state timeouts for one of the following network
             environments:

             aggressive
                     Aggressively expire connections.  This can greatly reduce
                     the memory usage of the firewall at the cost of dropping
                     idle connections early.
             conservative
                     Extremely conservative settings.  Avoid dropping
                     legitimate connections at the expense of greater memory
                     utilization (possibly much greater on a busy network) and
                     slightly increased processor utilization.
             high-latency
                     A high-latency environment (such as a satellite
                     connection).
             normal  A normal network environment.  Suitable for almost all
                     networks.
             satellite
                     Alias for high-latency.

Comparaison des valeurs des modes aggressif et normal

                 Agressive          Normal
tcp.first              30s            120s
tcp.opening             5s             30s
tcp.established     18000s          86400s
tcp.closing            60s            900s
tcp.finwait            30s             45s
tcp.closed             30s             90s
tcp.tsdiff             10s             30s
udp.first              60s             60s
udp.single             30s             30s
udp.multiple           60s             60s
icmp.first             20s             20s
icmp.error             10s             10s
other.first            60s             60s
other.single           30s             30s
other.multiple         60s             60s
frag                   60s             60s
interval               10s             10s
adaptive.start      6000 states     6000 states
adaptive.end       12000 states    12000 states
src.track               0s              0s

À titre d'indication, en mode satellite

tcp.first                   180s
tcp.opening                  35s
tcp.established           86400s
tcp.closing                 905s
tcp.finwait                  50s
tcp.closed                   95s
tcp.tsdiff                   60s
udp.first                    60s
udp.single                   30s
udp.multiple                 60s
icmp.first                   20s
icmp.error                   10s
other.first                  60s
other.single                 30s
other.multiple               60s
frag                         60s
interval                     10s
adaptive.start             6000 states
adaptive.end              12000 states
src.track                     0s