BPF fir déi Kleng, Deel Null: klassesch BPF

Berkeley Packet Filters (BPF) ass eng Linux Kernel Technologie déi zënter e puer Joer op de viischten Säiten vun engleschsproochegen Tech Publikatiounen ass. Konferenze si gefëllt mat Berichter iwwer d'Benotzung an d'Entwécklung vu BPF. Den David Miller, Linux-Netzwierk-Subsystem-Inhalter, nennt säi Gespréich bei Linux Plumbers 2018 "Dëst Gespréich ass net iwwer XDP" (XDP ass ee Benotzungsfall fir BPF). Brendan Gregg gëtt Gespréicher Recht Linux BPF Superpowers. Toke Høiland-Jørgensen laachtdatt de Kernel elo e Mikrokernel ass. Thomas Graf fördert d'Iddi datt BPF ass Javascript fir de Kernel.

Et gëtt nach ëmmer keng systematesch Beschreiwung vu BPF op Habré, an dofir wäert ech an enger Serie vun Artikelen probéieren iwwer d'Geschicht vun der Technologie ze schwätzen, d'Architektur an d'Entwécklungsinstrumenter ze beschreiwen, an d'Beräicher vun der Applikatioun an der Praxis vum BPF ze benotzen. Dësen Artikel, Null, an der Serie, erzielt d'Geschicht an d'Architektur vum klassesche BPF, an enthält och d'Geheimnisser vu senge Betribsprinzipien. tcpdump, seccomp, strace, a vill méi.

D'Entwécklung vu BPF gëtt vun der Linux Netzwierker Gemeinschaft kontrolléiert, déi Haapt existent Uwendunge vu BPF si mat Netzwierker verbonnen an dofir, mat Erlaabnis @eukariot, Ech hunn d'Serie "BPF fir déi Kleng" genannt, zu Éiere vun der grousser Serie "Netzwierker fir déi Kleng".

E kuerze Cours an der Geschicht vum BPF(c)

Modern BPF Technologie ass eng verbessert an erweidert Versioun vun der aler Technologie mam selwechten Numm, elo klassesch BPF genannt fir Duercherneen ze vermeiden. E bekannten Utility gouf op Basis vum klassesche BPF erstallt tcpdump, Mechanismus seccomp, souwéi manner bekannte Moduler xt_bpf fir iptables an Klassifizéierer cls_bpf. Am modernen Linux ginn klassesch BPF Programmer automatesch an déi nei Form iwwersat, awer aus engem Benotzersiicht ass d'API op der Plaz bliwwen an nei Benotzunge fir klassesch BPF, wéi mir an dësem Artikel gesinn, ginn nach ëmmer fonnt. Aus dësem Grond, an och well no der Geschicht vun der Entwécklung vu klassesche BPF am Linux, et méi kloer gëtt wéi a firwat et sech a seng modern Form entwéckelt huet, hunn ech decidéiert mat engem Artikel iwwer klassesch BPF unzefänken.

Um Enn vun den 80er Jore vum leschte Joerhonnert hunn d'Ingenieuren vum berühmten Lawrence Berkeley Laboratory interesséiert fir d'Fro wéi Dir Netzpäck op Hardware korrekt filtert, déi modern an de spéiden 80er vum leschte Joerhonnert war. D'Basis Iddi vum Filteren, ursprénglech an der CSPF (CMU/Stanford Packet Filter) Technologie implementéiert, war onnéideg Päckchen esou fréi wéi méiglech ze filteren, d.h. am Kernelraum, well dëst vermeit datt onnéideg Donnéeën an de Benotzerraum kopéiert ginn. Fir Runtime Sécherheet ze bidden fir de Benotzercode am Kernelraum ze lafen, gouf eng Sandbox virtuell Maschinn benotzt.

Wéi och ëmmer, déi virtuell Maschinnen fir existent Filtere goufen entwéckelt fir op Stack-baséiert Maschinnen ze lafen an hunn net esou effizient op méi nei RISC Maschinnen lafen. Als Resultat, duerch d'Efforte vun Ingenieuren aus Berkeley Labs, gouf eng nei BPF (Berkeley Packet Filters) Technologie entwéckelt, déi virtuell Maschinnarchitektur vun där entworf gouf baséiert op dem Motorola 6502 Prozessor - d'Aarbechtspäerd vu sou bekannte Produkter wéi Apple II oder Nes. Déi nei virtuell Maschinn huet d'Filterleistung zéngdausend Mol vergréissert am Verglach mat existente Léisungen.

BPF Maschinn Architektur

Mir wäerten op eng funktionell Manéier mat der Architektur kennen léieren, Beispiller analyséieren. Wéi och ëmmer, fir unzefänken, loosst eis soen datt d'Maschinn zwee 32-Bit Registere fir de Benotzer zougänglech hat, en Akkumulator A an Index Register X, 64 Bytes Erënnerung (16 Wierder), verfügbar fir ze schreiwen an duerno ze liesen, an e klenge System vu Kommandoen fir mat dësen Objeten ze schaffen. Spranginstruktioune fir d'Ëmsetzung vun bedingte Ausdréck waren och an de Programmer verfügbar, awer fir d'rechtzäiteg Ofschloss vum Programm ze garantéieren, konnten d'Spréng nëmme no vir gemaach ginn, dat heescht besonnesch et war verbueden Loops ze kreéieren.

