Tri linuxové hosty, jeden návrh: verejne dostupný hub OpenVPN, spotrebiteľský notebook a výstupný stroj za bežným domácim routerom, ktorý dovnútra nič nepreposiela. Výstup sa k hubu pripája sám. Potom prevádzka spotrebiteľa do internetu vstupuje do tunela na notebooku a vychádza vlastným upstreamom výstupu. Všetko prekvapivé v tomto usporiadaní vyplýva z jedného detailu: spojenie inicioval výstup, takže cesta dovnútra už existuje a na jej vytvorenie netreba presmerovanie portu.

Nasledujúci text sleduje cestu paketu, nie poradie konfigurácie, pretože konfigurácia má zmysel až vtedy, keď viete, ktorá komponenta rozhoduje o čom. Každá vrstva rozhoduje presne o jednej veci a chyby sa kopí tam, kde sa dve vrstvy považujú za jednu.

Dve transportné relácie, jedna vnútorná cesta

Každý host drží vlastné vonkajšie spojenie k hubu a ani jedno o tom druhom nič nevie. Prevádzka spotrebiteľa do internetu je samostatný vnútorný tok, ktorý sa nesie vnútri tunela spotrebiteľa a potom sa znovu vysiela z tunela výstupu. Práve tento tok musí hub smerovať a práve ten musí výstup preposielať.

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

Keďže obe vonkajšie spojenia odchádzajú z klientskej strany, router výstupu nikdy nevidí prichádzajúci SYN a nepotrebuje pravidlo cieľového NAT. Musí len udržiavať nadviazaný transport živý, čo už robí pre každé dlhodobé spojenie. Nič na verejnom internete nemusí najprv dosiahnuť výstup, a preto dynamická adresa na tomto uplinku nie je problém. Router stále musí povoliť odchádzajúcu reláciu, ale to je to isté povolenie, ktoré už používa prehliadač.

Čo iroute skutočne inštaluje vnútri servera

Hub je jediné zariadenie, ktoré rozhoduje, ktorý peer vlastní ktorú destináciu, a robí tak vo svojej vlastnej smerovacej tabuľke používateľského priestoru, nie v tabuľke jadra. Záznam client-config-dir pre výstup s menom exit-node tam môže nárokovať predvolený prefix:

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

Tento riadok hovorí serverovému procesu "vnútorné pakety s akoukoľvek destináciou patria tomuto klientovi". Nepridáva predvolenú trasu do operačného systému hubu a nerobí z hubu internetovú bránu. Referenčná príručka OpenVPN 2.6 drží vnútorné smerovanie špecifické pre klienta a smerovanie jadra ako oddelené mechanizmy, a práve toto oddelenie je dôvod, prečo návrh funguje bez zásahu do predvolenej trasy hubu.

Spotrebiteľ potrebuje zrkadlovú inštrukciu doručenú ako push, aby jeho vlastná prevádzka vstúpila do tunela, namiesto toho aby odišla cez miestnu bránu. Pri topológii podsiete je pool pripojená trasa na zariadení tun výstupu, takže spätný smer nepotrebuje ďalší push; čo výstup nesmie dostať, je presmerovanie nižšie, ktoré by poslalo jeho vlastnú upstreamovú prevádzku späť do tunela, ktorý sa snaží použiť. Posielajte ho len spotrebiteľovi a čítajte aplikované trasy na klientovi, namiesto toho aby ste verili, že bol vybraný súbor CCD.

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

Preposielanie vykonáva jadro výstupu

Vnútri výstupu dorazí paket od spotrebiteľa na rozhranie tun adresovaný nejakému internetovému hostu. Jadro nahliadne do svojej smerovacej tabuľky, nájde skutočný upstream ako najlepšiu zhodu a potom uplatní dve nezávislé politiky: či sa tento paket vôbec smie preposlať a či smie odísť týmto rozhraním s touto zdrojovou adresou. Preposielanie je sysctl a na mnohých distribúciách je predvolene vypnuté.

Výstup teda potrebuje trvalo zapnuté preposielanie IPv4, pravidlo, ktoré pripúšťa zdroje tunela spotrebiteľa k upstreamu, a cestu odpovede späť cez tun. Zapnutie preposielania pre celý host mení aj správanie všetkého ostatného, čo cez neho smeruje, a preto má pravidlo pomenovať zdroje a rozhrania, namiesto toho aby prijalo všetko.

Spiatočnú cestu kupuje preklad zdroja

Internetový host nemá trasu k adrese 10.90.0.x, takže odpovede by boli zahodené skôr, než by sa dostali k výstupu. Prepísanie zdroja pri odchode paketu z upstreamu to rieši a sledovanie spojení prepis na spiatočnej ceste obráti.

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

Pravidlo vyššie je východiskový bod pre jedno upstreamové rozhranie, nie firewallová politika. Zúžte zdroj na priradenia, ktoré ste skutočne autorizovali, a držte vlastnú vstupnú politiku výstupu oddelene, aby maskovanie prevádzky tunela ticho nevystavilo miestne služby. Na hoste s dynamickou adresou vás maskovanie ušetrí aj ručného sledovania adresy.

Kde hub môže presadzovať pravidlá a kde nie

S client-to-client a tradičnou dátovou cestou v používateľskom priestore hub odovzdáva vnútorné pakety medzi peermi vnútri serverového procesu. Nikdy neprechádzajú cez reťazec FORWARD jadra hubu, takže pravidlo v jadre tam nemôže obmedziť tranzit medzi peermi, akokoľvek starostlivo je napísané. Presadzovanie musí žiť vo vlastnej politike servera: kto sa smie pripojiť, aký súbor CCD dostane a či sa predvolené vlastníctvo výstupu vôbec udeľuje.

Preto je predvolený iroute široké rozhodnutie o dôvere. Výstup musí legitímne prijímať spätnú prevádzku z ľubovoľných internetových adries a musí to byť stroj, ktorý ovládate, záplatujete a sledujete. Udeliť rovnaké vlastníctvo peerovi, ktorému by ste router nezverili je chyba, ku ktorej tento návrh vyzýva.

Členstvo je skutočná kontrola. Každý klient, ktorý si vie nakonfigurovať vlastné trasy, môže skúsiť výstup použiť, takže obmedziť, kto sa smie pripojiť alebo ktorým peerom bude výstup slúžiť, je súčasťou návrhu, nie dodatočný nápad.

Bezpečne zlyhať, keď výstup zmizne

Odpojte výstup a vnútorné predvolené vlastníctvo zmizne spolu s jeho reláciou. Čo sa nesmie stať, je to, že sa hub ticho stane náhradným výstupom: žiadna predvolená trasa z poolu VPN do upstreamu hubu a žiadne široké pravidlo maskovania na hube, ktoré by tú istú prevádzku ochotne preposlalo. Otestujte toto zlyhanie zámerne a potom otestujte obnovu novým tokom, nie stránkou, ktorá už bola otvorená.

# 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

Ak sa prevádzka spotrebiteľa aj po zmiznutí výstupu stále dostane na internet, nesie ju niečo iné a zamýšľaná hranica neexistuje. Berte DNS a IPv6 tiež ako samostatné rozhodnutia: trasa IPv4 plus maskovanie nehovoria nič o prevádzke AAAA a resolver vytlačený hubom bude odpovedať odtiaľ, odkiaľ dopyt skutočne odchádza.

Súvisiace články