English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

gast
1 / ?
terug naar lessen

Twee verkeerstrichtingen, één box

Welkom

De meeste architectuurschema's tonen verkeer in één richting: client bovenaan, server onderaan, pijl naar beneden. In de realiteit gaat verkeer in beide richtingen.

Ingress: externe clients bereiken uw services via deze route. Een reverse proxy aan de rand van uw netwerk beëindigt TLS, routeert verzoeken en handhaaft het toegangsbeleid.

Egress: uw services bereiken externe services via deze route. Een API van een betaalverwerker aanroepen, een webhook-doel ophalen, een verzoek naar een partner sturen. Vaak via een forward proxy of NAT-gateway met een toelijst.

Veel architecturen beginnen met één box die beide verwerkt. Het werkt, tot de dag dat het niet meer werkt. Het falingspatroon is subtiel, wordt pas zichtbaar zodra er voldoende interne services bestaan, & leert een belangrijk lesje over scheiding van zorgen.

Aan het einde van deze les zult u begrijpen:

- Waarom ingress & egress fundamenteel verschillende verkeerpatronen vertegenwoordigen met verschillende schaalingsassen & verschillende falingspatronen

- Hairpin NAT & waarom een proxy die probeert met zichzelf te verbinden faalt

- De architecturale tak: één box wordt twee, & wat elk van hen dan exclusief bezit

- Winsten in beveiligingsisolatie: elke kant kan zich afsluiten voor zijn echte toegestane peers

- Hoe te identificeren wanneer uw single-box ontwerp de drempel heeft overschreden waar de splitsing noodzakelijk is

Waarom de Richtingen Verschillende Gereedschappen Vereisen

Twee verschillende werkbelastingen aan één netwerkgrens

Kenmerken van inkomend verkeer:

- Ingeleid door externe partijen (het brede internet)

- Volume schaalt met uw gebruikersbasis

- TLS-terminatie, verzoekroutings, rate limiting per bron

- Diepte-in-verdediging: DDoS, misbruik, scraping

- Publiek IP-adres moet verbindingen van iedereen accepteren

Kenmerken van uitgaand verkeer:

- Geïnitieerd door uw eigen services (een bekende, kleine set clients)

- Het volume schaalt met uw service-naar-service- & externe-API-aanroeppatronen

- Source-IP-allowlisting op afgelegen eindpunten (u heeft één vaste uitgaande IP-adres dat partners vertrouwen)

- Diepte-in-verdediging (defense-in-depth)-overwegingen: datadiefstal, gecompromitteerde interne services die naar buiten bellen

- Moet verbindingen van iedereen anders dan uw eigen services weigeren

De belangrijkste asymmetrie: ingress accepteert verkeer van de wereld; egress accepteert verkeer alleen van uw eigen services. Als u ze op dezelfde machine plaatst, moet die machine tegelijkertijd bereikbaar zijn vanuit de wereld (voor ingress) & alleen bereikbaar zijn vanuit uw services (voor egress). De firewallregels die aan de ene eis voldoen, werken tegen de andere.

De groeipad: een klein project kan beide achter één IP & één tool verbergen, omdat het volume klein is & de partner-IP-allowlist kort is. Naarmate het project groeit, neemt de wrijving tussen de twee rollen toe, & op een dag dwingt een specifiek falingspatroon (hairpin NAT) de splitsing af.

Ingress vs egress: verschillende bronnen, verschillende bestemmingen, verschillende vereisten

Een kleine startup draait alles (ingress reverse proxy, egress forward proxy / NAT, interne services) op één VM met één publiek IP. Ze zijn nog vroeg genoeg in het proces dat dit lijkt prima te werken. Noem twee specifieke falingsmodi of operationele pijnpunten die dit ontwerp zal tegenkomen naarmate ze groeien, en leg voor elk van deze de onderliggende oorzaak uit.

De bug die de splitsing dwingt

Een gesaniteerd verhaal over een storing

Stel je een echte architecturale takking voor die zich voordoet in productie-flotten. De namen hieronder zijn gewijzigd; de vorm is identiek aan wat teams in de praktijk tegenkomen.

Een organisatie draait een enkele proxy-server op 203.0.113.5. Deze verwerkt inkomend verkeer (poort 443 voor gebruikers) & uitgaand verkeer (poort 1080 SOCKS5 voor interne services die naar buiten toe bellen). Interne services bevinden zich in private subnets & routeren al hun uitgaand verkeer via die SOCKS5-proxy op 203.0.113.5:1080.