Den allgemenge Schema fir d'Maschinn ze starten ass wéi follegt. De Benotzer erstellt e Programm fir d'BPF Architektur a benotzt puer Kernel Mechanismus (wéi e System Uruff), lued a verbënnt de Programm mat zu e puer zum Eventgenerator am Kärel (zum Beispill en Event ass d'Arrivée vum nächste Paket op der Netzwierkkaart). Wann en Event geschitt, leeft de Kernel de Programm (zum Beispill an engem Dolmetscher), an d'Maschinn Erënnerung entsprécht der zu e puer Kernel Memory Regioun (zum Beispill Daten vun engem erakommen Paket).

Dat hei uewen ass genuch fir eis Beispiller ze kucken: mir kennen de System a Kommandoformat wéi néideg kennen. Wann Dir de Kommandosystem vun enger virtueller Maschinn direkt wëllt studéieren an iwwer all seng Fäegkeeten léieren, da kënnt Dir den ursprénglechen Artikel liesen BSD Packet Filter an / oder déi éischt Halschent vun der Datei Documentation/networking/filter.txt aus der Kerneldokumentatioun. Zousätzlech kënnt Dir d'Presentatioun studéieren libpcap: Eng Architektur an Optimiséierungsmethodologie fir Packet Capture, an deem de McCanne, ee vun den Autoren vu BPF, iwwer d'Geschicht vun der Schafung schwätzt libpcap.

Mir ginn elo weider fir all déi bedeitend Beispiller fir klassesch BPF op Linux ze benotzen: tcpdump (libpcap), seccomp, xt_bpf, cls_bpf.

tcpdump

D'Entwécklung vu BPF gouf parallel mat der Entwécklung vum Frontend fir Paketfilterung duerchgefouert - e bekannten Utility tcpdump. A well dëst dat eelst a bekanntst Beispill ass fir klassesch BPF ze benotzen, verfügbar op ville Betribssystemer, wäerte mir eis Etude vun der Technologie domat ufänken.

(Ech hunn all d'Beispiller an dësem Artikel op Linux lafen 5.6.0-rc6. D'Ausgab vun e puer Kommandoen gouf geännert fir besser Liesbarkeet.)

Beispill: IPv6 Pakete beobachten

Loosst eis virstellen datt mir all IPv6 Päck op enger Interface kucken wëllen eth0. Fir dëst ze maachen, kënne mir de Programm lafen tcpdump mat engem einfachen Filter ip6:

$ sudo tcpdump -i eth0 ip6

Sou tcpdump kompiléiert de Filter ip6 an de BPF Architektur Bytecode a schéckt en an de Kärel (kuckt Detailer an der Rubrik Tcpdump: lueden). De geluedene Filter gëtt fir all Paket lafen, deen duerch d'Interface passéiert eth0. Wann de Filter en Net-Null Wäert zréckkënnt n, dann bis n Bytes vum Paket ginn op de Benotzerraum kopéiert a mir wäerten et an der Ausgab gesinn tcpdump.

BPF fir déi Kleng, Deel Null: klassesch BPF

Et stellt sech eraus datt mir einfach erausfannen, wéi eng Bytecode an de Kernel geschéckt gouf tcpdump mat der Hëllef vun der tcpdump, wa mir et mat der Optioun lafen -d:

$ sudo tcpdump -i eth0 -d ip6
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2    jf 3
(002) ret      #262144
(003) ret      #0

Op der Linn Null lafe mir de Kommando ldh [12], wat steet fir "Load into register A en halleft Wuert (16 Bits) op der Adress 12 "an déi eenzeg Fro ass wéi eng Erënnerung mir adresséieren? D'Äntwert ass, datt um x fänkt un (x+1)Byte vum analyséierten Netzwierkpaket. Mir liesen Pakete vun der Ethernet Interface eth0, an dëst bedeitdatt de Paket esou ausgesäit (fir Einfachheet, mir huelen un datt et keng VLAN Tags am Paket sinn):

       6              6          2
|Destination MAC|Source MAC|Ether Type|...|

Also nodeems Dir de Kommando ausféiert ldh [12] am Register A et gëtt e Feld Ether Type - d'Zort vum Paket deen an dësem Ethernet Frame iwwerdroen gëtt. Op der Linn 1 vergläiche mir den Inhalt vum Register A (Pakettyp) c 0x86dd, an dëst an hunn Den Typ deen mir interesséiert sinn ass IPv6. Op der Linn 1, zousätzlech zum Verglach Kommando, ginn et zwou méi Kolonnen - jt 2 и jf 3 - Marken op déi Dir musst goen wann de Verglach erfollegräich ass (A == 0x86dd) an net erfollegräich. Also, an engem erfollegräiche Fall (IPv6) gi mir op d'Linn 2, an an engem net erfollegräiche Fall - op d'Linn 3. Op der Linn 3 schléisst de Programm mam Code 0 op (kopéiert de Paket net), op der Linn 2 gëtt de Programm mat Code ofgeschloss. 262144 (Kopie mech maximal 256 kilobytes Pak).

E méi komplizéiert Beispill: mir kucken TCP Pakete no Destinatiounsport

Loosst eis kucken wéi e Filter ausgesäit, deen all TCP-Pakete mam Destinatiounsport 666 kopéiert. Mir wäerten den IPv4 Fall betruechten, well den IPv6 Fall méi einfach ass. Nodeems Dir dëst Beispill studéiert hutt, kënnt Dir den IPv6 Filter selwer als Übung entdecken (ip6 and tcp dst port 666) an e Filter fir den allgemenge Fall (tcp dst port 666). Also, de Filter an deem mir interesséiert sinn gesäit esou aus:

$ sudo tcpdump -i eth0 -d ip and tcp dst port 666
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 10
(002) ldb      [23]
(003) jeq      #0x6             jt 4    jf 10
(004) ldh      [20]
(005) jset     #0x1fff          jt 10   jf 6
(006) ldxb     4*([14]&0xf)
(007) ldh      [x + 16]
(008) jeq      #0x29a           jt 9    jf 10
(009) ret      #262144
(010) ret      #0

Mir wësse scho wat d'Linnen 0 an 1 maachen. Op der Linn 2 hu mir scho gepréift datt dëst en IPv4 Paket ass (Ether Type = 0x800) a lued et an de Register A 24. Byte vum Paket. Eise Package gesäit aus

       14            8      1     1
|ethernet header|ip fields|ttl|protocol|...|

dat heescht mir lueden an de Register A de Protokollfeld vum IP Header, wat logesch ass, well mir nëmmen TCP Pakete kopéieren wëllen. Mir vergläichen Protokoll mat 0x6 (IPPROTO_TCP) op der Linn 3.

Op Linnen 4 a 5 luede mir d'Hallefwierder op der Adress 20 a benotzen de Kommando jset kontrolléieren ob ee vun deenen dräi agestallt ass Fändelen - Droen vun der erausginn Mask jset déi dräi bedeitendst Stécker sinn geläscht. Zwee vun den dräi Bits soen eis ob de Paket Deel vun engem fragmentéierte IP Paket ass, a wa jo, ob et de leschte Fragment ass. Déi drëtt Bit ass reservéiert a muss null sinn. Mir wëllen net onkomplett oder gebrach Pakete kontrolléieren, also iwwerpréift mir all dräi Bits.

Linn 6 ass déi interessantst an dëser Oplëschtung. Ausdrock ldxb 4*([14]&0xf) heescht datt mir an de Register lueden X déi mannst bedeitend véier Bits vum fofzéngten Byte vum Paket multiplizéiert mat 4. Déi mannst bedeitend véier Bits vum fofzéngten Byte ass d'Feld Internet Header Längt IPv4 Header, deen d'Längt vum Header a Wierder späichert, also musst Dir mat 4 multiplizéieren. Interessanterweis ass den Ausdrock 4*([14]&0xf) ass eng Bezeechnung fir e speziellen Adressschema deen nëmmen an dëser Form benotzt ka ginn an nëmme fir e Register X, d.h. mir kënnen och net soen ldb 4*([14]&0xf) nach ldxb 5*([14]&0xf) (mir kënnen nëmmen eng aner Offset uginn, zum Beispill, ldxb 4*([16]&0xf)). Et ass kloer datt dëst Adressschema zu BPF bäigefüügt gouf präzis fir ze kréien X (Indexregister) IPv4 Header Längt.

Also op der Linn 7 probéieren mir en halleft Wuert ze lueden (X+16). Denkt drun datt 14 Bytes vum Ethernet Header besat sinn, an X enthält d'Längt vum IPv4 Header, mir verstinn dat an A TCP Destinatioun port ass gelueden:

       14           X           2             2
|ethernet header|ip header|source port|destination port|

Endlech, op der Linn 8 vergläiche mir den Destinatiounsport mam gewënschten Wäert an op Linnen 9 oder 10 ginn d'Resultat zréck - ob de Paket kopéiert oder net.

Tcpdump: lueden

An de fréiere Beispiller hu mir spezifesch net am Detail op wéi genau mir BPF Bytecode an de Kernel lueden fir Paketfilter. Am Allgemengen, tcpdump op vill Systemer portéiert a fir mat Filteren ze schaffen tcpdump benotzt d'Bibliothéik libpcap. Kuerz gesot, fir e Filter op engem Interface ze setzen benotzt libpcap, Dir musst déi folgend maachen:

Fir ze kucken wéi d'Funktioun pcap_setfilter am Linux ëmgesat, mir benotzen strace (e puer Zeilen goufen ewechgeholl):

$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768)        = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...

