Dit artikel analyseert hoe Network Address Translation (NAT) heeft bijgedragen aan de huidige centralisatie van het internet. Oorspronkelijk geïntroduceerd in RFC 1631 als een kortetermijnoplossing voor de uitputting van IPv4-adressen, zorgt NAT ervoor dat meerdere apparaten één publiek IP-adres delen. Hoewel dit praktisch was voor IP-beheer, maakte het inkomende verbindingen naar persoonlijke computers complex.
De auteur bespreekt verschillende omwegen die zijn ontwikkeld om NAT te omzeilen, zoals:
- Port forwarding en UPnP: Handmatige of automatische configuraties om verkeer door te sturen, die vaak geblokkeerd worden door ISP's (CGNAT).
- STUN, TURN en ICE: Complexere protocollen (gebruikt in WebRTC) om verbindingen tot stand te brengen, vaak via externe relaisservers.
Hoewel IPv6 de definitieve oplossing had moeten zijn door iedereen een uniek wereldwijd adres te geven, is de adoptie traag en worden NAT-achtige principes soms zelfs op IPv6 toegepast. De conclusie is dat NAT het client-servermodel heeft genormaliseerd en het draaien van eigen services (zoals FTP- of mailservers) bemoeilijkt heeft, wat de weg vrijmaakte voor de huidige 'walled gardens' en de dominantie van de cloud.
Internetcentralisatie en de oorspronkelijke zonde van NAT
Iemand die "goed is met computers" maar geen netwerkspecialist is, heeft waarschijnlijk een mentaal model van het internet waarbij "servers" of "de cloud" op een betekenisvolle manier worden onderscheiden van persoonlijke computers. Echt peer-to-peer is, als ze daarover nadenken, een hele onderneming: WebRTC, STUN, TURN, ICE, enzovoort. Gezien het feit dat we in een wereld leven van NAT, CGNAT en restrictieve ISP's, is dit niet geheel onjuist, maar het doorbreekt het elegante ontwerp van het oorspronkelijke internet.
Waarom je geen FTP-server hebt
Network Address Translation (NAT) werd voor het eerst formeel voorgesteld in RFC 1631 in 1994. In de samenvatting staat:
De twee meest dwingende problemen waar het IP-internet voor staat, zijn de uitputting van IP-adressen en de schaalbaarheid van routing. Er worden korte- en langetermijnoplossingen voor deze problemen ontwikkeld. De kortetermijnoplossing is CIDR (Classless InterDomain Routing). De langetermijnoplossingen bestaan uit diverse voorstellen voor nieuwe internetprotocollen met grotere adressen.
Classless Inter-Domain Routing is niet het punt van dit artikel, maar in essentie begon men mensen meer opties te geven voor netwerkgroottes. Hoewel de implementatie complex was, was dit filosofisch gezien vrijwel onomstreden.
RFC 1631 stelde een tweede kortetermijnoplossing voor voor de uitputting van IP-adressen en de schaalbaarheid van routing: NAT. Hoewel dit niet precies hetzelfde type NAT is als wat vandaag de dag alomtegenwoordig is op thuisrouters, is het basisidee hetzelfde: het stelt meerdere apparaten in staat om één IP-adres te delen (vanuit het perspectief van een apparaat aan de andere kant van een routing-apparaat). Dit gebeurt door de netwerkadresinformatie in de IP-pakketheaders te wijzigen tijdens het verzenden van het pakket via een router. Later zijn bepaalde adressen gereserveerd voor privégebruik, en deze worden in combinatie gebruikt op de meeste IP-netwerken: privéadressen binnen het netwerk, die via NAT worden omgezet naar één publiek adres bij de router.
Op een typische thuisrouter werkt de verbinding met een externe server via NAT als volgt:
Je computer verzendt een pakket zoals dit:
- Bron IP: 10.11.70.21
- Bron Poort: 50413
- Bestemmings IP: 67.215.249.229
- Bestemmings Poort: 70
Het pakket bereikt je router, die het wijzigt naar:
- Bron IP: 146.7.15.85
- Bron Poort: 60612
- Bestemmings IP: 67.215.249.229
- Bestemmings Poort: 70
De server antwoordt:
- Bestemmings IP: 146.7.15.85
- Bestemmings Poort: 60612
Je router schrijft dit terug naar:
- Bestemmings IP: 10.11.70.21
- Bestemmings Poort: 50413
Als je hierover nadenkt, vraag je je misschien af: wat gebeurt er als een externe server als eerste met jou wil communiceren? De server stuurt een pakket naar 146.7.15.85, en je router...
Helaas. De router heeft geen idee waar hij het pakket naartoe moet sturen.
Omwegen en oplossingen
Natuurlijk merkten mensen vrijwel direct dat dit een probleem was, omdat mensen sinds het begin der tijden al gameservers, FTP-servers en webservers vanuit hun slaapkamer willen draaien. Daarom is er een heel ecosysteem aan omwegen ontstaan rondom NAT, waarvan geen enkele de fundamentele intentie van het internet herstelt en geen enkele voor elk scenario werkt.
Port forwarding (Poortdoorsturing)
De meest directe oplossing is om je router simpelweg te vertellen: "Hé, wanneer er een pakket binnenkomt op poort 60612, stuur het dan direct naar 10.11.70.21 op poort 50413, zonder vragen." Dit is port forwarding, en het is de meest bekende omweg voor NAT.
Een conceptueel probleem met port forwarding is dat één publiek IP + poort nog steeds maar naar één apparaat tegelijk kan worden toegewezen. Dit betekent dat twee apparaten geen service op dezelfde publieke IP + poort kunnen draaien. Dit is problematischer dan het klinkt; op grote bedrijfsnetwerken of universiteitsnetwerken die worden teruggebracht tot een klein aantal of zelfs slechts één publiek IP, maakt dit on-prem hosting vrijwel onmogelijk zonder nog complexere maatregelen. Bovendien heeft je ISP je externe IP soms ook achter NAT geplaatst — dit wordt Carrier-Grade NAT (CGNAT) genoemd. In dat geval heb je geen controle over het apparaat dat de vertaling uitvoert en kun je geen poorten doorsturen. Je bezit dan slechts een fractie van een fractie van een IP-adres.
Omdat niemand zich graag bezig houdt met handmatige configuraties, is het volgende uitgevonden:
UPnP
UPnP, en modernere varianten zoals NAT-PMP en PCP, probeerden het probleem van de gebruiksvriendelijkheid op te lossen door software direct aan de router te laten vragen om poorten door te sturen. Net als bij handmatige port forwarding is dit een verzoek aan je router; als je ISP je blokkeert, heb je pech. Bovendien is UPnP vaak uitgeschakeld vanwege misplaatste beveiligingsideeën — deels door een paar vroege, foutieve implementaties, en deels omdat het idee dat iemand zomaar verbinding kan maken met je computer voor veel mensen exotisch of gevaarlijk voelt. Er zijn genoeg geldige redenen om een firewall te willen, maar als je dat doet, implementeer deze dan bewust in plaats van te vertrouwen op het feit dat NAT niet weet waar pakketten naartoe gestuurd moeten worden.
STUN, TURN en ICE
- STUN (Session Traversal Utilities for NAT): In plaats van samenwerking met de firewall te zoeken, vraagt STUN simpelweg aan een server op het publieke internet: "Hoe ziet mijn pakket eruit op het moment dat het jou bereikt?" De STUN-server geeft het publieke IP en de poort terug die door je NAT zijn toegewezen, bijvoorbeeld
146.7.15.85:60612. Bij een "cone NAT", waarbij de router voor alle uitgaande verbindingen een identieke externe poortmapping gebruikt, werkt dit uitstekend. Je kunt deze mapping doorgeven aan een peer, die vervolgens direct pakketten naar jou kan sturen. Deze techniek staat bekend als hole punching. Echter, bij een "symmetric NAT" — gebruikelijk bij CGNAT en institutionele netwerken — krijg je voor elke verschillende bestemming een andere publieke poort. In dat geval is de STUN-mapping nutteloos voor het verbinden met een peer, omdat zij jou anders zien dan de STUN-server.
- TURN (Traversal Using Relays around NAT): Dit is simpelweg het doorsturen van verkeer via een relaisserver, waarbij beide zijden uitgaande verbindingen met deze server maken. Dit werkt bijna overal, maar omdat iemand een server moet draaien die eigenlijk onnodig is en je te maken hebt met extra latentie omdat elk pakket via een derde partij moet, is dit een zeer ongewenste oplossing.
- ICE (Interactive Connectivity Establishment): ICE accepteert dat geen enkele techniek volledig betrouwbaar is en probeert ze allemaal in volgorde van voorkeur. Het overweegt alles: directe verbinding, een via STUN ontdekt extern adres, of een TURN-relais. De lijst wordt uitgewisseld met de andere partij en er wordt geprobeerd tot er iets werkt. Dit is wat WebRTC doet, en het is het beste resultaat dat je op het huidige internet kunt behalen. Maar we hebben hiermee een eenvoudige directe verbinding vervangen door grotendeels externe infrastructuur.
De langetermijnoplossing die dat niet werd
De belangrijkste "langetermijnoplossing" waar RFC 1631 naar verwees, was IPv6. Dit had het probleem moeten oplossen door iedereen een echt, wereldwijd uniek adres te geven, waardoor NAT overbodig zou worden.
De adoptie van IPv6 lijkt echter te vroeg te stagneren. Zelfs waar het is geïmplementeerd, blijven veel ISP's en institutionele netwerken NAT-achtige praktijken hanteren uit inertie en wederom misplaatste beveiligingsideeën: firewalls die inkomend verkeer weigeren omdat men gewend is dat NAT dat doet, of het volledig onnodig toepassen van daadwerkelijke NAT op IPv6 — vaak door Unique Local Addresses (fc00::/7) in te zetten op de manier waarop men privé RFC1918-ruimte op IPv4 gebruikt, wat volkomen onbegrijpelijk is.
De gevolgen voor het internet
Er zijn veel zaken aan te wijzen die het open internet hebben gedood, maar ik denk dat NAT een van de vroegste was. Het draaien van een server was vroeger triviaal: start een executable, vertel mensen je adres, en klaar. Nu moet je, als je geluk hebt, poortdoorsturing configureren, wat vaak onmogelijk is als je achter CGNAT zit of op een institutioneel netwerk bent aangesloten.
Bovendien heeft het iedereen geleerd te denken dat het client-servermodel natuurlijk is. "Mijn apparaat praat met De Cloud, die praat met andere apparaten" voelt normaal, terwijl dat gevoel is ontstaan als een artefact van adressentekort. Het probleem waar de mensen in de XKCD-strip voor staan, is de absurditeit van het proberen te vestigen van een één-op-één communicatie waarbij beide zijden alleen uitgaande verbindingen kunnen maken. Nog ironischer is dat NAT genormaliseerd is als een beveiligingsfunctie — "je apparaten zijn verborgen!" — wat juist een van de redenen is waarom mensen zich verzetten tegen de oplossing die het probleem zou verhelpen.
NAT is zeker niet de enige reden waarom het moderne internet vol zit met gecentraliseerde walled gardens, maar het was wel de eerste. Het is de reden waarom het moeilijk is om een bestand naar iemand te sturen, waarom je je e-mail niet op je eigen computer draait, en waarom het draaien van je eigen services moeilijk en vaak duur is (als je geen poorten kunt doorsturen via je eigen internetverbinding, moet je een VPS kopen in plaats van hardware te gebruiken die je al hebt).
***
¹ Ja, ik gooi hier NAT en PAT op één hoop. Sorry.
Internetcentralisatie en de oorspronkelijke zonde van NAT
Iemand die "goed is met computers" maar geen netwerkspecialist is, heeft waarschijnlijk een mentaal model van het internet waarbij "servers" of "de cloud" op een betekenisvolle manier worden onderscheiden van persoonlijke computers. Echt peer-to-peer is, als ze daarover nadenken, een hele onderneming: WebRTC, STUN, TURN, ICE, enzovoort. Gezien het feit dat we in een wereld leven van NAT, CGNAT en restrictieve ISP's, is dit niet geheel onjuist, maar het doorbreekt het elegante ontwerp van het oorspronkelijke internet.
Waarom je geen FTP-server hebt
Network Address Translation (NAT) werd voor het eerst formeel voorgesteld in RFC 1631 in 1994. In de samenvatting staat:
De twee meest dwingende problemen waar het IP-internet voor staat, zijn de uitputting van IP-adressen en de schaalbaarheid van routing. Er worden korte- en langetermijnoplossingen voor deze problemen ontwikkeld. De kortetermijnoplossing is CIDR (Classless InterDomain Routing). De langetermijnoplossingen bestaan uit diverse voorstellen voor nieuwe internetprotocollen met grotere adressen.
Classless Inter-Domain Routing is niet het punt van dit artikel, maar in essentie begon men mensen meer opties te geven voor netwerkgroottes. Hoewel de implementatie complex was, was dit filosofisch gezien vrijwel onomstreden.
RFC 1631 stelde een tweede kortetermijnoplossing voor voor de uitputting van IP-adressen en de schaalbaarheid van routing: NAT. Hoewel dit niet precies hetzelfde type NAT is als wat vandaag de dag alomtegenwoordig is op thuisrouters, is het basisidee hetzelfde: het stelt meerdere apparaten in staat om één IP-adres te delen (vanuit het perspectief van een apparaat aan de andere kant van een routing-apparaat). Dit gebeurt door de netwerkadresinformatie in de IP-pakketheaders te wijzigen tijdens het verzenden van het pakket via een router. Later zijn bepaalde adressen gereserveerd voor privégebruik, en deze worden in combinatie gebruikt op de meeste IP-netwerken: privéadressen binnen het netwerk, die via NAT worden omgezet naar één publiek adres bij de router.
Op een typische thuisrouter werkt de verbinding met een externe server via NAT als volgt:
Je computer verzendt een pakket zoals dit:
- Bron IP: 10.11.70.21
- Bron Poort: 50413
- Bestemmings IP: 67.215.249.229
- Bestemmings Poort: 70
Het pakket bereikt je router, die het wijzigt naar:
- Bron IP: 146.7.15.85
- Bron Poort: 60612
- Bestemmings IP: 67.215.249.229
- Bestemmings Poort: 70
De server antwoordt:
- Bestemmings IP: 146.7.15.85
- Bestemmings Poort: 60612
Je router schrijft dit terug naar:
- Bestemmings IP: 10.11.70.21
- Bestemmings Poort: 50413
Als je hierover nadenkt, vraag je je misschien af: wat gebeurt er als een externe server als eerste met jou wil communiceren? De server stuurt een pakket naar 146.7.15.85, en je router...
Helaas. De router heeft geen idee waar hij het pakket naartoe moet sturen.
Omwegen en oplossingen
Natuurlijk merkten mensen vrijwel direct dat dit een probleem was, omdat mensen sinds het begin der tijden al gameservers, FTP-servers en webservers vanuit hun slaapkamer willen draaien. Daarom is er een heel ecosysteem aan omwegen ontstaan rondom NAT, waarvan geen enkele de fundamentele intentie van het internet herstelt en geen enkele voor elk scenario werkt.
Port forwarding (Poortdoorsturing)
De meest directe oplossing is om je router simpelweg te vertellen: "Hé, wanneer er een pakket binnenkomt op poort 60612, stuur het dan direct naar 10.11.70.21 op poort 50413, zonder vragen." Dit is port forwarding, en het is de meest bekende omweg voor NAT.
Een conceptueel probleem met port forwarding is dat één publiek IP + poort nog steeds maar naar één apparaat tegelijk kan worden toegewezen. Dit betekent dat twee apparaten geen service op dezelfde publieke IP + poort kunnen draaien. Dit is problematischer dan het klinkt; op grote bedrijfsnetwerken of universiteitsnetwerken die worden teruggebracht tot een klein aantal of zelfs slechts één publiek IP, maakt dit on-prem hosting vrijwel onmogelijk zonder nog complexere maatregelen. Bovendien heeft je ISP je externe IP soms ook achter NAT geplaatst — dit wordt Carrier-Grade NAT (CGNAT) genoemd. In dat geval heb je geen controle over het apparaat dat de vertaling uitvoert en kun je geen poorten doorsturen. Je bezit dan slechts een fractie van een fractie van een IP-adres.
Omdat niemand zich graag bezig houdt met handmatige configuraties, is het volgende uitgevonden:
UPnP
UPnP, en modernere varianten zoals NAT-PMP en PCP, probeerden het probleem van de gebruiksvriendelijkheid op te lossen door software direct aan de router te laten vragen om poorten door te sturen. Net als bij handmatige port forwarding is dit een verzoek aan je router; als je ISP je blokkeert, heb je pech. Bovendien is UPnP vaak uitgeschakeld vanwege misplaatste beveiligingsideeën — deels door een paar vroege, foutieve implementaties, en deels omdat het idee dat iemand zomaar verbinding kan maken met je computer voor veel mensen exotisch of gevaarlijk voelt. Er zijn genoeg geldige redenen om een firewall te willen, maar als je dat doet, implementeer deze dan bewust in plaats van te vertrouwen op het feit dat NAT niet weet waar pakketten naartoe gestuurd moeten worden.
STUN, TURN en ICE
- STUN (Session Traversal Utilities for NAT): In plaats van samenwerking met de firewall te zoeken, vraagt STUN simpelweg aan een server op het publieke internet: "Hoe ziet mijn pakket eruit op het moment dat het jou bereikt?" De STUN-server geeft het publieke IP en de poort terug die door je NAT zijn toegewezen, bijvoorbeeld
146.7.15.85:60612. Bij een "cone NAT", waarbij de router voor alle uitgaande verbindingen een identieke externe poortmapping gebruikt, werkt dit uitstekend. Je kunt deze mapping doorgeven aan een peer, die vervolgens direct pakketten naar jou kan sturen. Deze techniek staat bekend als hole punching. Echter, bij een "symmetric NAT" — gebruikelijk bij CGNAT en institutionele netwerken — krijg je voor elke verschillende bestemming een andere publieke poort. In dat geval is de STUN-mapping nutteloos voor het verbinden met een peer, omdat zij jou anders zien dan de STUN-server.
- TURN (Traversal Using Relays around NAT): Dit is simpelweg het doorsturen van verkeer via een relaisserver, waarbij beide zijden uitgaande verbindingen met deze server maken. Dit werkt bijna overal, maar omdat iemand een server moet draaien die eigenlijk onnodig is en je te maken hebt met extra latentie omdat elk pakket via een derde partij moet, is dit een zeer ongewenste oplossing.
- ICE (Interactive Connectivity Establishment): ICE accepteert dat geen enkele techniek volledig betrouwbaar is en probeert ze allemaal in volgorde van voorkeur. Het overweegt alles: directe verbinding, een via STUN ontdekt extern adres, of een TURN-relais. De lijst wordt uitgewisseld met de andere partij en er wordt geprobeerd tot er iets werkt. Dit is wat WebRTC doet, en het is het beste resultaat dat je op het huidige internet kunt behalen. Maar we hebben hiermee een eenvoudige directe verbinding vervangen door grotendeels externe infrastructuur.
De langetermijnoplossing die dat niet werd
De belangrijkste "langetermijnoplossing" waar RFC 1631 naar verwees, was IPv6. Dit had het probleem moeten oplossen door iedereen een echt, wereldwijd uniek adres te geven, waardoor NAT overbodig zou worden.
De adoptie van IPv6 lijkt echter te vroeg te stagneren. Zelfs waar het is geïmplementeerd, blijven veel ISP's en institutionele netwerken NAT-achtige praktijken hanteren uit inertie en wederom misplaatste beveiligingsideeën: firewalls die inkomend verkeer weigeren omdat men gewend is dat NAT dat doet, of het volledig onnodig toepassen van daadwerkelijke NAT op IPv6 — vaak door Unique Local Addresses (fc00::/7) in te zetten op de manier waarop men privé RFC1918-ruimte op IPv4 gebruikt, wat volkomen onbegrijpelijk is.
De gevolgen voor het internet
Er zijn veel zaken aan te wijzen die het open internet hebben gedood, maar ik denk dat NAT een van de vroegste was. Het draaien van een server was vroeger triviaal: start een executable, vertel mensen je adres, en klaar. Nu moet je, als je geluk hebt, poortdoorsturing configureren, wat vaak onmogelijk is als je achter CGNAT zit of op een institutioneel netwerk bent aangesloten.
Bovendien heeft het iedereen geleerd te denken dat het client-servermodel natuurlijk is. "Mijn apparaat praat met De Cloud, die praat met andere apparaten" voelt normaal, terwijl dat gevoel is ontstaan als een artefact van adressentekort. Het probleem waar de mensen in de XKCD-strip voor staan, is de absurditeit van het proberen te vestigen van een één-op-één communicatie waarbij beide zijden alleen uitgaande verbindingen kunnen maken. Nog ironischer is dat NAT genormaliseerd is als een beveiligingsfunctie — "je apparaten zijn verborgen!" — wat juist een van de redenen is waarom mensen zich verzetten tegen de oplossing die het probleem zou verhelpen.
NAT is zeker niet de enige reden waarom het moderne internet vol zit met gecentraliseerde walled gardens, maar het was wel de eerste. Het is de reden waarom het moeilijk is om een bestand naar iemand te sturen, waarom je je e-mail niet op je eigen computer draait, en waarom het draaien van je eigen services moeilijk en vaak duur is (als je geen poorten kunt doorsturen via je eigen internetverbinding, moet je een VPS kopen in plaats van hardware te gebruiken die je al hebt).
***
¹ Ja, ik gooi hier NAT en PAT op één hoop. Sorry.