BSD-pakkefilter

Den BPF ( Berkeley Packet Filter ) eller BSD packet filter , er en minimalistisk kode injiceres i kernen , det tillader brugeren at udføre netværk filtrering i kernen. I de forskellige versioner (eksempel: eBPF (udvid Berkeley Packet Filter)) er der implementeret nye værktøjer for at lette produktionen af ​​BPF-programmer. Derudover er nye anvendelsesområder blevet udnyttelige, såsom hændelsesovervågning i kernen og sporing af dens. Der eksisterer stadig forskellige problemer den dag i dag, hovedsageligt på revisorniveau.

Definition

BPF, oprindeligt designet i 1992, er minimalistisk binær kode, der injiceres i kernen fra brugerrummet . Det giver brugeren mulighed for at filtrere pakker, der cirkulerer i kernen, mens man undgår at skulle overføre dem til brugerrummet. På grund af sin minimalistiske side har den imidlertid få instruktioner. Desuden betyder dens programmeringsvanskelighed, at den bruges af et lille antal applikationer såsom tcpdump. I 2013 revideret Alexei Starovoitov (softwareingeniør med speciale i kernen på Facebook) BPF fuldstændigt ved at tilføje nye funktioner og forbedre dens ydeevne. Denne nye version kaldes eBPF, i modsætning til cBPF (klassisk BPF), der betegner den tidligere version. Dette nye sprog gør det muligt at designe en større række brugssager, som kan opdeles i to anvendelsesområder. Det første område er kernesporing og overvågning, mens det andet er netværksprogrammering.

Brug sag

Der er flere use cases såsom opsporing, beholder firewall filtrering eller netværk, socket filtrering, packet filtrering, og trafik kontrol. Det er også muligt at foretage filtrering på det laveste niveau i netværksstakken, det vil sige direkte af føreren af ​​netværksinterfacekortet. Så pakker kan smides meget tidligt; for eksempel XDP (Express Data Path) er et projekt, der bruger eBPF, som kan bruges til at forhindre angrebdenial of service . Derudover tillader BPF'er effektiv og fleksibel overvågning af netværksydelse til applikationer i virtuelle maskiner , et eksempel er vNetTracer-rammen.

Her er en ikke-udtømmende liste over projekter, der bruger GMP'er:

Sporing / overvågning:

Bpftrace er et plottersprog på højt niveau til forbedring af Linux Berkeley Packet Filters (eBPF), det er tilgængeligt i nyere versioner af linux-kernen (dvs. siden version 4.x). Derudover bruger bpftrace LLVM til at kompilere scripts og bruger BCC til at interagere med Linux BPF-system. Perf er et systempræstationsanalyseværktøj udviklet af Linux-kerneudviklingssamfundet. Ply er et let dynamisk sporingsværktøj uden andre afhængigheder end libc. Det understøtter x86_64 arch64, arm og powerpc-arkitekturer. Det kompilerer lagskripter til et BPF-program og bruger en syntaks svarende til C. Systemtap er et sporings- / sonderingsværktøj, licenseret under GPL , som giver dig mulighed for at omgå rutinen til rekompilering, installation og genstart for at indsamle data. Det har en kommandolinjegrænseflade såvel som et script-sprog. PCP står for "Performance Co-Pilot". Det er et modent, udvideligt værktøjssæt på tværs af platforme, der muliggør live og retrospektiv analyse af et system. Væveomfang er et værktøj til overvågning og kontrol af en Docker-container i realtid. Det giver en visning af metrics, tags og container metadata; samt håndtering af containere.


Netværk:

Cilium er open source-software, der leverer og sikrer netværks- og belastningsbalanceringsforbindelser mellem applikationscontainere eller processer. Det er integreret i Kubernetes og Mesos orkestrering rammer . Suricata er et detekteringssystem for netværksindtrængning, et system til forebyggelse af indtrængen og en netværkssikkerhedsstyringsenhed Systemd er et sæt programmer til systemadministration i linux-kernen. Iproute2 er en open source-software, der leverer hjælpeprogrammer til kontrol og overvågning af netværk i linux-kernen. P4c-xdp er en P4-kode backend-kompilator til XDP.


Andre:

LLVM er en C-kodekompilator i eBPF-programmet. BCC står for BPF Compiler Collection, er et værktøjssæt til at skrive effektive programmer til sporing og manipulation af kernen. Derudover letter BCC skrivning af BPF-programmer med instrumentering af kernen i C og dens frontend i Python og lua . Libbpf er et BPF-bibliotek, der tillader indlæsning af BPF-programmer i ELF-format produceret af LLVM i kernen. Bpftool er et værktøj til inspektion og manipulation af eBPF-programmer. Gobpf er et GO- bibliotek, der tillader BCC-værktøjssættet at producere eBPF-programmer fra GO-kode. Ebpf_asm er en samler til eBPF-programmer skrevet i en syntaks svarende til Intel.

Teknisk drift

