Systém správy konfigurace sítě pro filtrování Qrator

Systém správy konfigurace sítě pro filtrování Qrator

TL, DR: Popis architektury klient-server našeho systému pro správu interní konfigurace sítě QControl. Je založen na dvouvrstvém transportním protokolu, který pracuje se zprávami zabalenými v gzip bez dekomprese mezi koncovými body. Distribuované směrovače a koncové body dostávají aktualizace konfigurace a samotný protokol umožňuje instalaci lokalizovaných mezilehlých relé. Systém je postaven na principu rozdílová záloha („recent-stable“, vysvětleno níže) a k vykreslování konfiguračních souborů používá dotazovací jazyk JMESpath spolu s enginem šablon Jinja.

Qrator Labs provozuje globálně distribuovanou síť pro zmírnění útoků. Naše síť funguje na principu anycast a podsítě jsou inzerovány prostřednictvím BGP. Jelikož se jedná o síť BGP anycast fyzicky umístěnou v několika oblastech Země, můžeme zpracovávat a filtrovat nelegitimní provoz blíže k jádru internetu – operátorům Tier-1.

Na druhou stranu být geograficky distribuovanou sítí není snadné. Komunikace mezi síťovými body přítomnosti je kritická pro poskytovatele bezpečnostních služeb, aby měl konzistentní konfiguraci všech síťových uzlů a aktualizoval je včas. Proto, abychom mohli spotřebiteli poskytnout nejvyšší možnou úroveň základních služeb, museli jsme najít způsob, jak spolehlivě synchronizovat konfigurační data napříč kontinenty.

Na počátku bylo Slovo. Rychle se stal komunikačním protokolem, který potřebuje aktualizaci.


Základním kamenem existence QControl a zároveň hlavním důvodem pro vynaložení značného množství času a zdrojů na budování tohoto druhu protokolu je potřeba získat jediný autoritativní zdroj konfigurace a v konečném důsledku synchronizovat naše body přítomnosti. s tím. Samotné úložiště bylo jen jedním z několika požadavků při vývoji QControl. Kromě toho jsme také potřebovali integraci se stávajícími a plánovanými službami v bodech přítomnosti (POP), chytré (a přizpůsobitelné) metody pro ověřování dat a také řízení přístupu. Kromě toho jsme také chtěli takový systém ovládat pomocí příkazů, spíše než provádět úpravy souborů. Před QControl byla data odesílána do bodů přítomnosti téměř ručně. Pokud by některý z bodů přítomnosti byl nedostupný a zapomněli jsme jej později aktualizovat, konfigurace by se nakonec nesynchronizovala a museli bychom ztrácet čas jejím opětovným zprovozněním.

V důsledku toho jsme přišli s následujícím schématem:
Systém správy konfigurace sítě pro filtrování Qrator
Konfigurační server je zodpovědný za ověřování a ukládání dat; router má několik koncových bodů, které přijímají a vysílají aktualizace konfigurace od klientů a týmů podpory na server a ze serveru do bodů přítomnosti.

Kvalita internetového připojení se ve světě stále velmi liší – pro ilustraci se podívejme na jednoduchý MTR z Prahy, České republiky do Singapuru a Hong Kongu.

Systém správy konfigurace sítě pro filtrování Qrator
MTR z Prahy do Singapuru

Systém správy konfigurace sítě pro filtrování Qrator
To samé do Hong Kongu

Vysoká latence znamená nižší rychlost. Navíc dochází ke ztrátě paketů. Šířka kanálu tento problém nekompenzuje, což je třeba vždy vzít v úvahu při budování decentralizovaných systémů.

Úplná konfigurace bodu přítomnosti představuje značné množství dat, která musí být odeslána mnoha příjemcům prostřednictvím nespolehlivých připojení. Naštěstí, i když se konfigurace neustále mění, děje se tak v malých krocích.

Nedávný stabilní design

Dá se říci, že vybudování distribuované sítě na principu inkrementálních aktualizací je celkem samozřejmé řešení. Ale s diffy je spousta problémů. Musíme uložit všechny rozdíly mezi referenčními body a také je umět znovu odeslat v případě, že někdo vynechal část dat. Každá destinace je musí aplikovat v přesně stanoveném pořadí. V případě několika míst určení může taková operace obvykle trvat dlouho. Přijímač si také musí umět vyžádat chybějící části a samozřejmě centrální část musí na takový požadavek správně reagovat a odeslat pouze chybějící data.

Ve výsledku jsme došli k poměrně zajímavému řešení – máme pouze jednu referenční vrstvu, pevnou, říkejme jí stabilní, a pro ni pouze jeden rozdíl – nedávnou. Každá poslední je založena na poslední vygenerované stáji a je dostatečná k opětovnému sestavení konfiguračních dat. Jakmile čerstvý čerstvý dorazí na místo určení, starý již není potřeba.

Zbývá jen čas od času poslat novou stabilní konfiguraci, například proto, že nedávná se stala příliš velkou. Zde je také důležité, že všechny tyto aktualizace odesíláme v režimu vysílání/multicast, aniž bychom se starali o jednotlivé příjemce a jejich schopnost poskládat kusy dat. Jakmile jsme si jisti, že každý má správnou stáj, posíláme pouze nové nedávné. Má cenu objasňovat, že to funguje? funguje. Stabilní se ukládá do mezipaměti na konfiguračním serveru a příjemcích, poslední se vytváří podle potřeby.

