BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, Π½ΡƒΠ»Π΅Π²Π° част: класичСски BPF

Berkeley Packet Filters (BPF) Π΅ тСхнология Π½Π° ядрото Π½Π° Linux, която Π³ΠΎΠ΄ΠΈΠ½ΠΈ Π½Π°Ρ€Π΅Π΄ Π½Π΅ слиза ΠΎΡ‚ ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ страници Π½Π° Π°Π½Π³Π»ΠΎΠ΅Π·ΠΈΡ‡Π½ΠΈΡ‚Π΅ тСхничСски издания. ΠšΠΎΠ½Ρ„Π΅Ρ€Π΅Π½Ρ†ΠΈΠΈΡ‚Π΅ са пълни с Π΄ΠΎΠΊΠ»Π°Π΄ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° BPF. Π”Π΅ΠΉΠ²ΠΈΠ΄ ΠœΠΈΠ»ΡŠΡ€, ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Ρ‡ Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° подсистСма Π½Π° Linux, Π½Π°Ρ€ΠΈΡ‡Π° Π΄ΠΎΠΊΠ»Π°Π΄Π° си Π½Π° Linux Plumbers 2018 β€žΠ’Π°Π·ΠΈ лСкция Π½Π΅ Π΅ Π·Π° XDPβ€œ (XDP Π΅ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° BPF). Π‘Ρ€Π΅Π½Π΄Π°Π½ Π“Ρ€Π΅Π³Π³ изнася Π΄ΠΎΠΊΠ»Π°Π΄ΠΈ с Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅Ρ‚ΠΎ Linux BPF Superpowers. Π’ΠΎΠΊΠ΅ Π₯ΠΎΠΉΠ»Π°Π½Π΄-ЙоргСнсСн сС смСС, Ρ‡Π΅ ядрото Π²Π΅Ρ‡Π΅ Π΅ microkernel. Вомас Π“Ρ€Π°Ρ„ Ρ€Π΅ΠΊΠ»Π°ΠΌΠΈΡ€Π° идСята, Ρ‡Π΅ BPF Π΅ javascript Π·Π° ядрото.

На Π₯Π°Π±Ρ€Π° всС ΠΎΡ‰Π΅ няма систСматично описаниС Π½Π° BPF ΠΈ Π·Π°Ρ‚ΠΎΠ²Π° Π² сСрия статии Ρ‰Π΅ сС ΠΎΠΏΠΈΡ‚Π°ΠΌ Π΄Π° Ρ€Π°Π·ΠΊΠ°ΠΆΠ° историята Π½Π° тСхнологията, Π΄Π° опиша Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΈ срСдствата Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°, Π΄Π° очСртая области Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ Π½Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° BPF. Π’ Ρ‚Π°Π·ΠΈ, Π½ΡƒΠ»Π΅Π²Π°, статия ΠΎΡ‚ Ρ†ΠΈΠΊΡŠΠ»Π° сС Ρ€Π°Π·ΠΊΠ°Π·Π²Π° историята ΠΈ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° класичСския BPF, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π·Π°Π³Π°Π΄ΠΊΠΈΡ‚Π΅ Π½Π° ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΈΡ‚Π΅ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° tcpdump, seccomp, strace, ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ Π΄Ρ€ΡƒΠ³ΠΈ.

Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° BPF сС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€Π° ΠΎΡ‚ ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° общност Π½Π° Linux, основнитС ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΈ прилоТСния Π½Π° BPF са ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с ΠΌΡ€Π΅ΠΆΠΈ ΠΈ Π·Π°Ρ‚ΠΎΠ²Π°, с ΠΏΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° @eucariot, Π½Π°Ρ€Π΅ΠΊΠΎΡ… сСрията "BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅", Π² чСст Π½Π° Π²Π΅Π»ΠΈΠΊΠ°Ρ‚Π° сСрия "ΠœΡ€Π΅ΠΆΠΈ Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅".

ΠšΡ€Π°Ρ‚ΡŠΠΊ курс ΠΏΠΎ история Π½Π° BPF (с)

Π‘ΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ‚Π° тСхнология BPF Π΅ ΡƒΡΡŠΠ²ΡŠΡ€ΡˆΠ΅Π½ΡΡ‚Π²Π°Π½Π° ΠΈ допълнСна вСрсия Π½Π° старата тСхнология с ΡΡŠΡ‰ΠΎΡ‚ΠΎ ΠΈΠΌΠ΅, Π½Π°Ρ€ΠΈΡ‡Π°Π½Π° сСга, Π·Π° Π΄Π° сС ΠΈΠ·Π±Π΅Π³Π½Π΅ ΠΎΠ±ΡŠΡ€ΠΊΠ²Π°Π½Π΅, класичСски BPF. На Π±Π°Π·Π°Ρ‚Π° Π½Π° класичСския BPF Π±Π΅ създадСна извСстната ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° tcpdump, ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡŠΡ‚ seccomp, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ извСстния ΠΌΠΎΠ΄ΡƒΠ» xt_bpf Π·Π° iptables ΠΈ класификатор cls_bpf. Π’ ΡΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈΡ Linux класичСскитС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ BPF Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ сС трансформират Π² Π½ΠΎΠ²Π° Ρ„ΠΎΡ€ΠΌΠ°, Π½ΠΎ, ΠΎΡ‚ потрСбитСлска Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ°, API остана Π½Π° мястото си ΠΈ Π½ΠΎΠ²ΠΈΡ‚Π΅ прилоТСния Π½Π° класичСския BPF, ΠΊΠ°ΠΊΡ‚ΠΎ Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ Π² Ρ‚Π°Π·ΠΈ статия, всС ΠΎΡ‰Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‚. По Ρ‚Π°Π·ΠΈ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°, Π° ΡΡŠΡ‰ΠΎ ΠΈ Π·Π°Ρ‰ΠΎΡ‚ΠΎ прослСдявайки историята Π½Π° Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ Π½Π° класичСския BPF Π² Linux, Ρ‰Π΅ станС ΠΏΠΎ-ясно ΠΊΠ°ΠΊ ΠΈ Π·Π°Ρ‰ΠΎ тя Π΅ Π΅Π²ΠΎΠ»ΡŽΠΈΡ€Π°Π»Π° Π² ΡΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ‚Π° Ρ„ΠΎΡ€ΠΌΠ°, Ρ€Π΅ΡˆΠΈΡ… Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π° ΠΈΠΌΠ΅Π½Π½ΠΎ със статия Π·Π° класичСския BPF.

Π’ края Π½Π° осСмдСсСттС Π³ΠΎΠ΄ΠΈΠ½ΠΈ Π½Π° миналия Π²Π΅ΠΊ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈ ΠΎΡ‚ извСстната лаборатория Lawrence Berkeley сС заинтСрСсуваха ΠΎΡ‚ Π²ΡŠΠΏΡ€ΠΎΡΠ° ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΄Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚ ΠΌΡ€Π΅ΠΆΠΎΠ²ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° ΡΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΈΡ Π·Π° края Π½Π° осСмдСсСттС Π³ΠΎΠ΄ΠΈΠ½ΠΈ Ρ…Π°Ρ€Π΄ΡƒΠ΅Ρ€. ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° идСя Π½Π° филтрацията, Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π° ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ Π² тСхнологията CSPF (CMU/Stanford Packet Filter), сС ΡΡŠΡΡ‚ΠΎΠ΅ΡˆΠ΅ Π² Ρ‚ΠΎΠ²Π° Π΄Π° сС Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚ Π½Π΅Π½ΡƒΠΆΠ½ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ сС ΠΌΠΎΠΆΠ΅ ΠΏΠΎ-Ρ€Π°Π½ΠΎ, Ρ‚.Π΅. Π² ядрото, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚ΠΎΠ²Π° позволява Π΄Π° Π½Π΅ сС ΠΊΠΎΠΏΠΈΡ€Π°Ρ‚ Π½Π΅Π½ΡƒΠΆΠ½ΠΈ Π΄Π°Π½Π½ΠΈ Π² потрСбитСлското пространство. Π—Π° Π΄Π° сС осигури бСзопасност ΠΏΡ€ΠΈ изпълнСниС Π½Π° потрСбитСлски ΠΊΠΎΠ΄ Π² ядрото, бСшС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина - ΠΏΡΡΡŠΡ‡Π½ΠΈΠΊ.

ΠžΠ±Π°Ρ‡Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½ΠΈΡ‚Π΅ машини Π·Π° ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΈΡ‚Π΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ бяха ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° машини със стСкова Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° ΠΈ Π½Π° Π½ΠΎΠ²ΠΈΡ‚Π΅ RISC машини Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π΅Ρ…Π° Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ. Π’ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ Π½Π° усилията Π½Π° ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈΡ‚Π΅ ΠΎΡ‚ Berkeley Labs бСшС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½Π° Π½ΠΎΠ²Π° тСхнология BPF (Berkeley Packet Filters), Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина Π½Π° която бСшС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈΡ€Π°Π½Π° Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° процСсора Motorola 6502 - Ρ€Π°Π±ΠΎΡ‚Π½Π°Ρ‚Π° коня Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° извСстни ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΈ ΠΊΠ°Ρ‚ΠΎ Apple II ΠΈΠ»ΠΈ NES. Новата Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π° машина ΡƒΠ²Π΅Π»ΠΈΡ‡Π°Π²Π°ΡˆΠ΅ производитСлността Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ дСсСтократно Π² сравнСниС със ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ΠΈΡ‚Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ.

АрхитСктура Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° BPF

Π©Π΅ сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ с Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ°, Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°ΠΉΠΊΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ. ВсС ΠΏΠ°ΠΊ, ΠΏΡŠΡ€Π²ΠΎ Π½Π΅ΠΊΠ° спомСнСм, Ρ‡Π΅ ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° имашС Π΄Π²Π° Π΄ΠΎΡΡ‚ΡŠΠΏΠ½ΠΈ Π·Π° потрСбитСля 32-Π±ΠΈΡ‚ΠΎΠ²ΠΈ рСгистра, Π°ΠΊΡƒΠΌΡƒΠ»Π°Ρ‚ΠΎΡ€ A ΠΈ индСкс Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€ X, 64 Π±Π°ΠΉΡ‚Π° ΠΏΠ°ΠΌΠ΅Ρ‚ (16 Π΄ΡƒΠΌΠΈ), Π΄ΠΎΡΡ‚ΡŠΠΏΠ½Π° Π·Π° запис ΠΈ послСдващо Ρ‡Π΅Ρ‚Π΅Π½Π΅, ΠΈ ΠΌΠ°Π»ΠΊΠ° систСма ΠΎΡ‚ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ‚Π΅Π·ΠΈ ΠΎΠ±Π΅ΠΊΡ‚ΠΈ. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ бяха Π½Π°Π»ΠΈΡ‡Π½ΠΈ ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° скок, Π·Π° Π΄Π° сС Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ‚ условни ΠΈΠ·Ρ€Π°Π·ΠΈ, Π½ΠΎ Π·Π° Π΄Π° сС Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€Π° Π½Π°Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΡ‚ΠΎ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π°Π½Π΅ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, моТСшС Π΄Π° сС скача само Π½Π°ΠΏΡ€Π΅Π΄, Ρ‚.Π΅. ΠΏΠΎ-спСциално, бСшС Π·Π°Π±Ρ€Π°Π½Π΅Π½ΠΎ Π΄Π° сС ΡΡŠΠ·Π΄Π°Π²Π°Ρ‚ Ρ†ΠΈΠΊΠ»ΠΈ.

