[OpenBSD]

[Précédent : Haute-disponibilité des pare-feu avec CARP et pfsync] [Index]

PF : Exemple : Pare-feu pour réseau domestique ou petite société


Table des Matières


Le Scenario

Dans cet exemple, PF fonctionne sur une machine OpenBSD jouant le rôle de pare-feu et de passerelle NAT pour un réseau SoHo. L'objectif global est de fournir un accès Internet au réseau local, de fournir un accès limité au pare-feu depuis Internet et d'exposer un serveur web interne à l'Internet. Ce document a pour but de vous montrer comment on construit un jeu de règles correspondant à l'objectif précité.

Le Réseau

Le réseau est conçu de la manière suivante : [ COMP1 ] [ COMP3 ] | | ---+------+-----+------- xl0 [ OpenBSD ] fxp0 -------- ( Internet ) | [ COMP2 ]

Il y a un certain nombre de machines sur le réseau interne. Le diagramme en montre trois mais le vrai nombre n'est pas une donnée utile. Ces machines sont des stations de travail normales servant à surfer sur le web, écrire des messages électroniques, participer à des forums de discussion en ligne, etc à l'exception de COMP3 qui sert aussi de serveur Web. Le réseau interne utilise le bloc de réseau 192.168.0.0 / 255.255.255.0.

Le pare-feu OpenBSD est une machine dotée d'un Celeron 300 et de deux cartes réseau : une 3Com 3c905B (xl0) et une Intel EtherExpress Pro/100 (fxp0). Le pare-feu a une connexion câble vers Internet et utilise la NAT pour partager cette connexion avec le réseau interne. L'adresse IP de l'interface externe est attribuée dynamiquement par le Fournisseur d'Accès Internet.

Les Objectifs

Les objectifs sont les suivants :

Préparation

Ce document suppose que l'hôte OpenBSD a été correctement configuré pour fonctionner comme routeur : configuration réseau, connexion Internet et positionnement des variables sysctl(3) net.inet.ip.forwarding et/ou net.inet6.ip6.forwarding à "1". Vouc devez également activer PF en utilisant pfctl(8) ou en définissant la variable appropriée dans /etc/rc.conf.local.

Le Jeu de Règles

Les sections ci-après détaillent la manière dont le jeu de règles répondra aux objectifs précités.

Macros

Les macros suivantes sont définies pour rendre la maintenance et la lecture du jeu de règles plus faciles :
ext_if="fxp0"
int_if="xl0"

tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"

comp3 = "192.168.0.3"

Les deux premières lignes définissent les interfaces réseau sur lesquelles le filtrage sera effectué. En les définissant ici, si nous devons déplacer ce système vers une autre machine avec un matériel différent, nous pourrons alors ne changer que ces deux lignes et le reste des règles restera valable. Les troisièmes et quatrièmes lignes listent les numéros de port TCP des services ouverts depuis Internet (SSH et ident/auth) et les types de paquets ICMP qui sont autorisés à parvenir jusqu'aù pare-feu. Enfin, la dernière ligne définit l'adresse IP de COMP3.

Remarque : Si la connexion Internet nécessite l'utilisation de PPPoE, le filtrage et la NAT s'effectueront sur l'interface tun0 au lieu de fxp0.

Options

Les deux options suivantes spécifient la réponse par défaut fournie par les règles de filtrage block et activent la collecte de statistiques sur l'interface externe :
set block-policy return
set loginterface $ext_if

Chaque système Unix possède une interface de "loopback". C'est une interface réseau virtuelle utilisée par les applications pour converser avec les autres au sein du même système. Sur OpenBSD, l'interface de bouclage ("loopback") est lo(4). Le filtrage est communément désactivé sur ces interfaces. L'utilisation de set skip permet d'accomplir cela.

set skip on lo
Veuillez prendre note que nous n'effectuons pas de filtrage sur le groupe d'interfaces lo entier, de cette manière nous pourrions rajouter des interfaces de loopback supplémentaire sans avoir à nous soucier de mettre à jour cette partie de la configuration.

Scrub

Il n'y a aucune raison pour ne pas utiliser la normalisation de paquets recommandée pour tous les paquets entrants. Il suffit d'utiliser la ligne suivante :
scrub in

Traduction d'Adresses Réseau

Pour effectuer la NAT du réseau interne, la règle de nat suivante est utilisée :
nat on $ext_if from !($ext_if) to any -> ($ext_if)

Dans ce cas, "!($ext_if)" pourrait être aisément remplacé par "$int_if" mais si vous ajoutez plusieurs interfaces internes vous devrez ajouter de nouvelles règles NAT, alors qu'avec cette structure, NAT sera activé sur toutes les interfaces protégées.

Vu que l'adresse IP de l'interface externe est attribuée dynamiquement, des parenthèses sont utilisés autour de l'interface de traduction afin que PF tienne compte automatiquement des changements d'adresse IP sur cette interface.

Puisque nous souhaitons que le proxy FTP fonctionne, nous ajouterons également l'ancre NAT :

nat-anchor "ftp-proxy/*"

Redirection

