Tre Linux-vertar, eitt design: ein offentleg tilgjengeleg OpenVPN-hub, ein forbrukarbærbar og ein utgangsmaskin bak ein vanleg heimerutar som ikkje videresender noko innover. Utgangen ringjer sjølv til huben. Deretter går internettrafikken til forbrukaren inn i tunnelen på den berbare og ut gjennom utgangen sin eigen uplink. Alt overraskande ved dette følgjer av éin detalj: utgangen starta sambandet, så vegen innover finst allereie, og det trengst inga portvideresending for å lage han.

Det følgjande følgjer vegen til pakken framfor rekkjefølgja i konfigurasjonen, fordi konfigurasjonen først gjev meining når ein veit kva komponent som eig kva avgjerd. Kvart lag eig nøyaktig éi avgjerd, og feila samlar seg der to lag vert tekne for eitt.

To transportøktar, éin indre veg

Kvar vert held si eiga ytre samband til huben, og ingen av dei kjenner den andre. Trafikken til forbrukaren til internett er ein separat indre straum som tilfeldigvis vert boren inne i tunnelen til forbrukaren og deretter send ut att frå tunnelen til utgangen. Det er denne indre straumen huben må rute, og den utgangen må videresende.

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

Fordi begge dei ytre sambanda går utover frå klientsida, ser rutaren til utgangen aldri ein innkomande SYN og treng aldri ei destinasjons-NAT-regel. Han må berre halde den etablerte transporten i live, noko han allereie gjer for kvart langvarig samband. Ingenting på det opne internettet må først nå utgangen, og difor er ei dynamisk adresse på den uplinken ikkje noko problem. Rutaren må framleis tillate den utgåande økta, men det er same løyvet som ein nettlesar allereie brukar.

Kva iroute faktisk installerer inne i tenaren

Huben er den einaste eininga som avgjer kva peer som eig kva destinasjon, og han tek den avgjerda i si eiga brukartilstands-rutetabell, ikkje i kjerna si. Ei client-config-dir-oppføring for utgangen med namnet exit-node kan krevje standardprefikset der:

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

Den linja fortel tenarprosessen "indre pakkar med kva destinasjon som helst høyrer til denne klienten". Ho legg ikkje til ei standardrute i operativsystemet til huben og gjer ikkje huben til ein internett-gateway. OpenVPN 2.6-referanse held klientspesifikk intern ruting og kjerneruting som separate mekanismar, og den separasjonen er grunnen til at designet verkar utan å røre standardruta til huben.

Forbrukaren treng den spegelvende instruksjonen, levert som push, slik at hans eigen trafikk går inn i tunnelen i staden for ut gjennom den lokale gatewayen hans. Med subnettopologi er poolen ei tilkopla rute på tun-eininga til utgangen, så returretninga treng ingen ekstra push; det utgangen ikkje må ta imot, er omdirigeringa nedanfor, som ville sende hans eigen uplinktrafikk tilbake i tunnelen han prøver å bruke. Send han berre til forbrukaren, og les dei brukte rutene på klienten i staden for å stole på at CCD-fila vart vald.

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

Kjerna til utgangen gjer videresendinga

Inne i utgangen kjem ein pakke frå forbrukaren inn på tun-grensesnittet, adressert til ein eller annan internettvert. Kjerna slår opp i rutetabellen, finn den verkelege uplinken som beste treff og brukar deretter to uavhengige retningslinjer: kan denne pakken videresendast i det heile, og kan han forlate det grensesnittet med den kjeldadressa. Videresending er ein sysctl, og han er av som standard på mange distribusjonar.

Så utgangen treng varig påslått IPv4-videresending, ei regel som slepp tunnelkjeldene til forbrukaren til mot uplinken, og returvegen tilbake gjennom tun. Å slå på videresending for heile verten endrar òg åtferda til alt anna som rutast gjennom han, og difor bør regelen nemne kjeldene og grensesnitta i staden for å godta alt.

Returvegen vert kjøpt av kjeldeomsetjing

Ein internettvert har inga rute til ei 10.90.0.x-adresse, så svar ville bli forkasta før dei nådde utgangen. Å skrive om kjelda medan pakken forlèt uplinken løyser det, og sambandssporing snur omskrivinga på vegen tilbake.

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

Regelen ovanfor er eit utgangspunkt for eitt uplink-grensesnitt, ikkje ein brannmurpolitikk. Snevre kjelda inn til tildelingane du faktisk har autorisert, og hald eigen inngangspolitikk for utgangen skild, slik at maskering av tunneltrafikk ikkje stille eksponerer lokale tenester. På ein vert med dynamisk uplinkadresse sparer maskeringa deg òg for å spore adressa manuelt.

Kvar huben kan handheve og kvar han ikkje kan

Med client-to-client og den tradisjonelle brukarroms-datastien overleverer huben indre pakkar mellom peerar inne i tenarprosessen. Dei passerer aldri kjerne-FORWARD-kjeda til huben, så ein kjerneregel der kan ikkje avgrense peer-til-peer-transitt, same kor nøye han er skriven. Handheving må liggje i eigen politikk til tenaren: kven som får kople til, kva CCD-fil dei får, og om standardeigarskapet til utgangen i det heile vert gjeve.

Difor er ein standard-iroute ei brei tillitsavgjerd. Utgangen må rettmessig godta returtrafikk frå vilkårlege internettadresser, og han må vere ein maskin du kontrollerer, patchar og overvakar. Å gje same eigarskap til ein peer du ikkje ville gjeve ein rutar er feilen dette designet inviterer til.

Medlemskap er den eigentlege kontrollen. Kvar klient som kan konfigurere sine eigne ruter, kan prøve å bruke utgangen, så å avgrense kven som får kople til, eller kva peerar utgangen skal tene, er ein del av designet og ikkje ein ettertanke.

Feile trygt når utgangen forsvinn

Ta utgangen offline, og det interne standardeigarskapet forsvinn med økta. Det som ikkje må skje, er at huben stille vert erstatningsutgangen: inga standardrute frå VPN-poolen til uplinken til huben, og ingen brei maskeringsregel på huben som gjerne ville videresendt den same trafikken. Test den feilen med vilje, og test deretter attoppretting med ein fersk straum i staden for ei side som allereie var open.

# 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

Om trafikken til forbrukaren framleis når internett etter at utgangen er borte, ber noko anna han, og grensa du hadde tenkt på finst ikkje. Handsame DNS og IPv6 òg som separate avgjerder: ei IPv4-rute pluss maskering seier ingenting om AAAA-trafikk, og ein resolver som huben skyv på, vil svare frå der førespurnaden faktisk forlèt.

Relaterte artiklar