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

un

gäst
1 / ?

Två trafikriktningar, en box

Välkommen

De flesta arkitekturdigram visar trafik som går ett sätt: klient uppe, server nere, pil som pekar nedåt. I verkligheten går trafiken båda sätten.

Ingress: Externa klienter når dina tjänster via denna väg. En reverse proxy vid nätverkets kant avslutar TLS, riktar begärningar och tillämpar åtkomstpolicy.

Egress: Dina tjänster når externa tjänster via denna väg. Att anropa en betalningsprocessor API, hämta en webhook-mål, skicka en begäran till en partner. Ofta via en forward proxy eller NAT-gateway med en tillåtandelista.

Många arkitekturer börjar med en enda enhet som hanterar båda riktningarna. Det fungerar, tills den dag det inte längre gör. Felet är subtilt, dyker upp först när tillräckligt många interna tjänster finns, och lär en viktig lektion om separation av intressen.

Till slutet av denna lektion kommer du att förstå:

- Varför inkommande och utgående trafik representerar fundamentalt olika trafikmönster med olika skalningsaxlar och olika felmoder

- Hairpin NAT och varför en proxy som försöker ansluta till sig själv misslyckas

- Arkitekturen gaffel: en enhet blir två, och vad respektive enhet då exklusivt äger

- Säkerhetsvinster genom isolering: varje sida kan låsas till sina faktiskt tillåtna parter

- Hur du identifierar när din design med en enda enhet har passerat tröskeln där uppdelningen blir nödvändig

Varför riktningarna kräver olika verktyg

Två olika arbetsbelastningar vid en nätverksgräns

Karakteristika för inkommande trafik:

- Initierad av externa parter (det stora internet)

- Volymen skalar med din användarbaser

- TLS-avslutning, begärandesrouting, hastighetsbegränsning per källa

- Försvar i flera lager: DDoS, missbruk, skrapning

- Den publika IP-adressen måste acceptera anslutningar från vem som helst

Karakteristika för utgående trafik:

- Initierad av dina egna tjänster (en känd, liten mängd klienter)

- Volymen skalar med dina mönster för tjänst-till-tjänst- och externa API-anrop

- Käll-IP-allowlisting på fjärrändpunkter (du har en fast utgående IP som partnerföretag litar på)

- Överväganden kring djup i försvar: dataexfiltrering, komprometterade interna tjänster som ringer ut

- Bör avvisa anslutningar från alla utom dina egna tjänster

Den viktiga asymmetrin: Ingress accepterar trafik från världen; egress accepterar trafik endast från dina egna tjänster. Att placera dem på samma maskin innebär att maskinen samtidigt måste vara nåbar från världen (för ingress) och endast nåbar från dina tjänster (för egress). Brandväggsreglerna som uppfyller det ena arbetar mot det andra.

Växtpåsen: Ett litet projekt kan dölja båda bakom en IP och ett verktyg, eftersom volymen är liten och partner-IP-allowlistan är kort. När projektet växer ökar friktionen mellan de två rollerna, och en dag tvingar ett specifikt felmönster (hairpin NAT) uppdelningen.

Ingress vs egress: olika källor, olika destinationer, olika krav

Ett litet startup-företag kör allt (ingress reverse proxy, egress forward proxy / NAT, interna tjänster) på en enda VM med en offentlig IP-adress. De är tidigt nog i sin utveckling att detta verkar fungera. Nämner två specifika felmoder eller operationella problem som denna design kommer att stöta på när de växer, och förklara den underliggande orsaken för respektive fall.

Buggen som tvingar uppdelningen

En sanerad incidentberättelse

Tänk dig en verklig arkitekturell gaffel som inträffar i produktionsflottor. Namnen nedan har ändrats; formen är identisk med det som team stöter på i praktiken.

En organisation driver en enda proxyserver på 203.0.113.5. Den hanterar inkommande trafik (port 443 för användare) & utgående trafik (port 1080 SOCKS5 för interna tjänster som ringer utåt). Interna tjänster ligger i privata delnät & rutterar all utgående trafik genom den SOCKS5-proxy på 203.0.113.5:1080.