La première redirection est pour ftp-proxy(8) afin de permettre aux clients FTP sur le réseau interne de se connecter à des serveurs FTP sur Internet.
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 port 8021

Il est à noter que cette règle ne fonctionnera que pour les connexions FTP au port 21. Si les utilisateurs se connectent de manière régulière à des serveurs FTP sur d'autres ports, une liste devra être utilisée pour spécifier le port de destination, par exemple : from any to any port { 21, 2121 }.

La dernière règle de redirection est utilisée pour toutes les tentatives de connexion sur le port TCP 80 du pare-feu en provenance d'Internet. Les tentatives légitimes d'accès à ce port seront générées par des utilisateurs qui essaient d'accèder au serveur web du réseau. Ces tentatives de connexion doivent être redirigées vers COMP3 :

rdr on $ext_if proto tcp from any to any port 80 -> $comp3

Règles de Filtrage

Détaillons maintenant les règles de filtrage. Commencez par l'interdiction par défaut de tout trafic :
block in

A ce point, tout le trafic entrant sera bloqué même celui en provenance du réseau interne. Des règles suivantes vont ouvrir un certain nombre de flux sur le pare-feu afin de répondre aux objectifs précités et d'ouvrir toutes les interfaces virtuelles nécessaires.

Gardez à l'esprit que pf peut bloquer le trafic entrant ou sortant d'une interface. Cela peut vous simplifier la tâche de ne filtrer que dans une direction plutôt que d'essayer de rester consistant en filtrant le trafic sortant et entrant. Dans notre cas, nous choisirons de filtrer le trafic entrant uniquement, mais lorsque celui-ci sera permit sur une interface nous ne l'empêcherons pas d'en sortir. Pour se faire, nous utiliserons :

pass out keep state

Nous avons besoin d'une ancre pour ftp-proxy(8) :

anchor "ftp-proxy/*"
Il est utile d'utiliser la protection contre le spoofing d'adresses :
antispoof quick for { lo $int_if }

Maintenant, il faut ouvrir les ports utilisés par les services réseau disponibles depuis Internet. Tout d'abord, le trafic destiné au pare-feu lui-même :

pass in on $ext_if inet proto tcp from any to ($ext_if) \
   port $tcp_services flags S/SA keep state

La spécification des ports réseau par le biais de la macro $tcp_services rend l'ouverture de nouveaux services pour des connexions provenant d'Internet plus facile dans la mesure où il suffira de modifier la macro et recharger le jeu de règles. Des services UDP peuvent aussi être mis à disposition en créant la macro $udp_services et en ajoutant une règle de filtrage adéquate similaire à la règle de filtrage ci-dessus en spécifiant proto udp.

En plus de la règle rdr qui fait suivre tout le trafic web vers COMP3, nous DEVONS aussi autoriser ce trafic à travers le pare-feu :

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

Pour un niveau de sécurité plus élevé, nous utilisons TCP SYN Proxy pour améliorer la protection du web serveur.

Le trafic ICMP doit être permis :

pass in inet proto icmp all icmp-type $icmp_types keep state

Comme pour la macro $tcp_services, la macro $icmp_types peut facilement être modifiée pour changer les types des paquets ICMP qui doivent être autorisés à atteindre le pare-feu. Notez que cette règle s'applique à toutes les interfaces réseau.

Maintenant, le trafic en provenance du réseau interne doit être autorisé. Nous supposerons que les utilisateurs du réseau interne savent ce qu'ils font et ne provoqueront pas de problème sur Internet. Ce n'est pas nécessairement une bonne supposition pour de nombreux environnements.

pass in quick on $int_if

Le trafic TCP, UDP et ICMP à destination d'Internet est autorisé sortir du pare-feu grâce à la règle précédente "pass out keep state". L'information sur l'état des connexions est sauvegardée pour permettre aux paquets de retour de passer à leur tour la barrière que constitue le pare-feu.

Le Jeu de Règles Complet

# macros ext_if="fxp0" int_if="xl0" tcp_services = "{ 22, 113 }" icmp_types = "echoreq" comp3 = "192.168.0.3" # options set block-policy return set loginterface $ext_if set skip on lo # scrub scrub in # nat/rdr nat on $ext_if from !($ext_if) -> ($ext_if:0) nat-anchor "ftp-proxy/*" rdr-anchor "ftp-proxy/*" rdr pass on $int_if proto tcp to port ftp -> 127.0.0.1 port 8021 rdr on $ext_if proto tcp from any to any port 80 -> $comp3 # règles de filtrage block in pass out keep state anchor "ftp-proxy/*" antispoof quick for { lo $int_if } pass in on $ext_if inet proto tcp from any to ($ext_if) \ port $tcp_services flags S/SA keep state pass in on $ext_if inet proto tcp from any to $comp3 port 80 \ flags S/SA synproxy state pass in inet proto icmp all icmp-type $icmp_types keep state pass in quick on $int_if

[Précédent : Haute-disponibilité des pare-feu avec CARP et pfsync] [Index]


[back] www@openbsd.org
$OpenBSD: example1.html,v 1.27 2008/01/13 13:43:34 tobias Exp $