Eén van de services die achter hetzelfde 203.0.113.5 wordt gehost, is api.example.com. Openbare DNS lost api.example.com op naar 203.0.113.5.

Nu heeft een andere interne service de noodzaak om api.example.com aan te roepen. Het uitgaande pad:

1. Interne service lost api.example.com op → 203.0.113.5

2. Interne service stuurt de aanvraag via de SOCKS5-egress-proxy op 203.0.113.5:1080

3. De proxy probeert een verbinding van zichzelf naar 203.0.113.5:443 te openen

4. Verbinding geweigerd. Het pakket zou de zelfde NAT moeten verlaten en opnieuw moeten binnengaan, wat de meeste netwerkstacks afwijzen. De proxy kan niet met zichzelf verbinden via zijn eigen publieke IP.

Dit is hairpin NAT: een pakket dat een NAT verlaat en dezelfde NAT opnieuw moet binnengaan om zijn bestemming te bereiken. Zonder speciale hairpin-ondersteuning in de routinglaag wordt het pakket verstrengeld.

Waarom het laat opduikt

In de vroege fase van het project communiceerde elke interne service met andere interne services via een privé-hostnaam (internal-api.local) of riep geen publieke services van de eigen organisatie aan. Het hairpin-pad bestond simpelweg niet.

Toen vereiste een nieuwe functie dat service A api.example.com (een publieke hostnaam) aanroept. Het hairpin-pad werd geactiveerd. Verbinding geweigerd. Storing.

De oplossing verholp het symptoom (de resolver dwingen om het privé-IP van api.example.com te geven in plaats van het publieke). De oorzaak: één machine deed te veel taken.

Hairpin NAT: pakket verlaat de NAT en kan dezelfde NAT niet opnieuw binnengaan

De architecturale vork

Een box wordt twee

De nette oplossing: scheid de proxy in twee machines.

Ingress-server (openbaar IP-adres 203.0.113.5):

- Caddy / reverse proxy op poorten 80, 443

- Openbare DNS-records wijzen hierheen

- Hosts api.example.com, app.example.com, enz.

Egress-server (ander openbaar IP-adres 203.0.113.99):

- SOCKS5 / forward proxy op poort 1080

- De firewall beperkt inkomende verbindingen tot alleen IP-adressen van het interne subnet

- Interne services routeren alle uitgaand verkeer via dit adres

Wat dit oplevert:

1. Hairpin opgelost. Een interne service die api.example.com aanroept, routeert het uitgaande verkeer via 203.0.113.99 (egress), die vervolgens normaal verbinding maakt met 203.0.113.5 (ingress, een ander IP-adres). De NAT-loop verdwijnt omdat de twee IP-adressen op verschillende machines staan.

2. Beveiligingsisolatie. De firewall van de egress-server kan worden beperkt tot een klein aantal interne IP-adressen. De firewall van de ingress-server blijft open voor de wereld. Twee aparte regelsets, die elk één rol helder uitdrukken.

3. Onafhankelijke schaalbaarheid. Ingress-bandbreedte schaalt mee met het aantal gebruikers; egress-bandbreedte schaalt mee met de activiteit van interne services. U kunt de ene upgraden zonder de andere aan te raken.

4. Foutisolatie. Een verkeerd geconfigureerde egress breekt de openbare site niet langer. Een DDoS-aanval op de openbare site verstikt de egress-bandbreedte niet langer.

5. Helderder mentaal model. Elke machine heeft één taak. Ingenieurs redeneren over ingress-gerelateerde zaken zonder aan egress te hoeven denken, en omgekeerd.

Na de split moet een interne service nog steeds `api.example.com` aanroepen. Loop de nieuwe pakketpaden door van de interne service naar de api-backend. Neem op: welk IP-adres de interne service eerst aanspreekt, wat die machine met het verzoek doet, welk IP-adres het daarna naar toe stuurt, en waar het antwoord naartoe gaat.

Twee assen, twee afmetingsbeslissingen

Onafhankelijke schaling

Vóór de splitsing stelde groei in beide richtingen dezelfde machine onder druk. Na de splitsing heeft elke richting zijn eigen provisioning.

Ingress-grootte: schaalt met het aantal gebruikers. Capaciteitsbeslissingen zitten in de openbare laag (meer reverse proxy-replica's, grotere VM's, CDN ervoor). Bandbreedtebudget berekend op basis van gebruikersverkeer op piekmomenten.

