Hetzelfde server-IP, twee paden: de buitenste flow van OpenVPN markeren
Een hostroute die de VPN-server uitzondert, zondert ook HTTPS naar die server uit. Markeer in plaats daarvan de versleutelde envelop en geef niet-gemarkeerd verkeer de tunnel.
De gebruikelijke lusbeveiliging is een hostroute: stuur verkeer naar het openbare adres van de VPN-server via de uplink naar buiten, zodat de versleutelde sessie nooit in zijn eigen tunnel terechtkomt. Dat werkt precies tot het moment waarop je ook een webdienst op dezelfde server via de tunnel wilt bereiken, want de uitzondering hangt aan de bestemming en de bestemming is identiek. De uitweg is stoppen met classificeren op bestemming en in plaats daarvan classificeren op welke socket het pakket heeft verzonden.
Begin bij de twee flows die je wilt scheiden
De ene flow is het versleutelde OpenVPN-transport zelf, dat via de uplink naar buiten moet, anders zou de tunnel zijn eigen buitenste verbinding dragen. De andere is een gewoon HTTPS-verzoek aan hetzelfde openbare adres, dat je binnen de tunnel wilt hebben zodat het bij de dienst aankomt met een tunnelbron. Dezelfde bestemming, in veel gevallen hetzelfde poortnummer, een ander vereist pad.
Voor deze uiteenzetting nemen we een client op 10.90.0.10 via tun1, een openbaar serveradres van 198.51.100.25 en een onaangeroerde hoofdtabel waarvan de standaard naar de gewone uplink wijst. De serverkant moet de webdienst ook op het binnenste pad accepteren en verkeer terugsturen naar de tunnelbron; een pakket naar een openbaar adres sturen overrulet de listener of het firewallbeleid van de server niet.
Voordat je iets wijzigt, leg je de huidige regels van de host vast en kies je waarden die niemand anders gebruikt: een mark, een tabelnummer en drie regelprioriteiten. Houd een toegang terug de machine in open die niet over deze verbinding loopt, want een fout hier haalt je eigen externe toegang weg in plaats van alleen een browsertab te breken.
Markeer de socket die de envelop draagt
De clientconfiguratie krijgt een mark voor zijn versleutelde uitgaande pakketten en installeert zelf geen routes meer, zodat het vervangingsbeleid het enige is dat paden bepaalt:
mark 42
route-noexec
disable-dco
Decimaal 42 is hexadecimaal 0x2a, en die hexvorm is wat de routeringsregels matchen. De referentie voor link-opties beschrijft mark als iets dat op Linux geldt voor versleutelde uitgaande pakketten, precies de socket waarvan je het pad moet beheren. Het uitzetten van de data-kanaal-offload houdt dit voorbeeld op het userspace-pad, waar het markgedrag het gedrag is dat hier wordt beschreven.
route-noexec onderdrukt het automatisch toevoegen en verwijderen van routes door OpenVPN. Het zet daar niets voor in de plaats, dus vanaf dit moment moet de route-eigenaar elke route onderhouden die de tunnel nodig heeft. Als een private bestemming na de wijziging verdwijnt, is dat het ontbrekende vervangingsbeleid en geen fout in de mark.
Houd tijdens deze wijziging geen hostroute in de hoofdtabel voor 198.51.100.25 aan. Zo'n route herintroduceert precies de uitzondering die het ontwerp probeert te vernauwen, en hij wint voor de HTTPS-flow voordat een van de beleidsregels hieronder wordt geraadpleegd.
Stuur al het overige naar de tunneltabel
Zodra de tunnelinterface bestaat en zijn adres heeft, ziet het beleid er zo uit:
ip -4 route add default dev tun1 src 10.90.0.10 table 47100
ip -4 rule add priority 20000 lookup main suppress_prefixlength 0
ip -4 rule add priority 20001 not fwmark 0x2a lookup 47100
ip -4 rule add priority 20002 not fwmark 0x2a unreachable
De eerste regel houdt de specifieke routes van de host zichtbaar, inclusief een goedgekeurd lokaal netwerk, terwijl hij de standaardroute van de hoofdtabel onzichtbaar maakt voor deze opzoeking. Dat onderscheid is belangrijk: de standaard onderdrukken is niet hetzelfde als de tabel negeren, en de lokale uitzonderingen die je nog nodig hebt, overleven daardoor. Lees die uitzonderingen een voor een in plaats van aan te nemen dat het resultaat een universele noodschakelaar is.
Niet-gemarkeerd verkeer valt dan naar de tunneltabel, neemt de tunnelbron over en verlaat de host via de VPN. Gemarkeerd verkeer faalt op de fwmark-test van de volgende twee regels en gaat verder naar de gewone hoofdopzoeking verderop in de lijst, waar de uplink-standaard nog staat. De afsluitende unreachable-regel is wat voorkomt dat een niet-gemarkeerde flow stilletjes terugvalt op de uplink wanneer de tunnelroute ontbreekt. De selector is van begin tot eind de mark, en het bestemmingsadres komt nooit in de beslissing terecht.
Houd die bewaking in stand over verbindingen heen, en installeer hem samen met de rest van het beleid in plaats van met de hand. Een regel die met de interface verdwijnt, is geen beleid maar een toeval. Het beleid verwijderen wanneer de tunnel wegvalt, verandert de faalmodus van “geblokkeerd” naar “gelekt”, en een verouderde tunnelroute die later verloopt, is een veel makkelijker uit te leggen probleem dan verkeer dat via de verkeerde interface naar buiten ging.
Laat het retourpad dezelfde mark zien
Uitgaande marks zijn maar de helft van het mechanisme, en dit is het deel dat de meeste reproducties overslaan. Antwoorden op de versleutelde sessie komen binnen via de uplink en zijn onderworpen aan reverse-path-validatie, die vraagt of de bron dezelfde weg terug zou routeren. Zonder hulp past die opzoeking jouw niet-gemarkeerde tunnelbeleid toe en concludeert dat het pakket op de verkeerde interface zit.
De oplossing hoort bij de firewall-eigenaar: sla de mark op bij de uitgaande verbinding, herstel hem op overeenkomende inkomende pakketten en schakel bron-gevalideerde markafhandeling in voor het betreffende pad. Dat OpenVPN een socketmark zet, doet geen van die drie dingen, en een recept dat alleen de clientopties noemt, is onvolledig. Vraag die integratie schriftelijk aan, want het is het minst zichtbare deel van het ontwerp en het makkelijkst te verliezen bij een herbouw.
Ook losse reverse-path-controle is geen vervanging. Losse modus heeft nog steeds een route nodig voor de bron, en de unreachable-bewaking die je toevoegde haalt er bewust een weg voor niet-gemarkeerde opzoekingen. Laat de integratie van de verbindingsmark afronden en beoordelen voordat je op dit ontwerp vertrouwt, en behandel hostfilters als een aparte vraag: een mark is een routeringsignaal, geen toestemming. Ontbreekt de integratie, dan is het symptoom een sessie die opkomt en daarna stil wordt zodra antwoorden beginnen aan te komen.
Bewijs het met twee route-opzoekingen
Vergelijk wat de kernel voor de twee contexten beslist, en lees de velden dev en src in plaats van de exitstatus:
ip -4 route get 198.51.100.25
ip -4 route get 198.51.100.25 mark 0x2a
De eerste opzoeking hoort naar tun1 met de tunnelbron te wijzen, en de tweede naar de uplink. Dat zijn synthetische opzoekingen, dus ze bewijzen het beleid en niet het draaiende proces: bevestig het werkelijke transportpad van de draaiende client apart en doe daarna een echt HTTPS-verzoek met certificaatverificatie aan.
Schrijf op wat het ontwerp niet dekt voordat je het als klaar bestempelt. DNS, IPv6 en de levensduur van de regels vragen elk hun eigen beslissing, en dit is een IPv4-routeringsvoorbeeld in plaats van een volledige privacyconfiguratie. De waarde zit in de selector: de envelop krijgt de uplink-uitzondering, en een gewone dienst op hetzelfde adres hoeft die niet te erven.