ΠžΠ±Ρ‰Π°Ρ‚Π° схСма Π·Π° стартиранС Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° Π΅ слСдната. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡΡ‚ създава ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF ΠΈ, посрСдством някакъв ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π½Π° ядрото (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, систСмСн ΠΏΠΎΠ²ΠΈΠΊ), Π·Π°Ρ€Π΅ΠΆΠ΄Π° ΠΈ ΡΠ²ΡŠΡ€Π·Π²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° с някакъв Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ Π² ядрото (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ - ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π½ΠΎΠ² ΠΏΠ°ΠΊΠ΅Ρ‚ Π½Π° ΠΌΡ€Π΅ΠΆΠΎΠ²Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚Π°). ΠŸΡ€ΠΈ Π²ΡŠΠ·Π½ΠΈΠΊΠ²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ ядрото стартира ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π°), ΠΊΠ°Ρ‚ΠΎ Π² Ρ‚ΠΎΠ·ΠΈ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π° Π½Π° ΠΌΠ°ΡˆΠΈΠ½Π°Ρ‚Π° отговаря някакъв Ρ€Π΅Π³ΠΈΠΎΠ½ Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π° Π½Π° ядрото (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΏΠ°ΠΊΠ΅Ρ‚).

Π‘ΠΊΠ°Π·Π°Π½ΠΎΡ‚ΠΎ ΠΏΠΎ-Π³ΠΎΡ€Π΅ Ρ‰Π΅ Π½ΠΈ бъдС Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ, Π·Π° Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ с Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ: Ρ‰Π΅ сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ със систСмата ΠΈ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ ΠΏΠΎ нСобходимост. Ако ΠΎΠ±Π°Ρ‡Π΅ искатС Π²Π΅Π΄Π½Π°Π³Π° Π΄Π° ΠΈΠ·ΡƒΡ‡ΠΈΡ‚Π΅ систСмата Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡ‚Π΅ Π½Π° Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»Π½Π°Ρ‚Π° машина ΠΈ Π΄Π° Π½Π°ΡƒΡ‡ΠΈΡ‚Π΅ Π·Π° всичкитС ΠΉ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈ, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅Ρ‚Π΅ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»Π½Π°Ρ‚Π° статия BSD Packet Filter ΠΈ/ΠΈΠ»ΠΈ ΠΏΡŠΡ€Π²Π°Ρ‚Π° ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° Π½Π° Ρ„Π°ΠΉΠ»Π° Documentation/networking/filter.txt ΠΎΡ‚ докумСнтацията Π½Π° ядрото. Π’ допълнСниС, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΏΡ€ΠΎΡƒΡ‡ΠΈΡ‚Π΅ прСзСнтацията libpcap: АрхитСктура ΠΈ мСтодология Π·Π° оптимизация Π½Π° заснСманСто Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π² която McCanne, Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π½Π° BPF, Ρ€Π°Π·ΠΊΠ°Π·Π²Π° Π·Π° историята Π½Π° ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ libpcap.

ΠŸΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°ΠΌΠ΅ към Ρ€Π°Π·Π³Π»Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° всички ΡΡŠΡ‰Π΅ΡΡ‚Π²Π΅Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° класичСския BPF Π² Linux: tcpdump (libpcap), seccomp, xt_bpf, cls_bpf.

tcpdump

Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° BPF сС Π΅ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π»Π° ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ с Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄Π° Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ β€” извСстната ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Π° tcpdump. И Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚ΠΎΠ²Π° Π΅ Π½Π°ΠΉ-старият ΠΈ Π½Π°ΠΉ-извСстСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° класичСския BPF, Π½Π°Π»ΠΈΡ‡Π΅Π½ Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΈ систСми, с Π½Π΅Π³ΠΎ Ρ‰Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ ΠΈΠ·ΡƒΡ‡Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° тСхнологията.

(Всички ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π² Ρ‚Π°Π·ΠΈ статия съм стартирал Π½Π° Linux 5.6.0-rc6. Π˜Π·Ρ…ΠΎΠ΄ΡŠΡ‚ Π½Π° някои ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π΅ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€Π°Π½ Π·Π° ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π° чСтимост.)

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: наблюдавамС IPv6 ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ

Π”Π° ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Π΅ искамС Π΄Π° наблюдавамС всички IPv6 ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° интСрфСйса eth0. Π—Π° Ρ†Π΅Π»Ρ‚Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° стартирамС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° tcpdump с Π½Π°ΠΉ-простия Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ ip6:

$ sudo tcpdump -i eth0 ip6

ΠŸΡ€ΠΈ Ρ‚ΠΎΠ²Π° tcpdump Ρ‰Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π° ip6 Π² Π±Π°ΠΉΡ‚-ΠΊΠΎΠ΄ Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° BPF ΠΈ Ρ‰Π΅ Π³ΠΎ ΠΈΠ·ΠΏΡ€Π°Ρ‚ΠΈ Π² ядрото (Π²ΠΆ. подробности Π² Ρ€Π°Π·Π΄Π΅Π» Tcpdump: Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅). ЗарСдСният Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ Ρ‰Π΅ сС стартира Π·Π° всСки ΠΏΠ°ΠΊΠ΅Ρ‚, ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Ρ‰ ΠΏΡ€Π΅Π· интСрфСйса. eth0Ако Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ Π²ΡŠΡ€Π½Π΅ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ n, Ρ‚ΠΎ Π΄ΠΎ n Π±Π°ΠΉΡ‚ΠΎΠ²Π΅ ΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚Π° Ρ‰Π΅ Π±ΡŠΠ΄Π°Ρ‚ ΠΊΠΎΠΏΠΈΡ€Π°Π½ΠΈ Π² пространството Π½Π° потрСбитСля ΠΈ Ρ‰Π΅ Π³ΠΈ Π²ΠΈΠ΄ΠΈΠΌ Π² ΠΈΠ·Ρ…ΠΎΠ΄Π°. tcpdump.

BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, Π½ΡƒΠ»Π΅Π²Π° част: класичСски BPF

Оказва сС, Ρ‡Π΅ ΠΌΠΎΠΆΠ΅ΠΌ лСсно Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΊΠΎΠΉ Ρ‚ΠΎΡ‡Π½ΠΎ Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄ Π΅ ΠΈΠ·ΠΏΡ€Π°Ρ‚Π΅Π½ Π² ядрото tcpdump Ρ‡Ρ€Π΅Π· самия tcpdump, Π°ΠΊΠΎ Π³ΠΎ стартирамС с опцията -d:

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

На нулСвия Ρ€Π΅Π΄ стартирамС ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° ldh [12], която сС Ρ€Π°Π·ΡˆΠΈΡ„Ρ€ΠΎΠ²Π° ΠΊΠ°Ρ‚ΠΎ β€žΠ·Π°Ρ€Π΅Π΄Π΅Ρ‚Π΅ Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° A Π΅Π΄Π½ΠΎ ΠΏΠΎΠ»-слово (16 Π±ΠΈΡ‚Π°), находящо сС Π½Π° адрСс 12β€œ ΠΈ СдинствСният Π²ΡŠΠΏΡ€ΠΎΡ Π΅ ΠΊΠ°ΠΊΠ²Π° ΠΏΠ°ΠΌΠ΅Ρ‚ адрСсирамС? ΠžΡ‚Π³ΠΎΠ²ΠΎΡ€ΡŠΡ‚ Π΅, Ρ‡Π΅ Π½Π° адрСс x Π·Π°ΠΏΠΎΡ‡Π²Π° (x+1)-я Π±Π°ΠΉΡ‚ Π½Π° Π°Π½Π°Π»ΠΈΠ·Π° Π½Π° мрСТовия ΠΏΠ°ΠΊΠ΅Ρ‚. Π§Π΅Ρ‚Π΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ с Ethernet интСрфСйса eth0, Π° Ρ‚ΠΎΠ²Π° ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½ (Π·Π° опростяванС, Ρ‰Π΅ ΠΏΡ€ΠΈΠ΅ΠΌΠ΅ΠΌ, Ρ‡Π΅ Π² ΠΏΠ°ΠΊΠ΅Ρ‚Π° няма VLAN Ρ‚Π°Π³ΠΎΠ²Π΅):

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

Π—Π½Π°Ρ‡ΠΈ слСд ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° ldh [12] Π² рСгистра A Ρ‰Π΅ сС появи ΠΏΠΎΠ»Π΅ Ether Type β€” Ρ‚ΠΈΠΏΡŠΡ‚ Π½Π° прСдавания Π² Ρ‚ΠΎΠ·ΠΈ Ethernet Ρ„Ρ€Π΅ΠΉΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚. На Ρ€Π΅Π΄ 1 сравнявамС ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° рСгистра A (Ρ‚ΠΈΠΏ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°) с 0x86dd, Π° Ρ‚ΠΎΠ²Π° ΠΈ Ρ‚ΠΎΠ²Π° Π΅ интСрСсуващият Π½ΠΈ Ρ‚ΠΈΠΏ IPv6. На Ρ€Π΅Π΄ 1 освСн ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° Π·Π° сравнСниС ΠΈΠΌΠ° ΠΈ Π΄Π²Π΅ ΠΊΠΎΠ»ΠΎΠ½ΠΈ β€” jt 2 ΠΈ jf 3 β€” Π΅Ρ‚ΠΈΠΊΠ΅Ρ‚ΠΈ, Π½Π° ΠΊΠΎΠΈΡ‚ΠΎ трябва Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ ΠΏΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ сравнСниС (A == 0x86dd) ΠΈ ΠΏΡ€ΠΈ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ. И Ρ‚Π°ΠΊΠ°, ΠΏΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ (IPv6) ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°ΠΌΠ΅ Π½Π° Ρ€Π΅Π΄ 2, Π° ΠΏΡ€ΠΈ Π½Π΅ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ β€” Π½Π° Ρ€Π΅Π΄ 3. На Ρ€Π΅Π΄ 3 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π°Π²ΡŠΡ€ΡˆΠ²Π° с ΠΊΠΎΠ΄ 0 (Π½Π΅ ΠΊΠΎΠΏΠΈΡ€Π°ΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚Π°), Π½Π° Ρ€Π΅Π΄ 2 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π·Π°Π²ΡŠΡ€ΡˆΠ²Π° с ΠΊΠΎΠ΄ 262144 (ΠΊΠΎΠΏΠΈΡ€Π°ΠΉ ΠΌΠΈ максимум 256 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚Π° ΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚Π°).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ с ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎ-голяма слоТност: Π³Π»Π΅Π΄Π°ΠΌΠ΅ TCP ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ ΠΏΠΎ цСлСвия ΠΏΠΎΡ€Ρ‚

НСка Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€Π° всички TCP ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ с Ρ†Π΅Π»Π΅Π²ΠΈ ΠΏΠΎΡ€Ρ‚ 666. Π©Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ случая с IPv4, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΡΠ»ΡƒΡ‡Π°ΠΉΡŠΡ‚ с IPv6 Π΅ ΠΏΠΎ-прост. Π‘Π»Π΅Π΄ ΠΈΠ·ΡƒΡ‡Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ самостоятСлно Π΄Π° ΠΈΠ·ΡƒΡ‡ΠΈΡ‚Π΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ Π·Π° IPv6 (ip6 and tcp dst port 666) ΠΈ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ Π·Π° общия случай (tcp dst port 666). И Ρ‚Π°ΠΊΠ°, интСрСсуващият Π½ΠΈ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎ слСдния Π½Π°Ρ‡ΠΈΠ½:

$ 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

Какво правят Ρ€Π΅Π΄ΠΎΠ²Π΅ 0 ΠΈ 1 Π²Π΅Ρ‡Π΅ Π·Π½Π°Π΅ΠΌ. На Ρ€Π΅Π΄ 2 Π²Π΅Ρ‡Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ…ΠΌΠ΅, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ IPv4 (Ether Type = 0x800) ΠΈ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π² рСгистра A 24-Ρ‚ΠΈ Π±Π°ΠΉΡ‚ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°. ΠΠ°ΡˆΠΈΡΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΊΠ°Ρ‚ΠΎ

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

ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π² рСгистра A ΠΏΠΎΠ»Π΅Ρ‚ΠΎ Protocol Π½Π° Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° IP, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ искамС Π΄Π° ΠΊΠΎΠΏΠΈΡ€Π°ΠΌΠ΅ само TCP ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. БравнявамС Protocol с 0x6 (IPPROTO_TCP) Π½Π° Ρ€Π΅Π΄ 3.

