OpenBSD PF: Network Address Translation : (v1.79 ; 12/05/2021)
— [ FAQ Index ] | [ Index PF ] ~ Traduction française de la page OpenBSD PF : Traduction d’adresses réseaux —
La traduction d’adresses réseaux (NAT - Network Address Translation) est une manière de cartographier un réseau entier (ou des réseaux) à une simple adresse IP. Elle est nécessaire, par exemple, quand le nombre d’adresses IP assignées à un client par un fournisseur d'accès internet est inférieur au nombre total d’ordinateurs auxquels vous souhaitez fournir un accès internet. La NAT est décrit dans la RFC 1631.
La NAT permet à un administrateur de tirer partie des blocs d’adresses réservés décrits dans la RFC 1918. Typiquement, le réseau interne sera configuré pour utiliser un ou plusieurs de ces blocs d’adresses réseaux :
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 qui gère la NAT a au moins deux interfaces réseaux : une pour internet, l’autre pour votre réseau interne. La NAT traduira les requêtes du réseau interne comme si elles venaient du système OpenBSD faisant la NAT.
Lorsqu’un client sur un réseau interne contacte une machine sur internet, il envoie des paquets IP destinés à cette machine. Ces paquets contiennent toutes les informations d’adressage nécessaires pour les acheminer vers leur destination. La NAT est concernée par ces informations : adresse IP source et port TCP ou UDP source.
Lorsque les paquets passent au-travers de la passerelle NAT, ils sont modifiés de manière à apparaître comme s’ils venaient de la passerelle NAT elle-même. La passerelle NAT enregistre les changements dans sa table d’état afin qu’elle puisse inverser les modifications sur les paquets de retour et s’assurer que les paquets de retour passent au-travers du pare-feu et qu’ils ne soient pas bloqués. Pour l’exemple, les modifications suivantes pourraient être faites :
Ni la machine interne ni l’hôte Internet ne connaissent ces étapes de traduction. Pour la machine interne, le système NAT est simplement une passerelle Internet. Pour l’hôte sur Internet, les paquets semblent venir directement du système NAT ; il n'est pas conscient de l’existence même de la station de travail interne.
Lorsque l’hôte sur Internet répond aux paquets de la machine interne, ils seront adressés à l’IP externe de la passerelle NAT sur le port traduit. La passerelle NAT cherchera dans sa table d’état pour déterminer si les paquets de réponses correspondent à une connexion déjà établie. Une correspondance unique sera trouvée, basée sur la combinaison IP/Port qui indique à PF que les paquets appartiennent à une connexion initiée par la machine interne. PF fait alors les changements opposés sur les paquets sortants et transmet les paquets de réponses à la machine interne.
La traduction de paquets ICMP fonctionne de la même manière mais sans la modification du port source.
Étant donné que la NAT est presque toujours utilisée sur les routeurs et autres passerelles réseaux, il sera probablement nécessaire d’activer le transfert d’IP afin que les paquets puissent voyager entre les interfaces réseaux sur une machine OpenBSD. Le transfert d’IP est activé en utilisant le mécanisme de sysctl(3) :
# sysctl net.inet.ip.forwarding=1 # echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
Ou, pour IPv6:
# sysctl net.inet6.ip6.forwarding=1 # echo 'net.inet6.ip6.forwarding=1' >> /etc/sysctl.conf
La NAT est spécifiée avec le paramètre optionnel nat-to
sur une règle sortante pass
. Souvent, au lieu d'utiliser directement une règle pass
, une règle match
est utilisée. Quand un paquet est sélectionné par une règle match
, les paramètres (ex., nat-to
) dans cette règle sont rappelés et sont appliqués au paquet quand une règle pass
correspondante est atteinte. Cela permet à toute une classe de paquets d’être capturés par une simple règle match
et alors de prendre des décisions spécifiques sur l’opportunité d'allouer le trafic, ce qui peut être fait avec des règles block
et pass
.
Le format général dans le fichier 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
Lorsqu'un paquet parcourt le jeu de règles et correspond à une règle match
, tous les paramètres optionnels spécifiés dans cette règle sont mémorisés pour un usage ultérieur (rendue “collante”)
pass
Cette règle permet que le paquet soit transmis. Si le paquet correspondait précédemment à une règle match
où des paramètres étaient spécifiés, ils seront appliqués au paquet. Les règles pass
peuvent avoir leurs propres paramètres ; ceux-ci ont la priorité sur les paramètres spécifiés dans la règle match
.
out
Spécifie la direction du flux de paquets lorsque cette règle s’applique. nat-to
peut seulement être spécifié sur les paquets sortants.
log
Enregistre la correspondance des paquets via pflogd(8). Normalement, seul le premier paquet qui correspond sera enregistré. Pour consigner tous les paquets correspondants, utilisez log (all)
.
interface
Le nom ou le groupe d'interfaces réseaux où transmettre les paquets.
af
La famille d'adresse, soit inet
pour IPv4 ou inet6
pour IPv6. PF est généralement capable de déterminer le paramètre en fonction de la ou les adresse(s) sources ou destinations.
protocol
Le protocole (ex. tcp, udp, icmp) des paquets à autoriser. Si src_port
ou dst_port
est spécifié, le protocole doit également être donné.
src_addr
L’adresse source (interne) des paquets qui sera traduite. L’adresse source peut être spécifiée ainsi :
/netmask
(ex. /24
). Chaque adresse IP sur l’interface sera combinée avec le masque de réseau formant un bloc réseau CIDR qui sera substitué dans la règle.:network
- substitue le bloc réseau CIDR (ex., 192.168.0.0/24) :broadcast
- substitue l’adresse de bouclage réseau (ex., 192.168.0.255) :peer
- substitue l'adresse IP du pair d'un lien point à point. :0
peut être ajouté soit à un nom ou un groupe d'interface soit à un des modificateurs ci-dessus pour indiquer que PF ne devrait pas inclure les alias d'adresses IP dans la substitution. Ces modificateurs peuvent aussi être utilisés quand l’interface se trouve entre parenthèses. Exemple : fxp0:network:0
!
(“not”). any
signifiant toutes les adresses.
src_port
Le port source dans l’entête du paquet de la Couche 4. Les ports peuvent être spécifiés comme :
!=
(non égal) <
(+ petit que) >
(+ grand que) ⇐
(+ inférieur ou égal) >=
(+ supérieur ou égal)><
(plage ) <>
(plage inverse) :
(plage inclusive)
L'option port
n'est généralement pas utilisée dans les règles nat
car le but du NAT est habituellement de traduire tout le trafic quel que soit le(s) port(s) utilisé(s).
dst_addr
L'adresse de destination des paquets à traduire. L’adresse de destination est spécifiée de la même manière que pour l'adresse source.
dst_port
Le port de destination dans l’entête du paquet de la Couche 4. Ce port est spécifié de la même manière que le port source.
ext_addr
L’adresse externe (traduite) sur la passerelle NAT depuis laquelle les paquets vont être traduits. L'adresse externe peut être ainsi spécifiée :
( )
. Cela indique à PF de mettre à jour la règle si la ou les adresse(s) IP de l'interface désignée change(nt). Ceci est très utile quand l'interface externe obtient son adresse IP via DHCP ou connexion commutée, ainsi le jeu de règles n'a pas à être rechargé à chaque fois qu'une adresse change.:network
- substitue le bloc réseau CIDR (ex., 192.168.0.0/24) :peer
- substitue l'adresse IP du pair d'une liaison point à point :0
peut être ajouté soit à un nom ou un groupe d'interface soit à l'un des modificateurs ci-dessus pour indiquer que PF ne devrait pas inclure les alias d'adresses IP dans la substitution. Ces modificateurs peuvent aussi être utilisés lorsque l'interface est mis entre parenthèses. Exemple : fxp0:network:0
pool_type
Spécifie le type du groupe d'adresses à utiliser pour la traduction.
static-port
Indique à PF de ne pas traduire le port source dans les paquets TCP et UDP.
Cela conduirait à la forme la plus basique de ces lignes telles que :
match out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1 pass on tl0 from 192.168.1.0/24 to any
Ou ce qui suit peut être utiliser :
pass out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1
Cette règle dit d'assumer la NAT sur l'interface tl0
pour tout paquet venant depuis le réseau 192.168.1.0/24 et de remplacer l'adresse IP source par 198.51.100.1.
Bien que la règle ci-dessus soit correcte, elle n'est pas recommandée. La maintenance peut être difficile car toute modification des numéros de réseau externe ou interne exigerait que la ligne soit modifiée. Comparez plutôt avec cette ligne plus facile à maintenir (tl0
est l'externe, dc0
est l'interne) :
pass out on tl0 inet from dc0:network to any nat-to tl0
L'avantage doit être assez clair : les adresses IP de n'importe quelle interface peuvent être changer sans changer la règle. Notez que inet
devrait être spécifié dans ce cas afin de s'assurer que seules les adresses IPv4 soient utilisées, évitant les surprises inattendues.
Lors de la spécification d'un nom d'interface pour la traduction d'adresse comme ci-dessus, l'adresse IP est déterminée lors du chargement de pf.conf
, pas à la volée. Si DHCP est utilisé pour configurer l'interface externe, cela peut poser problème. Si l'adresse IP assignée change, la NAT continuera à traduire les paquets sortant en utilisant l'ancienne adresse IP. Ceci aura pour conséquence que les connexions sortantes cesseront de fonctionner. Pour contourner cela, PF peut mettre à jour automatiquement la traduction d'adresse en mettant des parenthèses autour du nom de l'interface :
pass out on tl0 inet from dc0:network to any nat-to (tl0)
Cette méthode fonctionne pour la traduction sur les adresses IPv4 et IPv6.
Une cartographie bidirectionnelle peut être établie en utilisant le paramètre binat-to
. Une règle binat-to
établit une correspondance 1 pour 1 entre l'adresse IP interne et l'adresse externe. Cela peut être utile, par exemple, pour fournir un serveur web sur un réseau interne avec sa propre adresse IP externe. Les connexions depuis Internet vers l'adresse externe seront traduites vers l'adresse interne et les connexions depuis le serveur web (telles que les requêtes DNS) seront traduites vers l'adresse externe. Les ports TCP et UDP ne sont jamais modifiés avec les règles binat-to
comme ils le sont avec les règles nat
.
Exemple :
web_serv_int = "192.168.1.100" web_serv_ext = "198.51.100.6" pass on tl0 from $web_serv_int to any binat-to $web_serv_ext
Si des exceptions aux règles NAT ont besoin d'être fournies dans certains cas, assurez vous que ces exceptions soient gérées par une règle de filtrage qui n'inclut pas le paramètre nat-to
. Par exemple, si l'exemple de NAT ci-dessus était modifié pour ressembler à cela :
pass out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.79 pass out on tl0 from 192.168.1.208 to any
Alors l'ensemble du réseau 192.168.1.0/24 aurait ses paquets traduits vers l'adresse externe 198.51.100.79 excepté pour 192.168.1.208.
Pour voir les traductions de la NAT en cours, pfctl(8) est utilisé avec l'option -s state
. Cette option listera toutes les sessions NAT courantes :
# pfctl -s state fxp0 tcp 192.168.1.35:2132 (198.51.100.1:53136) -> 198.51.100.10:22 TIME_WAIT:TIME_WAIT fxp0 udp 192.168.1.35:2491 (198.51.100.1:60527) -> 198.51.100.33:53 MULTIPLE:SINGLE
Des explications (seulement la première ligne) :
fxp0
Indique l'interface sur lequel l'état est traité. Le mot self
apparaîtra si l'état est flotting
.
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 est remplacée dans l'entête IP.
198.51.100.1:53136
L'adresse IP (198.51.100.1) et le port (53136) sur la passerelle vers laquelle les paquets sont traduits.
198.51.100.10:22
L'adresse IP (198.51.100.10) et le port (22) sur laquelle est connectée la machine interne.
TIME_WAIT:TIME_WAIT
Cela indique dans quel état PF croit que la connexion TCP est établie.
Cette page est la traduction officieuse de la page «Network Address Translation» de la FAQ officielle d'OpenBSD.
En cas de doute, merci de vous y référer !
Si vous voulez participer à l'effort de traduction, merci de lire ce topic.
Contribut(rice|eur)s :