Tri Linux hosta, jedan dizajn: javno dostupno OpenVPN čvorište, korisnički laptop i izlazna mašina iza običnog kućnog rutera koji ništa ne prosljeđuje prema unutra. Izlaz sam zove čvorište. Korisnički saobraćaj zatim ulazi u tunel na laptopu i izlazi kroz vlastiti izlazni link izlaza. Sve iznenađujuće slijedi iz jednog detalja: izlaz je započeo vezu, pa put prema unutra već postoji i port forward nije potreban.

Ono što slijedi prati put paketa, a ne redoslijed konfiguracije, jer konfiguracija ima smisla tek kad znate koji komponent nosi koju odluku. Svaki sloj nosi tačno jednu odluku, a greške se gomilaju gdje se dva sloja smatraju istim.

Dvije transportne sesije, jedan unutrašnji put

Svaki host drži vlastitu vanjsku vezu prema čvorištu i nijedna ne zna za drugu. Korisnički saobraćaj prema internetu je odvojen unutrašnji tok koji se prenosi unutar korisničkog tunela, a zatim ponovo emituje iz tunela izlaza. Čvorište mora rutirati taj tok, a izlaz ga mora prosljeđivati.

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

Pošto su obje vanjske veze odlazne sa klijentske strane, ruter izlaza nikada ne vidi dolazni SYN i ne treba mu pravilo za odredišni NAT. Mora samo održavati uspostavljeni transport živim, što već čini za svaku dugotrajnu vezu. Ništa na javnom internetu ne mora prvo stići do izlaza, zato dinamička adresa na tom linku nije problem. Ruter i dalje mora dozvoliti odlaznu sesiju, ali to je ista dozvola koju pretraživač već koristi.

Šta iroute zapravo instalira unutar servera

Čvorište je jedini uređaj koji odlučuje koji peer posjeduje koje odredište, i to u vlastitoj korisničkoj rutnoj tabeli, a ne u kernelovoj. Unos client-config-dir za izlaz pod imenom exit-node može tamo zatražiti zadani prefiks:

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

Ta linija govori serverskom procesu "unutrašnji paketi s bilo kojim odredištem pripadaju ovom klijentu". Ne dodaje zadanu rutu u operativni sistem čvorišta i ne čini čvorište internet gatewayem. OpenVPN 2.6 referenca drži interno rutiranje specifično za klijenta i kernel rutiranje kao odvojene mehanizme, i to razdvajanje je razlog zašto dizajn radi bez diranja zadane rute čvorišta.

Korisniku treba zrcalna instrukcija, dostavljena kao push, da njegov saobraćaj uđe u tunel umjesto da izađe kroz lokalni gateway. U subnet topologiji pool je povezana ruta na tun uređaju izlaza, pa povratni smjer ne treba dodatni push; ono što izlaz ne smije dobiti je preusmjeravanje ispod, koje bi poslalo njegov izlazni saobraćaj natrag u tunel koji pokušava koristiti. Pošaljite ga samo korisniku i čitajte primijenjene rute na klijentu, umjesto da vjerujete da je CCD datoteka odabrana.

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

Kernel izlaza obavlja prosljeđivanje

Unutar izlaza paket od korisnika stiže na tun interfejs, adresiran na neki internet host. Kernel konsultuje rutnu tabelu, nalazi pravi izlazni link kao najbolje poklapanje, pa primjenjuje dvije nezavisne politike: smije li se paket uopšte proslijediti i smije li izaći kroz taj interfejs s tom izvornom adresom. Prosljeđivanje je sysctl i na mnogim distribucijama je isključeno po zadanom.

Dakle, izlazu treba trajno omogućeno IPv4 prosljeđivanje, pravilo koje propušta izvore korisničkog tunela prema linku i povratni put kroz tun. Omogućavanje za cijeli host mijenja i ponašanje svega drugog što rutira kroz njega, zato pravilo treba imenovati izvore i interfejse umjesto prihvatiti sve.

Povratni put kupuje prevođenje izvora

Internet host nema rutu do adrese 10.90.0.x, pa bi odgovori bili odbačeni prije nego stignu do izlaza. Prepisivanje izvora dok paket napušta link to rješava, a praćenje konekcija poništava prepisivanje na povratku.

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

Pravilo iznad je početna tačka za jedan izlazni interfejs, ne firewall politika. Suzite izvor na dodjele koje ste odobrili i držite ulaznu politiku izlaza odvojenom, da maskiranje tunelskog saobraćaja tiho ne izloži lokalne servise. Na hostu s dinamičkom adresom maskiranje vas štedi i ručnog praćenja adrese.

Gdje čvorište može, a gdje ne može provesti pravila

Uz client-to-client i tradicionalni korisnički put podataka, čvorište predaje unutrašnje pakete između peerova unutar serverskog procesa. Oni nikada ne prolaze kroz kernel FORWARD lanac čvorišta, pa kernel pravilo tamo ne može ograničiti peer-to-peer tranzit, koliko god pažljivo bilo napisano. Provođenje mora živjeti u politici servera: ko se smije povezati, koju CCD datoteku dobija i da li se zadano vlasništvo izlaza uopšte daje.

Zato je zadani iroute široka odluka o povjerenju. Izlaz mora legitimno prihvatati povratni saobraćaj s proizvoljnih internet adresa i mora biti mašina koju kontrolišete, ažurirate i nadzirete. Dati isto vlasništvo peeru kojem ne biste dali ruter je greška na koju ovaj dizajn poziva.

Članstvo je prava kontrola. Svaki klijent koji može konfigurisati vlastite rute može pokušati koristiti izlaz, pa je ograničavanje ko se smije povezati, ili kojim peerovima izlaz služi, dio dizajna, a ne naknadna misao.

Siguran neuspjeh kada izlaz nestane

Isključite izlaz i unutrašnje zadano vlasništvo nestaje s njegovom sesijom. Ne smije se dogoditi da čvorište tiho postane zamjenski izlaz: nikakva zadana ruta iz VPN poola u link čvorišta i nikakvo široko pravilo maskiranja koje bi rado proslijedilo isti saobraćaj. Testirajte taj neuspjeh namjerno, a zatim oporavak svježim tokom, ne stranicom koja je već bila otvorena.

# 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

Ako korisnički saobraćaj i nakon odlaska izlaza stiže na internet, nosi ga nešto drugo i granica koju ste namjeravali ne postoji. Tretirajte DNS i IPv6 kao odvojene odluke: IPv4 ruta plus maskiranje ne govori ništa o AAAA saobraćaju, a resolver koji čvorište gurne odgovarat će odakle upit zaista izlazi.

Povezani članci