На Ρ€Π΅Π΄ΠΎΠ²Π΅ 4 ΠΈ 5 Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ Π΄ΡƒΠΌΠ°, находяща сС Π½Π° адрСс 20, ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° jset провСрявамС, Π΄Π°Π»ΠΈ Π½Π΅ Π΅ Π·Π°Π΄Π°Π΄Π΅Π½ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Ρ„Π»Π°Π³Π° β€” Π² маската са изчистСни Ρ‚Ρ€ΠΈΡ‚Π΅ Π½Π°ΠΉ-стари Π±ΠΈΡ‚Π°. Π”Π²Π° ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Π±ΠΈΡ‚Π° Π½ΠΈ подсказват, Π΄Π°Π»ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π΅ част ΠΎΡ‚ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°Π½ IP ΠΏΠ°ΠΊΠ΅Ρ‚, ΠΈ Π°ΠΊΠΎ Π΄Π°, Π΄Π°Π»ΠΈ Π΅ послСдният Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚. ВрСтият Π±ΠΈΡ‚ Π΅ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π°Π½ ΠΈ трябва Π΄Π° бъдС Π½ΡƒΠ»Π°. НС искамС Π΄Π° провСрявамС Π½ΠΈΡ‚ΠΎ Π½Π΅Ρ†Π΅Π»ΠΈΡ‚Π΅, Π½ΠΈΡ‚ΠΎ ΠΏΠΎΠ²Ρ€Π΅Π΄Π΅Π½ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π·Π°Ρ‚ΠΎΠ²Π° провСрявамС всички Ρ‚Ρ€ΠΈ Π±ΠΈΡ‚Π°. jset са очистСни Ρ‚Ρ€ΠΈΡ‚Π΅ ΡΡ‚Π°Ρ€ΡˆΠΈ Π±ΠΈΡ‚Π°. Π”Π²Π° Π±ΠΈΡ‚Π° ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Π½ΠΈ Π΄Π°Π²Π°Ρ‚ информация Π΄Π°Π»ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π΅ част ΠΎΡ‚ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°Π½ IP ΠΏΠ°ΠΊΠ΅Ρ‚, Π° Π°ΠΊΠΎ Π΄Π°, Π΄Π°Π»ΠΈ Π΅ послСдният Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚. ВрСтият Π±ΠΈΡ‚ Π΅ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π°Π½ ΠΈ трябва Π΄Π° бъдС Ρ€Π°Π²Π΅Π½ Π½Π° Π½ΡƒΠ»Π°. НС искамС Π΄Π° провСрявамС ΠΈ Π½Π΅Ρ†Π΅Π»Π΅Π²ΠΈ, ΠΈ ΠΏΠΎΠ²Ρ€Π΅Π΄Π΅Π½ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π·Π°Ρ‚ΠΎΠ²Π° провСрявамС всички Ρ‚Ρ€ΠΈ Π±ΠΈΡ‚Π°.

Π Π΅Π΄ 6 Π΅ Π½Π°ΠΉ-интСрСсна Π² Ρ‚ΠΎΠ·ΠΈ листинг. Π˜Π·Ρ€Π°Π· ldxb 4*([14]&0xf) ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° X Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈΡ‚Π΅ Π½Π°ΠΉ-ниски Π±ΠΈΡ‚ΠΎΠ²Π΅ Π½Π° пСтнадСсСтия Π±Π°ΠΉΡ‚ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°, ΡƒΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈ ΠΏΠΎ 4. Π§Π΅Ρ‚ΠΈΡ€ΠΈΡ‚Π΅ Π½Π°ΠΉ-ниски Π±ΠΈΡ‚ΠΎΠ²Π΅ Π½Π° пСтнадСсСтия Π±Π°ΠΉΡ‚ са ΠΏΠΎΠ»Π΅ Internet Header Length Π½Π° Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° IPv4, Π² която сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π° Π΄ΡŠΠ»ΠΆΠΈΠ½Π°Ρ‚Π° Π½Π° Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° Π² Π΄ΡƒΠΌΠΈ, Π·Π° Ρ‚ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ послС Π΄Π° сС ΡƒΠΌΠ½ΠΎΠΆΠΈ ΠΏΠΎ 4. Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎ Π΅, Ρ‡Π΅ ΠΈΠ·Ρ€Π°Π·ΡŠΡ‚ 4*([14]&0xf) Π΅ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π½Π° спСциалната адрСсна схСма, която ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° само ΠΏΠΎ Ρ‚ΠΎΠ·ΠΈ Π½Π°Ρ‡ΠΈΠ½ ΠΈ само Π·Π° Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° X, Ρ‚.Π΅. Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ Π½ΠΈΡ‚ΠΎ ldb 4*([14]&0xf) Π½ΠΈΡ‚ΠΎ ldxb 5*([14]&0xf) (ΠΌΠΎΠΆΠ΅ΠΌ само Π΄Π° ΡƒΠΊΠ°ΠΆΠ΅ΠΌ Π΄Ρ€ΡƒΠ³ offset, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ldxb 4*([16]&0xf)). Ясно Π΅, Ρ‡Π΅ Ρ‚Π°Π·ΠΈ адрСсна схСма Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π² BPF Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π° Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π² X (индСксСн Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€) Π΄ΡŠΠ»ΠΆΠΈΠ½Π°Ρ‚Π° Π½Π° Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° IPv4.

Π’Π°ΠΊΠ° Π½Π° Ρ€Π΅Π΄ 7 сС ΠΎΠΏΠΈΡ‚Π²Π°ΠΌΠ΅ Π΄Π° Π·Π°Ρ€Π΅Π΄ΠΈΠΌ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ Π΄ΡƒΠΌΠ° ΠΏΠΎ адрСс (X+16). ΠŸΡ€ΠΈΠΏΠΎΠΌΠ½ΡΠΉΠΊΠΈ си, Ρ‡Π΅ 14 Π±Π°ΠΉΡ‚Π° Π·Π°Π΅ΠΌΠ°Ρ‚ Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° Ethernet, Π° X ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π΄ΡŠΠ»ΠΆΠΈΠ½Π°Ρ‚Π° Π½Π° Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° IPv4, Ρ€Π°Π·Π±ΠΈΡ€Π°ΠΌΠ΅, Ρ‡Π΅ Π² A сС Π·Π°Ρ€Π΅ΠΆΠ΄Π° IP Π½Π° опрСдСлянС Π½Π° TCP:

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

Накрая, Π½Π° Ρ€Π΅Π΄ 8 сравнявамС ΠΏΠΎΡ€Ρ‚Π° Π½Π° ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с Ρ‚ΡŠΡ€ΡΠ΅Π½Π°Ρ‚Π° стойност ΠΈ Π½Π° Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅ 9 ΠΈΠ»ΠΈ 10 Π²Ρ€ΡŠΡ‰Π°ΠΌΠ΅ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π° β€” Π΄Π° ΠΊΠΎΠΏΠΈΡ€Π°ΠΌΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈΠ»ΠΈ Π½Π΅.

Tcpdump: Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅

Π’ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π½Π°Ρ€ΠΎΡ‡Π½ΠΎ Π½Π΅ сС Π·Π°Π΄ΡŠΠ»Π±ΠΎΡ‡Π°Π²Π°Ρ…ΠΌΠ΅ Π² Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ BPF Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄Π° Π² ядрото Π·Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. По ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, tcpdump ΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ систСми ΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ tcpdump ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libpcap. Накратко, Π·Π° Π΄Π° настроим Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π° Π½Π° интСрфСйса Ρ‡Ρ€Π΅Π· libpcap, трябва Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ слСдното:

  • Π΄Π° създадСм дСскриптор ΠΎΡ‚ Ρ‚ΠΈΠΏ pcap_t ΠΎΡ‚ ΠΈΠΌΠ΅Ρ‚ΠΎ Π½Π° интСрфСйса: pcap_create,
  • Π΄Π° Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°ΠΌΠ΅ интСрфСйса: pcap_activate,
  • Π΄Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π°: pcap_compile,
  • Π΄Π° ΡΠ²ΡŠΡ€ΠΆΠ΅ΠΌ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π°: pcap_setfilter.

Π—Π° Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊ Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π° функцията pcap_setfilter Π² Linux, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ strace (някои Ρ€Π΅Π΄ΠΎΠ²Π΅ бяха пропуснати):

$ 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
...

На ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ Π΄Π²Π° Ρ€Π΅Π΄Π° ΠΎΡ‚ ΠΈΠ·Π²ΠΎΠ΄Π° създавамС raw сокСт Π·Π° Ρ‡Π΅Ρ‚Π΅Π½Π΅ Π½Π° всички Ethernet Ρ€Π°ΠΌΠΊΠΈ ΠΈ Π³ΠΎ ΡΠ²ΡŠΡ€Π·Π²Π°ΠΌΠ΅ с интСрфСйса eth0. ΠžΡ‚ нашия ΠΏΡŠΡ€Π²ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π½Π°Π΅ΠΌ, Ρ‡Π΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ ip Ρ‰Π΅ сС ΡΡŠΡΡ‚ΠΎΠΈ ΠΎΡ‚ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ BPF инструкции, ΠΈ Π½Π° трСтия Ρ€Π΅Π΄ Π²ΠΈΠΆΠ΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° опцията SO_ATTACH_FILTER Π½Π° систСмния Π²ΠΈΠΊ setsockopt НиС Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΈ ΡΠ²ΡŠΡ€Π·Π²Π°ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ с дълТина 4. Π’ΠΎΠ²Π° Π΅ Π½Π°ΡˆΠΈΡΡ‚ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€.

Π’Π°ΠΆΠ½ΠΎ Π΅ Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ, Ρ‡Π΅ Π² класичСския BPF Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ ΠΈ ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π° Π²ΠΈΠ½Π°Π³ΠΈ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° ΠΊΠ°Ρ‚ΠΎ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Π° опСрация, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ Π² Π½ΠΎΠ²Π°Ρ‚Π° вСрсия Π½Π° BPF Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ ΠΏΡ€ΠΈΠ²ΡŠΡ€Π·Π²Π°Π½Π΅Ρ‚ΠΎ ѝ към Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ΠΎΡ€Π° Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ са Ρ€Π°Π·Π΄Π΅Π»Π΅Π½ΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅.

Π‘ΠΊΡ€ΠΈΡ‚Π°Ρ‚Π° истина

По-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π°Ρ‚Π° вСрсия Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Ρ‚Π°ΠΊΠ°:

$ 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 (Π Π΅ΡΡƒΡ€ΡΡŠΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π΅ Π½Π΅Π΄ΠΎΡΡ‚ΡŠΠΏΠ΅Π½)
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...

