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

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

TL;DR: Popis klient-server architektury našeho interního systému pro řízení konfigurace sítě, QControl. V základě spočívá dvouvrstvý transportní protokol, který pracuje s gzipem zabalenými zprávami bez dekomprese mezi koncovými body. Distribuované routéry a koncové body dostávají aktualizace konfigurací, a samotný protokol umožňuje instalaci lokalizovaných mezilehlých relayů. Systém je postaven na principu diferenciálního zálohování ('recent-stable', vysvětleno níže) a využívá dotazovací jazyk JMESpath spolu s templátorem Jinja pro renderování konfiguračních souborů.

Qrator Labs spravuje globálně distribuovanou síť neutralizace útoků. Naše síť funguje na principu anycast a podsítě jsou ohlášeny prostřednictvím BGP. Jako BGP anycast síť fyzicky umístěná v několika regionech Země můžeme zpracovávat a filtrovat nelegitimní provoz blíže k jádru internetu — Tier-1 operátorům.

Na druhou stranu, být geograficky distribuovanou sítí není snadné. Komunikace mezi síťovými body přítomnosti je kriticky důležitá pro poskytovatele bezpečnostních služeb, aby byla zajištěna konzistentní konfigurace všech uzlů sítě, s jejich včasným aktualizováním. Proto, abychom poskytli maximální možnou úroveň základní služby pro zákazníka, museli jsme najít způsob, jak spolehlivě synchronizovat konfigurační údaje mezi kontinenty.

Na počátku bylo Slovo. To se rychle stalo komunikačním protokolem, potřebujícím aktualizaci.


Základním kamenem existence QControl a zároveň hlavním důvodem značné ztráty času a prostředků na vytvoření tohoto typu protokolu je potřeba získat jednotný autoritativní zdroj konfigurace a v konečném důsledku synchronizovat naše přítomnost s ním. Samotné úložiště bylo jedním z několika požadavků při vývoji QControl. Kromě toho jsme také potřebovali integrace se stávajícími a plánovanými službami na místech přítomnosti (MP), chytré (a přizpůsobitelné) metody validace dat a také řízení přístupu. Dále jsme chtěli spravovat tento systém pomocí příkazů, nikoli úpravou souborů. Před QControl se data zasílala na místa přítomnosti téměř ručně. Pokud bylo jedno z míst přítomnosti nedostupné a my jsme na něj zapomněli aktualizovat později, došlo k desynchronizaci konfigurace — museli jsme trávit čas jejím uvedením zpět do provozu.

Nakonec jsme přišli na následující schéma:
Systém správy konfigurace sítě filtrování Qrator.
Konfigurační server je zodpovědný za validaci dat a úložiště, router má několik koncových bodů, které získávají a přenášejí konfigurační aktualizace od klientů a podpůrného týmu na server, a ze serveru na místa přítomnosti.

Kvalita internetového připojení se stále značně liší v různých koutech světa — pro ilustraci tohoto tvrzení se podívejme na jednoduché MTR z Prahy, Česká republika do Singapuru a Hongkongu.

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

Systém správy konfigurace sítě filtrování Qrator.
Totéž do Hongkongu

Vysoké latence znamenají menší rychlost. Kromě toho dochází ke ztrátě paketů. Šířka kanálů tuto problematiku nekompenzuje, což je třeba vždy brát v úvahu při budování decentralizovaných systémů.

Plná konfigurace místa přítomnosti je významný objem dat, který je třeba přenést mnoha příjemcům přes nespolehlivá připojení. Naštěstí, i když se konfigurace stále mění, dochází k tomu v malých porcích.

Design recent-stable

Lze říci, že budování distribuované sítě na principu inkrementálních aktualizací je poměrně zřejmým řešením. Ale s diferenciačními soubory je spojeno mnoho problémů. Je nutné uchovávat všechny difery mezi referenčními body a také mít možnost je doručit, pokud někdo ztratil část dat. Každý cílový bod je povinen je aplikovat ve striktně stanoveném pořadí. Obvykle v případě více cílových bodů může tato operace zabrat značný čas. Příjemce by také měl mít možnost požádat o ztracené části a samozřejmě centrální část by měla na takovou žádost správně reagovat, posílajíc pouze chybějící data.

Nakonec jsme přišli na poměrně zajímavé řešení — máme pouze jednu referenční vrstvu, pevnou, nazvěme ji stable, a pouze jeden diferenciální soubor pro ni — recent. Každý recent je založen na posledním vytvořeném stable a je dostatečný pro přestavbu konfiguračních dat. Jakmile nový recent dorazí na místo určení, starý již není potřeba.

Zůstává pouze čas od času odeslat čerstvou stable konfiguraci, například proto, že recent se stal příliš velkým. Také je důležité, že všechny tyto aktualizace rozesíláme v režimu broadcast/multicast, aniž bychom se starali o jednotlivé příjemce a jejich schopnost shromáždit kousky dat dohromady. Jakmile se ujistíme, že u všech je správný stable — posíláme pouze nové recent. Stojí za to podotknout, že to funguje? Ano, funguje. Stable je cachováno na konfiguračním serveru a u příjemců, recent se vytváří podle potřeby.

