[OpenBSD]

[Précédent : Traduction d'Adresses Réseau] [Index] [Suivant : Raccourcis pour la Création de Jeux de Règles]

PF : Redirection de Trafic ("Forwarding" de Ports)


Table des Matières


Introduction

Quand vous utilisez la NAT, les machines sur votre réseau peuvent accéder à la totalité des ressources Internet. Qu'en est-il lorsqu'une de vos machines derrière la passerelle NAT a besoin d'être accédée depuis Internet ? la redirection est utilisée pour résoudre ce genre de problèmes. Elle permet au trafic entrant d'être acheminé vers une machine derrière la passerelle NAT.

Prenons un exemple :

rdr on tl0 proto tcp from any to any port 80 -> 192.168.1.20

La ligne ci-dessus redirige le trafic à destination du port TCP 80 (serveur web) vers une machine sur le réseau d'adresse IP 192.168.1.20. Ainsi, même si cette machine est derrière votre passerelle, le monde externe peut y avoir accès.

La partie from any to any de la ligne rdr précitée peut être assez utile. Si vous voulez restreindre les adresses ou les sous-réseaux autorisés à avoir accès au serveur web sur le port 80, vous pouvez le faire de la façon suivante :

rdr on tl0 proto tcp from 27.146.49.0/24 to any port 80 -> \
   192.168.1.20

Ceci aura pour effet de rediriger uniquement le trafic en provenance du sous-réseau spécifié. Notez que cela implique la possibilité de rediriger différentes machines en entrée vers des machines derrière la passerelle. Une telle fonctionnalité est utile. Par exemple, vous pouvez autoriser des utilisateurs sur des sites distants à accèder à leur propre machine dans la mesure où vous connaissez leur adresse IP :

rdr on tl0 proto tcp from 27.146.49.14 to any port 80 -> \
   192.168.1.20
rdr on tl0 proto tcp from 16.114.4.89 to any port 80 -> \
   192.168.1.22
rdr on tl0 proto tcp from 24.2.74.178 to any port 80 -> \
   192.168.1.23

Une plage de ports peut aussi être redirigée par une même règle :

rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20
rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20 port 6000
rdr on tl0 proto tcp from any to any port 5000:5500 -> \
   192.168.1.20 port 7000:*

Les exemples précédents permettent de rediriger tout port entre 5000 et 5500 inclus vers 192.168.1.20. Dans la première règle, on a une correspondance de ports 1 à 1. Ainsi le port 5000 est redirigé vers le port 5000 de la machine destination, le port 5001 est redirigé vers le port 5001 et ainsi de suite. Dans la deuxième règle, la plage de ports toute entière est redirigée vers le port 6000. Enfin, dans la troisième règle, le port 5000 est redirigé vers le port 7000, 5001 vers 7001 et ainsi de suite.

Redirection et Filtrage de Paquets

REMARQUE : Les paquets redirigés doivent encore être autorisés par le moteur de filtrage. Ils seront bloqués ou autorisés selon les règles de filtrage qui ont été définies.

La seule exception à cette règle est lorsque le mot-clé pass est utilisé dans la règle rdr. Dans ce cas, les paquets redirigés passeront à travers le moteur de filtrage et l'état de connexion sera préservé : Les règles de filtrage ne seront pas considérées pour ces paquets. Ceci est un raccourci utile pour éviter de rajouter des règles de filtrage pass pour chaque règle de redirection. Il faut voir cela comme une règle rdr normale (sans mot-clé pass) associée à une règle de filtrage pass avec le mot-clé keep state. Cependant, si vous voulez mettre en oeuvre des options de filtrage spécifiques telles que synproxy, modulate state, etc... vous devrez utiliser une règle de filtrage pass dédiée étant donné que ces options ne sont pas implémentées au niveau des règles de redirection.

Notez aussi que la traduction est effectuée avant le filtrage. Le moteur de filtrage verra le paquet traduit, c'est à dire après que son adresse IP destination et/ou port de destination soient modifiés pour correspondre à l'adresse/au port de redirection spécifié(e) dans la règle rdr. Considérons le cas suivant :

Règle de redirection :

rdr on tl0 proto tcp from 192.0.2.1 to 24.65.1.13 port 80 \
   -> 192.168.1.5 port 8000

Avant que la règle de redirection rdr ne soit utilisée, le paquet est traité :

Puis la règle de redirection rdr est évaluée :

Le moteur de filtrage verra le paquet IP tel qu'il apparaît après la traduction effectuée par le mécanisme de redirection.

Implications au niveau de la Sécurité

La redirection a des implications au niveau de la sécurité. La création d'une ouverture pour autoriser le trafic à destination du réseau interne protégé peut causer la compromission d'une machine sur ce dernier. Par exemple, si le trafic est redirigé vers un serveur web interne et que par malheur, une vulnérabilité est découverte dans le service web ou dans un script CGI executé par le serveur, alors la machine peut être compromise par un utilisateur distant. Une fois cette compromission réalisée, l'utilisateur malveillant peut rebondir à partir de cette machine vers le réseau interne ce qui, bien entendu, ne peut être bloqué par le pare-feu étant donné qu'il ne voit pas ce trafic.

Ces risques peuvent être minimisés en confinant de manière stricte le système accédé depuis l'extérieur à un réseau séparé. Ce réseau est souvent appelé zone démilitarisée (DMZ) ou réseau de service privé (Private Service Network, PSN). De cette façon, si le serveur web est compromis, les effets peuvent être limités au réseau DMZ/PSN en filtrant soigneusement le trafic autorisé entre DMZ/PSN et vos autres réseaux.

Redirection et Réflexion

Souvent, les règles de redirection sont utilisées pour faire suivre des connexions Internet entrantes à un serveur local disposant d'une adresse privée sur le réseau interne comme le montre l'exemple suivant :
server = 192.168.1.40

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

Mais lorsque la règle de redirection est testée par un client du LAN, elle ne fonctionne pas. C'est normal car les règles de redirection ne s'appliquent qu'aux paquets qui passent à travers l'interface spécifiée dans chacune d'elles (dans l'exemple précité, c'est l'interface externe $ext_if). Cependant, une connexion émanant d'un client interne et à destination de l'adresse externe du pare-feu n'implique pas que les paquets vont passer à travers l'interface externe du pare-feu. La pile TCP/IP sur le pare- feu compare l'adresse de destination des paquets entrants avec ses propres adresses et aliases et détecte les connexions qui lui sont destinées lorsque les paquets constituant celles-ci passent son interface interne. De tels paquets ne passent pas physiquement à travers l'interface externe, et de toute façon la pile ne simule pas ce passage. Ainsi, PF ne voit jamais ces paquets sur l'interface externe. Du coup, la règle de redirection sur l'interface externe n'est jamais appliquée.

Que doit-on faire alors ? ajouter une seconde règle de redirection sur l'interface interne ? non, ça ne fonctionnera pas mieux. Lorsque le client local se connecte à l'interface externe du pare-feu, le paquet initial de l'échange TCP atteint le pare-feu via son interface interne. La nouvelle règle de redirection s'applique et l'adresse de destination est remplacée par celle du serveur interne. Le paquet et alors redirigé par l'interface interne du pare-feu vers le serveur interne. Mais l'adresse source n'a pas été modifiée. Elle contient l'adresse du client local. Le serveur envoie alors directement les réponses au client. Le pare-feu ne voit jamais le retour et n'a aucune chance de traduire correctement les paquets de retour. Le client reçoit une réponse à partir d'une source inattendue. Il met alors fin à cette connexion.

Cependant, il est souvent souhaitable que les clients sur le LAN se connectent au même serveur interne que les clients externes et de manière aussi transparente. Il existe plusieurs solutions à ce problème :

DNS en "Split-Horizon"

Il est possible de configurer les serveurs DNS pour fournir une réponse différente selon la provenance de la requête : clients internes ou externes. Ainsi les clients internes recevront l'adresse interne du serveur en réponse à leur demande de résolution de nom. Ils pourront alors se connecter directement au serveur local sans impliquer le pare-feu. Ce dernier sera alors moins sollicité.

Déplacer le Serveur Vers un Réseau Local Séparé

Une autre solution consiste à ajouter une carte réseau au pare-feu et à déplacer le serveur local vers un réseau dédié de type DMZ. Les connexions des clients locaux seront alors redirigées de la même manière que les connexions en provenance d'Internet. L'utilisation de réseaux séparés a plusieurs avantages. Entre autres, une amélioration du niveau de sécurité en isolant le serveur des machines internes. Si le serveur (qui, nous le rappelons, est joignable à partir d'Internet) est compromis, il ne peut se connecter à des machines internes directement vu que toutes ces connexions doivent passer à travers le pare-feu.

Mandater les Connexions TCP ("TCP Proxying")

Un mandataire TCP générique peut être mis en place sur le pare-feu. Ce mandataire devra écouter sur le port de redirection ou accepter les connexions sur l'interface interne et redirigées sur le port sur lequel il écoute. Lorsqu'un client se connecte sur le pare-feu, le mandataire accepte la connexion, établit une seconde connexion au serveur interne, et véhicule les données entre les deux connexions.

Des mandataires simples peuvent être crées avec inetd(8) et nc(1). L'entrée suivante dans le fichier /etc/inetd.conf crée une socket d'écoute rattachée à l'adresse de loopback (127.0.0.1) et le port 5000. Les connexions sont redirigées sur le port 80 du serveur 192.168.1.10.

127.0.0.1:5000 stream tcp nowait nobody /usr/bin/nc nc -w \
   20 192.168.1.10 80

La règle de redirection suivante redirige le port 80 sur l'interface interne du mandataire :

rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
   127.0.0.1 port 5000

Combinaison RDR et NAT

A l'aide d'une règle NAT supplémentaire sur l'interface interne, la traduction manquante d'adresse source décrite plus haut peut être réalisée.

rdr on $int_if proto tcp from $int_net to $ext_if port 80 -> \
   $server
no nat on $int_if proto tcp from $int_if to $int_net
nat on $int_if proto tcp from $int_net to $server port 80 -> \
   $int_if

Ceci aura pour effet d'effectuer une autre traduction d'adresse du paquet initial envoyé par le client lorsque celui-ci est redirigé à travers l'interface interne. Cette seconde opération de traduction remplacera l'adresse source du client par l'adresse interne du pare-feu. Le serveur interne répondra alors à l'adresse interne du pare-feu, qui effectuera les opérations de NAT et de RDR inverses avant de faire suivre le paquet au client. Cette méthode est relativement complexe. Elle crée deux états séparés pour chaque connexion redirigée. Il faut prendre des précautions pour éviter que la règle de NAT ne s'applique au reste du trafic tel que les connexions en provenance de hôtes externes (via d'autres redirections) ou en provenance du pare-feu lui-même. La règle rdr précitée soumettra à la pile TCP/IP des paquets en provenance du réseau interne et à destination de ce dernier.

Nous recommandons cependant de privilégier plutôt les autres solutions précédemment mentionnées.

[Précédent : Traduction d'Adresses Réseau] [Index] [Suivant : Raccourcis pour la Création de Jeux de Règles]


[back] www@openbsd.org
$OpenBSD: rdr.html,v 1.21 2007/05/09 05:49:53 jufi Exp $