ΠšΠ°ΠΊΡ‚ΠΎ бСшС ΠΊΠ°Π·Π°Π½ΠΎ ΠΏΠΎ-Π³ΠΎΡ€Π΅, Π½ΠΈΠ΅ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΈ ΡΠ²ΡŠΡ€Π·Π²Π°ΠΌΠ΅ нашия Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ Π½Π° Ρ€Π΅Π΄ 5, Π½ΠΎ ΠΊΠ°ΠΊΠ²ΠΎ сС случва Π½Π° Ρ€Π΅Π΄ΠΎΠ²Π΅ 3 ΠΈ 4? Оказва сС, Ρ‡Π΅ libpcap сС Π³Ρ€ΠΈΠΆΠΈ Π·Π° нас - Π·Π° Π΄Π° Π½Π΅ ΠΏΠΎΠΏΠ°Π΄Π°Ρ‚ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ Π½ΠΈ удовлСтворяват, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΡΠ²ΡŠΡ€Π·Π²Π° Ρ„ΠΈΠΊΡ‚ΠΈΠ²Π΅Π½ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ ret #0 (ΠΎΡ‚Ρ…Π²ΡŠΡ€Π»ΠΈ всички ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ), ΠΏΡ€Π΅Π²Ρ€ΡŠΡ‰Π° сокСта Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€Π°Ρ‰ Ρ€Π΅ΠΆΠΈΠΌ ΠΈ сС ΠΎΠΏΠΈΡ‚Π²Π° Π΄Π° ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅ всичкитС ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° са останали ΠΎΡ‚ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ.

Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ, Π·Π° Π΄Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° Linux Ρ‡Ρ€Π΅Π· класичСския BPF, трябва Π΄Π° ΠΈΠΌΠ°Ρ‚Π΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ ΠΏΠΎΠ΄ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° структура ΠΎΡ‚ Ρ‚ΠΈΠΏ struct sock_fprog ΠΈ ΠΎΡ‚Π²ΠΎΡ€Π΅Π½ сокСт, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΡΠ²ΡŠΡ€Π·Π°Π½ към сокСта Ρ‡Ρ€Π΅Π· систСмСн ΠΏΠΎΠ²ΠΈΠΊ. setsockopt.

Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎ Π΅, Ρ‡Π΅ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΡΠ²ΡŠΡ€Π·Π²Π° към всСки сокСт, Π½Π΅ само към raw. Π•Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, която отсява всичко, освСн ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ Π΄Π²Π° Π±Π°ΠΉΡ‚Π° Π½Π° всички входящи UDP Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠΈ. (ΠšΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΡ‚Π΅ съм Π΄ΠΎΠ±Π°Π²ΠΈΠ» Π² ΠΊΠΎΠ΄Π°, Π·Π° Π΄Π° Π½Π΅ Π½Π°Ρ‚ΠΎΠ²Π°Ρ€Π²Π°ΠΌ статията.)

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΡΡ‚ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ setsockopt Π·Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ Π² socket(7), Π° Π·Π° писанСто Π½Π° свои Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΎΡ‚ Π²ΠΈΠ΄Π° struct sock_fprog Π±Π΅Π· ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° tcpdump Ρ‰Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π² Ρ€Π°Π·Π΄Π΅Π»Π° ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅ Π½Π° BPF с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° собствСнитС Ρ€ΡŠΡ†Π΅..

ΠšΠ»Π°ΡΠΈΡ‡Π΅ΡΠΊΠΈ BPF ΠΈ XXI Π²Π΅ΠΊ

BPF бСшС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² Linux ΠΏΡ€Π΅Π· 1997 Π³ΠΎΠ΄ΠΈΠ½Π° ΠΈ дълго Π²Ρ€Π΅ΠΌΠ΅ ΠΎΡΡ‚Π°Π²Π°ΡˆΠ΅ Ρ€Π°Π±ΠΎΡ‚Π΅Π½ ΠΊΠΎΠ½ libpcap Π±Π΅Π· Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΈ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ (Ρ€Π°Π·Π±ΠΈΡ€Π° сС, имашС Linux-спСцифични ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ, Π½ΠΎ Ρ‚Π΅ Π½Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈΡ…Π° Π³Π»ΠΎΠ±Π°Π»Π½Π°Ρ‚Π° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Π°). ΠŸΡŠΡ€Π²ΠΈΡ‚Π΅ сСриозни ΠΏΡ€ΠΈΠ·Π½Π°Ρ†ΠΈ, Ρ‡Π΅ BPF Ρ‰Π΅ Π΅Π²ΠΎΠ»ΡŽΠΈΡ€Π°, сС появиха ΠΏΡ€Π΅Π· 2011 Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Eric Dumazet ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈ, добавяйки Just In Time Compiler Π² ядрото β€” транслационния ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ Π·Π° ΠΏΡ€Π΅Π²ΠΎΠ΄ Π½Π° Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄Π° BPF Π² Π½Π°Ρ‚ΠΈΠ²Π΅Π½ ΠΏΠ°Ρ‚Ρ‡x86_64 ΠΊΠΎΠ΄. JIT ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ бСшС ΠΏΡŠΡ€Π²ΠΈΡΡ‚ Π² ΠΏΠΎΡ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° ΠΎΡ‚ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ: ΠΏΡ€Π΅Π· 2012 Π³ΠΎΠ΄ΠΈΠ½Π°

Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚Ρ‚Π° Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½Π° , ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ BPF, Π±Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½Π° ΠΏΡ€Π΅Π· януари 2013. seccompΠ΄ΠΎΠ±Π°Π²Π΅Π½Π°. Π΄ΠΎΠ±Π°Π²Π΅Π½ ΠΌΠΎΠ΄ΡƒΠ» xt_bpf, позволяващ Π΄Π° сС ΠΏΠΈΡˆΠ°Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° iptables Ρ‡Ρ€Π΅Π· BPF, Π° ΠΏΡ€Π΅Π· ΠΎΠΊΡ‚ΠΎΠΌΠ²Ρ€ΠΈ 2013 бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½ ΡΡŠΡ‰ΠΎ ΠΌΠΎΠ΄ΡƒΠ» cls_bpf, позволяващ Π΄Π° сС ΠΏΠΈΡˆΠ°Ρ‚ Ρ‡Ρ€Π΅Π· BPF класификатори Π½Π° Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ°.

Π‘ΠΊΠΎΡ€ΠΎ Ρ‰Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ всички Ρ‚Π΅Π·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ, Π½ΠΎ ΠΏΡŠΡ€Π²ΠΎ Ρ‰Π΅ Π΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄Π° Π½Π°ΡƒΡ‡ΠΈΠΌ ΠΊΠ°ΠΊ Π΄Π° пишСм ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π·Π° BPF, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈΡ‚Π΅, прСдоставяни ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libpcap са ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈ (прост ΠΏΡ€ΠΈΠΌΠ΅Ρ€: Ρ„ΠΈΠ»Ρ‚ΡŠΡ€, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½ libpcap ΠΌΠΎΠΆΠ΅ Π΄Π° Π²ΡŠΡ€Π½Π΅ само Π΄Π²Π΅ стойности β€” 0 ΠΈΠ»ΠΈ 0x40000) ΠΈΠ»ΠΈ Π²ΡŠΠΎΠ±Ρ‰Π΅, ΠΊΠ°ΠΊΡ‚ΠΎ Π² случая с seccomp, Π½Π΅ са ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌΠΈ.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°Π½Π΅ Π½Π° BPF с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° собствСнитС Ρ€ΡŠΡ†Π΅.

НСка сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ с бинарния Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π½Π° инструкциитС BPF, Ρ‚ΠΎΠΉ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ прост:

   16    8    8     32
| ΠΊΠΎΠ΄ | jt | jf |  k  |

Всяка инструкция Π·Π°Π΅ΠΌΠ° 64 Π±ΠΈΡ‚Π°, Π² ΠΊΠΎΠΈΡ‚ΠΎ ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ 16 Π±ΠΈΡ‚Π° β€” Ρ‚ΠΎΠ²Π° Π΅ ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π°, слСдват Π΄Π²Π΅ осСмбитови ΠΎΡ‚ΡΡ‚ΡŠΠΏΠΊΠΈ, jt ΠΈ jf, ΠΈ 32 Π±ΠΈΡ‚Π° Π·Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° K, чиято Ρ†Π΅Π» сС промСня Π² зависимост ΠΎΡ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π°. НапримСр, ΠΊΠΎΠΌΠ°Π½Π΄Π°Ρ‚Π° ret, Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°Ρ‰Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°, ΠΈΠΌΠ° ΠΊΠΎΠ΄ 6, Π° Π²Ρ€ΡŠΡ‰Π°Π½Π°Ρ‚Π° стойност сС Π²Π·ΠΈΠΌΠ° ΠΎΡ‚ константата K. На C, Π΅Π΄Π½Π° инструкция BPF сС прСдставя ΠΊΠ°Ρ‚ΠΎ структура

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

Π° цялата ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° β€” ΠΊΠ°Ρ‚ΠΎ структура

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

Π’Π°ΠΊΠ° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° пишСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ (ΠΊΠΎΠ΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° инструкциитС, Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ, Π·Π½Π°Π΅ΠΌ ΠΎΡ‚ [1]). Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ Ρ‰Π΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ ip6 ΠΎΡ‚ нашия ΠΏΡŠΡ€Π²ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

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,
};

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° prog ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°ΠΊΠΎΠ½Π½ΠΎ Π΄Π° я ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π² ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅

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

ΠŸΠΈΡΠ°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΏΠΎΠ΄ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° машинни ΠΊΠΎΠ΄ΠΎΠ²Π΅ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ понякога сС Π½Π°Π»Π°Π³Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ, създаванС Π½Π° ΡŽΠ½ΠΈΡ‚-тСстовС, писанС Π½Π° статии Π² Ρ…Π°Π±Ρ€Π° ΠΈ Ρ‚.Π½.). Π—Π° удобство Π² Ρ„Π°ΠΉΠ»Π° <linux/filter.h> сС Π΄Π΅Ρ„ΠΈΠ½ΠΈΡ€Π°Ρ‚ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈ макроси β€” ΡΡŠΡ‰ΠΈΡΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠΉΡ‚ΠΎ ΠΈ ΠΏΠΎ-Π³ΠΎΡ€Π΅, ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС прСнаписан ΠΊΠ°Ρ‚ΠΎ

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

Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΈ Ρ‚ΠΎΠ·ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π΅Π½. Π’Π°ΠΊΠ° помислиха ΠΈ програмиститС Π½Π° ядрото Π½Π° Linux ΠΈ Π·Π°Ρ‚ΠΎΠ²Π° Π² дирСкторията tools/bpf Π½Π° ядрото ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΌΠ΅Ρ€ΠΈ асСмблСр ΠΈ Π΄Π΅Π±ΡŠΠ³Π΅Ρ€ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с класичСски BPF.

Π•Π·ΠΈΠΊΡŠΡ‚ Π½Π° асСмблСра Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π½Π° ΠΎΡ‚Π»Π°Π΄ΡŠΡ‡Π½ΠΈΡ ΠΈΠ·Ρ…ΠΎΠ΄ tcpdump, Π½ΠΎ Π² допълнСниС ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡƒΠΊΠ°Π·Π²Π°ΠΌΠ΅ символични Π΅Ρ‚ΠΈΠΊΠ΅Ρ‚ΠΈ. НапримСр, Π΅Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, която ΠΎΡ‚Ρ…Π²ΡŠΡ€Π»Ρ всички ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, освСн TCP/IPv4:

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

По ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ асСмблСр Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΊΠΎΠ΄ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ , ,..., Π·Π° нашия ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с TCP Ρ‰Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ

$ 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,

Π—Π° удобство Π½Π° C програмиститС ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π΄Ρ€ΡƒΠ³ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π°:

$ 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 },

Π’Π΅ΠΊΡΡ‚ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΊΠΎΠΏΠΈΡ€Π° Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° структура ΠΎΡ‚ Ρ‚ΠΈΠΏ struct sock_filter, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π½Π°ΠΏΡ€Π°Π²ΠΈΡ…ΠΌΠ΅ Π² Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ Ρ€Π°Π·Π΄Π΅Π».

Π Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ Π½Π° Linux ΠΈ netsniff-ng

