Näytti siltä, että NAT käyttää IP-osoitteen lisäksi porttia jonkinlaisena tarkennusosoitteena. Eli jos sisäverkon laitteelta tulee nettihaku (sisäinen osoite A, portti P) ulkoiseen osoitteeseen U ja toiselta laitteelta samanlainen haku (sisäinen osoite B, portti P) samaan osoitteeseen U, niin NAT vaihtaa A:n hakuun portiksi Q:n ja B:n hakuun portiksi R, ja molempiin tulee osoitteeksi tulee päätelaitteen C .
Kun sitten nettihaun vastaus tulee osoitteesta U ja portista Q tai R, niin portin perusteella tiedetään, ohjataanko se A:lle vai B:lle, ja osoite vaihdetaan vastaavasti – niin, ja myös portti vaihdetaan.
Jep, noinhan se menee. Ehdin kirjoitella hieman pidemmän selvityksen, joten laitan sen vielä tähän:
Kun avaat kotikoneesi nettiselaimella sivun
https://fast.com, selain selvittää ensin palvelimen IP-osoitteen DNS:n avulla. Olkoon se vaikka 23.13.33.111 (kyseessä on Akamain kautta hajautettu palvelu, joten eri selvityskerrat palauttavat eri osoitteen). Sitten selain lähettää HTTP-protokollan mukaisen GET-pyynnön TLS-salattuna osoitteen 23.13.33.111 porttiin 443, joka on siis standardi HTTPS:n TCP/IP-porttinumero. Salaamaton HTTP-pyyntö lähetettäisiin porttiin 80. Palvelin vastaa kyselyyn lähettämällä takaisin index.html-sivun sisällön.
Pykälää matalammalla tasolla viestinvälitys perustuu TCP/IP-protokollalla muodostettavaan yhteyteen, jossa viestejä kulkee itse asiassa molempiin suuntiin ennen kuin päästään edes itse asiaan, koska käyttöjärjestelmäsi TCP/IP-protokollapino
kättelee palvelimen kanssa. Sitä seuraa vielä TLS-salauksen vaatima kättely ja sertifikaattien varmistus. TCP/IP-yhteyttä pidetään kättelyn jälkeen auki ainakin niin kauan, että korkeamman tason HTTP-pyyntö saadaan toimitettua perille, ja vastaus toimitettua takaisin selaimelle. Käytännössä saman yhteyden yli ladataan myös sivun oheissisältöä, kuten kuvia ja skriptejä.
Osapuolten välinen viestiliikenne on pilkkoutuu TCP/IP-paketteihin, joiden otsakkeissa on tietoina kohdeosoite ja portti sekä lähdeosoite ja portti. Viestinvälitystä varten kotikoneesi käyttöjärjestelmä varaa satunnaisesti valitun vapaan TCP-porttinumeron (Linuxissa väliltä 32768 to 60999), esim. 48765, ja laittaa itselleen muistiin, että kyseisellä porttinumerolla lähetetyt ja vastaanotetut paketit kuuluvat tähän tiettyyn yhteyteen. Siten käyttöjärjestelmä osaa toimittaa vastaanottamiensa, porttinumerolla 48765 varustettujen pakettien sisällön oikeaan paikkaan (socketiin), ja selain saa pyyntöönsä vastauksen. Kaikki järjestelmän avoimet yhteydet voi listata komennolla
netstat tai
ss.
Selaimesi ja käyttöjärjestelmäsi, sekä vastapuolen palvelin ovat kuitenkin autuaan tietämättömiä siitä, että välissä on kotiverkon reititin, joka tekee osoitteenmuunnoksen ja porttimuunnoksen (PAT, NAPT). Tällöin kotikoneeltasi lähtevät TCP/IP-paketit, joiden lähetysportiksi ja osoitteeksi on merkitty 192.168.1.106:48765 välittyvät reitittimelle, joka vaihtaakin lähettäjän osoitteeksi internetiin näkyvän ulkoisen IP:n 91.66.77.88 ja portiksi satunnaisesti valitsemansa 59876. Reititin merkitsee samalla itselleen muistiin, että ulkoisen IP-osoitteen porttiin 59876 tulevat paketit välitetään toistaiseksi sisäverkon koneelle 192.168.1.106 porttiin 48765. fast.com-palvelimen osoite ja portti 23.13.33.111:443 pysyvät TCP/IP-paketeissa muuttumattomina. Sitten, kun reititin saa internetistä tulevan TCP/IP-paketin, jossa on kohteeksi on merkitty 91.66.77.88:59876, se vaihtaa osoitteeksi ja portiksi 192.168.1.106:48765 ja välittää paketin sisäverkkoon tietokoneellesi. Tietokoneesi ja käyttöjärjestelmäsi ei huomaa tapahtunutta osoitteenvaihdosta mitenkään. Fast.com puolestaan näkee, että yhteys on avattu osoitteesta 91.66.77.88, ja ilmoittaa sen tekstinä lähettämänsä HTML-sivun sisällössä.
Tässä kuvilla varustettu, kohtalaisen selkeä artikkeli aiheesta:
https://www.practicalnetworking.net/series/nat/dynamic-pat/Mutta entä sitten, jos sisäisellä laitteella (vaikkapa Ubuntu-tietokoneella) on kaksi käyttäjää, jotka molemmat tekevät nettihakuja, vieläpä samalla ohjelmalla, jolloin hakujen lähtöosoitteet ovat samat ja portitkin ovat samat?
Käyttöjärjestelmän sisällä homma toimii pistokkeilla eli socketeilla. Selain pyytää jokaista avaamaansa yhteyttä varten käyttöjärjestelmän TCP/IP-pinolta
socketin, jonka kautta viestit lähetetään ja otetaan vastaan. Selain ei välitä, minkä portin käyttöjärjestelmä varaa liikennettä varten, eikä selain näe TCP/IP-paketteja.
Käytännössä siis jokaisella selaimeen avaamallasi välilehdellä on varattuna yksi tai useampia erillisiä socketeja, joille käyttöjärjestelmä on varannut erilliset porttinsa. Kannattaa tosiaan vilkaista ss:n ja netstatin listauksia samalla, kun selaimessa on auki sivustoja eri välilehdillä. Ne listaavat avoimet socketit riveittäin. Sarakkaissa on mm. molempien osapuolten osoitteet ja portit sekä socketin avanneen prosessin tiedot (PID, komento).
ss -p -r
netstat -t -p