Jak se klient OpenVPN za NAT stane internetovým východem
Východ sám navazuje spojení, takže jeho router nepotřebuje žádný vstupní port. Sledujte, co hub směruje, co východ přeposílá a odkud se bere zpáteční cesta.
Tři linuxové hosty, jeden návrh: veřejně dostupný hub OpenVPN, spotřebitelský notebook a stroj východu za běžným domácím routerem, který dovnitř nic nepřeposílá. Východ se k hubu připojuje sám. Provoz spotřebitele pak u notebooku vstupuje do tunelu a vychází vlastním upstreamem východu. Vše překvapivé plyne z jednoho detailu: spojení inicioval východ, takže cesta dovnitř už existuje a přesměrování portu není potřeba.
Následující text sleduje cestu paketu, nikoli pořadí konfigurace, protože konfigurace dává smysl teprve tehdy, když víte, která komponenta o čem rozhoduje. Každá vrstva rozhoduje právě o jedné věci a chyby se kupí tam, kde se dvě vrstvy považují za jednu.
Dvě transportní relace, jedna vnitřní cesta
Každý host drží vlastní vnější spojení k hubu a ani jedno o tom druhém nic neví. Provoz spotřebitele do internetu je samostatný vnitřní tok, který se nese uvnitř tunelu spotřebitele a potom se znovu vysílá z tunelu východu. Právě tento tok musí hub směrovat a právě ten musí východ přeposílat.
outer: consumer --TLS--> hub
outer: exit --TLS--> hub
inner: consumer --tun--> hub --internal--> exit --tun--> uplink
Protože obě vnější spojení odcházejí z klientské strany, router východu nikdy nevidí příchozí SYN a nepotřebuje pravidlo cílového NAT. Musí jen udržovat navázaný transport živý, což už dělá pro každé dlouhodobé spojení. Nic na veřejném internetu nemusí nejdřív dosáhnout východu, a proto dynamická adresa na upstreamu není problém. Router stále musí odchozí relaci povolit, ale to je stejné povolení, které už používá prohlížeč.
Co iroute skutečně instaluje uvnitř serveru
Hub je jediné zařízení, které rozhoduje, který peer vlastní kterou destinaci, a činí tak ve své směrovací tabulce uživatelského prostoru, ne v tabulce jádra. Záznam client-config-dir pro východ se jménem exit-node tam může nárokovat výchozí prefix:
# /etc/openvpn/server/ccd/exit-node
iroute 0.0.0.0 0.0.0.0
Tento řádek říká serverovému procesu "vnitřní pakety s jakoukoli destinací patří tomuto klientovi". Nepřidává výchozí trasu do operačního systému hubu a nedělá z hubu internetovou bránu. Referenční příručka OpenVPN 2.6 drží vnitřní směrování specifické pro klienta a směrování jádra jako oddělené mechanismy, a právě toto oddělení je důvod, proč návrh funguje bez zásahu do výchozí trasy hubu.
Spotřebitel potřebuje zrcadlovou instrukci doručenou jako push, aby jeho provoz vstoupil do tunelu, místo aby odešel přes místní bránu. Při topologii podsítě je pool připojená trasa na zařízení tun východu, takže zpětný směr nepotřebuje další push; co východ nesmí dostat, je přesměrování níže, které by poslalo jeho upstreamový provoz zpět do tunelu, který se snaží použít. Posílejte ji jen spotřebiteli a čtěte aplikované trasy na klientovi, místo abyste věřili, že byl vybrán soubor CCD.
# /etc/openvpn/server/ccd/consumer-01
push "redirect-gateway def1"
Přeposílání provádí jádro východu
Uvnitř východu dorazí paket od spotřebitele na rozhraní tun, adresovaný nějakému internetovému hostu. Jádro nahlédne do směrovací tabulky, najde skutečný upstream jako nejlepší shodu a uplatní dvě nezávislé politiky: smí se paket vůbec přeposílat a smí odejít tímto rozhraním s touto zdrojovou adresou. Přeposílání je sysctl a na mnoha distribucích je ve výchozím stavu vypnuté.
Východ tedy potřebuje trvale zapnuté přeposílání IPv4, pravidlo, které připouští zdroje tunelu spotřebitele k upstreamu, a cestu odpovědi zpět přes tun. Zapnutí pro celý host mění i chování všeho ostatního, co přes něj směruje, a proto má pravidlo jmenovat zdroje a rozhraní, místo aby přijímalo všechno.
Zpáteční cestu kupuje překlad zdroje
Internetový host nemá trasu k adrese 10.90.0.x, takže odpovědi by byly zahozeny dřív, než by se dostaly k východu. Přepsání zdroje při odchodu paketu z upstreamu to řeší a sledování spojení přepis na zpáteční cestě obrátí.
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 výše je výchozí bod pro jedno upstreamové rozhraní, ne firewallová politika. Zužte zdroj na přiřazení, která jste skutečně povolili, a držte vstupní politiku východu oddělenou, aby maskování provozu tunelu tiše nevystavilo místní služby. Na hostu s dynamickou adresou vás maskování ušetří i ručního sledování adresy.
Kde hub může pravidla prosazovat a kde ne
S client-to-client a tradiční datovou cestou v uživatelském prostoru předává hub vnitřní pakety mezi peery uvnitř serverového procesu. Nikdy neprocházejí řetězem FORWARD jádra hubu, takže pravidlo v jádře tam nemůže omezit tranzit mezi peery, jakkoli pečlivě je napsané. Prosazování musí žít v politice serveru: kdo se smí připojit, jaký soubor CCD dostane a zda se výchozí vlastnictví východu vůbec uděluje.
Proto je výchozí iroute široké rozhodnutí o důvěře. Východ musí legitimně přijímat zpětný provoz z libovolných internetových adres a musí to být stroj, který ovládáte, záplatujete a sledujete. Udělit stejné vlastnictví peerovi, kterému byste router nesvěřili je chyba, ke které tento návrh vybízí.
Členství je skutečná kontrola. Každý klient, který si umí nakonfigurovat vlastní trasy, může východ zkusit použít, takže omezit, kdo se smí připojit nebo kterým peerům bude východ sloužit, je součástí návrhu, ne dodatečný nápad.
Bezpečné selhání, když východ zmizí
Odpojte východ a vnitřní výchozí vlastnictví zmizí spolu s jeho relací. Co se nesmí stát, je to, že se hub tiše stane náhradním východem: žádná výchozí trasa z poolu VPN do upstreamu hubu a žádné široké pravidlo maskování, které by stejný provoz ochotně přeposlalo. Otestujte toto selhání záměrně a potom obnovu novým tokem, ne stránkou, která už byla otevřená.
# 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
Jestliže se provoz spotřebitele i po zmizení východu stále dostane na internet, nese ho něco jiného a hranice, kterou jste zamýšleli, neexistuje. Berte DNS a IPv6 jako samostatná rozhodnutí: trasa IPv4 plus maskování neříká nic o provozu AAAA a resolver protlačený hubem bude odpovídat odtud, odkud dotaz skutečně odchází.