Op den éischten zwou Ausgangslinne kreéiere mir rau Socket fir all Ethernet Rummen ze liesen an et un d'Interface ze binden eth0. Vun eist éischt Beispill mir wëssen, datt de Filter ip wäert aus véier BPF Uweisungen besteet, an op der drëtter Linn gesi mir wéi d'Optioun benotzt SO_ATTACH_FILTER System Opruff setsockopt mir lueden a verbannen e Filter vun der Längt 4. Dëst ass eise Filter.

Et ass derwäert ze bemierken datt am klassesche BPF d'Luede an d'Verbindung vun engem Filter ëmmer als atomarer Operatioun geschitt, an an der neier Versioun vu BPF gëtt de Programm gelueden an et un den Eventgenerator verbënnt an der Zäit getrennt.

Verstoppt Wourecht

Eng liicht méi komplett Versioun vum Output gesäit esou aus:

$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768)        = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=1, filter=0xbeefbeefbeef}, 16) = 0
recvfrom(3, 0x7ffcad394257, 1, MSG_TRUNC, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...

Wéi uewen erwähnt, lueden a verbannen eise Filter un de Socket op der Linn 5, awer wat geschitt op de Linnen 3 a 4? Et stellt sech eraus datt dëst libpcap këmmert sech ëm eis - sou datt d'Ausgab vun eisem Filter keng Päckchen enthält déi et net erfëllen, d'Bibliothéik verbënnt dummy filter ret #0 (drop all Paketen), schalt de Socket op den net-blockéierende Modus a probéiert all Paketen ze subtrahéieren déi vu fréiere Filtere bleiwen.

Am Ganzen, fir Packagen op Linux mat klassesche BPF ze filteren, musst Dir e Filter a Form vun enger Struktur hunn wéi struct sock_fprog an en oppene Socket, duerno kann de Filter mat engem Systemruff un de Socket befestegt ginn setsockopt.

Interessanterweis kann de Filter un all Socket befestegt ginn, net nëmme rau. Hei Beispill e Programm deen all ausser déi éischt zwee Bytes vun all erakommen UDP Datagramme ofschnëtt. (Ech hunn Kommentaren am Code bäigefüügt fir den Artikel net ze klären.)

Méi Detailer iwwer d'Benotzung setsockopt fir Filteren ze verbannen, kuckt Socket (7), mee iwwer schreiwen Är eege Filtere wéi struct sock_fprog ouni Hëllef tcpdump mir wäerten an der Rubrik schwätzen Programméiere vun BPF mat Ären eegenen Hänn.

Klassesch BPF an den 21. Joerhonnert

BPF gouf am Linux am Joer 1997 abegraff an ass fir eng laang Zäit e Workhorse bliwwen libpcap ouni speziell Ännerungen (Linux-spezifesch Ännerungen, natierlech, et war, awer si hunn dat globalt Bild net geännert). Déi éischt sérieux Unzeeche datt BPF géif evoluéieren koumen am Joer 2011, wéi den Eric Dumazet proposéiert huet Patch, deen Just In Time Compiler zum Kernel bäidréit - en Iwwersetzer fir de BPF Bytecode op native ze konvertéieren x86_64 Code.

JIT Compiler war deen éischten an der Kette vun Ännerungen: am Joer 2012 erschéngt Fäegkeet Filteren ze schreiwen fir secomp, benotzt BPF, am Januar 2013 gouf et dobäigesat Modul xt_bpf, wat erlaabt Iech Regelen ze schreiwen fir iptables mat der Hëllef vun BPF, an am Oktober 2013 war dobäigesat och e Modul cls_bpf, wat Iech erlaabt Traffic Klassifizéierer mat BPF ze schreiwen.

Mir kucken all dës Beispiller geschwënn méi am Detail, awer als éischt wäert et nëtzlech sinn fir eis ze léieren wéi arbiträr Programmer fir BPF ze schreiwen an ze kompiléieren, well d'Fähigkeiten vun der Bibliothéik libpcap limitéiert (einfach Beispill: Filter generéiert libpcap kann nëmmen zwee Wäerter zréckginn - 0 oder 0x40000) oder allgemeng, wéi am Fall vu seccomp, sinn net applicabel.

Programméiere vun BPF mat Ären eegenen Hänn

Loosst eis mat dem binäre Format vu BPF Instruktioune kennen léieren, et ass ganz einfach:

   16    8    8     32
| code | jt | jf |  k  |

All Instruktioun besetzt 64 Bits, an deenen déi éischt 16 Bits den Instruktiounscode sinn, da ginn et zwee Aacht-Bit Indents, jt и jf, an 32 Bits fir d'Argument K, den Zweck vun deem variéiert vu Kommando zu Kommando. Zum Beispill, de Kommando ret, deen de Programm ofschléisst huet de Code 6, an de Retourwäert gëtt aus der Konstant geholl K. Am C gëtt eng eenzeg BPF Instruktioun als Struktur duergestallt

struct sock_filter {
        __u16   code;
        __u8    jt;
        __u8    jf;
        __u32   k;
}

an de ganze Programm ass a Form vun enger Struktur

struct sock_fprog {
        unsigned short len;
        struct sock_filter *filter;
}

Also kënne mir scho Programmer schreiwen (zum Beispill, mir kennen d'Instruktiounscodes aus [1]). Dëst ass wéi de Filter ausgesäit ip6 aus eist éischt Beispill:

struct sock_filter code[] = {
        { 0x28, 0, 0, 0x0000000c },
        { 0x15, 0, 1, 0x000086dd },
        { 0x06, 0, 0, 0x00040000 },
        { 0x06, 0, 0, 0x00000000 },
};
struct sock_fprog prog = {
        .len = ARRAY_SIZE(code),
        .filter = code,
};

Programm prog mir kënnen legal an engem Opruff benotzen

setsockopt(sk, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog))

Schreiwen Programmer a Form vun Maschinn Coden ass net ganz praktesch, mä heiansdo ass et néideg (zum Beispill, fir Debugging, schafen Eenheet Tester, Artikelen op Habré schreiwen, etc.). Fir d'Bequemlechkeet, an der Datei <linux/filter.h> Helper Makroen sinn definéiert - datselwecht Beispill wéi hei uewen kéint ëmgeschriwwe ginn als

struct sock_filter code[] = {
        BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 12),
        BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ETH_P_IPV6, 0, 1),
        BPF_STMT(BPF_RET|BPF_K, 0x00040000),
        BPF_STMT(BPF_RET|BPF_K, 0),
}

