Qrator filterend netwerkconfiguratiebeheersysteem

Qrator filterend netwerkconfiguratiebeheersysteem

TL; DR: Beschrijving van de client-serverarchitectuur van ons interne netwerkconfiguratiebeheersysteem, QControl. Het is gebaseerd op een tweelaags transportprotocol dat werkt met gzip-verpakte berichten zonder decompressie tussen eindpunten. Gedistribueerde routers en eindpunten ontvangen configuratie-updates, en het protocol zelf maakt de installatie van gelokaliseerde tussenliggende relais mogelijk. Het systeem is gebaseerd op het principe differentiële back-up (“recent-stable”, hieronder uitgelegd) en gebruikt de JMESpath-querytaal samen met de Jinja-sjabloonengine om configuratiebestanden weer te geven.

Qrator Labs exploiteert een wereldwijd gedistribueerd netwerk voor aanvalsbeperking. Ons netwerk werkt volgens het anycast-principe en subnetten worden via BGP geadverteerd. Omdat we een BGP-anycast-netwerk zijn dat zich fysiek in verschillende regio's van de aarde bevindt, kunnen we illegaal verkeer verwerken en filteren dichter bij de kern van het internet - Tier-1-operators.

Aan de andere kant is het niet eenvoudig om een ​​geografisch verspreid netwerk te zijn. Communicatie tussen netwerkpunten is van cruciaal belang voor de beveiligingsdienstverlener om een ​​consistente configuratie van alle netwerkknooppunten te hebben en deze tijdig bij te werken. Om de consument het hoogst mogelijke niveau van kernservice te kunnen bieden, moesten we daarom een ​​manier vinden om op betrouwbare wijze configuratiegegevens tussen continenten te synchroniseren.

In den beginne was het Woord. Het werd al snel een communicatieprotocol dat een update nodig had.


De hoeksteen van het bestaan ​​van QControl, en tegelijkertijd de belangrijkste reden om een ​​aanzienlijke hoeveelheid tijd en middelen te besteden aan het bouwen van dit soort protocollen, is de noodzaak om één enkele gezaghebbende configuratiebron te verkrijgen en uiteindelijk onze aanwezigheidspunten te synchroniseren. ermee. De opslag zelf was slechts een van de vele vereisten tijdens de ontwikkeling van QControl. Daarnaast hadden we ook behoefte aan integraties met bestaande en geplande diensten op Points of Presence (POP), slimme (en aanpasbare) methoden voor gegevensvalidatie en toegangscontrole. Daarnaast wilden we zo'n systeem ook besturen met behulp van commando's in plaats van wijzigingen aan te brengen in bestanden. Vóór QControl werden gegevens vrijwel handmatig naar Points of Presence verzonden. Als een van de Points of Presence niet beschikbaar was en we vergaten deze later bij te werken, zou de configuratie niet meer synchroon lopen en zouden we tijd moeten verspillen om deze weer operationeel te krijgen.

Als gevolg hiervan zijn we tot het volgende schema gekomen:
Qrator filterend netwerkconfiguratiebeheersysteem
De configuratieserver is verantwoordelijk voor de gegevensvalidatie en -opslag; de router heeft verschillende eindpunten die configuratie-updates ontvangen en uitzenden van clients en ondersteuningsteams naar de server, en van de server naar point-of-presence.

De kwaliteit van de internetverbinding varieert nog steeds sterk over de hele wereld. Laten we, om dit punt te illustreren, eens kijken naar een eenvoudige MTR van Praag, Tsjechië naar Singapore en Hong Kong.

Qrator filterend netwerkconfiguratiebeheersysteem
MTR van Praag naar Singapore

Qrator filterend netwerkconfiguratiebeheersysteem
Hetzelfde geldt voor Hongkong

Hoge latentie betekent lagere snelheid. Bovendien is er sprake van pakketverlies. De kanaalbreedte compenseert dit probleem niet, waarmee altijd rekening moet worden gehouden bij het bouwen van decentrale systemen.