ОсвСн стандартнитС инструкции BPF, Linux ΠΈ tools/bpf/bpf_asm ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°Ρ‚ ΠΈ нСстандартСн Π½Π°Π±ΠΎΡ€. По ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, инструкциитС слуТат Π·Π° Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ ΠΏΠΎΠ»Π΅Ρ‚Π°Ρ‚Π° Π½Π° структурата struct sk_buff, описваща ΠΌΡ€Π΅ΠΆΠΎΠ² ΠΏΠ°ΠΊΠ΅Ρ‚ Π² ядрото. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΈΠΌΠ° ΠΈ инструкции-ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΡ†ΠΈ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ Ρ‚ΠΈΠΏ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ldw cpu Ρ‰Π΅ Π·Π°Ρ€Π΅Π΄ΠΈ Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° A Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π° ΠΎΡ‚ ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° функцията Π² ядрото raw_smp_processor_id().(Π’ Π½ΠΎΠ²Π°Ρ‚Π° вСрсия Π½Π° BPF Ρ‚Π΅Π·ΠΈ нСстандартни Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ бяха Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈ Ρ‡Ρ€Π΅Π· прСдоставянСто Π½Π° kernel helpers Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π°, структуритС ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ.) Π•Ρ‚ΠΎ Π΅Π΄ΠΈΠ½ интСрСсСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€, Π² ΠΊΠΎΠΉΡ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°ΠΌΠ΅ Π² пространството Π½Π° потрСбитСля само Π·Π°Π³Π»Π°Π²ΠΊΠΈΡ‚Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅Ρ‚ΠΎ poff, payload offset:

ld poff
ret a

Π Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡΡ‚Π° BPF Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π² tcpdump, Π½ΠΎ Ρ‚ΠΎΠ²Π° Π΅ Π΄ΠΎΠ±Ρ€Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π΄Π° сС запозная с ΠΏΠ°ΠΊΠ΅Ρ‚Π° с инструмСнти netsniff-ng, ΠΊΠΎΠΉΡ‚ΠΎ, освСн всичко Π΄Ρ€ΡƒΠ³ΠΎ, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π½Π°ΠΏΡ€Π΅Π΄Π½Π°Π»Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° netsniff-ng, която, освСн филтрация с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° BPF, Π²ΠΊΠ»ΡŽΡ‡Π²Π° ΠΈ Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π΅Π½ Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ Π½Π° Ρ‚Ρ€Π°Ρ„ΠΈΠΊ, ΠΈ ΠΏΠΎ-Π½Π°ΠΏΡ€Π΅Π΄Π½Π°Π», ΠΎΡ‚ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ tools/bpf/bpf_asm, асСмблСр BPF с ΠΈΠΌΠ΅Ρ‚ΠΎ bpfc.ΠŸΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° доста ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π° докумСнтация, Π²ΠΈΠΆΡ‚Π΅ ΡΡŠΡ‰ΠΎ Π»ΠΈΠ½ΠΊΠΎΠ²Π΅Ρ‚Π΅ Π² края Π½Π° статията.

seccomp

И Ρ‚Π°ΠΊΠ°, Π²Π΅Ρ‡Π΅ Π·Π½Π°Π΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° пишСм BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½Π° слоТност ΠΈ смС Π³ΠΎΡ‚ΠΎΠ²ΠΈ Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Π½ΠΎΠ²ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ, ΠΏΡŠΡ€Π²ΠΈΡΡ‚ ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ Π΅ тСхнологията seccomp, позволяваща с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° BPF Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π΄Π° управлявамС мноТСство ΠΈ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ Π½Π° систСмнитС повиквания, Π΄ΠΎΡΡ‚ΡŠΠΏΠ½ΠΈ Π·Π° Ρ‚ΠΎΠ·ΠΈ процСс ΠΈ Π½Π΅Π³ΠΎΠ²ΠΈΡ‚Π΅ ΠΏΠΎΡ‚ΠΎΠΌΡ†ΠΈ.

ΠŸΡŠΡ€Π²Π°Ρ‚Π° вСрсия Π½Π° seccomp бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π² ядрото ΠΏΡ€Π΅Π· 2005 Π³ΠΎΠ΄ΠΈΠ½Π° ΠΈ Π½Π΅ сС ползвашС с голяма популярност, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΡΡˆΠ΅ само СдинствСната Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ β€” Π΄Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈ мноТСство систСмни повиквания, Π΄ΠΎΡΡ‚ΡŠΠΏΠ½ΠΈ Π·Π° процСса, слСднитС: read, write, exit ΠΈ sigreturn, Π° ΠΏΡ€ΠΎΡ†Π΅ΡΡŠΡ‚, ΠΊΠΎΠΉΡ‚ΠΎ Π½Π°Ρ€ΡƒΡˆΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π°, сС ΡƒΠ±ΠΈΠ²Π°ΡˆΠ΅ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° SIGKILL. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΏΡ€Π΅Π· 2012 Π³. Π² seccomp бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° BPF Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ, позволяващи опрСдСлянС Π½Π° мноТСство Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈ систСмни повиквания ΠΈ Π΄ΠΎΡ€ΠΈ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²ΡŠΡ€Ρ…Ρƒ Ρ‚Π΅Ρ…Π½ΠΈΡ‚Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈ. (Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎ Π΅, Ρ‡Π΅ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΠΈ Π½Π° Ρ‚Π°Π·ΠΈ функция бСшС Chrome, Π° Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Ρ…ΠΎΡ€Π°Ρ‚Π° ΠΎΡ‚ Chrome Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Ρ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° KRSI, Π±Π°Π·ΠΈΡ€Π°Π½ Π½Π° Π½ΠΎΠ²Π°Ρ‚Π° вСрсия Π½Π° BPF, ΠΊΠΎΠΉΡ‚ΠΎ позволява кастомизиранС Π½Π° Linux Security Modules.) Π’Ρ€ΡŠΠ·ΠΊΠΈΡ‚Π΅ към Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π°Ρ‚Π° докумСнтация ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ΠΈ Π² края Π½Π° статията.

Π‘Ρ‚Ρ€ΡƒΠ²Π° си Π΄Π° сС ΠΎΡ‚Π±Π΅Π»Π΅ΠΆΠΈ, Ρ‡Π΅ Π² Π₯Π°Π±Ρ€Π° Π²Π΅Ρ‡Π΅ ΠΈΠΌΠ° статии Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° seccomp, ΠΌΠΎΠΆΠ΅ Π±ΠΈ Π½Π° някого Ρ‰Π΅ ΠΌΡƒ Π΅ интСрСсно Π΄Π° Π³ΠΈ ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅ ΠΏΡ€Π΅Π΄ΠΈ (ΠΈΠ»ΠΈ вмСсто) Π΄Π° Ρ‡Π΅Ρ‚Π΅ слСдващитС сСкции. Π’ статията ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈ ΠΈ бСзопасност: seccomp са ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° seccomp, ΠΊΠ°ΠΊΡ‚ΠΎ вСрсията ΠΎΡ‚ 2007 Π³., Ρ‚Π°ΠΊΠ° ΠΈ вСрсията, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‰Π° BPF (Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° libseccomp), Ρ€Π°Π·ΠΊΠ°Π·Π²Π° сС Π·Π° Π²Ρ€ΡŠΠ·ΠΊΠ°Ρ‚Π° ΠΌΠ΅ΠΆΠ΄Ρƒ seccomp ΠΈ Docker, Π° ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° са ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠΈ. Π’ статията Π˜Π·ΠΎΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° Π΄Π΅ΠΌΠΎΠ½ΠΈ с systemd ΠΈΠ»ΠΈ β€žΠ½Π΅ Π²ΠΈ трябва Docker Π·Π° Ρ‚ΠΎΠ²Π°!β€œ сС Ρ€Π°Π·ΠΊΠ°Π·Π²Π°, ΠΏΠΎ-спСциално, ΠΊΠ°ΠΊ Π΄Π° добавятС Ρ‡Π΅Ρ€Π½ΠΈ ΠΈΠ»ΠΈ Π±Π΅Π»ΠΈ ΡΠΏΠΈΡΡŠΡ†ΠΈ Π½Π° систСмни повиквания Π·Π° Π΄Π΅ΠΌΠΎΠ½ΠΈΡ‚Π΅, управлявани ΠΎΡ‚ systemd.

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΊΠ°ΠΊ Π΄Π° пишСм ΠΈ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° seccomp Π½Π° чист C ΠΈ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libseccomp ΠΈ ΠΊΠ°ΠΊΠ²ΠΈ прСдимства ΠΈ Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ†ΠΈ ΠΈΠΌΠ° всСки Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Π° накрая Ρ‰Π΅ Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠ°ΠΊ seccomp сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° strace.

ПишСм ΠΈ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° seccomp

Π’Π΅Ρ‡Π΅ Π·Π½Π°Π΅ΠΌ ΠΊΠ°ΠΊ Π΄Π° пишСм BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΈ Π·Π°Ρ‚ΠΎΠ²Π° ΠΏΡŠΡ€Π²ΠΎ Ρ‰Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ програмния интСрфСйс Π½Π° seccomp. Π€ΠΈΠ»Ρ‚ΡŠΡ€ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π·Π°Π΄Π°Π΄Π΅Π½ Π½Π° Π½ΠΈΠ²ΠΎ процСс, ΠΏΡ€ΠΈ ΠΊΠΎΠ΅Ρ‚ΠΎ всички Π΄ΡŠΡ‰Π΅Ρ€Π½ΠΈ процСси Ρ‰Π΅ наслСдят ограничСнията. Π’ΠΎΠ²Π° става Ρ‡Ρ€Π΅Π· систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ &filter β€” Ρ‚ΠΎΠ²Π° Π΅ указатСлят към Π²Π΅Ρ‡Π΅ ΠΏΠΎΠ·Π½Π°Ρ‚Π°Ρ‚Π° Π½ΠΈ структура struct sock_fprog, Ρ‚.Π΅. BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°.

Π‘ ΠΊΠ°ΠΊΠ²ΠΎ ΠΎΠ±Π°Ρ‡Π΅ сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π°Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° seccomp ΠΎΡ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° сокСти? Π‘ прСдавания контСкст. Π’ случая Π½Π° сокСти, Π½ΠΈ сС ΠΏΡ€Π΅Π΄Π°Π²Π°ΡˆΠ΅ област ΠΎΡ‚ ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π°, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°, Π° Π² случая Π½Π° seccomp Π½ΠΈ сС ΠΏΡ€Π΅Π΄Π°Π²Π° структура ΠΎΡ‚ Π²ΠΈΠ΄Π°

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

Π’ΡƒΠΊ nr β€” Ρ‚ΠΎΠ²Π° Π΅ Π½ΠΎΠΌΠ΅Ρ€ΡŠΡ‚ Π½Π° Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°Π½ΠΎΡ‚ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅, arch β€” Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° (Π·Π° ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ), args β€” Π΄ΠΎ ΡˆΠ΅ΡΡ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π½Π° систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅, Π° instruction_pointer β€” Ρ‚ΠΎΠ²Π° Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π» към инструкция Π² потрСбитСлското пространство, която Π΅ Π½Π°ΠΏΡ€Π°Π²ΠΈΠ»Π° Ρ‚Π°Π·ΠΈ систСмна ΠΏΠΎΠ²ΠΈΠΊΠ²Π°. Π’Π°ΠΊΠ°, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π° Π΄Π° Π·Π°Ρ€Π΅Π΄ΠΈΠΌ Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° систСмната ΠΏΠΎΠ²ΠΈΠΊΠ²Π° Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° A трябва Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ

ldw [0]

