Kaksi DNS-nimeä, yksi OpenVPN-portti: mikä oikeastaan valitsee
Kaksi samaan osoitteeseen osoittavaa isäntänimeä päätyvät silti yhdelle kuuntelijalle. Vain kenttä, jonka asiakas lähettää, voi valita backendin, eikä natiivi OpenVPN lähetä sellaista.
Kaksi A-tietuetta, yksi osoite, yksi taustaprosessi: minkä nimen käyttäjä kirjoittaa, saapuva paketti on sama, eikä porttiin 1194 sidotulla prosessilla ole mitään, millä erottaa ne toisistaan. Tämä ei ole korjausta odottava väärä asetus; se on raja sille, mitä nimikysely voi ilmaista. Kaiken, mikä valitsee kahden OpenVPN-instanssin välillä, on oltava arvo, jonka asiakas laittaa yhteyteen ja jonka frontend voi lukea takaisin, eikä tavallinen OpenVPN-asiakas laita sellaista arvoa näkyviin. Seuraavaksi käydään läpi, mihin se jättää sinut ja mitkä järjestelyt todella jakavat liikenteen.
Aloita siitä, mitä resolveri palauttaa
Asiakas kysyy vpn-a.example ja saa osoitteen; tämä osoite plus portti on kaikki, mihin se soittaa. Nimi kuluu paikallisesti kyselyn aikana eikä siitä koskaan tule kenttää johdolle, joten toisen pään kuuntelija ei voi nähdä, mitä tunnistetta käytettiin. Kohdista vpn-a.example ja vpn-b.example samaan isäntään, ja molemmat haut antavat saman kohteen, minkä vuoksi taustaprosessi imee molemmat yhteydet yhteen instanssiin rekisteröimättä eroa. Osoitepohjaiset profiilit käyttäytyvät täsmälleen kuten nimipohjaiset, samasta syystä.
Tämä sulkee myös joukon houkuttelevia kiertoteitä: lisäaliakset, varmenteen valinta nimeä kohden yhdessä pistokkeessa tai kysyttyyn nimeen sidottu palomuurisääntö. Mikään niistä ei voi toimia tiedolla, joka oli jo hylätty ennen kuin ensimmäinen paketti lähti asiakkaasta. Jos kahden palvelimen on pysyttävä erillään, erottelun on kuljettava itse yhteyden mukana, eli osoite, portti tai protokollan määrittelemä hyötykuormakenttä.
Ainoa merkityksellinen valitsin kulkee paketin sisällä
HTTP hoitaa tämän Host-otsakkeella ja TLS palvelinnimen laajennuksella ClientHellossa, ja näin yksi osoite palvelee monia sivustoja yhden kuuntelijan takana. Molemmat toimivat, koska johdon protokolla kuljettaa pyyntöä tietystä palvelusta. Olennainen tosiasia OpenVPN:stä on, että kumpikaan näistä kentistä ei ole läsnä kerroksessa, jota välissä oleva laatikko tutkii.
Tavallisessa järjestelyssä ohjauskanavaa suojaava TLS-kättely tapahtuu, kun ulompi istunto on muodostettu, ja kuljetetaan sen sisällä, joten kuuntelija, joka ei ole päättänyt sitä istuntoa, näkee läpinäkymättömän virran. Se voi silti todeta, että kyse on OpenVPN:stä, koska aloitusbittien opcode ja kehystys ovat tunnistettavia, mutta palvelinnimi, jos sellainen on, istuu salatussa osassa. Suunnittelu, joka odottaa lukevansa virtuaalisen isännän ulommasta paketista, lukee kenttää, jota protokolla ei sinne koskaan kirjoita. Tämä johtuu siitä, miten tunneli on rakennettu, ei aukosta, jonka älykkäämpi kuviosovitus voisi sulkea.
Missä protokollan jakaja jää vajaaksi
Multiplekseri sitä tyyppiä, jota sslh-projekti dokumentoi, kuuntelee yhdellä portilla, tutkii aloitusbitit ja luovuttaa yhteyden sille backendille, joka puhuu tunnistettua protokollaa. Tämä on todellista arvoa, kun yhden portin on palveltava SSH, HTTPS ja OpenVPN yhdessä.
sslh pitää erillistä koetinta protokollaa kohden, ja sen TLS-koetin voi vetää palvelinnimen tai ALPN-arvon aidosta ClientHellosta. Natiivin OpenVPN:n tunnistaminen on eri luokittelu kuin TLS-laajennuksen lukeminen, eivätkä ne yhdisty, koska asiakas, joka ei koskaan lähetä ClientHelloa kuuntelevaan pistokkeeseen, jättää koettimen ilman luettavaa. Siksi OpenVPN:ään sopiva sääntö vastaa “tämä on OpenVPN-asiakas” eikä mene pidemmälle. Kaksi OpenVPN-backendia sen säännön takana ovat erottamattomia, frontendilla ei ole valinnalle perustaa, ja jokainen istunto päätyy samaan paikkaan. Multipleksointi jakaa yhden portin eri palvelujen kesken; se ei tee virtuaali-isännöintiä yhden palvelun sisällä.
Järjestelyt, jotka todella erottavat kaksi palvelinta
Halvin rehellinen erottelu on toinen julkinen osoite, yksi instanssia kohden, ja olemassa olevat profiilit kantavat jo tarvittavan, koska ne osoittavat eri osoitteisiin. Seuraava on eri portti samassa osoitteessa, mikä ei maksa mitään muuta kuin numeron kussakin profiilissa. TCP ja UDP pitävät erillisiä porttitauluja, joten 1194/tcp ja 1194/udp ovat toisiinsa liittymättömiä pistokkeita ja yksi kumpaakin voi olla samanaikaisesti samalla isännällä; se on kuljetuksen erottelua eikä nimipohjaista reititystä, ja se sekoitetaan usein siihen. Molemmat vaihtoehdot kestävät palomuurikatselmuksen, koska sääntö sopii johonkin, mitä paketti todella sisältää.
Jos tarvitsemasi raja kulkee käyttäjäryhmien välillä kahden toteutuksen sijaan, yksi instanssi, jolla on erilliset asiakasasetukset, oma varmenteiden käsittely ja nimenomainen käyttöoikeuskäytäntö, voi kattaa sen. Se ostaa käytäntöä palvelimen sisällä, ei eristystä palvelimien välillä, ja ne ovat eri vaatimuksia. Eristys, jonka on kestettävä kompromissin alla, tarvitsee yhä osoitteen tai palomuurin reunan.
OpenVPN:n eteen sijoitettu TLS-päättäjä voi paljastaa todellisen palvelinnimen kyvykkäälle frontendille, mutta vain kun myös asiakaspuoli on määritetty sitä lisäkerrosta varten. Olemassa olevat profiilit eivät saa tätä käyttäytymistä pelkästään sillä, että ne osoitetaan samaan osoitteeseen.
Todista valitsin ennen rakentamista
Nimeä kenttä, joka tunnistaa backendin, ja varmista sitten, että asiakas todella lähettää sen; jos vastaus on osoite, suunnitelma pitää, ja jos se on palvelinnimi kättelyn sisällä, joka ei koskaan saavuta kuuntelijaa, mikään määrä DNS-työtä ei pelasta sitä. Kolme komentoa selvittää kuuntelupuolen nopeasti.
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-rivi antaa varmenteen vain siellä, missä jokin kyseisessä osoitteessa päättää TLS:n; natiivia OpenVPN-kuuntelijaa vastaan se juuttuu tai epäonnistuu, ja se on itsessään vastaus siihen, mitä ulompi kerros paljastaa. journal-rivi, luettuna kullakin backendilla, näyttää, mikä instanssi hyväksyi istunnon. Frontendin lokit kirjaavat, mitä luokiteltiin, eivätkä koskaan sitä, mitä oli tarkoitettu, joten backend pysyy ainoana auktoriteettina siitä, mihin käyttäjä päätyi.
Lopeta kahteen profiiliin, jotka on tarkoitettu eri palvelimille, yhdistä ne yksi kerrallaan ja kirjaa backend-loki kummallekin. Jos molemmat istunnot näkyvät samassa journalistissa, valitsin puuttuu eikä ole väärin asetettu, ja korjaus on osoite tai portti, jota asiakas voi kohdistaa. Reitityssäännön muokkaaminen ei auta, koska säännölle ei koskaan annettu mitään reititettävää. Kun erottelu on todellista, kirjoita se profiilien viereen, ettei seuraava henkilö lisää toista aliasta ja odota sen tekevän työn.