De volledige configuratie van een point-of-presence omvat een aanzienlijke hoeveelheid gegevens die via onbetrouwbare verbindingen naar veel ontvangers moeten worden verzonden. Hoewel de configuratie voortdurend verandert, gebeurt dit gelukkig in kleine stappen.

Recent stabiel ontwerp

We kunnen zeggen dat het bouwen van een gedistribueerd netwerk gebaseerd op het principe van incrementele updates een vrij voor de hand liggende oplossing is. Maar er zijn veel problemen met diffs. We moeten alle verschillen tussen de referentiepunten opslaan en ze ook opnieuw kunnen verzenden voor het geval iemand een deel van de gegevens heeft gemist. Elke bestemming moet ze in een strikt gespecificeerde volgorde toepassen. In het geval van meerdere bestemmingen kan een dergelijke operatie doorgaans lang duren. Ook moet de ontvanger de ontbrekende delen kunnen opvragen en uiteraard moet het centrale deel op een dergelijk verzoek correct reageren en alleen de ontbrekende gegevens versturen.

Als resultaat kwamen we tot een nogal interessante oplossing: we hebben maar één referentielaag, vast, laten we het stabiel noemen, en er maar één diff voor - recent. Elke recente is gebaseerd op de laatst gegenereerde stal en is voldoende om de configuratiegegevens opnieuw op te bouwen. Zodra de nieuwe recente zijn bestemming bereikt, is de oude niet langer nodig.

Het enige dat overblijft is af en toe een nieuwe stabiele configuratie te sturen, bijvoorbeeld omdat de recente te groot is geworden. Wat hier ook belangrijk is, is dat we al deze updates verzenden in een broadcast/multicast-modus, zonder ons zorgen te hoeven maken over individuele ontvangers en hun vermogen om stukjes gegevens samen te voegen. Zodra wij er zeker van zijn dat iedereen de juiste stal heeft, sturen wij alleen nieuwe recente op. Is het de moeite waard om duidelijk te maken dat dit werkt? Werken. Stabiel wordt in de cache opgeslagen op de configuratieserver en ontvangers, en recent wordt indien nodig aangemaakt.

Architectuur van transport op twee niveaus

Waarom hebben we ons transport op twee niveaus gebouwd? Het antwoord is heel simpel: we wilden routing loskoppelen van logica op hoog niveau, waarbij we inspiratie haalden uit het OSI-model met zijn transport- en applicatielagen. We gebruikten Thrift voor de rol van het transportprotocol, en het msgpack-serialisatieformaat voor het hoogwaardige formaat van controleberichten. Dit is de reden waarom de router (die multicast/broadcast/relay uitvoert) niet in msgpack kijkt, de inhoud niet uitpakt of terugpakt, en alleen gegevens doorstuurt.

Thrift (uit het Engels - "thrift", uitgesproken als [θrift]) is een interfacebeschrijvingstaal die wordt gebruikt om services voor verschillende programmeertalen te definiëren en te creëren. Het is een raamwerk voor remote procedure calls (RPC). Combineert een softwarepijplijn met een codegeneratie-engine om services te ontwikkelen die min of meer efficiënt en gemakkelijk tussen talen werken.

We hebben voor het Thrift-framework gekozen vanwege RPC en ondersteuning voor veel talen. Zoals gewoonlijk waren de gemakkelijke onderdelen de client en de server. De router bleek echter een harde noot om te kraken, mede door het ontbreken van een pasklare oplossing tijdens onze ontwikkeling.

Qrator filterend netwerkconfiguratiebeheersysteemEr zijn andere opties, zoals protobuf/gRPC, maar toen we aan ons project begonnen, was gRPC vrij nieuw en durfden we het niet aan boord te nemen.

