To A-poster, én adresse, én dæmon: uanset hvilket navn en bruger skriver, er pakken, der ankommer, identisk, og processen bundet til port 1194 har intet at skelne de to med. Det er ikke en fejlkonfiguration, der venter på at blive rettet; det er grænsen for, hvad et navneopslag kan udtrykke. Alt, der vælger mellem to OpenVPN-instanser, skal være en værdi, som klienten lægger i forbindelsen, og som frontenden kan læse tilbage, og en standard OpenVPN-klient lægger ingen sådan værdi i det åbne. Det følgende handler om, hvor det efterlader dig, og hvilke arrangementer der reelt deler trafikken.

Begynd med det, resolveren giver tilbage

En klient spørger efter vpn-a.example og får en adresse; den adresse plus en port er alt, hvad den ringer til. Navnet bruges lokalt under opslaget og bliver aldrig et felt på ledningen, så lytteren i den anden ende kan ikke se, hvilken etiket der blev brugt. Peg vpn-a.example og vpn-b.example på én vært, og begge opslag giver samme destination, og derfor opsuger dæmonen begge forbindelser i én instans uden at registrere en forskel. Adressebaserede profiler opfører sig præcis som navnebaserede, af samme grund.

Det lukker også en familie af fristende omveje: ekstra aliaser, at vælge et certifikat pr. navn på én socket eller en firewallregel bundet til det navn, der blev spurgt om. Ingen af dem kan handle på information, der allerede var kasseret, før den første pakke forlod klienten. Hvis to servere skal forblive adskilte, skal opdelingen rejse med selve forbindelsen, hvilket betyder en adresse, en port eller et nyttelastfelt, som protokollen definerer.

Den eneste vælger, der tæller, kører inde i pakken

HTTP klarer det med en Host-header, og TLS klarer det med en server name-udvidelse i ClientHello, og det er sådan én adresse betjener mange websteder bag én lytter. Begge virker, fordi ledningsprotokollen bærer en anmodning om en bestemt tjeneste. Det relevante faktum om OpenVPN er, at ingen af de felter findes på det lag, en mellemboks undersøger.

I et standardarrangement sker TLS-håndtrykket, der beskytter kontrolkanalen, efter at den ydre session er etableret, og bæres inde i den, så en lytter, der ikke har afsluttet den session, ser en uigennemsigtig strøm. Den kan stadig se, at det er OpenVPN, fordi opkod og indramning i de første bytes er genkendelige, men servernavnet, hvis det findes, sidder i den krypterede del. Et design, der forventer at læse en virtuel vært fra den ydre pakke, læser et felt, som protokollen aldrig skriver der. Det kommer fra, hvordan tunnelen er bygget, ikke fra et hul, som en smartere mønstermatchning kunne lukke.

Hvor en protokolsplitter stopper

En multiplekser af den slags, som sslh-projektet dokumenterer, lytter på én port, undersøger de første bytes og giver forbindelsen videre til den backend, der taler den protokol, den genkendte. Det er reel værdi, når én port skal betjene SSH, HTTPS og OpenVPN sammen.

sslh holder en separat sonde pr. protokol, og dens TLS-sonde kan trække et servernavn eller en ALPN-værdi ud af et ægte ClientHello. At genkende native OpenVPN er en anden klassificering end at læse en TLS-udvidelse, og de to komponerer ikke, fordi en klient, der aldrig sender et ClientHello til lytte-socketten, efterlader sonden uden noget at læse. En regel, der matcher OpenVPN, svarer derfor “dette er en OpenVPN-klient” og går ikke videre. To OpenVPN-backends bag den regel kan ikke skelnes, frontenden har intet grundlag for et valg, og hver session lander samme sted. Multipleksing deler én port mellem forskellige tjenester; det udfører ikke virtuel hosting inde i én tjeneste.

Arrangementer, der reelt adskiller to servere

Den billigste ærlige opdeling er en anden offentlig adresse, én pr. instans, og eksisterende profiler har allerede det nødvendige, fordi de peger på forskellige adresser. Den næste er en anden port på samme adresse, hvilket ikke koster andet end et tal i hver profil. TCP og UDP holder separate porttabeller, så 1194/tcp og 1194/udp er ubeslægtede sockets, og en af hver kan eksistere på samme vært; det er transportadskillelse snarere end navnerouting, og det forveksles ofte med det. Begge muligheder overlever en firewallgennemgang, fordi reglen matcher noget, som pakken faktisk indeholder.

Hvis den grænse, du har brug for, går mellem grupper af brugere i stedet for mellem to implementeringer, kan én instans med forskellige klientkonfigurationer, egen certifikathåndtering og en udtrykkelig adgangspolitik dække det. Det køber politik inde i en server, ikke isolation mellem servere, og de to er forskellige krav. Isolation, der skal holde under kompromittering, kræver stadig adressen eller firewallkanten.

En TLS-terminator foran OpenVPN kan blotlægge et rigtigt servernavn for en kompetent frontend, men kun når klientsiden også er konfigureret til det ekstra lag. Eksisterende profiler får ikke adfærden ved at blive peget på samme adresse.

Bevis vælgeren, før du bygger

Navngiv det felt, der skal identificere en backend, og bekræft derefter, at klienten faktisk sender det; hvis svaret er en adresse, holder planen, og hvis det er et servernavn inde i et håndtryk, der aldrig når lytteren, kan ingen mængde DNS-arbejde redde det. Tre kommandoer afgør lytterens side hurtigt.

ss -lntup | grep -E ':443|:1194'
openssl s_client -connect vpn-a.example:443 -servername vpn-a.example </dev/null | head -n 20
journalctl -u openvpn-server@server-a -n 20 --no-pager

openssl-linjen giver kun et certifikat, hvor noget på den adresse afslutter TLS; mod en native OpenVPN-lytter går den i stå eller fejler, og det er i sig selv svaret på, hvad det ydre lag blotlægger. journal-linjen, læst på hver backend, viser, hvilken instans der accepterede sessionen. Frontend-logfiler registrerer, hvad der blev klassificeret, og aldrig hvad der var hensigten, så backenden er fortsat den eneste autoritet for, hvor en bruger landede.

Slut af med to profiler, der er beregnet til at nå forskellige servere, forbind dem en ad gangen, og noter backend-loggen for hver. Hvis begge sessioner dukker op i samme journal, mangler vælgeren, snarere end at den er fejlkonfigureret, og rettelsen er en adresse eller en port, som klienten kan målrette. Det hjælper ikke at redigere routingreglen, fordi reglen aldrig har fået noget at route på. Når opdelingen er reel, så skriv den ved siden af profilerne, så den næste person ikke tilføjer et ekstra alias og forventer, at det gør arbejdet.

Relaterede artikler