A BPF ( Berkeley Packet Filter ) vagy BSD csomagszűrő egy minimalista kód, amelyet a kernelbe injektálnak , lehetővé teszi a felhasználó számára, hogy hálózati szűrést hajtson végre a kernelben. Különböző verziói (példa: eBPF (kiterjeszteni a Berkeley csomagszűrőt)) során új eszközöket vezettek be a BPF programok előállításának megkönnyítése érdekében. Ezenkívül új felhasználási területek is kiaknázhatóvá váltak, például az eseményfigyelés a kernelben és annak nyomon követése. A mai napig különféle problémák állnak fenn, főként az auditor szintjén.
Az eredetileg 1992-ben tervezett BPF egy minimalista bináris kód, amelyet a kernelbe injektálnak a felhasználói térből . Lehetővé teszi a felhasználó számára, hogy szűrje a kernelben keringő csomagokat, miközben elkerüli, hogy át kell vinni őket a felhasználói helyre. Minimalista oldala miatt azonban kevés az utasítás, ráadásul a programozási nehézségek miatt kevés alkalmazás használja, például a tcpdump. 2013-ban Alekszej Starovoitov (a Facebook kernelére szakosodott szoftvermérnök) teljesen átalakította a BPF-et új funkciók hozzáadásával és teljesítményének javításával. Ezt az új verziót eBPF-nek hívják, szemben a korábbi verziót jelölő cBPF (klasszikus BPF) -vel. Ez az új nyelv lehetővé teszi a felhasználási esetek sokféleségének megtervezését, amelyek két alkalmazási területre bonthatók. Az első terület a kernel nyomon követése és figyelése, míg a második a hálózati programozás.
Számos felhasználási eset létezik, például nyomkövetés, tároló tűzfalszűrés vagy hálózatépítés, foglalatszűrés , csomagszűrés és forgalomirányítás. Lehetőség van szűrésre a hálózati verem legalacsonyabb szintjén is, vagyis közvetlenül a hálózati interfész kártya illesztőprogramja által. Tehát a csomagokat nagyon korán el lehet dobni; például az XDP (Express Data Path) az eBPF-et használó projekt, amely felhasználható a szolgáltatásmegtagadási támadások megelőzésére . Ezenkívül a BPF-ek lehetővé teszik a hálózati teljesítmény hatékony és rugalmas nyomon követését a virtuális gépek alkalmazásai számára , például a vNetTracer keretrendszer.
Itt van a GMP-ket használó projektek nem teljes listája:
Nyomon követés / figyelés:
Bpftrace egy magas szintű plotter nyelv a Linux Berkeley csomagszűrők (eBPF) fejlesztésére, elérhető a linux kernel legújabb verzióiban (azaz a 4.x verzió óta). Ezenkívül a bpftrace az LLVM-et használja a szkriptek összeállításához, és a BCC-t használja a linux BPF rendszerrel való interakcióhoz. Tökéletes egy olyan rendszer teljesítményelemző eszköz, amelyet a Linux kernel fejlesztői közösség fejlesztett ki. Ply egy könnyű dinamikus nyomkövető eszköz, a libc-n kívül más függőséggel nem rendelkezik. Támogatja az x86_64 arch64, az arm és a powerpc architektúrákat. Összeállítja a szkripteket egy BPF programba, és a C-hez hasonló szintaxist használ. Systemtap egy nyomkövető / szondázó eszköz, a GPL engedélyével , amely lehetővé teszi az újrafordítás, telepítés és újraindítás megkerülését az adatgyűjtés érdekében. Van parancssori felülete, valamint szkriptnyelve. PCP a "Performance Co-Pilot" kifejezés. Ez egy kiforrott, bővíthető, platformokon átívelő eszközkészlet, amely lehetővé teszi a rendszer élő és retrospektív elemzését. Weave Scope egy eszköz a Docker konténer valós idejű felügyeletéhez és vezérléséhez. Nézetet kínál a mutatókról, a címkékről és a tárolók metaadatairól; valamint a konténerek kezelése.
Hálózat:
Egyéb:
A BPF CFG vezérlő folyamatábrákat használ a csomagelemzésben használt kritériumok, valamint a famodell- kifejezések teljesítményének bemutatására . Ezenkívül a BPF ezeket a grafikonokat használja szűrési szabályok felállítására, amelyek lehetővé teszik a csomag elemzéséhez és a redundáns összehasonlításokhoz szükséges CFG útvonalak hatékony csökkentését. A rendszerhívások által végrehajtott adatátvitel kétirányú módon történik a kernel és a felhasználói tér között. Ezek lehetővé teszik az eBPF bináris kódnak a kernelbe történő injektálásának megfelelő előrehaladását, valamint az adatok kommunikációját a cél kernelből a felhasználói tér folyamatába. A BPF program által társított csomagokat részben átmásolják egy pufferbe, mielőtt átkerülnének a felhasználói helyre. A BPF lehetővé teszi a program számára, hogy meghatározza a pufferbe másolandó csomag bájtjainak számát. Ez időt takarít meg azzal, hogy elkerüli a felesleges adatok másolását. Például TCP / IP / Ethernet csomagokhoz 134 bájt elegendő. Az a program, amely statisztikákat kíván készíteni a TCP keretekről, csak a keretek egy részét képes lemásolni, ezzel megtakarítva a végrehajtási időt.
Az eBPF a BPF kiterjesztése, amely több szempontból is különbözik tőle: a programokat a felhasználó tölti be, és ellenőrzik a program megszüntetését annak biztosítása érdekében, hogy biztonságos legyen a futtatása. Az eBPF legújabb kiterjesztése a megosztott adatstruktúrákhoz való hozzáférés képessége. Valójában az adatok megosztása érdekében az eBPF három különböző mechanizmust használ:
Mivel a Linux kernel 3.15-ös verziója, az eBPF virtuális gép funkciói az alaputasításokkal és az új eBPF-funkcionalitások bevezetésével linkréteg-hozzáférést biztosítanak, ez lehetőséget teremt a szűrésre és a szűrésre. Elemezze a hálózati csomagokat. Az eBPF programokat azonban meg lehet hívni a hálózati verem különböző rétegeiben, amely lehetővé teszi az elfogott csomagok feldolgozását, mielőtt továbblépne a következő rétegre. Az EBPF a natív CPU utasításokba fordított bináris kódra támaszkodik, amikor a kiterjesztést betöltik a kernelbe. Ellentétben a klasszikus bájtkóddal, például a Java-val, az eBPF fordítója és végrehajtási ideje nem ír elő semmilyen típusú vagy memóriabiztonságot. Ehelyett a biztonságot egy statikus hitelesítő javítja, amely ellenőrzi, hogy a program nem fér hozzá a kernel adatszerkezeteihez, vagy oldalhibákat okozhat.
Biztonsági és stabilitási kockázatok vannak, amikor a kódot végrehajtják a kernelben. E kockázatok csökkentése érdekében a BPF tolmácsra támaszkodik a program biztonságos végrehajtásához. E kockázatok csökkentése érdekében az eBPF bevezet egy Linux verifikátort, amely biztosítja, hogy minden program megfeleljen bizonyos feltételeknek, mielőtt betöltenék a kernelbe, elkerülve ezzel az ellenőrzési idő magas költségeit. Biztosítja, hogy a program képes legyen befejezni, hogy ne tartalmazzon olyan hurkot, amely a kernel összeomlását okozhatja, vagy hogy bizonyos utasítások nem érhetők el. Egy másik időpontban minden egyes utasítást ellenőriz és szimulál, hogy megbizonyosodjon arról, hogy a regiszterek és az elemek állapota érvényes-e, megakadályozva ezzel a memóriához vagy a kernel kiosztott területén kívüli állapotához való hozzáférést. Az eBPF implementáció biztosítja, hogy biztonságos és biztonságos legyen a kernel számára, ugyanakkor lehetővé teszi a kernelben a különböző munkák beállítását, például a kernel nyomon követését és a hálózat létrehozását.
A rendszerhívások lehetővé teszik a bináris kód betöltését. A feltöltés sikeres végrehajtásához a programot az eBPF hitelesítőjének kell igazolnia. Az EBPF programok egyszerre, akár különféle kampókon is példányosíthatók. Tehát külön-külön is működhetnek, vagy láncolhatók.
A BPF program egy interfészen hallgathat, amikor ez megtörténik, az illesztőprogram meghívja először ezt a programot. Ezután a BPF elosztja a csomagokat a feldolgozásban részt vevő minden egyes szűrőnek. Ezután a felhasználó által definiált szűrők alkalmazódnak a csomagokra, és eldönthetik, hogy a csomagot elfogadják-e vagy sem, és hány bájtot kell menteni az egyes csomagokból. A BPF minden egyes szűrőhöz a kért mennyiségű adatot másolja pufferként társítani. ezt a szűrőt. A topológia módosításakor vagy az alkalmazások változásakor szükségessé válik a tűzfalként szolgáló szabályok módosítása annak érdekében, hogy hozzá lehessen adni, törölni vagy módosítani lehessen a szűrők által érintett portokat és címeket. Ehhez a bittérkép stratégiának köszönhetően, amely egyszerűvé teszi a C programot, csak hozzon létre egy új programot új térképekkel, töltse be a térképet új kulcsértékekkel, és cserélje le a régivel. iptables-restore.
A szűrőket bájtkódként értelmezik egy tolmácsos kernben. Ennek hiányában az eBPF használhatja a kern on-the-fly fordítóját (JIT fordító) az eBPF által előállított byte-kódok natív kódra történő lefordítására és opcionális gépfüggő optimalizálások végrehajtására.
LLVMA Clang (natív LLVM) lehetővé teszi a felhasználó számára, hogy C kódját egy ELF fájlban egy eBPF utasításba fordítsa.
BCCAz eBPF utasításokban történő programozás bonyolult lehet. Ezért létezik egy BPF Compiler Collection (BCC) nevű eszköztár, amely lehetővé teszi a felhasználó számára, hogy egyszerűen létrehozhasson eBPF programokat. A BCC felöleli és továbbfejleszti az LLVM-et, hogy a felhasználó számára lehetővé tegye az eBPF-térképek C-kódban történő meghatározását és a C-kód összeállítását eBPF-programba.
A BPF + virtuális gépnek 5 működési osztálya van:
2019-ben még számos probléma merül fel a fejlesztő számára, például:
Korlátozások vannak a kernelszolgáltatások használatában, kevés a segítő funkció, és az eBPF programokban nem használható felhasználói terület vagy harmadik féltől származó szolgáltatás. Bizonyos megszorítások rugalmassá teszik a programellenőrzéseket, és lehetővé teszik a rendszer integritását, például a dinamikus allokációk, a kernel adatszerkezeteihez való hozzáférés, a kernel API-k hívása vagy az ugrási utasítások képtelenek közvetetté tenni. Valamint az a tény, hogy egyetlen szálon futtatják, és ezért az utasítások számához kapcsolódik egy végrehajtási idő.
A cGMP olyan megvalósítási stratégia puffert használ, amely teljes teljesítményét akár 100-szor gyorsabbá teszi, mint az ugyanazon a hardveren futó NIT (Network Interface Tap ) SUN. A BPF-hez való hívás végrehajtási ideje csomagonként körülbelül 6 mikroszekundum egy olyan csomag esetén, amely eldobja az összes csomagot. Az EBPF-ek akár négyszer gyorsabbak az x86_64 architektúrákon, mint a cBPF-megvalósítás egyes hálózati szűrő mikrobarátoknál, és a legtöbb 1,5-szer gyorsabb. Az eBPF-ek teljesítményének 10-szeres javulása van az IPTABLES és az NFTABLES-hez képest.
Az XDP, amely a hálózati verem legalacsonyabb szintjéhez van csatlakoztatva, durva csomagszűrésre alkalmas, például a szolgáltatásmegtagadási támadások megelőzésére . Négyszeres teljesítményt képes produkálni a kernel hasonló feladatához képest. Ezen túlmenően az XDP a JIT (Just In Time) kódfordítás használatával is javítja a középső késleltetést, akár 45% -os teljesítmény-javulást eredményezhet a magasabb kiugró késési értékek költségével. Az XDP kompromisszumot kínál, nem kínál olyan jó teljesítményt, mint a kernelt felülíró nagy teljesítményű dedikált keretrendszerek. De kernelintegrációt kínál, ami azt jelenti, hogy a csomagok minden előnyével át tudnak menni a hálózati veremben. Bár csak egy 10 GbE-s vonal átbocsátásának 50% -át kezeli, ez egyetlen mag teljesítményét jelenti, vagyis skálázódik a CPU-magok számával.
A BPF eredetileg a „Berkeley csomagszűrő” kifejezést jelenti, amelyet 1992-ben fejlesztettek ki az UNIX számára a hálózati csomagok szűrése céljából, majd lehetővé teszik a hálózati felügyeleti alkalmazások, például a „tcpdump” teljesítményének javulását. A BPF-nek nem az a feladata, hogy eldobja a fogadott csomagokat, de szűrőként leírva csomagokat társíthatnak, csomagokat másolhatnak és csomagokat küldhetnek.A kezdetben a BPF-eket a 2 regiszteres linux 2.x kernelben implementálják 32 Ezután Alekszej Starovoitov 2013-ban javaslatot tett a BPF javítására, amely most megkülönbözteti a cBPF-t (klasszikus BPF) és az eBPF (kibővített BPF), az egyik legjelentősebb változás a 10 64 bites regiszterbe való átjutás, valamint a kernelben lévő függvényhívás egy új utasításnak köszönhetően. Egy másik különbség az, hogy nincs állapotállandóság a cBPF-ben míg az eBPF-ben az állapotok fenntarthatók a térképeknek köszönhetően, az eBPF-ek a 3. verzióban jelennek meg .x a linux kernelből, folyamatos fejlesztésekkel, például egy JIT (Just In Time) fordítóval, új funkciókkal, például a „maps” és a „tail hívások”.