Egress-grootte: schaalt met het volume van interne service-naar-externe API-aanroepen. Vaak gedomineerd door webhook-levering, aanroepen van betaalverwerkers of data-opvragingen van derden. Bandbreedtebudget berekend op basis van interne aanroeppatronen.

Foutisolatie: een DDoS-aanval op de openbare ingress verbruikt niet langer de egress-bandbreedte (die betaalverwerker-aanroepen gaan immers gewoon door). Een crash van een egress-proxy neemt de openbare site niet meer mee (gebruikers bereiken de site nog steeds; alleen interne uitgaande aanroepen falen).

Verschillende SLO's: ingress-beschikbaarheid is belangrijk voor gebruikers (zichtbare site-uitval); egress-beschikbaarheid is belangrijk voor operators (achtergrondstoringen die langer duren om te detecteren). Elke kant kan zijn eigen SLO dragen.

Meerdere egress-servers

Zodra de egress-rol een eigen machine is, is de volgende voor de hand liggende stap om meerdere egress-machines achter een load balancer te draaien voor HA. Elke nieuwe interne service wijst naar de egress-hostnaam (die oplost naar de load-balanced pool) in plaats van naar een enkel IP-adres.

Zelfde les als de rest van distributed systems: zodra een tier stateless is & een eigen rol heeft, kan deze goedkoop worden vermenigvuldigd.

Een nieuwe partnerintegratie

Je organisatie draait de ingress/egress-splitsing zoals ontworpen. De egress-server heeft een vast publiek IP-adres (203.0.113.99) dat je hebt allowlisted voor drie bestaande partner-API's (een betaalverwerker, een SMS-gateway en een e-mailprovider).

Een productteam wil een vierde integratie toevoegen: een webhook-leveringssysteem dat terugbelt naar klantendpoints over de hele wereld. Volumevoorspelling: 10.000 oproepen per minuut, met pieken tot 30.000.

Beslis: hoort deze nieuwe integratie op de bestaande egress-server, of heeft deze een aparte egress-pad nodig? Redeneer over bandbreedte, falingsisolatie en of de bestaande partner-allowlists in beide gevallen bijgewerkt moeten worden.

Ontwerp een netwerkgrens voor een groeiende service

Synthese

Je hebt geleerd waarom inkomend en uitgaand verkeer verschillende tools vereisen, de hairpin-NAT-fout die de splitsing in echte vloten afdwingt, en hoe onafhankelijke schaalbaarheid, beveiligingsisolatie en foutisolatie zich opbouwen zodra de splitsing is gerealiseerd.

Pas alle vier toe.

Een middelgrote SaaS-bedrijf exploiteert drie product-subdomeinen (app, api, admin) voor hun gebruikers, plus vier uitgaande integraties (Stripe, Twilio, SendGrid, een klant-webhooksysteem). Momenteel zit alles achter één proxy-machine met één openbaar IP-adres. Er zijn meldingen binnengekomen van intermitterende hairpin-fouten wanneer interne services proberen api.example.com aan te roepen. Ze willen een permanente oplossing ontwerpen.

Stel een ingress/egress-architectuur voor voor dit bedrijf. Behandel: hoeveel machines, welke IP-adressen welke rollen vervullen, waar de DNS van elke subdomein naartoe wijst, welke uitgaande integraties een egress-pad delen (& welke gesplitst moeten worden), & één concrete monitoringzorg die het nieuwe ontwerp mogelijk maakt en het oude niet deed.

Waar deze cursus naartoe gaat

Waar deze cursus naartoe gaat

Je hebt nu een van de schoonste scheiding-van-betrokkenheden-refactors in gedistribueerde systemen gezien: één box wordt twee, elk met een duidelijke rol, & het systeem erft op weg schaalbaarheid, beveiliging & foutisolatie.

De volgende les (cs_distsys_failure_modes_and_blast_radius) breidt de redenering over isolatie van storingen uit. Je leest een gesaniteerd postmortem over DNS-SERVFAIL, identificeert het patroon van kaskadelende storingen & schrijft schuldloze actiepunten die zich richten op systemen in plaats van personen.

Begeleidelijke les: geometry_of_ingress_egress_separation presenteert de scheiding als een tweetijdige graaf & verkent knutpunten, netwerkpartities & wat grafentheorie je vertelt over een netwerkgrens.

Goed gedaan. Verder.