BPF bruger CFG- kontrolflowdiagrammer til at repræsentere de kriterier, der anvendes i pakkeanalyse, og også for dets ydeevne på træmodeludtryk . Derudover bruges disse grafer af BPF til at indstille filtreringsregler, der gør det muligt effektivt at reducere CFG-stier, der er unødvendige til analyse af en pakke såvel som overflødige sammenligninger. Dataoverførslen foretaget af systemopkaldene sker på en tovejs måde mellem kernen og brugerområdet. Disse muliggør den korrekte udvikling af indsprøjtningen af ​​den binære eBPF-kode i kernen samt kommunikation af data fra målkernen til en brugerrumsproces. Pakkerne, der er tilknyttet BPF-programmet, kopieres delvist til en buffer, før de overføres til brugerrummet. BPF tillader, at programmet definerer antallet af bytes i pakken, der skal kopieres til bufferen. Dette sparer tid ved at undgå at kopiere unødvendige data. For eksempel er for TCP / IP / Ethernet-pakker tilstrækkelige 134 byte. Et program, der ønsker at lave statistik over TCP-rammer, vil kun kunne kopiere en del af rammerne, hvilket sparer udførelsestid.

eBPF er en udvidelse af BPF, som adskiller sig fra den på flere måder: indlæsning af programmer udføres af brugeren, og der foretages en kontrol af afslutningen af ​​et program for at sikre, at det er sikkert at køre. Den seneste udvidelse, der er bragt af eBPF, er muligheden for at få adgang til delte datastrukturer. Faktisk for at dele disse data bruger eBPF tre forskellige mekanismer:

Da version 3.15 af Linux-kernen giver funktionerne til den virtuelle eBPF-maskine adgang til linklag gennem grundlæggende instruktioner og introduktionen af ​​ny eBPF-funktionalitet, skaber dette et middel til filtrering og filtrering. Imidlertid kan eBPF-programmer påberåbes i forskellige lag af netværksstakken, hvilket gør det muligt at behandle de fangede pakker, inden de går videre til det næste lag. EBPF er afhængig af binær kode, der er sammensat til native CPU-instruktioner, når udvidelsen indlæses i kernen. I modsætning til klassisk bytecode for eksempel Java, pålægger compileren og udførelsestiden for eBPF ingen type eller hukommelsessikkerhed. I stedet forbedres sikkerheden af ​​en statisk verifikator, der verificerer, at programmet ikke kan få adgang til kernedatastrukturer eller forårsage sidefejl.

Sikkerheds- og stabilitetsrisici er til stede, når kode udføres i kernen. For at afbøde disse risici er BPF afhængig af en tolk, der sikkert udfører et program. Mens det reducerer disse risici, introducerer eBPF en Linux-verifikator, der sikrer, at hvert program opfylder visse betingelser, inden det indlæses i kernen, hvorved man undgår høje omkostninger i verifikationstiden. Det sikrer, at programmet er i stand til at afslutte, at det ikke indeholder en loop, der kan få kernen til at gå ned, eller at visse instruktioner er utilgængelige. Og i en anden tid kontrollerer den hver instruktion og simulerer den for at være sikker på, at registrernes og batteriernes tilstand er gyldige, hvilket forhindrer adgang til hukommelsen eller til kernens tilstand uden for det tildelte område. EBPF-implementeringen sørger for at være sikker og sikker for kernen, men også for at tilbyde muligheden for at oprette andet arbejde i kernen, såsom at spore kernen og oprette netværket.

Systemopkald tillader indlæsning af binær kode. For at overførslen skal lykkes, skal programmet verificeres af eBPF-verifikatoren. EBPF-programmer kan instantieres på samme tid, selv på forskellige kroge. Så de kan fungere individuelt eller lænkes.

Netværk

Et BPF-program kan lytte på en grænseflade, når dette sker, kalder grænsefladedriveren dette program først. BPF distribuerer derefter pakkerne til hvert filter, der deltager i behandlingen. Brugerdefinerede filtre gælder derefter for pakkerne og beslutter, om pakken accepteres eller ej, og hvor mange byte af hver pakke der skal gemmes. For hvert filter, der accepterer pakken, kopierer BPF den ønskede mængde data som bufferen, der skal tilknyttes dette filter. Når der opstår topologimodifikationer eller en ændring i applikationerne, bliver det nødvendigt at ændre de regler, der fungerer som en firewall, for at kunne tilføje, slette eller ændre de porte og adresser, der er påvirket af filtrene. For at gøre dette takket være bitmapstrategien, der holder C-programmet simpelt, skal du bare oprette et nyt program med nye kort og indlæse kortet med nye nøgleværdier og bytte det med det gamle. Program og dermed efterligne adfærden af iptables-gendannelse.

Værktøjer

Jit kompilere

Filtre fortolkes som bytecode i en kerne med tolk. I mangel af denne kan eBPF bruge kernens on-the-fly compiler (JIT compiler) til at oversætte de bytecodes, der produceres af eBPF, til native-kode og til at udføre valgfri maskinafhængige optimeringer.

LLVM