En av tjänsterna som hostas bakom samma 203.0.113.5 är api.example.com. Offentlig DNS löser upp api.example.com till 203.0.113.5.

Nu behöver en annan intern tjänst anropa api.example.com. Dess utgående väg:

1. Intern tjänst löser upp api.example.com → 203.0.113.5

2. Intern tjänst skickar förfrågan genom SOCKS5-utgående proxy på 203.0.113.5:1080

3. Proxyn försöker öppna en anslutning från sig själv till 203.0.113.5:443

4. Connection refused. Paketet skulle behöva lämna & återinträda samma NAT, vilket de flesta nätverksstackar avvisar. Proxyn kan inte ansluta till sig själv via sin egen publika IP.

Detta är hairpin NAT: ett paket som lämnar en NAT & behöver återinträda samma NAT för att nå sin destination. Utan speciellt hairpin-stöd i routningsskiktet släcks paketet.

Varför det dyker upp sent

Tidigt i projektets livstid kommunicerade varje intern tjänste antingen med andra interna tjänster via privat värdnamn (internal-api.local) eller gjorde inte återanrop till sin egen organisations publika tjänster. Hairpin-sökvägen existerade helt enkelt inte.

Därefter krävde en ny funktion att tjänst A skulle anropa api.example.com (ett publikt värdnamn). Hairpin-sökvägen aktiverades. Connection refused. Avbrott.

