Kolme Linux-isäntää, yksi suunnitelma: julkisesti saavutettava OpenVPN-keskitin, kuluttajan kannettava ja ulostulokone tavallisen kotireitittimen takana, joka ei välitä mitään sisäänpäin. Ulostulo soittaa itse keskittimelle. Sitten kuluttajan internettietoliikenne astuu tunneliin kannettavalla ja lähtee ulostulon omasta ylävirran linkistä. Kaikki tässä järjestelyssä yllättävä seuraa yhdestä yksityiskohdasta: ulostulo aloitti yhteyden, joten sisäänpäin menevä polku on jo olemassa eikä portinohjausta tarvita sen luomiseen.

Seuraava seuraa paketin polkua eikä kokoonpanon järjestystä, koska kokoonpano on mielekäs vasta kun tietää, mikä komponentti tekee minkä päätöksen. Jokainen kerros tekee täsmälleen yhden päätöksen, ja virheet kasaantuvat sinne, missä kaksi kerrosta oletetaan yhdeksi.

Kaksi kuljetusistuntoa, yksi sisäinen polku

Jokainen isäntä pitää oman ulkoisen yhteytensä keskittimeen, eikä kumpikaan näistä yhteyksistä tiedä toisesta. Kuluttajan liikenne internetiin on erillinen sisäinen virta, joka sattumalta kuljetetaan kuluttajan tunnelin sisällä ja lähetetään sitten uudelleen ulostulon tunnelista. Keskitin joutuu reitittämään juuri tämän sisäisen virran, ja ulostulo välittämään sen.

outer: consumer --TLS--> hub
outer: exit     --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink

Koska molemmat ulkoiset yhteydet lähtevät asiakkaan puolelta, ulostulon reititin ei koskaan näe saapuvaa SYN:iä eikä tarvitse koskaan kohde-NAT-sääntöä. Sen on vain pidettävä muodostettu kuljetus elossa, minkä se tekee jo jokaiselle pitkäikäiselle yhteydelle. Minkään julkisessa internetissä ei tarvitse saavuttaa ulostuloa ensin, siksi dynaaminen osoite tuossa ylävirran linkissä ei ole ongelma. Reitittimen on silti sallittava lähtevä istunto, mutta se on sama lupa, jota selain jo käyttää.

Mitä iroute oikeastaan asentaa palvelimen sisään

Keskitin on ainoa laite, joka päättää, mikä vastin omistaa minkä kohteen, ja se tekee päätöksen omassa käyttäjäavaruuden reititystaulussaan, ei ytimen taulussa. Ulostulon client-config-dir-merkintä nimeltä exit-node voi vaatia siellä oletusetuliitteen:

# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0

Tuo rivi kertoo palvelinprosessille "sisäiset paketit millä tahansa kohteella kuuluvat tälle asiakkaalle". Se ei lisää oletusreittiä keskitimen käyttöjärjestelmään eikä tee keskitimestä internet-yhdyskäytävää. OpenVPN 2.6 -viite pitää asiakaskohtaisen sisäisen reitityksen ja ytimen reitityksen erillisinä mekanismeina, ja juuri tämä erottelu on syy siihen, että suunnitelma toimii koskematta keskitimen oletusreittiin.

Kuluttaja tarvitsee peilikuvana olevan ohjeen pushina toimitettuna, jotta hänen oma liikenteensä astuu tunneliin paikallisen yhdyskäytävän kautta lähtemisen sijaan. Aliverkkotopologiassa allas on yhdistetty reitti ulostulon tun-laitteella, joten paluusuunta ei tarvitse lisäpushia; mitä ulostulo ei saa vastaanottaa, on alla oleva uudelleenohjaus, joka lähettäisi sen oman ylävirran liikenteen takaisin tunneliin, jota se yrittää käyttää. Lähetä se vain kuluttajalle ja lue käytetyt reitit asiakkaalta sen sijaan, että luottaisit CCD-tiedoston valintaan.

# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"

Ulostulon ydin tekee välityksen

Ulostulon sisällä kuluttajan paketti saapuu tun-rajapinnalle johonkin internet-isäntään osoitettuna. Ydin katsoo reititystauluaan, löytää todellisen ylävirran linkin parhaana osumana ja soveltaa sitten kahta riippumatonta käytäntöä: saako tätä pakettia välittää lainkaan ja saako se lähteä tuosta rajapinnasta tuolla lähdeosoitteella. Välitys on sysctl, ja se on monissa jakeluissa oletuksena pois päältä.

