Két A-rekord, egy cím, egy démon: bármelyik nevet írja be a felhasználó, a megérkező csomag azonos, és az 1194-es porthoz kötött folyamatnak semmije sincs, amivel megkülönböztethetné a kettőt. Ez nem javításra váró hibás konfiguráció; ez a névfeloldás kifejezőképességének a határa. Minden, ami két OpenVPN-példány között választ, olyan érték kell legyen, amelyet a kliens tesz a kapcsolatba, és amelyet a frontend vissza tud olvasni, a szokásos OpenVPN-kliens pedig nem tesz ilyen értéket nyíltan. A következők azt mutatják meg, hova jut ezzel, és mely elrendezések választják szét valóban a forgalmat.

Kezdje azzal, amit a feloldó visszaad

A kliens vpn-a.example-et kérdez, és kap egy címet; ez a cím plusz egy port mindaz, amit tárcsáz. A név helyben, a keresés során elhasználódik, és soha nem lesz mező a vezetéken, ezért a túloldali listener nem láthatja, melyik címkét használták. Irányítsa vpn-a.example-et és vpn-b.example-t ugyanarra a hosztra, és mindkét keresés ugyanazt a célt adja, ezért a démon mindkét kapcsolatot egyetlen példányba szívja be anélkül, hogy különbséget regisztrálna. A címalapú profilok pontosan úgy viselkednek, mint a névalapúak, ugyanezen okból.

Ez egy családnyi csábító kerülőutat is lezár: további álnevek, tanúsítvány választása névenként egy socketen, vagy a megkérdezett névre kötött tűzfal-szabály. Egyik sem tud olyan információra támaszkodni, amely már eldobódott, mielőtt az első csomag elhagyta a klienst. Ha két szervernek külön kell maradnia, a szétválasztásnak magával a kapcsolattal kell utaznia, azaz egy címnek, egy portnak vagy a protokoll által meghatározott hasznos teher mezőnek.

Az egyetlen számító szelektor a csomagon belül utazik

A HTTP ezt Host fejléccel oldja meg, a TLS pedig egy szervernév-kiterjesztéssel a ClientHello-ban, és így egy cím sok oldalt szolgál ki egyetlen listener mögött. Mindkettő azért működik, mert a vezetéken futó protokoll egy adott szolgáltatásra vonatkozó kérést hordoz. Az OpenVPN-nel kapcsolatos lényeges tény, hogy egyik mező sem jelenik meg azon a rétegen, amelyet egy köztes doboz vizsgál.

Szokásos elrendezésben a vezérlőcsatornát védő TLS-kézfogás akkor történik, amikor a külső munkamenet létrejött, és azon belül szállítódik, ezért az a listener, amely nem fejezte be azt a munkamenetet, átlátszatlan folyamot lát. Még mindig meg tudja mondani, hogy ez OpenVPN, mert a nyitó bájtok opkódja és keretezése felismerhető, de a szervernév, ha van, a titkosított részben ül. Az a terv, amely a külső csomagból akar virtuális hosztot olvasni, olyan mezőt olvas, amelyet a protokoll soha nem ír oda. Ez onnan jön, hogyan épül a tunell, nem pedig egy résből, amelyet egy okosabb mintaillesztés bezárhatna.

Ahol a protokollszétválasztó megáll

Az a fajta multiplexer, amelyet az sslh projekt dokumentál, egy porton figyel, megvizsgálja a nyitó bájtokat, és átadja a kapcsolatot annak a backendnek, amely a felismert protokollt beszéli. Ez valódi érték, amikor egyetlen portnak kell SSH-t, HTTPS-t és OpenVPN-t egyszerre kiszolgálnia.

