Přejít k navigační liště

Zdroják » Různé » Jak funguje proxy?

Jak funguje proxy?

Články Různé

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:

Různé typy proxy v jedné komponentě (Security Gateway)

Různé typy proxy v jedné komponentě (Security Gateway)

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í klientovi status kód 200 OK a teprve potom zahájí klient komunikaci se serverem. Přes proxy tak tečou jenom šifrovaná data.

TLS tunneling

TLS tunneling

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.

TLS termination

TLS termination

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.

Komentáře

Subscribe
Upozornit na
guest
6 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
franta

V clanku nebylo dle meho receno to nejdulezitejsi:

Proxy vzdy narozdil treba od natu/portforwardingu navazuje nove spojeni k cili a casto rozumi aplikacnimu protokolu (ne vzdy).Ma tedy vetsi rezii, ale na druhou stranu ma vetsi moznosti jak ridit, filtrovat a enbo dokonce agregovat provoz.

Dale loadbalancig zdaleka nemusi byt resen jen pomoci proxy, muze byt configurovan (a take v nekterych sdnkach resen je) na urovni ip (tcp/udp) pomoci treba iptables nebo jineho mechanismu v jadre systemu, pripadne dynamickych dns zaznamu (jeden a zaznam ma vic ip adress)Takove reseni sice neni nijak sofistikovane, ale zase je rychle :).

A konecne ingress controller neni nic jineho nez jakysi dynamicky prekladac ingress objektu v k8s do reci haproxy/nginxu ci jineho reseni. Samotny proxying pak dela vyse zminena technologie. Pro tuto funkci koneckoncu ani ingress controller nemusite potrebovat, staci Vam obycejny nginx s podporou treba srv zaznamu (tady uz je potreba naka distribuce openresty, protoze ce verze to tusim sama neumi)

Petr Sršeň

Ahoj,
nejdřív díky za článek o Proxy. Pohybuji se v tomto světě řádku roků a obecná averze vůči proxy je podle mě neopodstaněná a spávně nastavená proxy odvede spoustu práce. Proxy „rozumí“ protokolu, který přes ní má procházet a je schopná odchytit anomálie, případně něco co tam vůbec nepatří. K článku bych měl pár poznámek:

  • TLS terminace se většinou používá obráceně. mezi klientem a proxy je spojení šifrované a mezi proxy (reverzní) a serverem již TLS není použito. Jedná se primárně o SSL offload z důvodu snížení zatížení serveru.
  • Standardně používané názvosloví ohledně explicitní a transparentní proxy je u forward proxy dáno zapojením do infrastruktury. Explicitní proxy musí mít systém (nebo browser) nakonfigurovánu aby o ní věděl, případně musí být použit autovyhledávací nastavení (Pomocí DHCP či DNS). Transparentní proxy je z pohledu browseru (klienta) „neznámá“ a do provozu se vloží buď jako bridge (odchytává si provoz sama) případně tvz, virtuálně inline, kdy se na síťovém prvku použije např. WCCP pro přesměrování provozu na proxy.
  • S termíny Ingress a Egress jsem se primárně setkal ve spojení s identifikací směru provozu na proxy. Použití uvedené v článku je hodně specifické (alespoň myslím) pro použití v cloudové infrastruktuře. U klasické proxy je tak označován směr provozu z pohledu proxy. Client Egress je tok dat proxy > klient, Server Egress je proxy > server. Client ingress je client > proxy a Server Ingress server > proxy. Možná to vypadá jakou matoucí, ale bez ohledu na topologii sítě a konkrétní použití proxy to jednoznačně identifikuje kam daná data „tečou“.
    Nakonec jedna podstatná poznámka. Forward a reverse proxy jdou většinou nakonfigurovat zároveň na jenom zařízení, SW, instanci, jak to kdo nazve. Pak je nutné poctivě ošetřit aby se z toho nestala vůči internetu tzv. OpenProxy, kdy umožní každému připojit se přes ní kamkoli a efektivně se za ní schovat. Pár adminům se to již povedlo a většinou následuje velmi rychlý problém v podobě IP adresy na blacklistech apod. Tak pozor na to.
Borůvka

Mělo to hezký, začátek, ale pak to rychle skončilo.

Ohledně transparetní proxy: pojem Transparentní může znament víc věcí a není jendoznačný. V kontextu TLS, transparentní proxy by bylo že by přenos nebyl nijak modikován, tedy bez terminace a opakovaného šifrování (jiným certifikátem). Jenže to vyvolá chybu certifikátu.

= Transparentní pro uživatele = nemusí nikde nic měnit ; případně ženepozná že ke změně došlo (což ale u https nelze, právě díky neshodě certifikátu)

Historicky, transparentní znamenalo, že se nic neděje s daty, což je jednoduché dosáhnout v HTTP. Nebo jiný příklad: TPROXY v iptables (nebo divert či redirect se tomu říká v bsd firewall pravidlech) je hezký příklad co transparentní znamená. Je to takové znásilnění routingu – IP adresy datagramů zůstanou, ale lze je směrovat dle libosti (na rozhraní nebo danému procesu)…

Právě tohle je klíčem k správnému fungování HTTPS proxy bez CONNECT, SOCKS atd. Právě znalost IP adresy je kritické místo.. když ji proxy nebude znát, jak pozná kam se připojit (Hlavička Host je zasifrovaná – problém slepice a vejce)… Ještě do toho vstupuje SNI

Ale dál se to vyvíjí ještě dalším směrem: domain fronting, kdy klient se snaží přisotupit k cenzuovanému obsahu například na doméně blabla.appspot.com (patří googlu). Klient vyšle request na nějakou doménu googlu (tedy IP adrese, kterou získá, za přepodkladu že google.es, google.com, gstatic atd není cenzurované), v SNI uvede taky nějakou doménu googlu. Ale až samotném TLS vesele použije hlavičku Host: dle libosti.

Kromě toho je úsilí o zašifrované SNI. (Mozilla)

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.