De IPFW à PF

Date: 28/08/2008 | Catégories: Open-source,Reseau | Tags: ,

istockphoto_143506_burning_fire_wall.jpgFidèle utilisateur de l'operating système FreeBSD pour toutes les fonctions réseaux (notamment les Firewall), je suis tombé il y a quelques temps sur un problème d'interopérabilité entre l'utilisation du couple CARP/PFSYNC (le truc pour faire de la redondance de Firewall) avec IPFW.

J'ai donc décidé de switcher de IPFW vers PF. Je vais donc abordé dans ce billet les quelques choses à avoir en tête si vous suivez le même chemin… Si vous souhaitez vous formez sur PF, je vous conseille la lecture de l'excellent article paru dans Linux Magazine HS n°29, dont vous trouverez une version électronique ici.

Un peu d'histoire

IPFW (IPFireWall) est un module logiciel permettant de faire du filtrage de paquets réseau sous BSD (c'est actuellement le module de firewall utilisé par défaut sous Mac OS X).

Jusqu'à la version 3.0 de OpenBSD, ce module était intégré par défaut au noyau du système, mais de sombres histoires de licences et de batailles interne entre Darren Reed (l'auteur de IPFW) et les développeurs d'OpenBSD ont débouché par son remplacement par PF (Packet Filter).

PF est maintenant fourni en standard sur l'OS FreeBSD (depuis la version 5.3).

Les principales différences entre IPFW et PF

Voici une liste non-exhaustive:

  • le fichier de configuration unique (/etc/pf.conf) comprend, la définition des règles (comme sous IPFW) mais aussi la configuration du NAT et du PAT (délégué au processus IPNAT avec IPFW)
  • comportement atomique du chargement de la configuration: si une erreur est détectée dans le fichier de configuration, aucune règle n'est appliquée
  • l'interprétation des règles est de type “last matching rules wins”: la dernière règle qui correspond au paquet est appliquée
  • le suivi de connexions complexes comme FTP se fait via un module externe (ftp-proxy)
  • il est possible de rediriger les paquets en fonction de l'OS émetteur (ne marche pas dans tout les cas de figures)
  • assure une compatibilité native avec CARP et PFSYNC pour faire de la redondance active de Firewall

Architecture du fichier de configuration /etc/pf.conf

Le fichier comporte plusieurs sections (l'ordre est important).

1) Définition des macros, listes et des tables

En plus des listes (comme sous IPFW), il est possible d'utiliser des tables pour stocker des adresses IP. L'avantage des tables par rapport aux listes est la rapidité d'accès à l'information. En effet, basées sur des tables de hachage, le temps pour accéder à une information est constant quel que soit la taille de la table. De plus il est possible de modifier dynamiquement ces tables (à l'aide de la commande “pfctl -t …”) sans avoir à recharger les règles.

Quelques exemples de macros:

Définition

ip_interne=”192.168.1.254”

ip_externe=”80.80.80.80”

Utilisation dans les règles

pass quick proto tcp from $ip_interne to any port 80

pass quick from $lan_interne to any keep state

Quelques exemples de listes:

Définition

lan_interne=”{ 192.168.1.0/24 192.168.2.0.24 }”

lan_interne_saufdmz=”{ 192.168.1.0/24 192.168.2.0.24 !192.168.2.0/29 }”

web_ports=”{ http https ftp }”

Utilisation dans les règles

pass quick from $lan_interne to any keep state

Quelques exemples de tables:

Définition

table <ip_clients> “{ 192.168.1.10 192.168.1.100 }”

Utilisation

pass quick from <ip_clients> to any keep state

Modification de la table

pfctl -t ip_clients -T add 192.168.1.101

pfctl -t ip_clients -T delete 192.168.1.101

2) Options et normalisation des paquets

Personnellement, j'utilise les options suivantes:

# On ne filtre pas sur l'interface locale

set skip on lo

# En cas de blocage, on envoie un RST sur les paquets TCP

# et UNREACHABLE sur les ICMP

set block-policy return

# On normalise les paquets avec gestion de la fragmentation

scrub in all fragment reassemble

3) Gestion des queues pour la QoS

Permet de faire de la qualité de service: CBQ, Priorité et HFSC. Il faut cependant passer par un module externe: altq.

Je reviendrai sûrement sur ces fonctions 12c4.

4) Translation d'adresse (NAT) et re-direction de ports (PAT)

Contrairement à IPFW qui ne gérait pas la translation d'adresse et de port (il fallait utiliser IPNAT), PF s'acquitte parfaitement de ces taches. La syntaxe est très proche de celle utilisée par IPNAT.

Exemple de NAT:

nat pass on eth0 from eth1:network to any -> $ip_externe

On notera l'utilisation de la macro eth1:network qui donne le réseau associé à l'interface réseau eth1

binat on $if_externe from 192.168.1.100 to any -> 80.80.80.81

Exemple de PAT:

rdr on $if_externe from any to $ip_externe port 8080 -> $ip_serveur port 80

5) Règles de filtrage

On entre (enfin ?) dans le vif du sujet avec l'adaptation des règles de IPFW vers PF.

La première chose à se rappeler est que l'interprétation des règles est de type “last matching rules wins”: la dernière règle qui correspond au paquet est appliquée. C'est le contraire de la logique que l'on suivait avec IPFW. Cependant, si comme moi vous avez du mal à réfléchir à l'envers, il reste la possibilité d'utiliser l'option quick. Quand cette dernière est présente dans une règle, PF arrête l'interprétation des règles suivantes.

L'option permettant de faire du suivi de connexion (sur TCP mais aussi sur UDP ou tout autre protocole IP) est “keep state” (attention c'était “keep-state” avec un - sous IPFW…). Cette option est maintenant ajouté par défaut sur les OS BSD (depuis OpenBSD 4.0 et FreeBSD 7.0).

Exemple de filtres:

pass in on $int_if from $internal_net to any

pass out on $ext_if proto tcp all modulate state flags S/SA

pass out on $ext_if proto { udp, icmp } all keep state

pass in on $ext_if inet proto tcp from any to $webserver port 80 flags S/SA synproxy state

Gestion de votre nouveau Firewall PF

La gestion de la configuration de votre Firewall PF se fait via l'utilitaire pfctl.

Quelques commandes utiles:

Vérification de la syntaxe du fichier /etc/pf.conf

pfctl -n -f /etc/pf.conf

Activation du filtrage:

pfctl -e

Dés-activation du filtrage:

pfctl -d

Rechargement des règles:

pfctl -f /etc/pf.conf

Affichage des règles de filtrage:

pfctl -s rules

Affichage des NAT et PAT:

pfctl -s nat

Affichage l'état des sessions existantes (connections):

pfctl -s state

Affichage du fichier de log (pour voir les paquets rejetés):

tcpdump -r /var/log/pflog

ou bien:

tcpdump -i pflog0 -qea -ttt

Conclusion

Je dois vous avouer que j'étais très réticent pour ce passage de IPFW et PF mais après quelques heures d'utilisations je pense que ce système de filtrage est très bon et aussi facile à administrer (en tout cas beaucoup plus simple que l'usine à gaz IPTABLES… je sais je troll…).