Π—Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ seccomp ΠΈΠΌΠ° ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ особСности, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΄ΠΎΡΡ‚ΡŠΠΏΡŠΡ‚ Π΄ΠΎ контСкста Π΅ възмоТСн само ΠΏΡ€ΠΈ 32-Π±ΠΈΡ‚Π½ΠΎ подравняванС ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π·Π°Ρ€Π΅ΠΆΠ΄Π° ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ Π΄ΡƒΠΌΠ° ΠΈΠ»ΠΈ Π±Π°ΠΉΡ‚ β€” ΠΏΡ€ΠΈ ΠΎΠΏΠΈΡ‚ Π·Π° Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½Π΅ Π½Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ ldh [0] систСмната ΠΏΠΎΠ²ΠΈΠΊΠ²Π° seccomp Ρ‰Π΅ Π²ΡŠΡ€Π½Π΅ EINVAL. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°Ρ‚Π° Π½Π° Π·Π°Ρ€Π΅ΠΆΠ΄Π°Π½ΠΈΡ‚Π΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° ΠΎΡ‚ функцията seccomp_check_filter() Π½Π° ядрото. (ΠžΡ‚ ΡΠΌΠ΅ΡˆΠ½Π°Ρ‚Π° страна, Π² оригиналния ΠΊΠΎΠΌΠΈΡ‚, добавящ функционалността seccomp, Π·Π°Π±Ρ€Π°Π²ΠΈΠ»ΠΈ са Π΄Π° добавят Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° инструкцията mod (ΠΎΡΡ‚Π°Ρ‚ΡŠΠΊ ΠΎΡ‚ Π΄Π΅Π»Π΅Π½ΠΈΠ΅) ΠΈ сСга тя Π½Π΅ Π΅ Π½Π°Π»ΠΈΡ‡Π½Π° Π·Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ seccomp BPF, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π½Π΅ΠΉΠ½ΠΎΡ‚ΠΎ добавянС Ρ‰Π΅ счупи ABI.)

По ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏ, Π²Π΅Ρ‡Π΅ Π·Π½Π°Π΅ΠΌ всичко Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, Π·Π° Π΄Π° пишСм ΠΈ Ρ‡Π΅Ρ‚Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ seccomp. ОбикновСно Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ устроСна ΠΊΠ°Ρ‚ΠΎ бял ΠΈΠ»ΠΈ Ρ‡Π΅Ρ€Π΅Π½ списък Π½Π° систСмнитС повиквания, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°

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

провСрява чСрния списък ΠΎΡ‚ Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ систСмни повиквания с Π½ΠΎΠΌΠ΅Ρ€Π° 304, 176, 239, 279. Какво прСдставляват Ρ‚Π΅Π·ΠΈ систСмни повиквания? НС ΠΌΠΎΠΆΠ΅ΠΌ Ρ‚ΠΎΡ‡Π½ΠΎ Π΄Π° ΠΊΠ°ΠΆΠ΅ΠΌ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π½Π΅ Π·Π½Π°Π΅ΠΌ Π·Π° коя Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π΅ писана ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π°. Π—Π°Ρ‚ΠΎΠ²Π° Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π½Π° seccomp ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Ρ‚ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌ всяка ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° (Ρ‚Π΅ΠΊΡƒΡ‰Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° сС посочва Π² контСкста ΠΊΠ°Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ arch Π½Π° структурата struct seccomp_data). Π‘ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°Ρ‚Π° Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΡŠΡ‚ Π±ΠΈ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Π» Ρ‚Π°ΠΊΠ°:

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

ΠΈ Ρ‚ΠΎΠ³Π°Π²Π° Π½Π°ΡˆΠΈΡ‚Π΅ Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° систСмнитС повиквания Π±ΠΈΡ…Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ стойности.

ПишСм ΠΈ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° seccomp с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° libseccomp

ΠŸΠΈΡΠ°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π½Π° машинни ΠΊΠΎΠ΄ΠΎΠ²Π΅ ΠΈΠ»ΠΈ Π·Π° асСмблСра BPF позволява пълСн ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π²ΡŠΡ€Ρ…Ρƒ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π°, Π½ΠΎ понякога Π΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡ΠΈΡ‚Π°Π½ΠΎ Π΄Π° ΠΈΠΌΠ°ΠΌΠ΅ прСносим ΠΈ/ΠΈΠ»ΠΈ Ρ‡Π΅Ρ‚ΠΈΠΌ ΠΊΠΎΠ΄. Π’ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ Π½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libseccomp, прСдоставяща стандартСн интСрфСйс Π·Π° писанС Π½Π° Ρ‡Π΅Ρ€Π½ΠΈ ΠΈΠ»ΠΈ Π±Π΅Π»ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ.

НСка напишСм ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, която стартира Π±ΠΈΠ½Π°Ρ€Π΅Π½ Ρ„Π°ΠΉΠ» ΠΏΠΎ ΠΈΠ·Π±ΠΎΡ€ Π½Π° потрСбитСля, ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ установявайки Ρ‡Π΅Ρ€Π΅Π½ списък Π½Π° систСмнитС повиквания ΠΎΡ‚ ΠΏΠΎ-Π³ΠΎΡ€Π΅ спомСнатата статия (ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ опростСна Π·Π° ΠΏΠΎ-голяма чСтимост, ΠΏΡŠΠ»Π½Π°Ρ‚Π° вСрсия ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС Π½Π°ΠΌΠ΅Ρ€Π΅Π½Π° Ρ‚ΡƒΠΊ):

#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]);
}

Π’ Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ опрСдСлямС масив sys_numbers ΠΎΡ‚ 40+ систСмни повиквания Π·Π° Π±Π»ΠΎΠΊΠΈΡ€Π°Π½Π΅. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€Π°ΠΉΡ‚Π΅ контСкста ctx ΠΈ ΠΊΠ°Π·Π²Π°ΠΌΠ΅ Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°, Ρ‡Π΅ искамС Π΄Π° Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΠΌ (SCMP_ACT_ALLOW) всички систСмни повиквания ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ (ΡΡŠΠ·Π΄Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‡Π΅Ρ€Π½ΠΈ ΡΠΏΠΈΡΡŠΡ†ΠΈ Π΅ ΠΏΠΎ-лСсно). Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, Π΅Π΄ΠΈΠ½ ΠΏΠΎ Π΅Π΄ΠΈΠ½, добавямС всички систСмни повиквания ΠΎΡ‚ чСрния списък. Π’ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ Π½Π° систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ ΠΎΡ‚ списъка, изисквамС SCMP_ACT_TRAP, Π² Ρ‚ΠΎΠ·ΠΈ случай seccomp Ρ‰Π΅ ΠΈΠ·ΠΏΡ€Π°Ρ‚ΠΈ сигнал Π½Π° процСса SIGSYS с описаниС Π½Π° Ρ‚ΠΎΡ‡Π½ΠΎΡ‚ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅, ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ Π½Π°Ρ€ΡƒΡˆΠΈΠ»ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π°Ρ‚Π°. Накрая, Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π² ядрото с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° seccomp_load, която Ρ‰Π΅ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ Ρ‰Π΅ я ΡΠ²ΡŠΡ€ΠΆΠ΅ с процСса Ρ‡Ρ€Π΅Π· систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ seccomp(2).

Π—Π° ΡƒΡΠΏΠ΅ΡˆΠ½Π° компилация, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° трябва Π΄Π° бъдС ΡΠ²ΡŠΡ€Π·Π°Π½Π° с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libseccomp, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ изпълнСниС:

$ .\/seccomp_lib echo ok
ok

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° Π±Π»ΠΎΠΊΠΈΡ€Π°Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅:

$ sudo .\/seccomp_lib mount -t bpf bpf \/tmp
Π›ΠΎΡˆΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅

ИзползвамС strace, Π·Π° Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ Π΄Π΅Ρ‚Π°ΠΉΠ»ΠΈΡ‚Π΅:

$ 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} ---
+++ ΡƒΠ±ΠΈΡ‚ ΠΎΡ‚ SIGSYS (ядро Π΄ΡŠΠΌΠΏΠ½Π°Ρ‚ΠΎ) +++
Π›ΠΎΡˆΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅

ΠΎΡ‚ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ Π·Π°Π²ΡŠΡ€ΡˆΠ΅Π½Π° ΠΏΠΎΡ€Π°Π΄ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π·Π°Π±Ρ€Π°Π½Π΅Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ mount(2).

И Ρ‚Π°ΠΊΠ°, написахмС Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° libseccomp, ΡΡŠΡ‡Π΅Ρ‚Π°Π²Π°ΠΉΠΊΠΈ Π½Π΅Ρ‚Ρ€ΠΈΠ²ΠΈΠ°Π»Π΅Π½ ΠΊΠΎΠ΄ Π² Ρ‡Π΅Ρ‚ΠΈΡ€ΠΈ Ρ€Π΅Π΄Π°. Π’ горния ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π½Π° ΠΌΠ½ΠΎΠ³ΠΎ систСмни повиквания, Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° изпълнСниС ΠΌΠΎΠΆΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° Π½Π°ΠΌΠ°Π»Π΅Π΅, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°Ρ‚Π° Π΅ просто списък ΠΎΡ‚ сравнСния. Π—Π° оптимизация, наскоро Π² libseccomp бСшС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΏΠ°Ρ‚Ρ‡, добавящ ΠΏΠΎΠ΄Π΄Ρ€ΡŠΠΆΠΊΠ° Π½Π° Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° Π½Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€Π° SCMP_FLTATR_CTL_OPTIMIZE. Ако сС Π·Π°Π΄Π°Π΄Π΅ Ρ‚ΠΎΠ·ΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ Π½Π° 2, Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ΡŠΡ‚ Ρ‰Π΅ бъдС трансформиран Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π·Π° Π±ΠΈΠ½Π°Ρ€Π½ΠΎ Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅.

Ако искатС Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΊΠ°ΠΊ са структурирани Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ с Π±ΠΈΠ½Π°Ρ€Π½ΠΎ Ρ‚ΡŠΡ€ΡΠ΅Π½Π΅, ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅Ρ‚Π΅ прост скрипт, Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‰ Ρ‚Π°ΠΊΠΈΠ²Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π° асСмблСр BPF ΠΏΠΎ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π½ΠΎΠΌΠ΅Ρ€Π° Π½Π° систСмни повиквания, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

$ 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

Нищо Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-Π±ΡŠΡ€Π·ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС написано, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ BPF Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° ΠΈΠ·Π²ΡŠΡ€ΡˆΠ°Ρ‚ ΠΏΡ€Π΅Ρ…ΠΎΠ΄ΠΈ ΠΏΠΎ ΠΎΡ‚ΡΡ‚ΡŠΠΏΠΈ (Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, jmp A ΠΈΠ»ΠΈ jmp [label+X]) ΠΈ слСдоватСлно всички ΠΏΡ€Π΅Ρ…ΠΎΠ΄ΠΈ са статични.

seccomp ΠΈ strace

Всички знаят инструмСнта strace β€” Π½Π΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌ инструмСнт ΠΏΡ€ΠΈ изслСдванС Π½Π° ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° процСситС Π² Linux. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΌΠ½ΠΎΠ³ΠΎ Ρ…ΠΎΡ€Π° ΡΡŠΡ‰ΠΎ са Π·Π°ΠΏΠΎΠ·Π½Π°Ρ‚ΠΈ с ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈΡ‚Π΅ с производитСлността ΠΏΡ€ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Ρ‚ΠΎΠ·ΠΈ инструмСнт. Π Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π΅ Ρ‚Π°ΠΌ, Ρ‡Π΅ strace Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° ptrace(2), Π° Π² Ρ‚ΠΎΠ·ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΡƒΠΊΠ°ΠΆΠ΅ΠΌ Ρ‚ΠΎΡ‡Π½ΠΎ Π½Π° какъв Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ систСмни повиквания трябва Π΄Π° спрСм процСса, Ρ‚.Π΅., Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ

$ 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

сС ΠΈΠ·ΠΏΡŠΠ»Π½ΡΠ²Π°Ρ‚ Π·Π° ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»Π½ΠΎ Π΅Π΄Π½ΠΎ ΠΈ ΡΡŠΡ‰ΠΎ Π²Ρ€Π΅ΠΌΠ΅, Π΄ΠΎΠΊΠ°Ρ‚ΠΎ във втория случай искамС Π΄Π° слСдим само Π΅Π΄Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅.

Нова опция --seccomp-bpf, Π΄ΠΎΠ±Π°Π²Π΅Π½Π° Π² strace вСрсия 5.3, позволява ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ Π΄Π° ускори процСса ΠΈ Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° стартиранС ΠΏΠΎΠ΄ трасировка Π½Π° Π΅Π΄Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ Π²Π΅Ρ‡Π΅ Π΅ сравнимо с Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ стартиранС:

$ 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

(Π’ΡƒΠΊ, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, ΠΈΠΌΠ° ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ΄ΠΌΠ°ΠΌΠ° Π² Ρ‚ΠΎΠ²Π°, Ρ‡Π΅ слСдим Π½Π΅ основното систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° Ρ‚Π°Π·ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°. Ако слСдяхмС, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, newfsstat, Ρ‚ΠΎ strace Π±ΠΈΡ…ΠΌΠ΅ Π·Π°Π±Π°Π²ΠΈΠ»ΠΈ ΠΏΠΎ ΡΡŠΡ‰ΠΈΡ Π½Π°Ρ‡ΠΈΠ½, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π±Π΅Π· --seccomp-bpf.)

Как Π»ΠΈ Ρ€Π°Π±ΠΎΡ‚ΠΈ Ρ‚Π°Π·ΠΈ опция? Π‘Π΅Π· нСя strace сС ΡΠ²ΡŠΡ€Π·Π²Π° с процСса ΠΈ Π³ΠΎ стартира с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° PTRACE_SYSCALL. ΠšΠΎΠ³Π°Ρ‚ΠΎ управляваният процСс стартира (всяко) систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅, ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π° strace, ΠΊΠΎΠΉΡ‚ΠΎ Π³Π»Π΅Π΄Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ ΠΈ Π³ΠΎ стартира с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° PTRACE_SYSCALL. Π‘Π»Π΅Π΄ извСстно Π²Ρ€Π΅ΠΌΠ΅ ΠΏΡ€ΠΎΡ†Π΅ΡΡŠΡ‚ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡Π²Π° систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ ΠΈ ΠΏΡ€ΠΈ ΠΈΠ·Π»ΠΈΠ·Π°Π½Π΅Ρ‚ΠΎ ΠΌΡƒ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΎΡ‚Π½ΠΎΠ²ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π° strace, ΠΊΠΎΠΉΡ‚ΠΎ Π³Π»Π΅Π΄Π° Π²ΡŠΡ€Π½Π°Ρ‚ΠΈΡ‚Π΅ стойности ΠΈ стартира процСса с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° PTRACE_SYSCALL, ΠΈ Ρ‚.Π½.

BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, Π½ΡƒΠ»Π΅Π²Π° част: класичСски BPF

Π‘ ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° seccomp, ΠΎΠ±Π°Ρ‡Π΅, Ρ‚ΠΎΠ·ΠΈ процСс ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π° Ρ‚ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊΠ°, ΠΊΠ°ΠΊΡ‚ΠΎ Π½ΠΈ сС иска. ИмСнно, Π°ΠΊΠΎ искамС Π΄Π° Π³Π»Π΅Π΄Π°ΠΌΠ΅ само Π½Π° систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ X, ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° напишСм BPF Ρ„ΠΈΠ»Ρ‚ΡŠΡ€, ΠΊΠΎΠΉΡ‚ΠΎ Π·Π° X Π²Ρ€ΡŠΡ‰Π° стойност SECCOMP_RET_TRACE, Π° Π·Π° нСинтСрСсуващитС Π½ΠΈ повиквания β€” SECCOMP_RET_ALLOW:

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

Π’ Ρ‚ΠΎΠ·ΠΈ случай strace ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ стартира процСса ΠΊΠ°Ρ‚ΠΎ PTRACE_CONT, Π½Π° всяко систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π²Π° нашия Ρ„ΠΈΠ»Ρ‚ΡŠΡ€, Π°ΠΊΠΎ систСмното ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π΅ X, Ρ‚ΠΎ ΠΏΡ€ΠΎΡ†Π΅ΡΡŠΡ‚ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π° Ρ€Π°Π±ΠΎΡ‚Π°, Π½ΠΎ Π°ΠΊΠΎ Ρ‚ΠΎΠ²Π° X, Ρ‚ΠΎ seccomp Ρ‰Π΅ ΠΏΡ€Π΅Π΄Π°Π΄Π΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅Ρ‚ΠΎ strace, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ Π³Π»Π΅Π΄Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ‚Π΅ ΠΈ Ρ‰Π΅ стартира процСса ΠΊΠ°Ρ‚ΠΎ PTRACE_SYSCALL (Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π² seccomp няма Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° сС стартира ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π² ΠΈΠ·Ρ…ΠΎΠ΄Π° Π½Π° систСмния ΠΏΠΎΠ²ΠΈΠΊ). ΠšΠΎΠ³Π°Ρ‚ΠΎ систСмният ΠΏΠΎΠ²ΠΈΠΊ ΠΏΡ€ΠΈΠΊΠ»ΡŽΡ‡ΠΈ, strace Ρ‰Π΅ рСстартира процСса с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° PTRACE_CONT ΠΈ Ρ‰Π΅ ΠΈΠ·Ρ‡Π°ΠΊΠ° Π½ΠΎΠ²ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΎΡ‚ seccomp.

BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, Π½ΡƒΠ»Π΅Π²Π° част: класичСски BPF

ΠŸΡ€ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° опцията --seccomp-bpf ΠΈΠΌΠ° Π΄Π²Π΅ ограничСния. ΠŸΡŠΡ€Π²ΠΎ, Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΈΡΡŠΠ΅Π΄ΠΈΠ½ΠΈΡ‚Π΅ към Π²Π΅Ρ‡Π΅ ΡΡŠΡ‰Π΅ΡΡ‚Π²ΡƒΠ²Π°Ρ‰ процСс (опцията -p ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° strace), Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚ΠΎΠ²Π° Π½Π΅ сС ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΎΡ‚ seccomp. На Π²Ρ‚ΠΎΡ€ΠΎ място, няма Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π½Π΅ Π΄Π° сС Π³Π»Π΅Π΄Π° Π½Π° Π΄ΡŠΡ‰Π΅Ρ€Π½ΠΈ процСси, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ seccomp Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ‚Π΅ сС наслСдяват ΠΎΡ‚ всички Π΄ΡŠΡ‰Π΅Ρ€Π½ΠΈ процСси Π±Π΅Π· Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° Π΄Π΅Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€Π°Π½Π΅ Π½Π° Ρ‚ΠΎΠ²Π°.

Малко ΠΏΠΎΠ²Π΅Ρ‡Π΅ подробности относно Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ Ρ‚ΠΎΡ‡Π½ΠΎ strace Ρ€Π°Π±ΠΎΡ‚ΠΈ с seccomp ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΡƒΡ‡ΠΈΡ‚Π΅ ΠΎΡ‚ ΡΠΊΠΎΡ€ΠΎΡˆΠ΅Π½ Π΄ΠΎΠΊΠ»Π°Π΄. Π—Π° нас Π½Π°ΠΉ-интСрСсният Ρ„Π°ΠΊΡ‚ Π΅, Ρ‡Π΅ класичСският BPF Π² Π»ΠΈΡ†Π΅Ρ‚ΠΎ Π½Π° seccomp всС ΠΎΡ‰Π΅ Π½Π°ΠΌΠΈΡ€Π° прилоТСния.

xt_bpf

Π‘Π΅Π³Π° Π΄Π° сС Π²ΡŠΡ€Π½Π΅ΠΌ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² свСта Π½Π° ΠΌΡ€Π΅ΠΆΠΈΡ‚Π΅.

ΠŸΡ€Π΅Π΄ΠΈΡΡ‚ΠΎΡ€ΠΈΡ: ΠΎΡ‚Π΄Π°Π²Π½Π°, ΠΏΡ€Π΅Π· 2007 Π³., Π² ядрото бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½ ΠΌΠΎΠ΄ΡƒΠ» xt_u32 Π·Π° netfilter. Π’ΠΎΠΉ бСшС написан ΠΏΠΎ аналогия с ΠΎΡ‰Π΅ ΠΏΠΎ-дрСвния класификатор Π½Π° Ρ‚Ρ€Π°Ρ„ΠΈΠΊ cls_u32 ΠΈ позволявашС Π΄Π° сС ΠΏΠΈΡˆΠ°Ρ‚ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»Π½ΠΈ Π±ΠΈΠ½Π°Ρ€Π½ΠΈ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° iptables с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° слСднитС прости ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ: Π·Π°Ρ€Π΅Π΄Π΅Ρ‚Π΅ 32 Π±ΠΈΡ‚Π° ΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚Π° ΠΈ ΠΈΠ·Π²ΡŠΡ€ΡˆΠ΅Ρ‚Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π°Ρ€ΠΈΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‡Π½ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. НапримСр,

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

Π—Π°Ρ€Π΅ΠΆΠ΄Π° 32 Π±ΠΈΡ‚Π° ΠΎΡ‚ IP Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π°, Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ ΠΎΡ‚ ΠΎΡ‚ΡΡ‚ΡŠΠΏ 6, ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π° маска 0xFF (Π²Π·Π΅ΠΌΠ° Π½Π°ΠΉ-младия Π±Π°ΠΉΡ‚). Π’ΠΎΠ²Π° Π΅ ΠΏΠΎΠ»Π΅Ρ‚ΠΎ protocol Π½Π° IP Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π° ΠΈ Π³ΠΎ сравнявамС с 1 (ICMP). Π’ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€Π°Ρ‚ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ, Π° ΡΡŠΡ‰ΠΎ Ρ‚Π°ΠΊΠ° ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ @ β€” ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅Ρ‚Π΅ с X Π±Π°ΠΉΡ‚Π° надясно. НапримСр, ΠΏΡ€Π°Π²ΠΈΠ»ΠΎΡ‚ΠΎ

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

провСрява Π΄Π°Π»ΠΈ TCP Sequence Number 0x29. Няма Π΄Π° сС Π·Π°Π΄ΡŠΠ»Π±ΠΎΡ‡Π°Π²Π°ΠΌ ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π²Π΅Ρ‡Π΅ Π΅ ясно, Ρ‡Π΅ Ρ€ΡŠΡ‡Π½ΠΎΡ‚ΠΎ писанС Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° ΠΏΡ€Π°Π²ΠΈΠ»Π° Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ. Π’ статията BPF β€” the forgotten bytecode, ΠΈΠΌΠ° няколко Π²Ρ€ΡŠΠ·ΠΊΠΈ с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° xt_u32. Π’ΠΈΠΆΡ‚Π΅ ΡΡŠΡ‰ΠΎ ΠΈ Π²Ρ€ΡŠΠ·ΠΊΠΈΡ‚Π΅ Π² края Π½Π° Ρ‚Π°Π·ΠΈ статия.

ΠžΡ‚ 2013 Π³. ΠΌΠΎΠ΄ΡƒΠ» вмСсто ΠΌΠΎΠ΄ΡƒΠ»Π° xt_u32 ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΌΠΎΠ΄ΡƒΠ», основан Π½Π° BPF. xt_bpfНа всички, ΠΊΠΎΠΈΡ‚ΠΎ стигнаха Π΄ΠΎ Ρ‚ΡƒΠΊ, Π²Π΅Ρ‡Π΅ трябва Π΄Π° ΠΈΠΌ Π΅ ясСн ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΡŠΡ‚ Π½Π° Ρ€Π°Π±ΠΎΡ‚Π°: стартиранС Π½Π° Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄ BPF ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π½Π° iptables. Ново ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС създадСно, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π°ΠΊΠ°:

iptables -A INPUT -m bpf --bytecode  -j LOG

Ρ‚ΡƒΠΊ. <Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄> β€” Ρ‚ΠΎΠ²Π° Π΅ ΠΊΠΎΠ΄ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° асСмблСрСн ΠΈΠ·Ρ…ΠΎΠ΄ bpf_asm ΠΏΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€,

$ 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

