Jak funguje proxy?
Publikováno: 8.2.2021
Posledních pár let mě baví se zabývat bezpečností aplikací. Čistě technicky. A když člověk tyhle věci implementuje, dostane se k zajímavým problémům, které by ho ani nenapadly. A tak se stalo, že jsem se dostal k proxy. Jako slepý k houslím.
Text vyšel původně na autorově webu.
Proxy pro mne dlouhá léta byla tím, čím pro mnoho jiných, běžných vývojářů — pain-in-the-ass, která dělala problémy při vývoji aplikací. Pořád se muselo řešit, jak se dostat do nějaké síťě, nebo na internet, jak nastavit tenhle nástroj, aby fungoval přes proxy, vykoumat, aby to fungovalo jak přes VPN, tak mimo firemní síť, atd. Utrpení.
Samozřejmě, proxy mají své důvody, proto vlastně vznikly. Ale běžným uživatelům přinášejí jenom nepříjemnosti. A najednou jsem měl takovou proxy napsat já. Naštěstí ne pro uživatele, ale pro jiné služby. A protože jsem o proxy nevěděl nic, trochu jsem si to nastudoval. A tady máte výsledek.
Kolik je druhů proxy?
Jedním slovem: moc. Záleží, z jakého úhlu se na to podíváme. Já jsem to potřeboval uchopit tak ze dvou, ze tří směrů. A skončil jsem s něčím takovýmhle:
Forward, nebo reverse proxy?
Tohle je nejspíš nejběžnější rozdělení a vlastně ho každý z nás zná — víme přece, co je to load balancer a firewall, ne? Jaký je v tom ale rozdíl? Co znamená forward a co reverse?
Forward proxy je taková proxy, kdy klient zná přesnou cílovou adresu, ale musí z nějakého důvodu komunikaci odklonit přes proxy. Třeba proto, že na cílovou adresu se přímo nedostane, nebo proto, že je request potřeba něčím obohatit, či zkontrolovat. To jsou ty typické firemní proxy, kdy sedíme “za” proxy a chceme se dostat “někam ven” (i když to nemusí být vždycky “ven” — viz dále). Patří sem také třeba firewally.
Reverse proxy je naopak (proto reverse) proxy, kdy klient nezná cílovou adresu, zná jenom adresu prostředníka. Až teprve proxy ví, kam má request dále přeposlat. Každého asi napadne load balancer, ale nemusí jít jenom o rozhazování requestů na backendy. Spadají sem třeba i ingress controllery v Kubernetes a obecně jakákoliv gateway, kdy se potřebujeme dostat do jinak nepřístupné sítě.
Ingress, nebo egress proxy?
V přešlé sekci jsem uvedl nejčastější a nejběžnější případy reverse a forward proxy. Což by mohlo dávát představu, že je daný i směr, kterým by měla proxy komunikovat. Ale není to tak. Když se podíváte výše na obrázek Různé typy proxy, uvidíte, že jsou tam jak dvě reverse proxy, kdy jedna míří jenom dovnitř (na obrázku v pravo) a druhá jenom ven. Stejně tak je tam reverse proxy i forward proxy, které obě míří do venkovního prostředí.
Tady příchází ke slovu termíny ingress a egress. Tyhle dva termíny můžete znát z nastavování firewallu, ale tam ty názvy nepramení. Ačkoli většinou lidi zhruba rozumí, co ty výrazy představují, jen málokdo ví, co znamenají. To není nic divného, protože ty termíny pocházejí z právnické mluvy.
Ingress proxy je proxy, která zpracovává příchozí komunikaci (právnicky entering to a property). Tento termín mluví pouze o směru komunikace, neříká nic o tom, co se na chází na “pozemku” — může to být server, ale může to být i klient. Podstatný je úhel pohledu a kontextová důležitost toku informací.
Egress proxy je pak logicky proxy, která zpracovává odchozí komunikaci (leaving the property). Opět pouze říká směr komunikace, který je daný kontextem.
Když se tímto prizmatem podíváme na firewall, tak můžeme říct, že je to ingress i egress proxy zároveň.
A mimochodem, víte, že existuje i třetí právnický termín? V softwarovém inženýrství ho známe taky, akorát se nepoužívá ve spojení s proxy — regress znamená return to a property, čili možnost/právo se na “pozemek” vrátit.
A co TLS? Tunel, termination, nebo interception?
Další způsob, jak se podívat na rozdělení proxy je skrze to, jak se chovají ke komunikačnímu protokolu. Nemám teď na mysli odlehlé věci, jako že bychom měnili například HTTP na gRPC (což jde), ale starý dobrý HTTP vs. HTTPS.
HTTPS je v dnešní době zajišťován pomocí TLS. Zjednodušeně řečeno, TLS šifrovaně “obalí” probíhající komunikaci mezi klientem a severem. Z hlediska proxy tak nastává otázka, jak se k takové šifrované komunikaci chovat.
Dva nejběžnější způsoby jsou TLS tunneling a TLS termination.
TLS tunneling funguje tak, že klient prvně kontaktuje proxy a požádá ji o vytvoření TLS tunelu na požadovaný server. To se děje pomocí HTTP metody CONNECT. Jakmile se tunel vytvoří, proxy vrátí klientovy status kód 200 OK a teprve potom zahájí klient komunikaci se serverem. Přes proxy tak tečou jenom šifrovaná data.
TLS termination pak funguje tak, že klient komunikuje s proxy nešifrovaně pomocí čistého HTTP a až teprve proxy vytvoří TLS spojení se serverem. Data na proxy jsou tedy nešifrovaná a ta je může volně modifikovat.
Speciálním případem pak je TLS interception, kdy proxy zachytává šifrovanou komunikaci, která přes ni teče, rozkóduje ji do čistého HTTP, potencionálně modifikuje a konečně, vytvoří nové TLS spojení do cílové destinace. Tento typ proxy se někdy nazývá Transparent proxy, což může být zavádějící, protože jak říká RFC 2616 dokument:
A “transparent proxy” is a proxy that does not modify the request or response beyond what is required for proxy authentication and identification. A “non-transparent proxy” is a proxy that modifies the request or response in order to provide some added service to the user agent, such as group annotation services, media type transformation, protocol reduction, or anonymity filtering.
Čili transparentní proxy je taková, která nemodifikuje request a response. V opačném případě je netransparentní.
Jak poznám, že je v cestě proxy?
Jak je vidět, v běžném životě dnešního počítačového uživatele, se nachází spousta proxy. Většinou o nich neví (dokud nezačnou problémy). Možná vás ale napadlo, jestli se dá taková proxy detekovat. Odpovědí je klasické “to záleží”…
Proxy se totiž můžou chovat různě — můžou svoji existenci schovávat a stejně tak můžou svoji existenci dávat explicitně najevo. Pokud chce proxy svoji existenci utajit, může být velmi těžké její přítomnost zjistit — přece jenom, síťová analýza není pro každého.
Pokud je naopak proxy slušně vychovaná, stačí si většinou prohlédnout HTTP hlavičky a mohlo by být jasno. Sice není žádný standard, který by to vynucoval, ale můžete se dívat například po hlavičkách Forwarded či Via:
Forwarded: by=12.34.56.78,for=23.45.67.89;host=sw-samuraj.cz;proto=https
Via: HTTP/1.1 sw-samuraj.cz
Jsou to všechny proxy?
Uvedl jsem některé, spíše obecné typy proxy, se kterými se běžně setkáváme, respektive jsme jejich uživateli. Ale kromě toho existuje spousta dalších typu a rozdělení. Třeba CGI proxy (ach, kde jsou ty časy, kdy jsem mastil PHP přes PHProxy), DNS proxy, nebo anonymizační I2P a Tor proxy. Škála proxy je zkrátka široká. A málo se o ní píše.