Allerdéngs ass dës Optioun net ganz bequem. Dëst ass wat d'Linux Kernel Programméierer begrënnt hunn, an dofir am Verzeechnes tools/bpf kernels Dir kënnt en Assembler an Debugger fannen fir mat klassesche BPF ze schaffen.

Assemblée Sprooch ass ganz ähnlech dem Debug Output tcpdump, mä zousätzlech kënne mir symbolesch Etiketten uginn. Zum Beispill, hei ass e Programm deen all Pakete fällt ausser TCP / IPv4:

$ cat /tmp/tcp-over-ipv4.bpf
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0

Par défaut generéiert den Assembler Code am Format <количество инструкций>,<code1> <jt1> <jf1> <k1>,..., Fir eist Beispill mat TCP wäert et sinn

$ tools/bpf/bpf_asm /tmp/tcp-over-ipv4.bpf
6,40 0 0 12,21 0 3 2048,48 0 0 23,21 0 1 6,6 0 0 4294967295,6 0 0 0,

Fir d'Bequemlechkeet vun C Programméierer, kann en anert Output Format benotzt ginn:

$ tools/bpf/bpf_asm -c /tmp/tcp-over-ipv4.bpf
{ 0x28,  0,  0, 0x0000000c },
{ 0x15,  0,  3, 0x00000800 },
{ 0x30,  0,  0, 0x00000017 },
{ 0x15,  0,  1, 0x00000006 },
{ 0x06,  0,  0, 0xffffffff },
{ 0x06,  0,  0, 0000000000 },

Dësen Text kann an d'Typ Struktur Definitioun kopéiert ginn struct sock_filter, wéi mir am Ufank vun dëser Rubrik gemaach hunn.

Linux an netsniff-ng Extensiounen

Zousätzlech zu Standard BPF, Linux an tools/bpf/bpf_asm Ënnerstëtzung an net-Standard Set. Prinzipiell gi Instruktioune benotzt fir Zougang zu de Felder vun enger Struktur ze kréien struct sk_buff, wat e Netzwierkpaket am Kernel beschreift. Wéi och ëmmer, et ginn och aner Aarte vun Hëllefsinstruktiounen, zum Beispill ldw cpu wäert an de Register lued A Resultat vun enger Kernelfunktioun raw_smp_processor_id(). (An der neier Versioun vu BPF sinn dës net-Standard-Extensiounen erweidert ginn fir Programmer mat enger Rei vu Kernelhëllefer ze bidden fir Zougang zu Erënnerung, Strukturen an Eventer ze generéieren.) Hei ass en interessant Beispill vun engem Filter an deem mir nëmmen d'Kopie kopéieren Packet Header an de Benotzerraum mat der Extensioun poff, Notzlaascht Offset:

ld poff
ret a

BPF Extensiounen kënnen net benotzt ginn tcpdump, awer dëst ass e gudde Grond fir d'Utility Package kennenzeléieren netsniff-ng, deen ënner anerem en fortgeschrattem Programm enthält netsniff-ng, déi, nieft der Filterung mat BPF, och en effektiven Traffic Generator enthält, a méi fortgeschratt wéi tools/bpf/bpf_asm, engem BPF assembler genannt bpfc. De Package enthält zimlech detailléiert Dokumentatioun, kuckt och d'Links um Enn vum Artikel.