Natuurlijk hadden we onze eigen fiets kunnen (en eigenlijk hadden moeten) bouwen. Het zou gemakkelijker zijn om een ​​protocol te maken voor wat we nodig hebben, omdat de client-server-architectuur relatief eenvoudig te implementeren is vergeleken met het bouwen van een router op Thrift. Op de een of andere manier bestaat er (niet voor niets) een traditionele voorkeur voor zelfgeschreven protocollen en implementaties van populaire bibliotheken; bovendien komt tijdens discussies altijd de vraag naar voren: “Hoe gaan we dit overbrengen naar andere talen?” Dus hebben we het idee van een fiets meteen van tafel geveegd.

Msgpack is vergelijkbaar met JSON, maar sneller en kleiner. Het is een binair gegevensserialisatieformaat waarmee gegevens tussen meerdere talen kunnen worden uitgewisseld.

Op het eerste niveau hebben we Thrift met de minimale informatie die nodig is voor de router om het bericht door te sturen. Op het tweede niveau zijn er verpakte msgpack-structuren.

We hebben voor msgpack gekozen omdat het sneller en compacter is vergeleken met JSON. Maar wat nog belangrijker is, het ondersteunt aangepaste gegevenstypen, waardoor we coole functies kunnen gebruiken, zoals het doorgeven van onbewerkte binaire bestanden of speciale objecten die de afwezigheid van gegevens aangeven, wat belangrijk was voor ons ‘recent-stabiele’ schema.

JMESPath
JMESPath is een JSON-querytaal.
Dit is precies hoe de beschrijving die we uit de officiële JMESPath-documentatie halen eruit ziet, maar in feite doet het veel meer dan dat. Met JMESPath kunt u subbomen in een willekeurige boomstructuur zoeken en filteren, en direct wijzigingen in gegevens aanbrengen. U kunt er ook speciale filters en gegevenstransformatieprocedures mee toevoegen. Hoewel het natuurlijk herseninspanning vereist om het te begrijpen.

Jinja
Voor sommige consumenten moeten we de configuratie in een bestand omzetten, dus gebruiken we een sjabloonengine en Jinja is de voor de hand liggende keuze. Met zijn hulp genereren we een configuratiebestand op basis van de sjabloon en de gegevens die op de bestemming zijn ontvangen.

Om een ​​configuratiebestand te genereren, hebben we een JMESPath-verzoek nodig, een sjabloon voor de bestandslocatie in de FS en een sjabloon voor de configuratie zelf. Het is in dit stadium ook een goed idee om de bestandsrechten te verduidelijken. Dit alles werd met succes gecombineerd in één bestand - vóór de start van de configuratiesjabloon hebben we een header in YAML-indeling geplaatst die de rest beschrijft.

Bijvoorbeeld:

---
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) }}

Om een ​​configuratiebestand voor een nieuwe dienst te maken, voegen we alleen een nieuw sjabloonbestand toe. Er zijn geen wijzigingen aan de broncode of software op de Points of Presence vereist.

Wat is er veranderd sinds QControl live ging? Het eerste en belangrijkste is een consistente en betrouwbare levering van configuratie-updates aan alle knooppunten in het netwerk. De tweede is het ontvangen van een krachtig hulpmiddel voor het controleren van de configuratie en het aanbrengen van wijzigingen daarin door ons ondersteuningsteam, maar ook door consumenten van de dienst.

We konden dit allemaal doen met behulp van het recent-stable updateschema om de communicatie tussen de configuratieserver en configuratieontvangers te vereenvoudigen. Gebruik van een tweelaags protocol ter ondersteuning van een inhoudsonafhankelijke manier om gegevens te routeren. Met succes een op Jinja gebaseerde configuratiegeneratie-engine geïntegreerd in een gedistribueerd filternetwerk. Dit systeem ondersteunt een breed scala aan configuratiemethoden voor onze gedistribueerde en heterogene randapparatuur.

Bedankt voor je hulp bij het schrijven van het materiaal. VolanDamrod, serenheit, Niet.

Engelse versie post.

Bron: www.habr.com

Voeg een reactie