[Précédent : Filtrage de Paquets]
[Index]
[Suivant : Redirection du Trafic]
PF : Traduction des Adresses IP ("NAT")
Table des Matières
Introduction
La traduction d'adresses IP ("NAT") est un mécanisme destiné à
faire correspondre un réseau entier (ou des réseaux) à une seule adresse
IP. Un tel mécanisme est nécessaire lorsque le nombre des adresses IP
qui vous sont attribuées par votre Fournisseur d'Accès à Internet est plus
petit que le nombre de machines qui doivent pouvoir bénéficier d'une
connexion Internet. La NAT est décrite dans la
RFC 1631,
"The IP Network Address Translator (NAT)".
La NAT vous permet de bénéficier des blocs d'adressage privés décrits
dans la
RFC 1918,
"Address Allocation for Private Internets".
Typiquement, votre réseau interne sera paramétré pour
utiliser un ou plusieurs des blocs réseau suivants :
10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
Un système OpenBSD mettant en oeuvre la NAT aura au moins deux cartes
réseau dont une est connectée à Internet; l'autre étant connectée à
votre réseau interne. La NAT traduit les requêtes en provenance de votre
réseau interne de telle façon à les faire apparaître comme si elles
étaient générées par votre système de NAT OpenBSD.
Comment Fonctionne la NAT
Lorsqu'un client du réseau interne entre en communication avec une
machine sur Internet, il envoie des paquets IP à destination de cette
machine. Ces paquets contiennent toutes les informations sur leur
émetteur et leur destinataire nécessaires à leur bon acheminement. La
NAT prend en compte les informations suivantes :
- L'adresse IP source (192.168.1.35 par exemple)
- Port TCP ou UDP source (2132 par exemple)
Lorsque les paquets passent à travers la passerelle NAT, ils sont
modifiés de telle façon à ce qu'ils semblent provenir de la passerelle
NAT. Cette passerelle enregistrera les modifications effectuées dans sa
table d'état afin de a) inverser les modifications pour les paquets de
retour et b) s'assurer que les paquets de retour sont autorisés à
traverser le pare-feu et ne sont pas bloqués. Par exemple, les
modifications suivantes peuvent être effectuées :
- Adresse IP source : remplacée par l'adresse externe de la passerelle
(24.5.0.5 par exemple)
- Port source : remplacé par un port non utilisé sur la passerelle et
choisi de manière aléatoire (53136 par exemple)
Aucune des deux extrémités de la communication ne se rend compte de ces
modifications. Pour la machine interne, le système qui effectue la NAT
est simplement une passerelle Internet. Pour l'hôte sur Internet, les
paquets semblent provenir directement du système de NAT; il ne sait même
pas que la machine interne existe.
Lorsque l'hôte sur Internet répond aux paquets de la machine interne, ils
seront envoyés à l'adresse IP externe de la passerelle NAT (24.5.0.5)
sur le port de traduction (53136). Dès réception de ces paquets, la
passerelle NAT cherchera dans sa table d'état si ces paquets de retour
correspondent à une connexion déjà établie. Une correspondance unique
sera trouvée, basée sur la combinaison IP/port qui permet à PF de voir
que les paquets appartiennent à une connexion initiée par la machine
interne 192.168.1.35. PF effectuera les modifications inverses à celles
effectuées sur les paquets sortants puis enverra ces paquets à la
machine interne.
La traduction de paquets ICMP s'effectue de manière similaire mais sans
la modification du port source.
Routage IP
Vu que la NAT est utilisée la plupart du temps sur des routeurs et des
passerelles réseau, il sera probablement nécessaire d'activer le routage
IP pour permettre aux paquets de traverser les interfaces réseau du
système OpenBSD. Le routage IP peut être activé à l'aide du mécanisme
sysctl(3) :
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (si Ipv6 est utilisé)
Pour rendre cette modification permanente, les lignes suivantes doivent
être ajoutées au fichier
/etc/sysctl.conf :
net.inet.ip.forwarding=1
net.inet6.ip6.forwarding=1
Ces lignes sont déjà présentes dans l'installation par défaut mais sont
commentées (préfixées avec un caractère #). Supprimez le
# et sauvegardez le fichier. Le routage IP sera désormais
activé automatiquement à chaque redémarrage.
Configurer la NAT
NOTE : Cette information est pour OpenBSD 4.7.
La configuration du NAT était très différente dans les versions pécédentes.
Le NAT est spécifié comme un paramètre optionnel nat-to pour une
règle de sortie pass.
Souvent, plutôt que de configurer directement la règle pass,
une règle match est utilisée.
Quand un paquet est selectionné par une règle match, les paramètres
dans cette règle (par exemple nat-to) sont retenus et sont
appliqués au paquet quand une règle pass correspondante est
atteinte.
Cela permet a une grande classe de paquets d'être traités par une unique
règle match et les décisions spécifiques concernant l'opportunité
d'autoriser le trafic peuvent-être faite avec des règles block et pass.
Le format général dans pf.conf ressemble à quelque chose comme cela :
match out on interface [af] \
from src_addr to dst_addr \
nat-to ext_addr [pool_type] [static-port]
...
pass out [log] on interface [af] [proto protocol] \
from ext_addr [port src_port] \
to dst_addr [port dst_port]
- match
- Quand un paquet traverse le jeu de règles et correspond à une règle match,
tous les paramètres optionnels spécifiés dans cette règle sont retenus
pour des usages futurs (devient "sticky").
- pass
- Cette règle permet au paquet d'être transmis.
Si le paquet a obtenu précedemment une correspondance avec une règle match
ou des paramètres ont été spécifiés, ils seront appliqués au paquet.
Les règles pass peuvent avoir leurs propres paramètres; ils ont la
priorité sur les paramètres spécifiés dans une règle match.
- out
- Spécifie la direction du flot de paquet ou s'applique cette règle.
nat-to ne peut s'appliquer qu'aux paquets sortants.
- log
- Journaliser les paquets correspondants à l'aide de
pflogd(8).
Normalement, uniquement le premier paquet qui correspond à la règle sera
tracé. Pour tracer tous les paquets correspondants, utilisez log
(all).
- interface
- Le nom ou groupe de l'interface réseau sur laquelle les paquets
seront transmis.
- af
- La famille d'adresses : inet pour IPv4 ou inet6
pour IPv6. PF est normalement capable de déterminer ce paramètre à
partir des adresses source/destination.
- protocol
- Le protocole (par exemple tcp, udp, icmp) des paquets qui est permis.
Si src_port ou dst_port est spécifié, le protocole
doit aussi être donné.
- src_addr
- L'adresse source (interne) des paquets qui seront traduits.
L'adresse source peut être spécifiée de plusieurs manières :
- Une seule adresse IPv4 ou IPv6.
- Un bloc réseau en notation
CIDR.
- Un nom de domaine au format FQDN qui sera résolu via DNS lorsque les
règles seront chargées. Ce nom de domaine sera remplacé par toutes
les adresses IP résultant de la résolution.
- Un nom ou groupe d'interface réseau. Ce nom sera remplacé par toutes
les adresses IP attribuées à cette interface au moment du chargement
des règles.
- Un nom d'interface réseau suivi d'un /netmask
(/24 par exemple). Chaque adresse IP attribuée à
l'interface sera combinée avec le netmask pour former un bloc réseau
en notation CIDR. Le résultat remplacera la spécification initiale
dans la règle.
- Le nom ou groupe d'une interface réseau suivi par un modificateur
parmi les modificateurs suivants :
- :network - remplace le bloc réseau en notation
CIDR (192.168.0.0/24 par exemple)
- :broadcast - remplace l'adresse de broadcast
réseau (192.168.0.255 par exemple)
- :peer - remplace l'adresse IP du pair dans une
communication point-à-point
- De plus, le modificateur :0 peut être ajouté au
nom/groupe de l'interface ou à l'un des modificateurs précités
pour indiquer à PF que les alias IP ne doivent pas être inclus
dans la substitution. Ces modificateurs peuvent aussi être
utilisés lorsque le nom de l'interface est entre parenthèses.
Exemple :
fxp0:network:0
- Une table.
- N'importe quelle spécification précitée préfixée du modificateur
! ("not") pour indiquer la négation.
- Un ensemble d'adresses en utilisant une
liste.
- Le mot-clé any signifiant toutes les adresses.
- src_port
- Le port source dans l'en-tête du paquet (couche 4). Les ports
peuvent être spécifiés de la manière suivante :
- Un nombre entre 1 et 65535
- Un nom de service valide figurant dans le fichier
/etc/services
- Un ensemble de ports sous forme de
liste
- Un intervalle :
- != (différent de)
- < (inférieur à)
- > (supérieur à)
- <= (inférieur ou égal à)
- >= (supérieur ou égal à)
- >< (intervalle)
- <> (intervalle inverse)
- Les deux derniers opérateurs sont des opérateurs binaires
(ils prennent deux arguments) et n'incluent pas les
arguments dans l'intervalle.
- : (intervalle avec inclusion)
- L'opérateur d'intervalle avec inclusion est aussi un
opérateur binaire mais contrairement aux deux opérateurs
précédents, il inclut les arguments dans l'intervalle.
L'option port n'est pas habituellement utilisée dans les règles
nat vu que le but est souvent de traduire tout le trafic peu
importe le(s) port(s) utilisé(s).
- dst_addr
- L'adresse destination des paquets à traduire. L'adresse de
destination est spécifiée de la même manière que l'adresse source.
- dst_port
- Le port destination dans l'en-tête du paquet (couche 4). Ce port est
spécifié de la même manière que le port source.
- ext_addr
- L'adresse externe (de traduction) sur la passerelle NAT. C'est
l'adresse qui figurera dans les paquets une fois ceux-ci traduits.
L'adresse externe peut être spécifiée comme suit :
- Une seule adresse IPv4 ou IPv6.
- Un bloc réseau en notation
CIDR.
- Un nom de domaine au format FQDN qui sera résolu via DNS lorsque les
règles seront chargées. Ce nom de domaine sera remplacé par toutes
les adresses IP résultant de la résolution.
- Le nom ou le groupe de l'interface réseau externe. Ce nom sera remplacé par
toutes les adresses IP attribuées à cette interface au moment du
chargement des règles.
- Le nom ou le groupe de l'interface réseau externe entouré de parenthèses (
). Ceci permet à PF de mettre à jour la règle si l'adresse ou
les adresses IP de cette interface change(nt). C'est très utile
lorsque l'interface obtient son adresse IP via DHCP ou un système
dial-up. Dans ce cas, les règles n'ont pas à être rechargées chaque
fois que l'adresse change.
- Le nom ou le groupe d'une interface réseau suivi par un modificateur parmi les
modificateurs suivants :
- :network - remplace le bloc réseau en notation
CIDR (192.168.0.0/24 par exemple)
- :peer - remplace l'adresse IP du pair dans une
communication point-à-point
- De plus, le modificateur :0 peut être ajouté au nom/groupe de
l'interface ou à l'un des modificateurs précités pour indiquer à
PF que les alias IP ne doivent pas être inclus dans la
substitution. Ces modificateurs peuvent aussi être utilisés lorsque
le nom de l'interface est entre parenthèses. Exemple :
fxp0:network:0
- Un ensemble d'adresses en utilisant une
liste.
- pool_type
- Spécifie le type de pool d'adresses à
utiliser pour la traduction.
- static-port
- Si cette option est utilisée, PF ne traduira pas le port source des
paquets TCP et UDP.
Ceci nous donne des lignes de la forme basique suivante :
match out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5
pass on tl0 from 192.168.1.0/24 to any
ou vous pouvez utiliser simplement
pass out on tl0 from 192.168.1.0/24 to any nat-to 24.5.0.5
Cette règle permet d'effectuer la NAT sur l'interface tl0 sur
tout paquet provenant de 192.168.1.0/24 et remplace l'adresse IP source
par 24.5.0.5.
Bien que cette règle soit correcte, ce n'est pas la forme recommandée.
La maintenance peut s'avérer difficile vu que toute modification des
adresses réseau externe ou interne nécessitera une modification de la
règle. La forme suivante est plus facile à maintenir (tl0 est
l'interface externe, dc0 est l'interface interne) :
pass out on tl0 from dc0:network to any nat-to tl0
L'avantage de cette forme doit être clair maintenant : vous pouvez
changer les adresses IP des deux interfaces sans changer la règle.
Lorsque vous spécifiez un nom d'interface comme adresse de traduction
tel que c'est fait dans la règle ci-dessus, l'adresse IP est déterminée
lors du chargement de pf.conf. Elle n'est pas déterminée à la
volée. Si vous utilisez DHCP pour configurer votre interface externe,
ceci peut poser problème. Par exemple, si l'adresse qui vous est
attribuée change, le système de NAT continuera à traduire les paquets
sortants en utilisant l'ancienne adresse IP. Les connexions sortantes ne
fonctionneront donc plus. Pour éviter ce problème, vous pouvez dire à PF
de mettre à jour automatiquement l'adresse de traduction en mettant des
parenthèses autour du nom de l'interface :
pass out on tl0 from dc0:network to any nat-to (tl0)
Cette méthode fonctionne aussi bien pour la traduction d'adresses IPv6
que pour la traduction d'adresses IPv4.
Mise en Correspondance Bidirectionnelle (mise en correspondance
1:1)
Une mise en correspondance bidirectionnelle (traduction 1 à 1) peut être
établie en utilisant un paramètre binat-to.
Une règle binat-to établit une correspondance 1 à 1 entre une
adresse IP interne et une adresse externe.
Ceci peut être pratique par exemple pour permettre à un
serveur web interne d'avoir sa propre adresse de traduction externe. Les
connexions en provenance d'Internet à destination de cette adresse
externe seront acheminées vers l'adresse interne du serveur web. Quant
aux requêtes émanant du serveur web (telles que les requêtes DNS), elles
seront traduites par l'adresse externe.
Les ports TCP et UDP ne sont jamais modifiés par les règles binat-to
comme pour les règles nat.
Exemple :
web_serv_int = "192.168.1.100"
web_serv_ext = "24.5.0.6"
pass on tl0 from $web_serv_int to any binat-to $web_serv_ext
Exceptions aux Règles de Traduction
Si vous avez besoin de traduire la plupart du trafic, mais avoir des
exceptions dans certains cas, soyez sûr que les exceptions sont prises en
compte par une règle de filtrage qui n'est pas incluse dans le paramètre
nat-to.
Par exemple, si la règle de NAT précédente était modifiée de la manière suivante :
pass out on tl0 from 192.168.1.0/24 to any nat-to 24.2.74.79
pass out on tl0 from 192.168.1.208 to any
Alors tous les paquets du réseau 192.168.1.0/24 seront traduits avec
l'adresse externe 24.2.74.79 excepté pour la machine 192.168.1.208.
Vérification de l'état de la NAT
Pour voir les traductions actives, il faut utiliser
pfctl(8)
avec l'option -s state. Cette option affichera une liste de
toutes les sessions NAT en cours :
# pfctl -s state
fxp0 tcp 192.168.1.35:2132 (24.5.0.5:53136) -> 65.42.33.245:22 TIME_WAIT:TIME_WAIT
fxp0 udp 192.168.1.35:2491 (24.5.0.5:60527) -> 24.2.68.33:53 MULTIPLE:SINGLE
Explications (première ligne uniquement) :
- fxp0
- Indique l'interface à laquelle est rattachée la session. Le mot-clé
self apparaîtra si la session est de type
floating.
- TCP
- Le protocole utilisé par la connexion.
- 192.168.1.35:2132
- L'adresse IP (192.168.1.35) de la machine sur le réseau interne. Le
port source (2132) est affiché après l'adresse. C'est aussi
l'adresse qui sera remplacée au niveau de l'en-tête IP.
- 24.5.0.5:53136
- L'adresse IP (24.5.0.5) et le port (53136) sur la passerelle
utilisés pour la traduction.
- 65.42.33.245:22
- L'adresse IP (65.42.33.245) et le port (22) auxquels la machine
interne est connectée.
- TIME_WAIT:TIME_WAIT
- Indique l'état de la connexion TCP, vu par PF.
[Précédent : Filtrage de Paquets]
[Index]
[Suivant : Redirection du Trafic]
www@openbsd.org
$OpenBSD: nat.html,v 1.36 2012/11/02 07:24:05 ajacoutot Exp $