Architektura dvouúrovňové dopravy

Proč jsme postavili naši dopravu na dvou úrovních? Odpověď je docela jednoduchá – chtěli jsme oddělit směrování od logiky na vysoké úrovni a inspirovat se modelem OSI s jeho transportními a aplikačními vrstvami. Pro roli transportního protokolu jsme použili Thrift a pro vysokoúrovňový formát řídicích zpráv serializační formát msgpack. To je důvod, proč router (provádějící multicast/broadcast/relay) nenahlíží do msgpacku, nerozbaluje ani nezabaluje obsah zpět a pouze přeposílá data.

Thrift (z angličtiny - „thrift“, vyslovováno [θrift]) je jazyk pro popis rozhraní, který se používá k definování a vytváření služeb pro různé programovací jazyky. Je to rámec pro vzdálená volání procedur (RPC). Kombinuje softwarový kanál s modulem pro generování kódu pro vývoj služeb, které více či méně efektivně a snadno fungují mezi jazyky.

Zvolili jsme framework Thrift kvůli RPC a podpoře mnoha jazyků. Jako obvykle byly nejjednoduššími částmi klient a server. Router se však ukázal být tvrdým oříškem, částečně kvůli tomu, že během našeho vývoje chybělo hotové řešení.

Systém správy konfigurace sítě pro filtrování QratorExistují další možnosti, jako je protobuf / gRPC, ale když jsme s naším projektem začínali, gRPC bylo docela nové a neodvážili jsme se ho vzít na palubu.

Samozřejmě jsme si mohli (a vlastně měli) postavit vlastní kolo. Bylo by snazší vytvořit protokol pro to, co potřebujeme, protože architektura klient-server je relativně přímočará na implementaci ve srovnání s budováním routeru na Thriftu. Tak či onak existuje tradiční zaujatost vůči samostatně psaným protokolům a implementacím populárních knihoven (z dobrého důvodu); navíc během diskusí vždy padne otázka: „Jak to přeneseme do jiných jazyků? Takže jsme okamžitě zavrhli myšlenku na kolo.

Msgpack je podobný JSON, ale rychlejší a menší. Jedná se o binární formát serializace dat, který umožňuje výměnu dat mezi více jazyky.

Na první úrovni máme Thrift s minimálními informacemi, které router potřebuje k předání zprávy. Na druhé úrovni jsou zabalené struktury msgpack.

Vybrali jsme msgpack, protože je rychlejší a kompaktnější ve srovnání s JSON. Ale co je důležitější, podporuje vlastní datové typy, což nám umožňuje používat skvělé funkce, jako je předávání nezpracovaných binárních souborů nebo speciální objekty indikující absenci dat, což bylo důležité pro naše „nedávno stabilní“ schéma.

JMESPath
JMESPath je dotazovací jazyk JSON.
Přesně tak vypadá popis, který získáme z oficiální dokumentace JMESPath, ale ve skutečnosti toho umí mnohem víc. JMESPath umožňuje vyhledávat a filtrovat podstromy v libovolné stromové struktuře a aplikovat změny na data za běhu. Umožňuje také přidat speciální filtry a procedury transformace dat. I když k pochopení to samozřejmě vyžaduje mozkové úsilí.

Jinja
Pro některé spotřebitele potřebujeme konfiguraci převést do souboru – proto používáme šablonový engine a Jinja je jasná volba. S jeho pomocí vygenerujeme konfigurační soubor ze šablony a dat přijatých v cíli.

Pro vygenerování konfiguračního souboru potřebujeme požadavek JMESPath, šablonu pro umístění souboru ve FS a šablonu pro samotnou konfiguraci. V této fázi je také dobré ujasnit si oprávnění k souboru. To vše se podařilo zkombinovat do jednoho souboru – před spuštěním konfigurační šablony jsme vložili hlavičku ve formátu YAML, která popisuje zbytek.

Například:

---
selector: "[@][[email protected]._meta.version == `42`] | items([0].fft_config || `{}`)"
destination_filename: "fft/{{ match[0] }}.json"
file_mode: 0644
reload_daemons: [fft] ...
{{ dict(match[1]) | json(indent=2, sort_keys=True) }}

Abychom vytvořili konfigurační soubor pro novou službu, přidáme pouze nový soubor šablony. Nejsou vyžadovány žádné změny ve zdrojovém kódu nebo softwaru v bodech přítomnosti.

Co se změnilo od spuštění QControl? První a nejdůležitější věcí je konzistentní a spolehlivé doručování aktualizací konfigurace všem uzlům v síti. Druhým je získání výkonného nástroje pro kontrolu konfigurace a provádění změn od našeho týmu podpory i od uživatelů služby.

To vše jsme mohli udělat pomocí nedávno stabilního schématu aktualizací, abychom zjednodušili komunikaci mezi konfiguračním serverem a příjemci konfigurace. Použití dvouvrstvého protokolu pro podporu způsobu směrování dat nezávislého na obsahu. Úspěšně integrován modul pro generování konfigurace založený na Jinja do distribuované filtrační sítě. Tento systém podporuje širokou škálu konfiguračních metod pro naše distribuované a heterogenní periferie.

Děkuji za pomoc při psaní materiálu. VolanDamrod, klid, NeN.

anglická verze pošta.

Zdroj: www.habr.com

Přidat komentář