Ulostulo tarvitsee siis pysyvästi käytössä olevan IPv4-välityksen, välityssäännön, joka päästää kuluttajan tunnelin lähteet ylävirran linkkiä kohti, ja vastauspolun takaisin tun:n kautta. Välityksen käyttöönotto koko isännälle muuttaa myös kaiken muun sen kautta reitittyvän käyttäytymistä, siksi säännön pitäisi nimetä lähteet ja rajapinnat sen sijaan, että se hyväksyy kaiken.

Paluupolku ostetaan lähdeosoitteen käännöksellä

Internet-isännällä ei ole reittiä osoitteeseen 10.90.0.x, joten vastaukset pudotettaisiin ennen kuin ne koskaan saavuttaisivat ulostulon. Lähdeosoitteen uudelleenkirjoitus paketin lähtiessä ylävirran linkistä ratkaisee sen, ja yhteyksien seuranta kääntää uudelleenkirjoituksen paluumatkalla.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -s 10.90.0.0/24 -o enp1s0 -j MASQUERADE
ip -4 route get 10.90.0.9   # run on the exit: must point at the tun

Yllä oleva sääntö on lähtökohta yhdelle ylävirran rajapinnalle, ei palomuurikäytäntö. Kavennä lähde niihin määrityksiin, jotka todella valtuutit, ja pidä ulostulon oma syötekäytäntö erillään, jotta tunneliliikenteen maskaus ei hiljaa paljasta paikallisia palveluita. Isännällä, jonka ylävirran osoite on dynaaminen, maskaus säästää sinut myös osoitteen seuraamiselta käsin.

Missä keskitin voi valvoa ja missä ei

client-to-client:n ja perinteisen käyttäjäavaruuden datapolun kanssa keskitin ojentaa sisäiset paketit vastineiden välillä palvelinprosessin sisällä. Ne eivät koskaan kulje keskitimen ytimen FORWARD-ketjun läpi, joten ytimen sääntö siellä ei voi rajoittaa vastineiden välistä kulkua, kuinka huolellisesti tahansa kirjoitettu. Valvonnan on elettävä palvelimen omassa käytännössä: kuka saa yhdistää, minkä CCD-tiedoston hän saa ja myönnetäänkö ulostulon oletusomistus lainkaan.

Siksi oletus-iroute on laaja luottamuspäätös. Ulostulon on laillisesti hyväksyttävä paluuliikennettä mielivaltaisista internet-osoitteista, ja sen on oltava kone, jota hallitset, paikkaat ja valvot. Saman omistuksen antaminen vastineelle, jolle et antaisi reititintä on se virhe, johon tämä suunnitelma kutsuu.

Jäsenyys on todellinen valvonta. Kuka tahansa asiakas, joka osaa määrittää omat reittinsä, voi yrittää käyttää ulostuloa, joten sen rajaaminen, kuka saa yhdistää tai ketä ulostulo palvelee, on osa suunnitelmaa eikä jälkijättöinen ajatus.

Turvallinen epäonnistuminen, kun ulostulo katoaa

Kytke ulostulo pois ja sisäinen oletusomistus katoaa istuntonsa mukana. Mitä ei saa tapahtua, on se, että keskitimestä tulee hiljaa korvaava ulostulo: ei oletusreittiä VPN-altaasta keskitimen ylävirran linkkiin eikä laajaa maskaussääntöä keskitimessä, joka välittäisi saman liikenteen mielellään. Testaa tuo vika tarkoituksella ja sitten palautuminen tuoreella virralla, ei sivulla, joka oli jo auki.

# on the consumer, with the exit up and then down
ip -4 route get 1.1.1.1
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com

Jos kuluttajan liikenne saavuttaa internetin vielä ulostulon kadottua, jokin muu kuljettaa sitä eikä aiottua rajaa ole. Käsittele DNS ja IPv6 myös erillisinä päätöksinä: IPv4-reitti ja maskaus eivät kerro mitään AAAA-liikenteestä, ja keskitimen työntämä resolver vastaa sieltä, mistä kysely todella lähtee.

Aiheeseen liittyvät artikkelit