Lagringen åtgärde symptomet (tvinga resolvern att ge api.example.com's privata IP istället för den publika). Rotorsaken: en enda maskin gjorde för många jobb.

Hairpin NAT: paketet lämnar & kan inte återinträda samma NAT

Den arkitektoniska gaffeln

En box blir två

Det rena fixet: separera proxyn till två maskiner.

Ingress-server (offentlig IP 203.0.113.5):

- Caddy / omvänd proxy på portarna 80, 443

- Offentliga DNS-poster pekar hit

- Värd för api.example.com, app.example.com m.m.

Egress-server (annan offentlig IP 203.0.113.99):

- SOCKS5 / framåtriktad proxy på port 1080

- Brandväggen begränsar inkommande anslutningar till endast interna subnät-IP:er

- Interna tjänster routar all utgående trafik via denna adress

Detta ger:

1. Hairpin löst. En intern tjänst som anropar api.example.com routar utgående trafik via 203.0.113.99 (egress), som sedan ansluter normalt till 203.0.113.5 (ingress, en annan IP). NAT-loopen försvinner eftersom de två IP:erna finns på olika maskiner.

2. Säkerhetsisolering. Egress-serverns brandvägg kan låsas ner till en liten uppsättning interna IP:er. Ingress-serverns brandvägg hålls öppen för världen. Två separata regeluppsättningar, där var och en uttrycker en roll tydligt.

3. Oberoende skalning. Ingress-bandbredd skalar med användare; egress-bandbredd skalar med intern tjänsteaktivitet. Uppgradera den ena utan att röra den andra.

4. Felisolering. En felkonfigurerad egress bryr inte längre den publika sajten. En DDoS mot den publika sajten svälter inte längre egress-bandbredden.

5. Tydligare mentalt modell. Varje maskin har ett jobb. Ingenjörer resonemang om ingress-frågor utan att tänka på egress, och vice versa.

Efter uppdelningen behöver en intern tjänst fortfarande anropa `api.example.com`. Gå igenom den nya paketvägen från den interna tjänsten till API-bakänden. Inkludera: vilken IP-adress den interna tjänsten först ansluter till, vad den maskinen gör med förfrågan, vilken IP-adress den skickar till näst, och var svaret går.

Två axlar, två storleksbestämningar

Oberoende skalning

Före uppdelningen belastade tillväxt i någon som helst riktning samma maskin. Efter uppdelningen har varje riktning sin egen resursförsörjning.

Ingress-storlek: skalerar med användare. Kapacitetsbeslut ligger i det publika lagret (fler reverse proxy-replikor, större VM:er, CDN framför). Bandbreddsbudget beräknas mot användartrafiken vid toppbelastning.

Egress-storlek: skalerar med volymen av interna tjänste- till externa API-anrop. Oftast dominerad av webhook-leverans, anrop till betalningsprocessorer eller hämtningar av tredjepartsdata. Bandbreddsbudget beräknas mot interna anropsmönster.

Felisolering: en DDoS mot den publika ingressen äter inte längre egress-bandbredd (dessa anrop till betalningsprocessorer går igenom ändå). En krasch i egress-proxyen tar inte längre ner den publika sajten (användare når fortfarande sajten; endast interna utgående anrop misslyckas).

Olika SLO:er: ingress-tillgänglighet är viktig för användare (synlig sajtstörning); egress-tillgänglighet är viktig för operatörer (bakgrundsfel som kan ta längre tid att upptäcka). Varje sida kan ha sitt eget SLO.

Flera egress-server

När egress-rollen är en egen maskin är nästa uppenbara åtgärd att köra flera egress-maskiner bakom en lastbalanserare för HA. Varje ny intern tjänst pekar mot egress-värdnamnet (som löses upp till lastbalanserade poolen) istället för mot en enskild IP-adress.

Samma lektion som resten av distribuerade system: när en tier blir stateless och har en egen roll, kan den multipliceras billigt.

En ny partnerintegration

Din organisation kör uppdelningen ingress/egress som designad. Egress-servern har en fast publik IP-adress (203.0.113.99) som du har allowlistat med tre befintliga partner-API:er (en betalningsprocessor, ett SMS-gateway och en e-postleverantör).

Ett produktteam vill lägga till en fjärde integration: ett webhook-leveranssystem som ringer tillbaka till kundändpunkter världen över. Volymprognos: 10 000 anrop per minut, med toppar upp till 30 000.

Beslut: Tillhör denna nya integration den befintliga egress-servern, eller behöver den en separat egress-sökväg? Resonera om bandbredd, felisolering och om de befintliga partner-allowlisten behöver uppdateras oavsett.

Designa en nätverksgräns för en växande tjänst

Syntes

Du har lärt dig varför inkommande och utgående trafik kräver olika verktyg, det hairpin NAT-fel som tvingar fram uppdelningen i verkliga flottor, och hur oberoende skalning, säkerhetsisolering och felfördröjning uppstår när uppdelningen är på plats.

Tillämpa alla fyra.

Ett medelstort SaaS-företag driver tre produktunderdomäner (app, api, admin) för sina användare, samt fyra utgående integrationer (Stripe, Twilio, SendGrid och ett kundwebhook-system). Idag ligger allt bakom en enda proxy-maskin med en offentlig IP-adress. De har börjat få rapporter om tillfälliga hairpin-fel när interna tjänster försöker anropa api.example.com. De vill designa en permanent lösning.

Föreslå en ingress-/egressarkitektur för detta företag. Besvara: hur många maskiner, vilka IP-adresser som fyller vilka roller, vart DNS för varje deldomän pekar, vilka utgående integrationer som delar en egressväg (& vilka som bör separeras) & ett konkret övervakningsproblem som den nya designen möjliggör men den gamla inte gjorde.

Vart kursen går härnäst

Vart kursen går härnäst

Du har nu sett en av de renaste separation-of-concerns-refaktoreringarna inom distribuerade system: en maskin blir två, var och en med en tydlig roll, & systemet får fördelar med skalbarhet, säkerhet & felisolering på vägen dit.

Nästa lektion (cs_distsys_failure_modes_and_blast_radius) utöjer resonemanget kring isolering av fel. Du kommer att läsa ett rensat postmortem-dokument om DNS-SERVFAIL, identifiera det kaskadliknande felförloppet och skriva skuldfrifriande åtgärder som riktar sig mot systemet snarare än till individer.

Systudie: geometry_of_ingress_egress_separation omformulerar uppdelningen som en bipartit graf och utforskar skärningsnoder, nätverkspartitioner och vad grafteori säger om en nätverksgräns.

Bra jobbat. Framåt.