Stora nedladdningar mot VPN: välj vägen vid förfrågan
En router kan inte mäta storleken på ett svar innan det anländer. Styrning per uppgift kräver en beslutspunkt i applikationen, eller en köpolicy som behåller den väg den har.
”Skicka de stora nedladdningarna runt VPN:en och håll de små svaren på den” låter som en routingpolicy, och det är det inte. En router beslutar med information som är tillgänglig i det ögonblicket: adresser, portar, protokoll, brandväggsmarkeringar, ett identifierat flöde. Den slutliga storleken på ett svar finns inte i den mängden, eftersom det inte har anlänt ännu, och när routern skulle kunna mäta byten transporterar den dem redan. Vill du styra per uppgift måste beslutet flyttas till en punkt som känner till uppgiften, och checklistan nedan visar om din design har en sådan punkt.
Varför en router inte kan mäta ett svar
I det ögonblick ett paket behöver en väg har routern sett högst de första få paketen i ett flöde. Den kan säga vem som talar med vem, över vilket protokoll, med vilken markering och hur många byten som passerat hittills. Byten hittills beskriver det förflutna. Svarens storlek är en egenskap hos ett svar som ännu inte genererats, och för delade eller strömmande svar är den kanske aldrig känd i förväg.
Till och med protokollets egna metadata är svagare än de ser ut. HTTP tillåter svar vars längd inte annonseras före kroppen, och en enda användarhandling kan ge många förfrågningar vars sammanlagda kostnad inte liknar något enskilt headervärde. Att behandla en header som storleken på en uppgift är ett modelleringsfel innan det är ett routingfel.
Kontroll 1: finns det en beslutspunkt som kan välja en väg?
Namnge komponenten som gör valet, och nämn sedan vad den vet i valögonblicket. En uppdaterare som hämtar från en dokumenterad uppsättning värdar känner sitt syfte innan överföringen börjar. En nedladdningstjänst som läser metadata och sedan öppnar förfrågan känner uppgiften innan anslutningen finns. En samarbetande proxy kan tillämpa policy på förfrågningsnivå eller cacha svaret utan att låtsas vara en router.
Om svaret är ”gatewayen” har checklistan redan misslyckats. En gateway kan klassificera kända flöden efter destination, markering eller klientsegment och skicka dem längs en definierad väg från första paketet, vilket ofta räcker för en godkänd uppdaterare och aldrig räcker för en okänd svarsstorlek.
Kontroll 2: vad säger metadata dig egentligen?
Applikationsmedveten styrning är bara så bra som fälten den läser. Reglerna för svarslängd i HTTP:s semantik tillåter fall där längden inte är tillgänglig i början, och innehållskodningar gör antalet överförda byten ändå olikt representationens storlek. Därför kommer en policy som byter väg när en header passerar ett tröskelvärde att bete sig inkonsekvent, och mest just vid de stora överföringar den skulle fånga.
Det applikationsmetadata kan stödja är ett beslut om en uppgift: detta arbetsflöde är en massiv synkronisering, detta är interaktivt, detta är en programvaruuppdatering från en känd källa. Det är en policy skriven i avsiktsbegrepp, och den är stabil nog att testas. ”Detta svar blir större än fyrtio megabyte” är inte den sortens policy.
Kontroll 3: finns flödet redan?
Routing kan ändras för ett flöde utan att anslutningens identitet ändras, och den skillnaden är värd att hålla reda på. En TCP-anslutning identifieras av adresserna och portarna hos sina ändpunkter, och paketen kan ta en annan väg om routingtabellen ändras under dem. Det som inte kan ändras osynligt är tillståndet för nätverksadressöversättning: att flytta trafik till en annan utgång ändrar vanligtvis den offentliga källtupeln, och den bortre sidan kommer att se en annan peer utan matchande tillstånd.
conntrack -L -p tcp --dport 443 | head -5
ip route get 203.0.113.10
ss -tn state established dst 203.0.113.10
Den praktiska regeln är alltså att en flytt mitt i anslutningen från en utgång till en annan är en ny relation, inte en migrering. Om designen kräver att samma anslutning fortsätter måste beslutet ha fattats före den första SYN, och ingen paketregel som läggs till senare kan rekonstruera den rent.
Kontroll 4: är det egentliga kravet latens, inte utgång?
Väldigt många förfrågningar om att ”skicka bulktrafiken någon annanstans” är egentligen klagomål på att en stor överföring får interaktivt arbete att kännas långsamt. Det är ett schemaläggningsproblem, och det har ett schemaläggningssvar: rättvis kö eller en stödd bandbreddspolicy på den befintliga vägen hindrar ett bulkflöde från att svälta ett chattmeddelande utan att flytta något av dem.
tc qdisc replace dev eth0 root cake bandwidth 100mbit
Att hantera symptomet så här behåller utgångsbeslutet där säkerhetspolicyn placerade det, och det kan rullas tillbaka med ett enda kommando. Att ändra utgången för en hel trafikklass är en policyändring med konsekvenser för autentisering, loggning och åtkomstregler, så det bör inte vara det första verktyget vid ett klagomål om latens.
Om kravet verkligen är en annan internetutgång, säg det med de orden och implementera det vid en stödd gräns: en ny anslutning från ett godkänt arbetsflöde, eller en applikation som öppnar sin egen förfrågan genom en vald utgång. Registrera sedan vilka uppgifter som använder vilken utgång, så att nästa person inte behöver sluta sig till det från en routingtabell.
Behåll checklistan i ändringsregistret: beslutspunkten, fältet eller uppgiften som driver den, om flödet redan finns och om det uppmätta symptomet var latens eller utgång. Fyra frågor, och en policy som svarar på alla fyra är en du kan driva i stället för att försvara.