secomp

Also, mir wësse scho wéi BPF Programmer vun arbiträrer Komplexitéit schreiwen a si prett fir nei Beispiller ze kucken, déi éischt vun deenen ass d'seccomp Technologie, déi et erlaabt, mat BPF Filteren, de Set an de Set vu System Call Argumenter ze managen. e bestëmmte Prozess a seng Nokommen.

Déi éischt Versioun vu seccomp gouf am Kernel am Joer 2005 bäigefüügt a war net ganz populär, well et nëmmen eng eenzeg Optioun ubitt - fir de Set vu Systemappellen, déi zu engem Prozess verfügbar sinn, op déi folgend ze limitéieren: read, write, exit и sigreturn, an de Prozess, deen d'Regele verletzt huet, gouf ëmbruecht benotzt SIGKILL. Wéi och ëmmer, am Joer 2012 huet seccomp d'Fäegkeet bäigefüügt fir BPF Filteren ze benotzen, wat Iech erlaabt eng Rei vun erlaabte Systemruffen ze definéieren a souguer Kontrollen op hir Argumenter auszeféieren. (Interessanterweis war Chrome ee vun den éischte Benotzer vun dëser Funktionalitéit, an d'Chrome Leit entwéckelen de Moment e KRSI-Mechanismus baséiert op enger neier Versioun vu BPF an erlaabt Personnalisatioun vu Linux Sécherheetsmoduler.) Links op zousätzlech Dokumentatioun kënnen um Enn fonnt ginn. vum Artikel.

Notéiert datt et schonn Artikelen um Hub iwwer d'Benotzung vun seccomp gewiescht sinn, vläicht wëllt een se liesen ier (oder amplaz) déi folgend Ënnersektiounen ze liesen. Am Artikel Container a Sécherheet: secomp bitt Beispiller fir seccomp ze benotzen, souwuel d'2007 Versioun wéi och d'Versioun mat BPF (Filtere gi mat libseccomp generéiert), schwätzt iwwer d'Verbindung vu seccomp mam Docker, a bitt och vill nëtzlech Linken. Am Artikel Dämonen isoléieren mat Systemd oder "Dir braucht keen Docker fir dëst!" Et deckt virun allem wéi Dir Schwaarzlëschten oder Wäisslëschte vu Systemruffe fir Daemone füügt, déi systemd lafen.

Als nächst wäerte mir kucken wéi Dir Filtere schreift a lued seccomp am Bare C a benotzt d'Bibliothéik libseccomp a wat sinn d'Virdeeler an Nodeeler vun all Optioun, a schliisslech kucke mer wéi seccomp vum Programm benotzt gëtt strace.

Schreiwen a Luede Filtere fir seccomp

Mir wësse scho wéi BPF Programmer schreiwen, also loosst eis fir d'éischt d'seccomp Programméierungsinterface kucken. Dir kënnt e Filter um Prozessniveau setzen, an all Kandprozesser ierwen d'Restriktiounen. Dëst gëtt mat engem Systemruff gemaach seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

wou &filter - Dëst ass e Hiweis op eng Struktur déi eis scho vertraut ass struct sock_fprog, d.h. BPF Programm.

Wéi ënnerscheede Programmer fir seccomp vu Programmer fir Sockets? Iwwerdroen Kontext. Am Fall vu Sockets krute mir e Gedächtnisberäich mat dem Paket, an am Fall vu Seccomp krute mir eng Struktur wéi

struct seccomp_data {
    int   nr;
    __u32 arch;
    __u64 instruction_pointer;
    __u64 args[6];
};

et ass nr ass d'Nummer vum System Uruff fir ze starten, arch - aktuell Architektur (méi iwwer dëst hei ënnen), args - bis zu sechs System Opruff Argumenter, an instruction_pointer ass e Pointer op d'Benotzerrauminstruktioun déi de System uruffe gemaach huet. Also, zum Beispill, d'System Uruffnummer an de Register ze lueden A mir musse soen

ldw [0]

Et ginn aner Funktiounen fir seccomp Programmer, zum Beispill, de Kontext kann nëmmen duerch 32-Bit Ausrichtung zougänglech sinn an Dir kënnt net en halleft Wuert oder e Byte lueden - wann Dir probéiert e Filter ze lueden ldh [0] System Opruff seccomp wäert zréck EINVAL. D'Funktioun kontrolléiert déi gelueden Filteren seccomp_check_filter() Kären. (Komesch Saach ass, an der ursprénglecher Verpflichtung, déi d'Seccomp Funktionalitéit bäigefüügt huet, hu se vergiess d'Erlaabnes ze addéieren fir d'Instruktioun fir dës Funktioun ze benotzen mod (Divisioun Rescht) an ass elo net verfügbar fir seccomp BPF Programmer, zënter senger Zousatz wäert briechen ABI.)

Prinzipiell wësse mir schonn alles fir seccomp Programmer ze schreiwen an ze liesen. Normalerweis ass d'Programmlogik als wäiss oder schwaarz Lëscht vu Systemruffen arrangéiert, zum Beispill de Programm

ld [0]
jeq #304, bad
jeq #176, bad
jeq #239, bad
jeq #279, bad
good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
bad: ret #0

iwwerpréift eng schwaarz Lëscht vu véier System Uriff nummeréiert 304, 176, 239, 279. Wat sinn dës System Appellen? Mir kënnen net sécher soen, well mir wëssen net fir wéi eng Architektur de Programm geschriwwe gouf. Dofir hunn d'Auteuren vun seccomp ze bidden Start all Programmer mat engem Architekturcheck (déi aktuell Architektur gëtt am Kontext als Feld uginn arch Strukturen struct seccomp_data). Mat der Architektur gepréift, géif den Ufank vum Beispill ausgesinn wéi:

ld [4]
jne #0xc000003e, bad_arch ; SCMP_ARCH_X86_64

an da géif eise System Call Zuelen bestëmmte Wäerter kréien.

Mir schreiwen a lued Filtere fir seccomp benotzt libseccomp

Schreift Filteren am gebiertege Code oder an der BPF Assemblée erlaabt Iech voll Kontroll iwwer d'Resultat ze hunn, awer gläichzäiteg ass et heiansdo léiwer portable an / oder liesbare Code ze hunn. D’Bibliothéik wäert eis domatter hëllefen libsecomp, déi e Standard-Interface gëtt fir schwaarz oder wäiss Filteren ze schreiwen.

Loosst eis, zum Beispill, e Programm schreiwen, deen eng binär Datei vun der Wiel vum Benotzer leeft, nodeems Dir virdru eng schwaarz Lëscht vu Systemappellen installéiert hutt den uewen Artikel (de Programm gouf vereinfacht fir méi Liesbarkeet, déi voll Versioun ka fonnt ginn hei):

#include <seccomp.h>
#include <unistd.h>
#include <err.h>

static int sys_numbers[] = {
        __NR_mount,
        __NR_umount2,
       // ... еще 40 системных вызовов ...
        __NR_vmsplice,
        __NR_perf_event_open,
};

int main(int argc, char **argv)
{
        scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);

        for (size_t i = 0; i < sizeof(sys_numbers)/sizeof(sys_numbers[0]); i++)
                seccomp_rule_add(ctx, SCMP_ACT_TRAP, sys_numbers[i], 0);

        seccomp_load(ctx);

        execvp(argv[1], &argv[1]);
        err(1, "execlp: %s", argv[1]);
}

Als éischt definéiere mir eng Array sys_numbers vun 40+ System Opruff Zuelen ze Spär. Dann initialiséiert de Kontext ctx a sot der Bibliothéik wat mir wëllen erlaben (SCMP_ACT_ALLOW) all System Uriff par défaut (et ass méi einfach Blacklists ze bauen). Dann, een nom aneren, addéiere mir all d'Systemappellen aus der schwaarzer Lëscht. Als Äntwert op e System Opruff aus der Lëscht, mir froen SCMP_ACT_TRAP, an dësem Fall seccomp wäert e Signal un de Prozess schécken SIGSYS mat enger Beschreiwung vun deem System Opruff d'Regele verletzen. Endlech luede mir de Programm an de Kernel mat seccomp_load, deen de Programm kompiléiert an un de Prozess mat engem Systemruff befestegt seccomp(2).

Fir erfollegräich ze kompiléieren, muss de Programm mat der Bibliothéik verbonne sinn libseccomp, zum Beispill:

cc -std=c17 -Wall -Wextra -c -o seccomp_lib.o seccomp_lib.c
cc -o seccomp_lib seccomp_lib.o -lseccomp

Beispill vun engem erfollegräiche Start:

$ ./seccomp_lib echo ok
ok

Beispill vun engem blockéierte System Uruff:

$ sudo ./seccomp_lib mount -t bpf bpf /tmp
Bad system call

Mir benotzen stracefir Detailer:

$ sudo strace -e seccomp ./seccomp_lib mount -t bpf bpf /tmp
seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=50, filter=0x55d8e78428e0}) = 0
--- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0xboobdeadbeef, si_syscall=__NR_mount, si_arch=AUDIT_ARCH_X86_64} ---
+++ killed by SIGSYS (core dumped) +++
Bad system call

wéi kënne mir wëssen, datt de Programm wéinst der Benotzung vun engem illegal System Uruff ofgeschloss gouf mount(2).

Also hu mir e Filter mat der Bibliothéik geschriwwen libseccomp, passend net-trivial Code a véier Zeilen. Am Beispill hei uewen, wann et eng grouss Unzuel u Systemappellen ass, kann d'Ausféierungszäit merkbar reduzéiert ginn, well de Scheck just eng Lëscht vu Vergläicher ass. Fir Optimisatioun, libsecomp huet viru kuerzem Patch abegraff, wat Ënnerstëtzung fir d'Filterattribut bäidréit SCMP_FLTATR_CTL_OPTIMIZE. Wann Dir dëst Attribut op 2 setzt, konvertéiert de Filter an e binäre Sichprogramm.

Wann Dir wëllt gesinn wéi binär Sichfilter funktionnéieren, kuckt op einfach Schrëft, déi esou Programmer am BPF Assembler generéiert andeems Dir System Uruffnummeren wielt, zum Beispill:

$ echo 1 3 6 8 13 | ./generate_bin_search_bpf.py
ld [0]
jeq #6, bad
jgt #6, check8
jeq #1, bad
jeq #3, bad
ret #0x7fff0000
check8:
jeq #8, bad
jeq #13, bad
ret #0x7fff0000
bad: ret #0

Dir kënnt näischt wesentlech méi séier schreiwen, well BPF Programmer kënnen Indentatiounssprong net maachen (mir kënnen z.B. net maachen, jmp A oder jmp [label+X]) an dofir sinn all Iwwergäng statesch.

secomp an strace

Jidderee weess den Utility strace ass en onverzichtbar Tool fir d'Behuele vu Prozesser op Linux ze studéieren. Wéi och ëmmer, vill hunn och iwwer héieren Leeschtung Problemer wann Dir dëst Utility benotzt. D'Tatsaach ass dat strace ëmgesat benotzt ptrace(2), an an dësem Mechanismus kënne mir net spezifizéieren op wéi engem Set vu Systemruffen mir de Prozess stoppen mussen, dh zum Beispill Kommandoen

$ time strace du /usr/share/ >/dev/null 2>&1

real    0m3.081s
user    0m0.531s
sys     0m2.073s

и

$ time strace -e open du /usr/share/ >/dev/null 2>&1

real    0m2.404s
user    0m0.193s
sys     0m1.800s

ginn an ongeféier gläichzäiteg veraarbecht, obwuel mir am zweete Fall nëmmen ee Systemruff wëllen tracéieren.

Nei Optioun --seccomp-bpf, dobäi strace Versioun 5.3, erlaabt Iech de Prozess vill Mol ze beschleunegen an d'Startzäit ënner der Spuer vun engem Systemruff ass scho vergläichbar mat der Zäit vun engem normale Startup:

$ time strace --seccomp-bpf -e open du /usr/share/ >/dev/null 2>&1

real    0m0.148s
user    0m0.017s
sys     0m0.131s

$ time du /usr/share/ >/dev/null 2>&1