Az sslh protokollonként külön próbát tart, és a TLS-próbája ki tud húzni egy szervernevet vagy ALPN-értéket egy valódi ClientHello-ból. A natív OpenVPN felismerése más osztályozás, mint egy TLS-kiterjesztés olvasása, és a kettő nem komponálódik, mert az a kliens, amely soha nem küld ClientHello-t a figyelő socketre, semmi olvasnivalót nem hagy a próbának. Ezért az OpenVPN-hez illeszkedő szabály azt válaszolja: „ez egy OpenVPN-kliens”, és nem megy tovább. Két OpenVPN-backend e szabály mögött megkülönböztethetetlen, a frontendnek nincs alapja a választásra, és minden munkamenet ugyanoda landol. A multiplexelés egy portot oszt meg különböző szolgáltatások között; nem végez virtuális hosztingot egy szolgáltatáson belül.

Elrendezések, amelyek valóban szétválasztanak két szervert

A legolcsóbb tisztességes szétválasztás egy második nyilvános cím, példányonként egy, és a meglévő profilok már hordozzák, ami kell, mert különböző címekre mutatnak. A következő egy másik port ugyanazon a címen, ami semmibe nem kerül egy számon kívül minden profilban. A TCP és az UDP külön porttáblákat tart, ezért a 1194/tcp és a 1194/udp független socketek, és mindkettőből egy-egy létezhet ugyanazon a hoszton; ez szállítási szétválasztás, nem névszerinti forgalomirányítás, és gyakran összekeverik vele. Mindkét lehetőség átmegy egy tűzfal-átvizsgáláson, mert a szabály olyasmivel egyezik, ami valóban benne van a csomagban.

Ha a szükséges határ nem két implementáció, hanem felhasználói csoportok között húzódik, egy példány különböző klienskonfigurációkkal, saját tanúsítványkezeléssel és kifejezett hozzáférési szabályzattal lefedheti. Ez szabályzatot vásárol egy szerveren belül, nem izolációt a szerverek között, és a kettő különböző követelmény. Az izolációnak, amelynek kompromittálás alatt is tartania kell, továbbra is kell a cím vagy a tűzfal pereme.

Az OpenVPN elé helyezett TLS-lezáró valódi szervernevet tárhat fel egy rátermett frontend előtt, de csak akkor, ha a kliensoldal is konfigurálva van erre a plusz rétegre. A meglévő profilok nem szerzik meg ezt a viselkedést attól, hogy ugyanarra a címre mutatnak.

Bizonyítsa a szelektort, mielőtt épít

Nevezze meg a mezőt, amely azonosítani fog egy backendet, majd erősítse meg, hogy a kliens valóban küldi; ha a válasz egy cím, a terv tart, ha pedig egy kézfogáson belüli szervernév, amely soha nem ér el a listenerig, semmilyen DNS-munka nem menti meg. Három parancs gyorsan eldönti a figyelő oldalt.

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

Az openssl sor csak ott ad tanúsítványt, ahol valami azon a címen lezárja a TLS-t; natív OpenVPN-listenerrel szemben elakad vagy meghiúsul, és ez maga a válasz arra, mit tár fel a külső réteg. A journal sor, minden backendben elolvasva, megmutatja, melyik példány fogadta el a munkamenetet. A frontend naplói azt rögzítik, mit osztályoztak, és soha azt, mit szándékoztak, ezért a backend marad az egyetlen illetékes abban, hova landolt a felhasználó.

Fejezze be két profillal, amelyek különböző szerverek elérésére készültek, csatlakoztassa őket egyenként, és jegyezze fel mindegyik backend-naplóját. Ha mindkét munkamenet ugyanabban a jurnalban jelenik meg, a szelektor hiányzik, nem pedig hibásan van beállítva, és a javítás egy cím vagy egy port, amelyet a kliens megcélozhat. Az útválasztási szabály szerkesztése nem segít, mert a szabálynak soha nem adtak semmit, amin útválasztani lehetne. Amint a szétválasztás valódi, írja le a profilok mellé, hogy a következő ember ne adjon hozzá egy második álnevet, és ne várja, hogy az végezze el a munkát.

Kapcsolódó cikkek