Π’ Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°ΠΌΠ΅ всички UDP ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚ΡŠΡ‚ Π·Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π² ΠΌΠΎΠ΄ΡƒΠ»Π° xt_bpf, Ρ€Π°Π·Π±ΠΈΡ€Π° сС, ΡƒΠΊΠ°Π·Π²Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚Π°, Π² случая Π½Π° iptables β€” Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° IPv4 Π·Π°Π³Π»Π°Π²ΠΊΠ°Ρ‚Π°. Π’ΡŠΡ€Π½Π°Ρ‚Π°Ρ‚Π° стойност ΠΎΡ‚ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π±ΡƒΠ»Π΅Π²Π°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π½Π΅Π²Π΅Ρ€Π½ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π½Π΅ съвпада.

Π Π°Π·Π±ΠΈΡ€Π° сС, ΠΌΠΎΠ΄ΡƒΠ»ΡŠΡ‚ xt_bpf ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΏΠΎ-слоТни Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΠΎ-Π³ΠΎΡ€Π΅. НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ€Π΅Π°Π»Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ ΠΎΡ‚ компанията Cloudflare. Π”ΠΎ скоро Ρ‚Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…Π° ΠΌΠΎΠ΄ΡƒΠ»Π° xt_bpf Π·Π° Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS Π°Ρ‚Π°ΠΊΠΈ. Π’ статията ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡΠ½Π΅ Π½Π° BPF инструмСнтитС Ρ‚Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ‚ ΠΊΠ°ΠΊ (ΠΈ Π·Π°Ρ‰ΠΎ) Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ BPF Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΈ ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π°Ρ‚ Π²Ρ€ΡŠΠ·ΠΊΠΈ към Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ инструмСнти Π·Π° създаванС Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ. НапримСр, с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° инструмСнта bpfgen ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°, която ΠΌΠ°Ρ‡Π²Π° DNS Π·Π°ΠΏΠΈΡ‚Π²Π°Π½Π΅ Π·Π° ΠΈΠΌΠ΅Ρ‚ΠΎ 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

Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΏΡŠΡ€Π²ΠΎ Π·Π°Ρ€Π΅ΠΆΠ΄Π°ΠΌΠ΅ Π² Ρ€Π΅Π³ΠΈΡΡ‚ΡŠΡ€Π° X адрСса Π½Π° Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° Π½ΠΈΠ· x04habrx03comx00 Π² Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° UDP Π΄Π°Ρ‚Π°Π³Ρ€Π°ΠΌΠ°Ρ‚Π° ΠΈ слСд Ρ‚ΠΎΠ²Π° провСрявамС заявката: 0x04686162 "x04hab" ΠΈ Ρ‚.Π½.

Няколко Π΄Π½ΠΈ ΠΏΠΎ-късно Cloudflare ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π° ΠΊΠΎΠ΄Π° Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€Π° p0f -> BPF. Π’ статията ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡΠ½Π΅ Π½Π° p0f BPF ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€Π° Ρ‚Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ‚ ΠΊΠ°ΠΊΠ²ΠΎ Π΅ p0f ΠΈ ΠΊΠ°ΠΊ Π΄Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Ρ‚ p0f сигнатури Π² BPF:

$ ./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,
...

Π’ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Cloudflare Π²Π΅Ρ‡Π΅ Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° xt_bpf, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Ρ…Π° Π½Π° XDP β€” Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΈΡ‚Π΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π½ΠΎΠ²Π°Ρ‚Π° вСрсия BPF, Π²ΠΈΠΆ. L4Drop: XDP DDoS Mitigирания.

cls_bpf

ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ‚ ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° класичСски BPF Π² ядрото Π΅ класификатор cls_bpf Π·Π° подсистСмата Π·Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ» Π½Π° Ρ‚Ρ€Π°Ρ„ΠΈΠΊΠ° Π² Linux, Π΄ΠΎΠ±Π°Π²Π΅Π½ Π² Linux Π² края Π½Π° 2013 Π³. ΠΈ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»Π½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΠ» дрСвния cls_u32.

Но Π½ΠΈΠ΅ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° няма Π΄Π° описвамС Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° cls_bpf, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‰ΠΎ сС отнася Π΄ΠΎ знанията Π·Π° класичСския BPF, Ρ‚ΠΎΠ²Π° Π½Π΅ Π½ΠΈ Π΄Π°Π²Π° Π½ΠΈΡ‰ΠΎ β€” Π²Π΅Ρ‡Π΅ смС сС Π·Π°ΠΏΠΎΠ·Π½Π°Π»ΠΈ с цялата функционалност. ОсвСн Ρ‚ΠΎΠ²Π°, Π² слСдващитС статии, ΠΊΠΎΠΈΡ‚ΠΎ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ‚ Π·Π° Π Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ BPF, Π½ΠΈΠ΅ ΠΎΡ‰Π΅ няколко ΠΏΡŠΡ‚ΠΈ Ρ‰Π΅ сС сблъскамС с Ρ‚ΠΎΠ·ΠΈ класификатор.

ΠžΡ‰Π΅ Π΅Π΄Π½Π° ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π° Π΄Π° Π½Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°ΠΌΠ΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° класичСски BPF с cls_bpf Π΅, Ρ‡Π΅ Π² сравнСниС с Π Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ BPF Π² Ρ‚ΠΎΠ·ΠΈ случай Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ сС стСснява областта Π½Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅: класичСскитС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° промСнят ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ ΠΈ Π½Π΅ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π·Π°ΠΏΠ°Π·Π²Π°Ρ‚ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ повикванията.

Π’Π°ΠΊΠ° Ρ‡Π΅ Π΄ΠΎΠΉΠ΄Π΅ Π²Ρ€Π΅ΠΌΠ΅ Π΄Π° сС сбогувамС с класичСския BPF ΠΈ Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌ Π² Π±ΡŠΠ΄Π΅Ρ‰Π΅Ρ‚ΠΎ.

Π‘Π±ΠΎΠ³ΠΎΠΌ Π½Π° класичСския BPF

НиС Ρ€Π°Π·Π³Π»Π΅Π΄Π°Ρ…ΠΌΠ΅ ΠΊΠ°ΠΊ тСхнологията BPF, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½Π° Π² Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° дСвСтдСсСттС Π³ΠΎΠ΄ΠΈΠ½ΠΈ, ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π° Ρ‡Π΅Ρ‚Π²ΡŠΡ€Ρ‚ Π²Π΅ΠΊ ΠΈ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π° Π΄Π° Π½Π°ΠΌΠΈΡ€Π° Π½ΠΎΠ²ΠΈ прилоТСния. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° ΠΏΡ€Π΅Ρ…ΠΎΠ΄Π° ΠΎΡ‚ стСкови машини към RISC, ΠΊΠΎΠΉΡ‚ΠΎ послуТи Π·Π° Ρ‚Π»Π°ΡΡŠΠΊ Π·Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° класичСския BPF, ΠΏΡ€Π΅Π· Π΄Π²Π΅ хиляди Π³ΠΎΠ΄ΠΈΠ½ΠΈ сС случи ΠΏΡ€Π΅Ρ…ΠΎΠ΄ ΠΎΡ‚ 32-Π±ΠΈΡ‚ΠΎΠ²ΠΈ към 64-Π±ΠΈΡ‚ΠΎΠ²ΠΈ машини ΠΈ класичСският BPF Π·Π°ΠΏΠΎΡ‡Π½Π° Π΄Π° остарява. ОсвСн Ρ‚ΠΎΠ²Π°, Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈΡ‚Π΅ Π½Π° класичСския BPF са силно ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈ, Π° освСн остарялата Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° β€” нямамС Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΠΌ ΡΡŠΡΡ‚ΠΎΡΠ½ΠΈΠ΅Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ извикванията Π½Π° BPF ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ, нямамС Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ взаимодСйствиС с потрСбитСля, нямамС Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° взаимодСйствиС с ядрото, освСн Π·Π° Ρ‡Π΅Ρ‚Π΅Π½Π΅ Π½Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ Π±Ρ€ΠΎΠΉ ΠΏΠΎΠ»Π΅Ρ‚Π° ΠΎΡ‚ структурата. sk_buff ΠΈ стартиранС Π½Π° Π½Π°ΠΉ-проститС ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° сС промСня ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ ΠΈ Π΄Π° сС прСнасочват.

Π’ΡΡŠΡ‰Π½ΠΎΡΡ‚, към ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° ΠΎΡ‚ класичСския BPF Π² Linux остава само API интСрфСйс, Π° Π²ΡŠΡ‚Ρ€Π΅ Π² ядрото всички класичСски ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ, нСзависимо Π΄Π°Π»ΠΈ са Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° сокСти ΠΈΠ»ΠΈ Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ seccomp, Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΡ‡Π½ΠΎ сС транслират Π² новия Ρ„ΠΎΡ€ΠΌΠ°Ρ‚, Extended BPF. (Π©Π΅ обсъдим ΠΊΠ°ΠΊ Ρ‚ΠΎΡ‡Π½ΠΎ сС случва Ρ‚ΠΎΠ²Π° Π² слСдващата статия.)

ΠŸΡ€Π΅Ρ…ΠΎΠ΄ΡŠΡ‚ към Π½ΠΎΠ²Π°Ρ‚Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° стартира ΠΏΡ€Π΅Π· 2013 Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ АлСксСй Π‘Ρ‚Π°Ρ€ΠΎΠ²ΠΎΠΉΡ‚ΠΎΠ² ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈ схСма Π·Π° ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ Π½Π° BPF. ΠŸΡ€Π΅Π· 2014 Π³ΠΎΠ΄ΠΈΠ½Π° ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ‚Π΅ ΠΏΠ°Ρ‡ΠΎΠ²Π΅ Π·Π°ΠΏΠΎΡ‡Π½Π°Ρ…Π° Π΄Π° сС появяват Π² ядрото. Насколько Ρ€Π°Π·Π±Ρ€Π°Ρ…, ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ бСшС ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄Π΅Π½ΠΎ само ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€Π°Π½Π΅ Π½Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΈ JIT-ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€Π° Π·Π° ΠΏΠΎ-Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° 64-Π±ΠΈΡ‚ΠΎΠ²ΠΈ машини, Π½ΠΎ вмСсто Ρ‚ΠΎΠ²Π° Ρ‚Π΅Π·ΠΈ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ…Π° Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° Π½ΠΎΠ²Π° Π³Π»Π°Π²Π° Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° Linux.

По-Π½Π°Ρ‚Π°Ρ‚ΡŠΡˆΠ½ΠΈ статии Π² Ρ‚Π°Π·ΠΈ сСрия Ρ‰Π΅ Ρ€Π°Π·ΠΊΠ°ΠΆΠ°Ρ‚ Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°Ρ‚Π° ΠΈ прилоТСнията Π½Π° Π½ΠΎΠ²Π°Ρ‚Π° тСхнология, ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ извСстна ΠΊΠ°Ρ‚ΠΎ internal BPF, слСд Ρ‚ΠΎΠ²Π° extended BPF, Π° сСга просто BPF.

Π’Ρ€ΡŠΠ·ΠΊΠΈ

  1. Steven McCanne ΠΈ 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 β€” забравСният Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡΠ½Π΅ Π½Π° BPF инструмСнта: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. ΠžΠ±Π·ΠΎΡ€ Π½Π° seccomp: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΈ ΠΈ сигурност: seccomp
  11. habr: Π˜Π·ΠΎΠ»ΠΈΡ€Π°Π½Π΅ Π½Π° Π΄Π΅ΠΌΠΎΠ½ΠΈ с systemd ΠΈΠ»ΠΈ "Π½Π΅ Π²ΠΈ Π΅ Π½ΡƒΠΆΠ΅Π½ Docker Π·Π° Ρ‚ΠΎΠ²Π°!"
  12. Paul Chaignon, "strace β€”seccomp-bpf: ΠΏΠΎΠ³Π»Π΅Π΄ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠ°ΠΊΠ°", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster