Network Address Translation (NAT) is een manier om een volledig netwerk
(of netwerken) op een enkel IP adres af te beelden. NAT is nodig wanneer
het aantal IP adressen dat u toegekend is door uw Internet Service Provider
kleiner is dan het totale aantal computers waarvoor u Internet toegang wil
bieden. NAT wordt beschreven in
RFC 1631,
"The IP Network Address Translator (NAT)."
NAT laat u toe voordeel te halen uit de gereserveerde adresblokken
beschreven in
RFC 1918,
"Address Allocation for Private Internets."
Typisch zal uw intern netwerk ingesteld zijn om ййn of meer van deze
netwerkblokken te gebruiken. Dat zijn:
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)
Een OpenBSD systeem dat NAT doet, zal ten minste twee netwerkadapters
hebben, ййn naar het Internet, de andere naar uw intern netwerk. NAT zal
aanvragen vertalen van het interne netwerk zodat ze allemaal van uw
OpenBSD NAT systeem lijken te komen.
Hoe NAT Werkt
Wanneer een client op het interne netwerk een machine op het Internet
contacteert, verzendt hij IP pakketten bestemd voor die machine. Deze
pakketten bevatten alle adresseringsinformatie die nodig is om ze op
hun bestemming te krijgen. NAT heeft betrekking op deze onderdelen van
informatie:
Bron IP adres (bijvoorbeeld 192.168.1.35)
Bron TCP of UDP poort (bijvoorbeeld 2132)
Wanneer de pakketten doorheen de NAT gateway passeren, zullen ze gewijzigd
worden zodat ze van de NAT gateway zelf lijken te komen. De NAT gateway
zal de veranderingen die hij uitvoert, opslaan in zijn toestandstabel zodat
hij a) de wijzigingen kan omkeren op terugkerende pakketten en b) kan
verzekeren dat terugkerende pakketten doorgelaten worden door de firewall
en niet geblokkeerd worden. De volgende wijzigingen zouden bijvoorbeeld
kunnen gedaan worden:
Bron IP: vervangen door het externe adres van de
gateway (bijvoorbeeld 24.5.0.5)
Bron poort: vervangen door een willekeurig gekozen, ongebruikte poort op
de gateway (bijvoorbeeld 53136)
Noch de interne machine noch de Internet host is zich bewust van deze
vertalingsstappen. Voor de interne machine is het NAT systeem gewoon een
Internet gateway. Voor de Internet host lijken de pakketten rechtstreeks
van het NAT systeem te komen; deze is zich er helemaal niet van bewust
dat het interne werkstation zelfs bestaat.
Wanneer de Internet host antwoordt op de pakketten van de interne machine,
zullen ze geadresseerd zijn aan het externe IP (24.5.0.5) van de NAT
gateway op de vertalingspoort (53136). De NAT gateway zal vervolgens in de
toestandstabel zoeken om te bepalen of de antwoordpakketten overeenstemmen
met een reeds opgerichte verbinding. Een unieke overeenstemming zal
gevonden worden op basis van de IP/poort combinatie die PF vertelt dat de
pakketten toebehoren aan een verbinding geпnitieerd door de internet
machine 192.168.1.35. PF zal vervolgens de omgekeerde veranderingen
doen dan bij de uitgaande pakketten en de antwoordpakketten doorsturen
naar de interne machine.
Vertaling van ICMP pakketten gebeurt op gelijkaardige wijze maar zonder
wijziging van de bronpoort.
NAT en Pakketten Filteren
OPMERKING: Vertaalde pakketten moeten nog
steeds door de filtermotor gaan en zullen geblokkeerd of doorgelaten worden
op basis van de filterregels die gedefinieerd werden.
De enige uitzondering op deze regel is wanneer het pass
sleutelwoord binnen de nat regel gebruikt wordt.
Dit zal ervoor zorgen dat NAT pakketten gewoon recht doorheen de filtermotor
doorgelaten worden.
Besef ook dat aangezien vertaling gebeurt vууr filteren, de
filtermotor het vertaalde pakket zal zien met het vertaalde IP
adres en poort zoals geschetst in Hoe NAT Werkt.
IP Forwarding
Aangezien NAT bijna steeds gebruikt wordt op routers en netwerk gateways,
zal het waarschijnlijk nodig zijn om IP forwarding in te schakelen zodat
pakketten tussen de netwerk interfaces kunnen reizen op de OpenBSD machine.
IP forwarding wordt ingeschakeld met het
sysctl(3) mechanisme:
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet6.ip6.forwarding=1 (indien u IPv6 gebruikt)
Om deze wijziging blijvend te maken, moeten de volgende lijnen toegevoegd
worden aan
/etc/sysctl.conf:
Deze lijnen zijn aanwezig maar uitgecommentarieerd (voorafgegaan door een
#) in de standaardinstallatie. Verwijder de # en bewaar
het bestand. IP forwarding zal ingeschakeld worden wanneer de machine
herstart wordt.
NAT Configureren
Het algemeen formaat voor NAT regels in pf.conf ziet er ongeveer
zo uit:
nat [pass] [log] on interface [af] from src_addr
[port src_port] to \ dst_addr [port dst_port] ->
ext_addr [pool_type] [static-port]
nat
Het sleutelwoord dat een NAT regel begint.
pass
Zorgt ervoor dat vertaalde pakketten de filterregels volledig omzeilen.
log
Log overeenstemmende pakketten via
pflogd(8).
Normaal zal slechts het eerste pakket dat overeenstemt, gelogged worden.
Om alle overeenstemmende pakketten te loggen, gebruikt u log (all).
interface
De naam of groep van de netwerkinterface waarop pakketten vertaald worden.
af
De adresfamilie, ofwel inet voor IPv4 ofwel inet6
voor IPv6. PF kan deze parameter gewoonlijk bepalen op basis van het (de)
bron/bestemmingsadres(sen).
src_addr
Het (intern) bronadres van pakketten die vertaald zullen worden.
Het bronadres kan gespecificeerd worden als:
Een "fully qualified domain name" die via DNS vertaald zal worden wanneer
de regelset geladen wordt. Alle resulterende IP adressen zullen
gesubstitueerd worden in de regel.
De naam of groep van een netwerkinterface.
Gelijk welke IP adressen toegekend
aan de interface zullen gesubstitueerd worden in de regel bij het laden.
De naam van een netwerkinterface gevolgd door
/netmask (bv. /24). Elk IP adres op de interface
wordt gecombineerd met het netmask om een CIDR netwerkblok te vormen
dat gesubstitueerd wordt in de regel.
De naam of groep van een netwerkinterface gevolgd door gelijk welke van
deze modifiers:
:network - substitueert het CIDR netwerkblok (bv.
192.168.0.0/24)
:broadcast - substitueert het netwerk broadcast adres
(bv. 192.168.0.255)
:peer - substitueert het IP adres van de peer bij een
punt-tot-punt verbinding
Bijkomend kan de :0 modifier aan ofwel een interfacenaam/groep
of aan gelijk welke van de bovenstaande modifiers vastgehangen worden
om aan te geven dat PF geen ge-aliaste IP adressen in de substitutie
moet opnemen.
Deze modifiers kunnen ook gebruikt worden wanneer de interface tussen
haakjes staat.
Voorbeeld: fxp0:network:0
De laatste twee zijn binaire operatoren (ze nemen twee argumenten)
en bevatten de argumenten in het bereik niet.
: (inclusief bereik)
De inclusief bereik operator is ook een binaire operator en
bevat de argumenten in het bereik niet.
De port optie wordt gewoonlijk niet gebruikt in nat regels
omdat het doel gewoonlijk is om NAT te doen voor alle verkeer ongeacht de
gebruikte poort(en).
dst_addr
Het bestemmingsadres van de pakketten die vertaald moeten worden. Het
bestemmingsadres wordt op dezelfde manier gespecificeerd als het bronadres.
dst_port
De bestemmingspoort in de Layer 4 pakkethoofding. Deze poort wordt
op dezelfde manier gespecificeerd als de bronpoort.
ext_addr
Het externe (vertalings)adres op de NAT gateway waarnaar pakketten
zullen vertaald worden. Het externe adres kan gespecificeerd worden als:
Een "fully qualified domain name" die via DNS zal vertaald worden wanneer
de regelset geladen wordt.
De naam van een externe netwerkinterface. Gelijk welke IP adressen
toegekend aan de interface zullen gesubsitueerd worden in de regel bij
het laden.
De naam van de externe netwerkinterface tussen haakjes ( ). Dit
vertelt PF om de regel te updaten als het (de) IP adres(sen) op de genoemde
interface verandert (veranderen). Dit is nuttig op een interface die haar
IP adres via DHCP of dial-up verkrijgt aangezien de regelset niet hoeft
herladen te worden elke keer het adres verandert.
De naam van een netwerkinterface gevolgd door gelijk welke van deze
modifiers:
:network - substitueert het CIDR netwerkblok (bv.
192.168.0.0/24)
:peer - substitueert het IP adres van de peer bij een
punt-tot-punt verbinding
Bijkomend kan de :0 modifier aan ofwel een interfacenaam
of aan gelijk welke van de bovenstaande modifiers vastgehangen worden
om aan te geven dat PF geen ge-aliaste IP adressen in de substitutie
moet opnemen.
Deze modifiers kunnen ook gebruikt worden wanneer de interface tussen
haakjes staat.
Voorbeeld: fxp0:network:0
Specificeert het type van adrespool om te
gebruiken voor de vertaling.
static-port
Vertelt PF om de bronpoort in TCP en UDP pakketten niet te vertalen.
Dit zou leiden tot een heel elementaire vorm van deze lijn, gelijkaardig
aan dit:
nat on tl0 from 192.168.1.0/24 to any -> 24.5.0.5
Deze regel zegt NAT uit te voeren op de tl0 interface voor gelijk
welke pakketten die komen van 192.168.1.0/24 en om het bron IP adres te
vervangen door 24.5.0.5.
Hoewel de bovenstaande regel juist is, is het niet de aanbevolen vorm.
Onderhoud zou moeilijk kunnen zijn aangezien gelijk welke verandering van
de externe of interne netwerknummers zou vereisen dat de lijn veranderd
wordt. Vergelijk in de plaats met deze gemakkelijker te onderhouden lijn
(tl0 is extern, dc0 intern):
nat on tl0 from dc0:network to any -> tl0
Het voordeel zou redelijk duidelijk moeten zijn: u kan de IP adressen van
van beide interfaces veranderen zonder deze regel hoeven te veranderen.
Wanneer u een interfacenaam specificeert voor het vertalingsadres zoals
hierboven, wordt het IP adres bepaald op het moment dat pf.conf
geladen wordt, niet "on the fly". Als u DHCP gebruikt om uw externe
interface te configureren, kan dit een probleem zijn. Als uw toegekend
IP adres verandert, zal NAT verder gaan met uitgaande pakketten te vertalen
met het oude IP adres. Dit zal ervoor zorgen dat uitgaande verbindingen
ophouden te werken. Om hier om heen te geraken, kan u PF vertellen
automatisch het vertalingsadres te updaten door haakjes rond de
interfacenaam te zetten:
nat on tl0 from dc0:network to any -> (tl0)
Deze methode werkt voor vertaling naar zowel IPv4 als IPv6 adressen.
Bidirectionele Afbeelding (1:1 mapping)
Een bidirectionele afbeelding kan opgericht worden door de binat
regel te gebruiken. Een binat regel richt een ййn tot ййn
afbeelding op tussen een intern IP adres en een extern adres. Dit kan
nuttig zijn, bijvoorbeeld om een webserver op het interne netwerk te
voorzien met zijn eigen extern IP adres. Verbindingen vanaf het Internet
naar het externe adres zullen vertaald worden naar het interne adres en
verbindingen van de webserver (zoals DNS requests) zullen vertaald worden
naar het externe adres. TCP en UDP poorten worden nooit gewijzigd met
binat regels zoals dat gedaan wordt bij nat regels.
binat on tl0 from $web_serv_int to any -> $web_serv_ext
Vertalingsregel Uitzonderingen
Er kunnen uitzonderingen gemaakt worden op de vertalingsregels door het
no sleutelwoord. Als het NAT voorbeeld hierboven bijvoorbeeld
gewijzigd werd om er zo uit te zien:
no nat on tl0 from 192.168.1.208 to any
nat on tl0 from 192.168.1.0/24 to any -> 24.2.74.79
Dan zou het volledige 192.168.1.0/24 netwerk zijn pakketten vertaald
zien naar het externe adres 24.2.74.79, behalve 192.168.1.208.
Merk op dat de eerste overeenstemmende regel wint; als het een no
regel is, dan wordt het pakket niet vertaald. Het no sleutelwoord
kan ook gebruikt worden met binat en
rdr regels.
NAT Status Nakijken
Om de actieve NAT vertalingen te bekijken wordt
pfctl(8) gebruikt met de -s state optie. Deze optie zal al de
huidige NAT sessies opsommen:
# 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
Uitleg (enkel eerste lijn):
fxp0
Geeft de interface aan waarmee de toestand verbonden is. Het woord
self zal verschijnen als de toestand
floating is.
TCP
Het protocol dat door de verbinding gebruikt wordt.
192.168.1.35:2132
Het IP adres (192.168.1.35) van de machine op het interne netwerk.
De bronpoort (2132) wordt getoond na het adres. Dit is ook het adres dat
vervangen wordt in de IP hoofding.
24.5.0.5:53136
Het IP adres (24.5.0.5) en de poort (53136) op de gateway waarnaar
pakketten vertaald worden.
65.42.33.245:22
Het IP adres (65.42.33.245) en de poort (22) waarnaar de interne
machine aan het verbinden is.
TIME_WAIT:TIME_WAIT
Dit geeft aan in welke staat PF denkt dat de TCP verbinding zich bevindt.