
Sporing af forbindelser (“conntrack”) er en grundlæggende funktion i netværksstakken i Linux-kernen. Det gør det muligt for kernen at spore alle logiske netværksforbindelser eller strømme, og på den måde identificere alle pakker, der udgør hver strøm, så de kan behandles sekventielt sammen.
Conntrack er en vigtig funktion i kernen, der anvendes i en række centrale tilfælde:
- NAT er afhængig af information fra conntrack, så det kan behandle alle pakker fra én strøm ens. For eksempel, når en pod kontakter en Kubernetes-service, bruger load balancer kube-proxy NAT til at dirigere trafik til en specifik pod inden for klyngen. Conntrack registrerer, at for en given forbindelse skal alle pakker til IP-adressen på servicen sendes til den samme pod, og at pakkerne, der returneres fra backend-poden, skal dirigeres tilbage af NAT til den pod, som anmodningen kom fra.
- Firewalls med tilstandsbaseret sporing, såsom Calico, er afhængige af information fra conntrack for at tilføje “respons” trafik til hvidlisten. Dette giver dig mulighed for at skrive en netværkspolitik, der siger: «tillad min pod at oprette forbindelse til enhver ekstern IP-adresse», uden at du skal skrive en politik for eksplicit at tillade respons trafik. (Uden dette ville du skulle tilføje en langt mindre sikker regel om at tillade pakker til min pod fra enhver IP.)
Derudover øger conntrack normalt systemets ydeevne (ved at reducere procesortid og pakker forsinkelse), da kun den første pakke i strømmen
skal gennemgå den fulde behandling af netværksstakken for at bestemme, hvad der skal gøres med den. Se indlægget «for at se et eksempel på, hvordan det fungerer.
Men conntrack har sine begrænsninger...
Så hvor gik alting galt?
Conntrack-tabellen har en konfigurerbar maksimale størrelse, og hvis den fyldes, begynder forbindelser normalt at blive afvist eller afbrudt. Til behandling af trafik fra de fleste applikationer er der som regel tilstrækkeligt med fri plads i tabellen, og det bliver aldrig et problem. Alligevel er der nogle scenarier, hvor det er værd at overveje at bruge conntrack-tabellen:
- Den mest åbenlyse situation opstår, hvis din server håndterer et ekstremt stort antal samtidige aktiverede forbindelser. For eksempel, hvis din conntrack-tabel er indstillet til 128k poster, men du har > 128k samtidige forbindelser, vil du helt sikkert støde på problemer!
- En lidt mindre åbenbar situation er, hvis din server håndterer et meget stort antal forbindelser pr. sekund. Selv hvis forbindelserne er kortvarige, vil Linux stadig holde styr på dem i et stykke tid (som standard 120 sekunder). For eksempel, hvis din conntrack-tabel er indstillet til 128.000 poster og du forsøger at håndtere 1100 forbindelser pr. sekund, vil de overstige størrelsen på conntrack-tabellen, selvom forbindelserne er meget kortvarige (128k / 120 sek = 1092 forbindelser / sek).
Der er flere nichetyper applikationer, der falder ind under disse kategorier. Derudover, hvis du har mange onde aktører, kan fyldning af din servers conntrack-tabel med mange halvåbne forbindelser bruges i et angreb af typen "denial of service" (DOS). I begge tilfælde kan conntrack blive et begrænsende flaskehals i dit system. I nogle tilfælde kan justeringen af conntrack-tabelindstillingerne være tilstrækkelig til at opfylde dine behov — ved at øge størrelsen eller reducere conntrack-tidsbegrænsningerne (men hvis du gør det forkert, vil du støde på store vanskeligheder). For andre tilfælde vil det være nødvendigt at omgå conntrack for aggressiv trafik.
Et konkret eksempel
Lad os tage et specifikt eksempel: en stor SaaS-udbyder, som vi arbejdede med, havde en række memcached-servere på hosts (ikke virtuelle maskiner), hver af dem håndterede 50K+ kortvarige forbindelser pr. sekund.
De eksperimenterede med konfigurationen af conntrack, øgede størrelserne af tabellerne og reducerede tracking-tiden, men konfigurationen var ustabil, hvilket betød betydeligt øget hukommelsesforbrug (op til flere GB!), og forbindelserne var så korte, at conntrack ikke gav den sædvanlige gevinst i ydelse (reducering af CPU-forbrug eller pakkeefterslæb).
Som et alternativ henvendte de sig til Calico. Calicos netværkspolitikker gør det muligt at undgå brugen af conntrack for bestemte typer trafik (ved at bruge indstillingen doNotTrack til politikker). Dette sikrede dem det nødvendige ydeevne plus et ekstra sikkerhedsniveau, der tilbydes af Calico.
Hvad må man gøre for at omgå conntrack?
- Netværkspolitikker do-not-track skal som regel være symmetrisk. I tilfældet med en SaaS-udbyder: deres applikationer kørte inden for en beskyttet zone, og derfor kunne de med netværkspolitik tilføje trafik fra andre specifikke applikationer til whitelist, der fik lov til at tilgå memcached.
- Do-not-track politikken tager ikke højde for forbindelsesretningen. Således kan man teoretisk forsøge at oprette forbindelse til en hvilken som helst af memcached-klienterne, hvis memcached-serveren er blevet kompromitteret, så længe den bruger den rigtige kildeport. Men hvis du korrekt har defineret netværkspolitikken for dine memcached-klienter, vil disse forbindelsesforsøg stadig blive afvist på klientsiden.
- Do-not-track politikken anvendes på hver pakke, i modsætning til normale politikker, som kun anvendes på den første pakke i strømmene. Dette kan øge CPU-ressourceforbruget pr. pakke, da politikken skal anvendes på hver pakke. Men for kortvarige forbindelser balanceres dette forbrug mod et reduceret ressourceforbrug til håndtering af conntrack. For eksempel, i tilfælde af en SaaS-udbyder, var antallet af pakker til hver forbindelse meget lille, så den ekstra CPU-ressourceomkostning ved at anvende politikker på hver pakke var rimelig.
Lad os begynde testene
Vi udførte testen på en pod med memcached-serveren og mange pod'er af memcached-klienter, der kørte på fjerntliggende noder, så vi kunne køre et meget stort antal forbindelser i sekundet. Serveren med pod'en til memcached-serveren havde 8 kerner og 512k poster i conntrack-tabellen (standardkonfigureret tabelstørrelse for værten).
Vi målte forskellen i ydeevne mellem: uden netværkspolitik; med almindelig Calico-politik; og Calico do-not-track politik.
I den første test satte vi antallet af forbindelser til 4.000 pr. sekund, så vi kunne fokusere på forskellen i CPU-forbrug. Her var der ikke væsentlige forskelle mellem fraværet af politik og standardpolitikken, men do-not-track øgede CPU-forbruget med cirka 20%:

I den anden test kørte vi så mange forbindelser, som vores kunder kunne generere, og målte det maksimale antal forbindelser pr. sekund, som vores memcached-server kunne håndtere. Som forventet nåede både 'uden politik' og 'standardpolitik' grænsen for conntrack på mere end 4.000 forbindelser pr. sekund (512k / 120s = 4.369 forbindelser/s). Med do-not-track politik sendte vores kunder 60.000 forbindelser pr. sekund uden problemer. Vi er sikre på, at vi kunne øge dette antal ved at tilslutte flere kunder, men vi mener, at disse tal allerede er tilstrækkelige til at illustrere essensen af denne artikel!

Konklusion
Conntrack er en vigtig funktion i kernen. Den udfører sit arbejde fremragende. Den benyttes ofte af centrale systemkomponenter. Men i nogle specifikke scenarier kan overbelastningen fra conntrack opveje de normale fordele, den giver. I dette scenarie kan netværkspolitikker fra Calico bruges til selektivt at deaktivere brugen af conntrack samtidig med at netværkssikkerheden forbedres. For al anden trafik fortsætter conntrack med at være din partner!
Læs også andre artikler på vores blog:
Kilde: habr.com