real    0m0.140s
user    0m0.024s
sys     0m0.116s

(Hei gëtt et natierlech eng liicht Täuschung, datt mir den Haaptsystem Uruff vun dësem Kommando net tracéieren. Wa mir z.B. newfsstat, dann strace géif grad esou schwéier bremsen wéi ouni --seccomp-bpf.)

Wéi funktionéiert dës Optioun? Ouni hatt strace verbënnt mam Prozess a fänkt et un PTRACE_SYSCALL. Wann e verwaltete Prozess e (all) Systemruff erausginn, gëtt d'Kontroll iwwerdroen strace, déi kuckt op d'Argumenter vum System Opruff a leeft et mat PTRACE_SYSCALL. No enger Zäit fäerdeg de Prozess de System Uruff a wann et erausgeet, gëtt d'Kontroll erëm iwwerginn strace, deen d'Retourwäerter kuckt an de Prozess mat der Hëllef ufänkt PTRACE_SYSCALL, a sou weider.

BPF fir déi Kleng, Deel Null: klassesch BPF

Mat seccomp kann dëse Prozess awer genau optimiséiert ginn wéi mir wëllen. Nämlech, wa mir wëllen nëmmen op de System Opruff kucken X, da kënne mir e BPF Filter schreiwen dat fir X gëtt Wäert zréck SECCOMP_RET_TRACE, a fir Uruff déi eis net interesséieren - SECCOMP_RET_ALLOW:

ld [0]
jneq #X, ignore
trace: ret #0x7ff00000
ignore: ret #0x7fff0000

An dësem Fall strace Ufank fänkt de Prozess als PTRACE_CONT, eise Filter gëtt fir all System Uruff veraarbecht, wann de System Uruff net ass X, da leeft de Prozess weider, awer wann dëst X, da wäert seccomp Kontroll iwwerdroen stracedéi d'Argumenter kucken an de Prozess starten wéi PTRACE_SYSCALL (zënter seccomp huet net d'Fäegkeet fir e Programm beim Sortie vun engem Systemruff ze lafen). Wann de System Uruff zréckkënnt, strace wäert de Prozess Reouverture benotzt PTRACE_CONT a wäert op nei Messagen aus seccomp waarden.

BPF fir déi Kleng, Deel Null: klassesch BPF

Wann Dir d'Optioun benotzt --seccomp-bpf et ginn zwou Restriktiounen. Als éischt wäert et net méiglech sinn e scho existente Prozess matzemaachen (Optioun -p Programmer strace), well dëst net vun secomp ënnerstëtzt gëtt. Zweetens gëtt et keng Méiglechkeet Net kuckt op Kand Prozesser, well seccomp Filtere vun all Kand Prozesser ierflecher ouni d'Fähegkeet dëst auszeschalten.

E bësse méi Detail iwwer wéi genau strace schaffen mat seccomp kann aus fonnt ginn rezent Rapport. Fir eis ass déi interessantst Tatsaach datt de klassesche BPF representéiert vu seccomp haut nach benotzt gëtt.

xt_bpf

Loosst eis elo zréck an d'Welt vun de Netzwierker.

Hannergrond: viru laanger Zäit, 2007, war de Kär dobäigesat Modul xt_u32 fir netfilter. Et gouf duerch Analogie mat engem nach méi antike Verkéiersklassifizéierer geschriwwen cls_u32 an erlaabt Iech arbiträr binär Reegele fir iptables ze schreiwen mat de folgenden einfachen Operatiounen: lued 32 Bits aus engem Package a maacht eng Rei vun arithmeteschen Operatiounen op hinnen. Zum Beispill,

sudo iptables -A INPUT -m u32 --u32 "6&0xFF=1" -j LOG --log-prefix "seen-by-xt_u32"

Lued déi 32 Bits vum IP Header, ugefaange bei der Padding 6, an applizéiert hinnen eng Mask 0xFF (huelt den nidderegen Byte). Dëst Feld protocol IP Header a mir vergläichen et mat 1 (ICMP). Dir kënnt vill Schecken an enger Regel kombinéieren, an Dir kënnt och de Bedreiwer ausféieren @ - réckelt X Bytes no riets. Zum Beispill, d'Regel

iptables -m u32 --u32 "6&0xFF=0x6 && 0>>22&0x3C@4=0x29"

kontrolléiert ob TCP Sequence Number net gläich ass 0x29. Ech wäert net méi an Detailer goen, well et scho kloer ass datt sou Reegelen mat der Hand schreiwen net ganz bequem ass. Am Artikel BPF - de vergiessen Bytecode, ginn et e puer Linken mat Beispiller vun Benotzung a Regel Generatioun fir xt_u32. Kuckt och d'Links um Enn vun dësem Artikel.

Zënter 2013 Modul amplaz Modul xt_u32 Dir kënnt e BPF baséiert Modul benotzen xt_bpf. Jiddereen deen esou wäit gelies huet, sollt scho kloer sinn iwwer de Prinzip vu senger Operatioun: BPF Bytecode als iptables Regelen lafen. Dir kënnt eng nei Regel erstellen, zum Beispill, sou:

iptables -A INPUT -m bpf --bytecode <байткод> -j LOG

hei <байткод> - dëst ass de Code am Assembler Output Format bpf_asm par défaut, z.B.

$ cat /tmp/test.bpf
ldb [9]
jneq #17, ignore
ret #1
ignore: ret #0

$ bpf_asm /tmp/test.bpf
4,48 0 0 9,21 0 1 17,6 0 0 1,6 0 0 0,

# iptables -A INPUT -m bpf --bytecode "$(bpf_asm /tmp/test.bpf)" -j LOG

An dësem Beispill filtere mir all UDP Pakete. Kontext fir e BPF Programm an engem Modul xt_bpf, natierlech weist op d'Paketdaten, am Fall vun iptables, op den Ufank vum IPv4 Header. Retour Wäert vum BPF Programm booleschwou false heescht datt de Pak net gepasst huet.

Et ass kloer, datt de Modul xt_bpf ënnerstëtzt méi komplex Filtere wéi d'Beispill hei uewen. Loosst eis richteg Beispiller vu Cloudfare kucken. Bis viru kuerzem hunn se de Modul benotzt xt_bpf géint DDoS Attacken ze schützen. Am Artikel Aféierung vun de BPF Tools si erkläre wéi (a firwat) se BPF Filteren generéieren a verëffentlechen Linken op eng Rei vun Utilities fir esou Filteren ze kreéieren. Zum Beispill, benotzt d'Utility bpfgen Dir kënnt e BPF Programm erstellen deen mat enger DNS Ufro fir en Numm passt habr.com:

$ ./bpfgen --assembly dns -- habr.com
ldx 4*([0]&0xf)
ld #20
add x
tax

lb_0:
    ld [x + 0]
    jneq #0x04686162, lb_1
    ld [x + 4]
    jneq #0x7203636f, lb_1
    ldh [x + 8]
    jneq #0x6d00, lb_1
    ret #65535

lb_1:
    ret #0

Am Programm luede mir als éischt an de Register X Ufank vun der Linn Adress x04habrx03comx00 bannent engem UDP Datagram a kontrolléiert dann d'Ufro: 0x04686162 <-> "x04hab" an esou weider.

E bësse méi spéit huet Cloudfare de p0f -> BPF Compiler Code publizéiert. Am Artikel Aféierung vum p0f BPF Compiler si schwätzen iwwer wat p0f ass a wéi een p0f Ënnerschrëften op BPF konvertéiert:

$ ./bpfgen p0f -- 4:64:0:0:*,0::ack+:0
39,0 0 0 0,48 0 0 8,37 35 0 64,37 0 34 29,48 0 0 0,
84 0 0 15,21 0 31 5,48 0 0 9,21 0 29 6,40 0 0 6,
...

De Moment benotzt Cloudfare net méi xt_bpf, well se op XDP geplënnert sinn - eng vun den Optiounen fir déi nei Versioun vu BPF ze benotzen, kuckt. L4Drop: XDP DDoS Mitigatiounen.

cls_bpf

Dat lescht Beispill fir klassesch BPF am Kärel ze benotzen ass de Klassifizéierer cls_bpf fir de Verkéierskontroll-Subsystem zu Linux, op Linux bäigefüügt Enn 2013 a konzeptuell den antike ersat cls_u32.

Mir wäerten awer elo d'Aarbecht net beschreiwen cls_bpf, well aus der Siicht vu Wëssen iwwer klassesch BPF wäert dëst eis näischt ginn - mir hu scho mat all Funktionalitéit vertraut. Zousätzlech, an de spéideren Artikelen iwwer Extended BPF schwätzen, wäerte mir dëse Klassifizéierer méi wéi eemol treffen.

En anere Grond net iwwer d'Benotzung vu klassesche BPF c ze schwätzen cls_bpf De Problem ass datt, am Verglach zum Extended BPF, den Ëmfang vun der Uwendung an dësem Fall radikal schmuel ass: klassesch Programmer kënnen den Inhalt vu Packagen net änneren a kënnen den Zoustand tëscht Uriff net späicheren.

Also ass et Zäit dem klassesche BPF Äddi ze soen an an d'Zukunft ze kucken.

Äddi vum klassesche BPF

Mir hu gekuckt wéi d'BPF Technologie, déi an de fréien 32er entwéckelt gouf, erfollegräich fir e Véierel vun engem Joerhonnert gelieft huet a bis zum Schluss nei Uwendungen fonnt huet. Wéi och ëmmer, ähnlech wéi den Iwwergank vu Stackmaschinnen op RISC, deen als Impuls fir d'Entwécklung vu klassesche BPF gedéngt huet, an den 64er gouf et en Iwwergang vun XNUMX-bëssen op XNUMX-bëssen Maschinnen a klassesch BPF huet ugefaang ze veränneren. Zousätzlech sinn d'Kapazitéite vu klassesche BPF ganz limitéiert, an zousätzlech zu der aler Architektur - mir hunn net d'Fäegkeet fir Staat tëscht Uruff un BPF Programmer ze späicheren, et gëtt keng Méiglechkeet fir direkt Benotzerinteraktioun, et gëtt keng Méiglechkeet fir ze interagéieren mam Kärel, ausser fir eng limitéiert Zuel vu Strukturfelder ze liesen sk_buff a lancéiert déi einfachst Helperfunktiounen, Dir kënnt den Inhalt vu Pakete net änneren an se viruleeden.

Tatsächlech ass de Moment alles wat vum klassesche BPF am Linux bleift ass d'API Interface, an am Kernel sinn all klassesch Programmer, sief et Socket Filteren oder Seccomp Filteren, automatesch an en neit Format iwwersat, Extended BPF. (Mir schwätze genau wéi dëst am nächsten Artikel geschitt.)

Den Iwwergank zu enger neier Architektur huet am Joer 2013 ugefaang, wéi Alexey Starovoitov e BPF Update Schema proposéiert huet. 2014 déi entspriechend Patches ugefaang ze erschéngen am Kär. Sou wäit wéi ech verstinn, war den initialen Plang nëmmen d'Architektur an de JIT Compiler ze optimiséieren fir méi effizient op 64-Bit Maschinnen ze lafen, awer amplaz hunn dës Optimisatiounen den Ufank vun engem neie Kapitel an der Linux Entwécklung markéiert.

Weider Artikelen an dëser Serie wäerten d'Architektur an d'Applikatioune vun der neier Technologie ofdecken, ursprénglech bekannt als intern BPF, duerno verlängert BPF, an elo einfach BPF.

Referenze

  1. Steven McCanne a Van Jacobson, "The BSD Packet Filter: A New Architecture for User-Level Packet Capture", https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Steven McCanne, "libpcap: An Architecture and Optimization Methodology for Packet Capture", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. IPtable U32 Match Tutorial.
  5. BPF - de vergiessene Bytecode: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. Aféierung vum BPF Tool: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. Eng zweet Iwwersiicht: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: Container a Sécherheet: secomp
  11. habr: Daemon isoléieren mat Systemd oder "Dir braucht keen Docker fir dëst!"
  12. Paul Chaignon, "strace --seccomp-bpf: e Bléck ënner der Hood", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

Source: will.com

Setzt e Commentaire