[Précédent : Authpf: Shell Utilisateur pour les Passerelles d'Authentification] [Index]
[ COMP1 ] [ COMP3 ] | | ADSL ---+------+-----+------- fxp0 [ OpenBSD ] ep0 -------- ( 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. Le réseau interne utilise le bloc de réseau 192.168.0.0 / 255.255.255.0.
Le routeur OpenBSD est une machine dotée d'un Pentium 100 et de deux cartes réseau : une 3Com 3c509B (ep0) et d'une Intel EtherExpress Pro/100 (fxp0). Le routeur a une connexion ADSL 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.
int_if = "fxp0"
ext_if = "ep0"
tcp_services = "{ 22, 113 }"
icmp_types = "echoreq"
priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
Les deux premières lignes définissent les interfaces réseau sur lesquelles le filtrage sera effectué. Les deux lignes suivantes 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. La dernière ligne définit le réseau de loopback et les blocs d'adresses RFC 1918.
Remarque : Si la connexion Internet ADSL nécessite l'utilisation de PPPoE, le filtrage et la NAT s'effectueront sur l'interface tun0 au lieu de ep0.
set block-policy return
set loginterface $ext_if
scrub in all
nat on $ext_if from $int_if:network to any -> ($ext_if)
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.
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 }.
block all
Avec cette règle, aucun trafic ne sera autorisé y compris le trafic provenant du réseau interne. Les règles ci-après 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.
Tout système Unix a une interface de "loopback". C'est une interface virtuelle représentant un réseau utilisé par les applications pour établir des canaux de communication locaux à la machine. De manière générale, tout le trafic au niveau de l'interface de "loopback" doit être autorisé. Sous OpenBSD, l'interface de "loopback" est lo(4).
pass quick on lo0 all
Ensuite, les adresses RFC 1918 doivent être bloquées en entrée et en sortie de l'interface externe. Ces adresses ne doivent jamais apparaître sur le réseau Internet public. Leur filtrage permet de s'assurer que le routeur ne divulgue pas les adresses utilisées par le réseau interne et de bloquer tous les paquets entrants avec une adresse source appartenant à l'un de ces réseaux.
block drop in quick on $ext_if from $priv_nets to any
block drop out quick on $ext_if from any to $priv_nets
Il est à noter que block drop est utilisé pour dire à PF de ne pas répondre par un paquet TCP RST ou ICMP "Unreachable". Vu que les adresses correspondant à la RFC 1918 n'existent pas sur Internet, tout paquet envoyé vers une de ces adresses ne sera jamais acheminé vers sa destination de toute façon. L'option quick est utilisée pour dire à PF de ne pas évaluer le reste des règles de filtrage si un paquet correspond à l'une des règles ci-dessus; les paquets de et vers les réseaux $priv_nets seront immédiatement détruits.
Maintenant, il faut ouvrir les ports utilisés par les services réseau disponibles depuis Internet :
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.
Le trafic ICMP doit aussi ê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 certains environnements, il serait plus judicieux d'utiliser un jeu de règles plus restrictif.
pass in on $int_if from $int_if:network to any keep state
La règle ci-dessus permettra à n'importe quelle machine interne d'envoyer des paquets à travers le pare-feu; cependant, le pare-feu ne sera pas autorisé à à initier une connexion vers une machine interne. Est-ce une bonne idée ? Ceci dépendra de certains détails fins de la configuration réseau. Si le pare-feu est aussi un serveur DHCP, il aurait éventuellement besoin de vérifier la présence d'une adresse ("ping") pour voir si elle est disponible avant de l'attribuer à une machine. Permettre au pare-feu de se connecter au réseau interne veut dire aussi que quelqu'un qui accéderait en SSH au pare-feu depuis Internet sera autorisé à accèder aux machines sur le réseau. Gardez à l'esprit qu'interdire au pare-feu de communiquer directement avec le réseau n'est pas d'un grand bénéfice du point de vue de la sécurité; si quelqu'un accède au pare-feu, il pourra très probablement altérer les règles de filtrage de toute façon. En ajoutant la règle suivante, le pare-feu sera capable d'initier des connexions vers le réseau interne :
pass out on $int_if from any to $int_if:network keep state
Notez que si les deux lignes ci-dessus sont utilisées, l'option keep state n'est pas nécessaire car il y a une règle pour laisser passer les paquets dans les deux directions. Cependant, si la ligne pass out n'est pas utilisée, la règle pass in doit comporter l'option keep state. Garder l'état d'une connexion permet aussi d'améliorer les performances : Les tables d'état sont vérifiées avant l'évaluation des règles, et si un état est trouvé, le passage du paquet à travers le pare-feu est autorisé sans que le jeu de règles ne soit évalué. Cette méthode de fonctionnement peut offrir de meilleures performances pour un pare-feu très chargé bien que pour un système aussi simple, la charge ne sera très certainement pas assez significative pour que cela fasse une différence.
Finalement, il faut laisser le trafic sortir de l'interface externe :
pass out on $ext_if proto tcp all modulate state flags S/SA
pass out on $ext_if proto { udp, icmp } all keep state
Le trafic TCP, UDP, et ICMP à destination d'Internet est autorisé sortir du pare-feu. 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.
# macros int_if = "fxp0" ext_if = "ep0" tcp_services = "{ 22, 113 }" icmp_types = "echoreq" priv_nets = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }" # options set block-policy return set loginterface $ext_if # scrub scrub in all # nat/rdr nat on $ext_if from $int_if:network to any -> ($ext_if) rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \ port 8021 # règles de filtrage block all pass quick on lo0 all block drop in quick on $ext_if from $priv_nets to any block drop out quick on $ext_if from any to $priv_nets pass in on $ext_if inet proto tcp from any to ($ext_if) \ port $tcp_services flags S/SA keep state pass in inet proto icmp all icmp-type $icmp_types keep state pass in on $int_if from $int_if:network to any keep state pass out on $int_if from any to $int_if:network keep state pass out on $ext_if proto tcp all modulate state flags S/SA pass out on $ext_if proto { udp, icmp } all keep state |
[Précédent : Authpf: Shell Utilisateur pour les Passerelles d'Authentification] [Index]