Clang (native LLVM) giver brugeren mulighed for at kompilere deres C-kode til en eBPF-instruktion i en ELF-fil.

BCC

Programmering i eBPF-instruktion kan være kompliceret. Derfor findes der et værktøjssæt kaldet BPF Compiler Collection (BCC), der giver brugeren mulighed for nemt at oprette eBPF-programmer. BCC omfatter og forbedrer LLVM for at give brugeren mulighed for at definere eBPF-kort i C-kode og kompilere denne C-kode til et eBPF-program.

Instruktioner

BPF + virtuel maskine har 5 driftsklasser:

Forbedringer og begrænsninger

I 2019 opstår der stadig forskellige problemer for udvikleren som:

Der er begrænsninger i brugen af ​​kernetjenester, få hjælpefunktioner, og ingen brugerplads eller tredjeparts tjenester kan bruges i eBPF-programmer. Visse begrænsninger gør programkontrol fleksibel og tillader systemintegritet, såsom manglende evne til at foretage dynamiske tildelinger, få adgang til kernedatastrukturer, kalde kernel API'er eller springe instruktioner. Samt det faktum, at det udføres på en enkelt tråd og derfor har en udførelsestid knyttet til antallet af instruktioner.

BPF ydeevne

Det cGMP bruger en implementeringsstrategi buffer , der gør sin samlede præstation op til 100 gange hurtigere end NIT (Network Interface Tap ) SUN kører på den samme hardware. Eksekveringstiden for et opkald til BPF er ca. 6 mikrosekunder pr. Pakke til et filter, der kasserer alle pakker. EBPF'er er op til 4 gange hurtigere på x86_64-arkitekturer end cBPF-implementeringen for nogle netværksfiltreringsmikrobenchmarks, og de fleste er 1,5 gange hurtigere. Der er en faktor på 10 præstationsforbedringer af eBPF'er sammenlignet med IPTABLES og NFTABLES.

Forkerne (XDP)

XDP, der er knyttet til det laveste niveau af netværksstakken, er velegnet til grov pakkefiltrering, såsom at forhindre benægtelse af tjenesteangreb . Det kan producere fire gange præstationen sammenlignet med en lignende opgave i kernen. Derudover tilbyder XDP også forbedringer af median latenstid ved hjælp af kodekompilering i JIT (Just In Time), op til 45% forbedring af ydeevnen med omkostningerne ved højere outlier-latensværdier. XDP tilbyder et kompromis, det tilbyder ikke så god ydelse som dedikerede rammer med høj ydeevne, der tilsidesætter kernen. Men tilbyder kerneintegration, hvilket betyder, at pakker kan gå gennem netværksstakken med alle dens fordele. Selvom den kun håndterer 50% af gennemstrømningen af ​​en 10 GbE-linje, repræsenterer dette ydeevnen for en enkelt kerne, det vil sige den skaleres med antallet af CPU-kerner.

BPF historie

BPF står oprindeligt for "Berkeley pakkefilter", udviklet til UNIX i 1992 for at filtrere netværkspakker, de tillader derefter en forbedring af ydeevnen i netværksovervågningsapplikationer såsom "tcpdump". BPF har ikke funktionen til at kassere modtagne pakker, men beskrevet som et filter kan de knytte pakker, kopiere pakker og sende pakker.Oprindeligt blev BPF'er implementeret i linux 2.x-kernen med 2 registre 32 Så i 2013 foreslog Alexei Starovoitov en forbedring af BPF'er, der nu differentierer cBPF (klassisk BPF) og eBPF (udvidet BPF), en af ​​de mest bemærkelsesværdige ændringer er passagen til 10 registre på 64 bit samt funktionsopkaldet i kernen takket være en ny instruktion En anden forskel er fraværet af tilstandspersistens i cBPF mens i eBPF kan staterne opretholdes takket være kortene eBPF'er vises i version 3 .x fra linux-kernen med kontinuerlige forbedringer såsom en JIT-kompilator (Just In Time), nye funktioner såsom “maps” og “tail calls”.

Reference

  1. Monnet 2016
  2. Chaignon 2018
  3. Suo 2018
  4. Scholz 2018
  5. Cilium Authors 2019
  6. bpftrace
  7. perf
  8. lag
  9. systemtap
  10. PCP
  11. Væveomfang
  12. Cilium
  13. Suricata
  14. systemd
  15. iproute2
  16. p4c-xdp
  17. LLVM
  18. BCC
  19. libbpf
  20. bpftool
  21. gobpf
  22. ebpf_asm
  23. McCanne 1993
  24. Lidl 2002
  25. Baidya 2018
  26. Saif 2018
  27. Ellis 2017
  28. Belkalem 2018
  29. Nam 2017
  30. Gershuni 2019
  31. Fleming 2017
  32. Miano 2018
  33. Deepak 2018
  34. Begel 1999
  35. Tu 2018
  36. Tu 2017
  37. Toy 2015
  38. Corbet 2014
  39. Toy 2017
  40. Bos 2004

Bibliografi

Internet side

Se også