Architektura dvouvrstvého transportu

Proč jsme postavili náš transport na dvou úrovních? Odpověď je poměrně jednoduchá — chtěli jsme oddělit routování od high-level logiky, čerpaje inspiraci z modelu OSI s jeho transportní úrovní a úrovní aplikací. Na roli transportního protokolu jsme vzali Thrift a pro high-level formát řídicích zpráv — formát serializace msgpack. Právě proto router (provádějící multicast/broadcast/relay) se nedívá do msgpacku, nerozbalí a nebalí obsah zpět a provádí pouze přenos dat.

Thrift (z angličtiny – „úspornost“, vyslovuje se jako [θrift]) – jazyk pro popis rozhraní, který se používá k definování a vytváření služeb pro různé programovací jazyky. Je to framework pro vzdálené volání procedur (RPC). Kombinuje softwarový kanál s generátorem kódu pro vývoj služeb, které mezi jazyky pracují efektivně a snadno.

Rozhodli jsme se pro framework Thrift kvůli RPC a podpoře mnoha jazyků. Jak je obvyklé, nejjednodušší části byly klient a server. Nicméně, router se ukázal jako tvrdý oříšek, částečně kvůli nedostatku hotového řešení během našeho vývoje.

Systém správy konfigurace sítě filtrování Qrator.Existují i další možnosti, jako protobuf / gRPC, ale když jsme začínali náš projekt, gRPC bylo stále poměrně nové a neodvážili jsme se ho přijmout.

Samozřejmě, mohli jsme (a ve skutečnosti, mělo by se to tak udělat) vytvořit vlastní řešení. Bylo by snazší vytvořit protokol, který potřebujeme, protože klient-server architektura je relativně přímočará ve srovnání s tím, abychom vytvořili router na Thrift. Tak či onak, k vlastním protokolům a implementacím populárních knihoven (není náhodou) existuje tradiční předsudek, navíc se při diskusi vždy zvedá otázka: „Jak to přeneseme do jiných jazyků?“. Proto jsme ihned zavrhli myšlenku vlastního řešení.

Msgpack je alternativou k JSON, ale rychlejší a menší. Je to binární formát serializace dat, který umožňuje výměnu dat mezi mnoha jazyky.

Na prvním úrovni máme Thrift s minimem potřebných informací pro router pro přeposílání zpráv. Na druhém úrovni – zabalované struktury msgpack.

Zvolili jsme msgpack, protože je rychlejší a kompaktnější v porovnání s JSON. Ale co je ještě důležitější, podporuje vlastní datové typy, které nám umožňují používat skvělé funkce, jako je přenos syrových binárních dat nebo speciálních objektů reprezentujících absenci dat, což bylo důležité pro naši schéma “recent-stable”.

JMESPath
JMESPath je jazyk pro dotazy na JSON.
Takto vypadá popis, který získáváme z oficiální dokumentace JMESPath, ale ve skutečnosti nabízí mnohem více. JMESPath umožňuje hledat a filtrovat podstromy v libovolné stromové struktuře a také provádět změny dat za běhu. Navíc umožňuje přidávat speciální filtry a postupy pro transformaci dat. I když je samozřejmě náročné to pochopit.

Jinja
Pro některé uživatele je třeba převést konfiguraci do souboru — proto používáme šablonový engine a Jinja je jasnou volbou. S její pomocí generujeme konfigurační soubor z šablony a dat, která byla získána na cílovém místě.

Pro vygenerování konfiguračního souboru potřebujeme dotaz JMESPath, šablonu pro umístění souboru v systému souborů a šablonu pro samotný konfigurační soubor. Také v této fázi je dobré upřesnit přístupová práva k souboru. To vše se nám podařilo úspěšně zkombinovat do jednoho souboru — před začátkem šablony konfigurace vložíme hlavičku ve formátu YAML, popisující zbytek.

Například:

---
selector: "[@][?@.fft._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, stačí přidat pouze nový šablonový soubor. Není třeba provádět žádné změny v původním kódu nebo softwaru na místech nasazení.

Co se změnilo po zavedení QControl do provozu? První a nejdůležitější — konzistentní a spolehlivý přenos aktualizací konfigurace napříč všemi uzly sítě. Druhé — získání mocného nástroje pro kontrolu konfigurace a provádění změn naší podpůrnou skupinou, a také uživateli služby.

To vše jsme dokázali pomocí schématu aktualizací recent-stable pro zjednodušení komunikace mezi konfiguračním serverem a příjemci konfigurace. Používáme dvoustupňový protokol pro podporu nezávislého na obsahu způsobu směrování dat. Úspěšně jsme integrovali engine pro generování konfigurace založený na Jinja do distribuované sítě filtrování. Tento systém podporuje širokou škálu metod konfigurace pro naši distribuovanou a různorodou periferii.

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

Anglická verze příspěvku.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster