Wat zich voor vrijwel elke webdienst bevindt
Welkom
Als je example.com in een browser typt, bereik je bijna nooit de machine die de applicatie daadwerkelijk uitvoert. Je bereikt een machine die de aanvraag doorstuurt naar een machine die dat wel doet. Die doorsturende machine heeft een naam: een reverse proxy.
In deze les leer je wat een reverse proxy doet, waarom vrijwel elke publieke webdienst zich achter zo'n proxy verbergt, & welke drie taken de edge layer tegelijkertijd uitvoert.
Aan het einde begrijp je:
- Het verschil tussen een client, een proxy en een oorsprong
- Waarom een proxy vóór een oorsprong beschermt, schaalt en het mogelijk maakt onderdelen te verwisselen zonder dat iemand het merkt
- De drie taken die een reverse proxy tegelijk uitvoert: het verbergen van de oorsprong, het afsluiten van TLS en het verdelen van de belasting over replica's
- Hoe een verzoek stap voor stap reist van browser naar proxy naar upstream en terug
Aan het einde redeneer je zelfverzekerd over de plaatsing van proxies, de scheiding van zorgen aan de rand en waarom een stateless proxy-laag goedkoop vermenigvuldigd kan worden, terwijl een enkele oorsprong dat niet kan.
Forward Proxy vs Reverse Proxy
Twee proxy-richtingen
Beide soorten proxy staan tussen twee partijen en relayen verkeer. Ze verschillen in welke partij ze vertegenwoordigen.
Forward proxy: staat vóór een groep clients. De clients weten van het bestaan van een proxy; een externe server ziet een proxy-adres, niet een client-adres. Corporate egress proxies, content filters en SOCKS proxies vallen onder dit patroon.
Reverse proxy: staat vóór een groep servers. De buitenwereld (clients) communiceert met een proxy-adres; clients hebben geen idee dat er een echte server achter schuilt. Bijna elke openbare webdienst maakt er gebruik van.
Mnemonic: een forward proxy verbergt clients voor servers. Een reverse proxy verbergt servers voor clients.
Waarom maakt het uit welke richting? De taak, de falingsmodi en de beveiligingsgrens verschillen allemaal. Een forward proxy maakt zich zorgen over wie zijn gebruikers contacten; een reverse proxy maakt zich zorgen over wie zijn servers contacteert.
Een client die verkeer via beide types tegelijk stuurt, volgt dit pad: client -> forward_proxy -> internet -> reverse_proxy -> origin.
Waarom zoveel op de rand gebeurt
De randlaag verdient zijn plek
Een reverse proxy vervult tegelijkertijd drie taken. Elke afzonderlijke taak rechtvaardigt de laag; het feit dat alle drie tegelijk op hetzelfde adres worden uitgevoerd, verklaart waarom vrijwel elke productie-webarchitectuur dezelfde vorm heeft aan de voorkant.
Taak 1: Verberg de oorsprong. De proxy antwoordt op een openbaar IP-adres. Backends zitten op privé-IP-adressen die niet vanuit het internet bereikbaar zijn. Een aanvaller die de oorsprong wil raken, moet eerst de proxy compromitteren.
Taak 2: TLS afsluiten. De proxy bezit het certificaat voor example.com & decodeert inkomende HTTPS-verzoeken. De backends communiceren via een vertrouwd netwerksegment met de proxy via plain HTTP (of een eenvoudigere interne TLS). Certificaatrotatie, vernieuwing & cipherbeleid zitten allemaal op één plek.
Taak 3: Belasting verdelen. De proxy kiest welke backend elk verzoek afhandelt. De backends achter één proxy vormen een pool; de proxy kiest per verzoek er één uit met behulp van een strategie (round-robin, minste verbindingen, hash op een header). Capaciteit uitbreiden betekent een backend toevoegen aan de pool, in plaats van aan elke client een nieuw adres mee te delen.
Elke taak is een klein programma. Samen verklaren ze waarom een laag zo eenvoudig als 'Caddy voor een Python-app' meer ontwerpgewicht heeft dan de Python-app zelf.
Ontwerpen voor alle drie
Jouw team draait een kleine API op een enkel Python-proces dat luistert op poort 8000 op een enkele VM. Het verkeer is zo gegroeid dat één VM het niet meer aankan, & een beveiligingsreview heeft gemarkeerd dat de VM een publiek IP-adres heeft & zijn eigen TLS-certificaat draait.
Je besluit een reverse proxy voor te plaatsen. Schets de opzet: waar wijst DNS naartoe, waar bevindt zich het certificaat, hoe bereikt de belasting de backends, & wat verandert er aan de oorspronkelijke VM?
Vervang een component zonder dat iemand het merkt
Indirectheid koopt vrijheid
Een oude informatica-uitdrukking luidt: elk probleem kan worden opgelost door een laag van indirectie toe te voegen (behalve het probleem van te veel lagen van indirectie). De reverse proxy is een van de meest nuttige vormen van indirectie in gedistribueerde systemen.
Wat het je oplevert:
- Vervangbare backends. De applicatie van Python naar Go verplaatsen? Migreren van het ene datacenter naar het andere? Een nieuwe versie uitrollen met nul downtime? Elk van deze scenario's gebeurt achter een stabiel publiek adres. Voor gebruikers verandert er niets.
- Onafhankelijke schaalbaarheid. De proxy-laag schaalt op basis van bandbreedte & CPU op het TLS-niveau. De backend-laag schaalt op basis van applicatielast. Elke laag groeit op zijn eigen as, omdat ze op verschillende machines draaien.
- Beperking van storingen. Een mislukte deploy op de backend zorgt er niet voor dat het publieke adres offline gaat. De proxy blijft draaien; je duwt een fix of rollt terug; de wereld herverbindt wanneer de backend hersteld is.
- Kruisdoorsnende aspecten op één plek. Rate limiting, geo-blokkering, request logging, header rewriting, caching, response compressie: alles zit op de proxy. De backend-code blijft gefocust op de applicatie.
Zonder de proxy moet elk van deze problemen binnen het applicatieproces leven. Met de proxy leven ze op één laag die door één team wordt beheerd.
De kosten: een extra laag om te beheren. Ervaren teams accepteren deze kosten, omdat de proxy-laag zelf stateless draait & horizontaal schaalt; het vervangen van één proxy door twee vereist geen coördinatie.
Een Blue/Green-deploy via de proxy
Jouw team draait versie 1 van de API op drie backend-VM's (blauwe pool) achter een reverse proxy. Je wilt versie 2 deployen met de mogelijkheid om binnen dertig seconden terug te rollen als er iets misgaat.
Je start drie nieuwe backend-VM's (groene pool) op die versie 2 draaien, naast de blauwe pool, maar je routeert nog geen verkeer naar hen.
Van browser naar backend en terug
Volg één verzoek van begin tot eind
Volg een enkele HTTPS GET van https://api.example.com/users/42 door een reverse proxy voor een backend-pool.
Hop 1: DNS-resolutie. De browser vraagt een resolver om api.example.com. De resolver retourneert het publieke IP-adres van de proxy (bijvoorbeeld 203.0.113.10). De browser opent een TCP-verbinding naar 203.0.113.10:443.
Hop 2: TLS-handshake. De proxy presenteert zijn certificaat voor api.example.com. De browser valideert het certificaat, beide partijen komen overeen over een sessiesleutel, & de versleutelde kanaal wordt geopend.
Hop 3: HTTP-verzoek binnen TLS. De browser verzendt GET /users/42 HTTP/1.1\nHost: api.example.com\n.... De proxy decodeert de verzoekbytes.
Hop 4: Backendselectie. De proxy raadpleegt zijn upstream-pool voor api.example.com & kiest een backend (bijvoorbeeld 10.0.0.21:8000) met behulp van zijn load-balancing-strategie.
Hop 5: Upstream-verzoek. De proxy opent (of hergebruikt) een gewone HTTP-verbinding naar 10.0.0.21:8000 & voert het verzoek door. De proxy kan headers onderweg herschrijven: X-Forwarded-For: <client-ip> toevoegen, Host: correct instellen, en hop-by-hop headers zoals Connection verwijderen.
Hop 6: Backendverwerking. De backendapplicatie leest het verzoek, queryt zijn database en bouwt een JSON-respons.
Hop 7: Upstream-respons. De backend stuurt de respons terug naar de proxy als gewone HTTP.
Hop 8: Edge-respons. De proxy kan de respons herschrijven of comprimeren, versleutelt deze opnieuw via de TLS-sessie & stuurt deze naar de browser.
Hop 9: Verbindingslevenscyclus. De TLS-sessie blijft doorgaans open voor het volgende verzoek (HTTP/2 multiplexeert vele verzoeken op één verbinding). De verbinding van proxy naar backend wordt vaak gepoold voor hergebruik.
Elke publieke webdienst volgt een variatie op deze vorm. Door de hops te kennen, kun je redeneren over waar latentie zich ophoopt, waar logging thuishoort, & waar een fout zich kan verbergen.
Waar is de tijd gebleven?
Een gebruiker klaagt dat de API traag aanvoelt. Je meet en ontdekt dat de request 850 ms duurt van begin tot eind. De serverlogs op de backend tonen aan dat de applicatie de request in 40 ms heeft verwerkt. De proxylogs tonen aan dat de proxy 50 ms heeft besteed aan zijn deel van het werk (TLS-handshake + routing + schrijven van het antwoord).
Ontwerp een minimale edge voor een nieuwe service
Synthese
Je hebt geleerd wat het verschil is tussen een forward- en reverse-proxy, welke drie taken een reverse-proxy tegelijk uitvoert, waarom het verbergen van de origin dividend oplevert telkens wanneer je iets moet wijzigen, en hoe een verzoek hop voor hop door de edge stroomt.
Pas dit nu toe.
Een klein team plant de lancering van een nieuwe service genaamd notes.example.com. Gebruikers kunnen persoonlijke notities lezen en schrijven. Het team zal bij de lancering twee backend-VM's draaien en verwacht binnen een jaar uit te groeien naar tien. Ze willen HTTPS voor gebruikers, een geleidelijke rollout voor nieuwe versies, en geen openbare blootstelling van backend-IP-adressen.
Waar deze cursus naartoe gaat
Waar deze cursus naartoe gaat
Deze les legde de vorm van de edge-laag vast. Nog vier lessen in deze cursus bouwen hierop voort:
- Stateless horizontale schaling: waarom een proxy-laag (& de backends erachter) goedkoop vermenigvuldigd kan worden, & de wiskunde voor het bepalen van het aantal replica's bij piekbelasting.
- Scheiding van Ingress / Egress: waarom een enkele proxy-server die zowel inkomend als uitgaand verkeer verwerkt uiteindelijk op verrassende manieren faalt, & hoe de lagen gesplitst kunnen worden.
- Foutmodi & Blast Radius: hoe een enkele configuratieverandering kan leiden tot een uitval, en hoe je schuldvrije actiepunten opstelt om herhaling te voorkomen.
- Observability & Capaciteit: wat je moet meten aan de edge, zodat je ontdekt dat er iets kapot is voordat gebruikers dat doen.
Elke les staat op zichzelf. Samen geven ze je een werkend mentaal model van een web-schaal vloot.
Begeleide les: geometry_of_proxies_and_origins herformuleert alles in deze les als een gerichte graf en onderzoekt wat grafentheorie je vertelt over een verzoekspad.
Goed gedaan. Verder.