Vraag drie ingenieurs hoe je een interne dienst bereikt en je krijgt drie ontwerpen: een webproxy, een SSH-tunnel of een volledige VPN. Alle drie kunnen een externe dienst binnen bereik brengen, en alle drie kunnen verkeer laten lijken alsof het ergens anders vandaan komt. De verschillen komen later aan het licht, wanneer het gebruikte protocol niet het protocol is dat het gekozen hulpmiddel veronderstelt. Een ontwerp dat een snelle browservalidatie doorstaat, faalt steevast in de toepassing die het verzoek veroorzaakte.

Beslis op basis van twee feiten: welke protocollen moeten passeren, en wie de betrokken namen kan oplossen. Al het andere is voorkeur.

Een proxy verplaatst alleen wat hij begrijpt

Een webproxy analyseert het protocol waarvoor hij is gebouwd. De client geeft hem een verzoek en hij geeft dat verzoek door, dus een toepassing zonder proxyinstelling doet helemaal niet mee. Voor HTTPS heeft de client een ondoorzichtig kanaal nodig, dat de proxy via CONNECT levert in plaats van door het verzoek te lezen.

Een dynamische SSH-doorstuur opent een lokale poort die SOCKS spreekt, en die poort stuurt een TCP-stroom door naar elke bestemming die de client noemt. Protocollen op TCP werken er meestal doorheen. UDP niet, tenzij een hulpmiddel ondersteuning expliciet toevoegt. Een lokale doorstuur is nog smaller: één lokale poort gekoppeld aan één vaste host en poort, wat één bekende dienst dient en niets meer.

ssh -D 1080 user@bastion
ssh -L 8443:fileserver.internal:443 user@bastion

Een VPN verplaatst pakketten. Alles wat de client de tunnel in routeert, gaat erdoorheen, UDP en ICMP inbegrepen, daarom past hij bij een netwerkvereiste en niet bij één verbinding.

Iemand moet de naam oplossen

Wanneer de doelnaam alleen in de DNS van het externe netwerk bestaat, moet de machine die de opzoeking doet die zone kunnen zien. Een webproxy doet de opzoeking zelf, dus een interne naam werkt erdoorheen, zelfs wanneer de laptop de naam helemaal niet kan oplossen. SOCKS kan zich hetzelfde gedragen, maar alleen als de client de naam doorstuurt in plaats van verbinding te maken met een adres dat hij al heeft opgelost. Die keuze ligt bij de client, niet bij de server.

curl toont de scheiding duidelijk: de ene vlag geeft de hostnaam aan de proxy, de andere lost hem eerst lokaal op. Bij lokale resolutie faalt een alleen interne naam voordat er ook maar een tunnel wordt aangeraakt, en de fout geeft de proxy de schuld van wat in werkelijkheid een DNS-beslissing was.

Een VPN neemt de derde route door de private resolver en het zoekdomein naast de routes te installeren. Dat is handig, en het schept een vertrouwde illusie: een route die bestaat met een resolver die niet antwoordt, ziet er precies uit als een dode tunnel, ook al bereiken pakketten de andere kant.

Wanneer het netwerk maar één uitgang toestaat

Veel bedrijfsnetwerken staan uitgaande verbindingen alleen toe via een geauthenticeerde webproxy. OpenVPN en SSH kunnen daar allebei aan de praat worden gebracht, de eerste door zijn eigen transport door de proxy te tunnelen en de tweede via een proxycommando dat een kleine CONNECT-helper uitvoert.

Tunnels op TCP overleven die beperking, en een op UDP gebaseerde VPN niet, wat heel veel configuraties verklaart die thuis werken en op kantoor falen. Een tweede kostenpost is makkelijk te missen: een TCP-tunnel die in een TCP-verbinding via een proxy wordt gedragen, heeft nu twee lagen die opnieuw verzenden, en onder verlies stokt dat paar op een manier die geen enkele laag alleen veroorzaakt.

Tussenpersonen aaneenrijgen is een andere vraag dan een laag kiezen. Een tweede proxy of Tor toevoegen verandert wie wat waarneemt, en de positie in de keten bepaalt welke hop de ciphertext ziet.

De volgorde is belangrijker dan het aantal hops. Een buitenste hop kijkt naar een versleutelde stroom terwijl een binnenste de leesbare tekst ziet die hij draagt, dus een keten is alleen zo privé als de minst zorgvuldige schakel. Protocollen over hops heen mengen verbetert dat niet automatisch. Het maakt vooral de faalwijzen moeilijker te doordenken.

Een vervalst adres is niet een van de opties

Pakketten bouwen met het bronadres van iemand anders levert niets nuttigs op: antwoorden reizen naar de echte eigenaar, en de meeste netwerken gooien het verkeer gewoon weg. Een tussenpersoon is juist nodig omdat de bron niet verzonnen kan worden, en dat is de eerlijke rechtvaardiging van alle drie de ontwerpen.

Het beperkt ook wat elk ervan mag beweren. Lijken te komen van een bepaald adres is een vraag over waar dat adres rechtmatig is toegewezen en wie het mag routeren, niet over welk hulpmiddel een header kan vervalsen. Als een ontwerp het omgekeerde aanneemt, faalt de aanname bij de eerste provider die hem filtert. Schrijf de aanname op, zodat de fout herkenbaar is wanneer hij komt.

Beslis op protocollen en namen

Kies een proxy wanneer één webclient één webdienst nodig heeft en proxyinstellingen heeft. Kies een SSH-tunnel wanneer een handvol bekende TCP-diensten genoeg is en SSH-toegang al bestaat. Kies een VPN wanneer meerdere toepassingen, niet-TCP-verkeer, private DNS of een herbruikbaar pad deel van de eis zijn.

Verifieer daarna met de echte client en de echte naam. Een pagina via een proxy laden leert je niets over UDP, en één hulpmiddel over SOCKS aan de praat krijgen leert je niets over de resolver van het systeem. Lees welk lokaal adres het proces bond en welke resolver antwoordde. Dat is het verschil tussen een pad dat werkt en een dat toevallig één keer werkte.

Gerelateerde artikelen