BPF Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, част Π½ΡƒΠ»Π°: classic BPF

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

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

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

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

Π‘ΡŠΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ‚Π° тСхнология 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 ΠΈ/ΠΈΠ»ΠΈ ΠΏΡŠΡ€Π²Π°Ρ‚Π° ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° Π½Π° Ρ„Π°ΠΉΠ»Π° Documentation/networking/filter.txt ΠΎΡ‚ докумСнтацията Π½Π° ядрото. ОсвСн Ρ‚ΠΎΠ²Π°, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° изслСдватС прСзСнтацията libpcap: АрхитСктура ΠΈ мСтодология Π·Π° оптимизация Π·Π° улавянС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π² която МакКан, Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π°Π²Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π½Π° 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 Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, част Π½ΡƒΠ»Π°: classic 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 провСрявамС, Π΄Π°Π»ΠΈ Π½Π΅ Π΅ Π·Π°Π΄Π°Π΄Π΅Π½ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Ρ„Π»Π°Π³Π° β€” Π² маската, прСдоставСна jset са ΠΈΠ·Π³Π»Π°Π΄Π΅Π½ΠΈ Ρ‚Ρ€ΠΈ ΡΡ‚Π°Ρ€ΡˆΠΈ Π±ΠΈΡ‚Π°. Π”Π²Π° ΠΎΡ‚ Ρ‚Ρ€ΠΈΡ‚Π΅ Π±ΠΈΡ‚Π° Π½ΠΈ ΠΊΠ°Π·Π²Π°Ρ‚, Π΄Π°Π»ΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π΅ част ΠΎΡ‚ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΈΡ€Π°Π½ IP ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΈ Π°ΠΊΠΎ Π΄Π°, Π΄Π°Π»ΠΈ Π΅ послСдният Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚. ВрСтият Π±ΠΈΡ‚ Π΅ Ρ€Π΅Π·Π΅Ρ€Π²ΠΈΡ€Π°Π½ ΠΈ трябва Π΄Π° бъдС Ρ€Π°Π²Π΅Π½ Π½Π° Π½ΡƒΠ»Π°. НС искамС Π΄Π° провСрявамС Π½ΠΈ цСлостта, Π½ΠΈ ΠΏΠΎΠ²Ρ€Π΅Π΄Π΅Π½ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π·Π°Ρ‚ΠΎΠ²Π° провСрявамС всички Ρ‚Ρ€ΠΈ Π±ΠΈΡ‚Π°.

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

Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»Π½ΠΎ, Π² Ρ€Π΅Π΄ 7 сС ΠΎΠΏΠΈΡ‚Π²Π°ΠΌΠ΅ Π΄Π° Π·Π°Ρ€Π΅Π΄ΠΈΠΌ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½ Π΄ΡƒΠΌΠ°, Π½Π° адрСс (X+16). Бпомняйки си, Ρ‡Π΅ 14 Π±Π°ΠΉΡ‚Π° Π·Π°Π΅ΠΌΠ° Π·Π°Π³Π»Π°Π²ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ethernet, Π° X ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° Π΄ΡŠΠ»ΠΆΠΈΠ½Π°Ρ‚Π° Π½Π° Π·Π°Π³Π»Π°Π²ΠΈΠ΅Ρ‚ΠΎ Π½Π° IPv4, Ρ€Π°Π·Π±ΠΈΡ€Π°ΠΌΠ΅, Ρ‡Π΅ Π² A сС Π·Π°Ρ€Π΅ΠΆΠ΄Π° ΠΏΠΎΡ€Ρ‚ΡŠΡ‚ Π½Π° Ρ†Π΅Π»Ρ‚Π° TCP:

       14           X           2             2
|Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π½Π° ethernet|Π·Π°Π³Π»Π°Π²ΠΈΠ΅ Π½Π° ip|ΠΈΠ·Ρ…ΠΎΠ΄Π΅Π½ ΠΏΠΎΡ€Ρ‚|Ρ†Π΅Π»Π΅Π²ΠΈ ΠΏΠΎΡ€Ρ‚|

Накрая, Π² Ρ€Π΅Π΄ 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 (Resource temporarily unavailable)
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 Π³ΠΎΠ΄ΠΈΠ½Π°, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π•Ρ€ΠΈΠΊ Π”ΡŽΠΌΠ°Π·Π΅ ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠΈ ΠΏΠ°Ρ‡, добавящ Π² ядрото Just In Time Compiler β€” транслятор Π·Π° ΠΏΡ€Π΅Π²ΠΎΠ΄ Π½Π° Π±Π°ΠΉΡ‚ΠΊΠΎΠ΄ Π½Π° BPF Π² Π½Π°Ρ‚ΠΈΠ²Π΅Π½ x86_64 ΠΊΠΎΠ΄.

JIT ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ бСшС ΠΏΡŠΡ€Π²ΠΈΡΡ‚ Π² Ρ€Π΅Π΄ΠΈΡ†Π°Ρ‚Π° ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ: ΠΏΡ€Π΅Π· 2012 Π³ΠΎΠ΄ΠΈΠ½Π° сС появи Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° писанС Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° seccomp, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ BPF, ΠΏΡ€Π΅Π· януари 2013 бСшС Π΅ Π΄ΠΎΠ±Π°Π²Π΅Π½ ΠΌΠΎΠ΄ΡƒΠ» 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   ΠΊΠΎΠ΄;
        __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() Π½Π° ядрото. (ΠžΡ‚ ΡΠΌΠ΅ΡˆΠ½ΠΎΡ‚ΠΎ, Π² оригиналния commit, добавящ функционалността seccomp, Π½Π° Ρ‚Π°Π·ΠΈ функция Π·Π°Π±Ρ€Π°Π²ΠΈΡ…Π° Π΄Π° добавят Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° инструкция ΠΌΠΎΠ΄ (ΠΎΡΡ‚Π°Ρ‚ΡŠΠΊ ΠΎΡ‚ Π΄Π΅Π»Π΅Π½ΠΈΠ΅) ΠΈ сСга тя Π½Π΅ Π΅ Π΄ΠΎΡΡ‚ΡŠΠΏΠ½Π° Π·Π° 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 (core dumped) +++
Π›ΠΎΡˆΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅

ΠΎΡ‚ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ, Ρ‡Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ Π±ΠΈΠ»Π° Π·Π°Π²ΡŠΡ€ΡˆΠ΅Π½Π° ΠΏΠΎΡ€Π°Π΄ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° Π·Π°Π±Ρ€Π°Π½Π΅Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ 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 Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, част Π½ΡƒΠ»Π°: classic 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 Π·Π° Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΈΡ‚Π΅, част Π½ΡƒΠ»Π°: classic 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Π΅ Ρ€Π°Π²Π΅Π½ Π½Π° 0. Няма Π΄Π° Π·Π°Π΄ΡŠΠ»Π±ΠΎΡ‡Π°Π²Π°ΠΌ Ρ‚Π΅ΠΌΠ°Ρ‚Π°, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π²Π΅Ρ‡Π΅ Π΅ ясно, Ρ‡Π΅ Ρ€ΡŠΡ‡Π½ΠΎΡ‚ΠΎ написванС Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° ΠΏΡ€Π°Π²ΠΈΠ»Π° Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ. Π’ статията BPF β€” 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 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ Π±ΡƒΠ»Π΅Π²ΠΎ, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ false ΠΊΠΎΠ΅Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π²Π°, Ρ‡Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΡŠΡ‚ Π½Π΅ Π΅ съвпаднал.

Ясно, Ρ‡Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΡŠΡ‚ xt_bpf ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΏΠΎ-слоТни Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈΡ‚Π΅ ΠΏΠΎ-Π³ΠΎΡ€Π΅. НСка Π΄Π° Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ€Π΅Π°Π»Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ ΠΎΡ‚ компанията Cloudfare. Π”ΠΎΠΏΡ€Π΅Π΄ΠΈ извСстно Π²Ρ€Π΅ΠΌΠ΅ Ρ‚Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ…Π° ΠΌΠΎΠ΄ΡƒΠ» xt_bpf Π·Π° Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS Π°Ρ‚Π°ΠΊΠΈ. Π’ статията Introducing the BPF Tools Ρ‚Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ‚ ΠΊΠ°ΠΊ (ΠΈ Π·Π°Ρ‰ΠΎ) Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Ρ‚ 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" ΠΈ Ρ‚.Π½.

Няколко мСсСца ΠΏΠΎ-късно Cloudfare ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π° ΠΊΠΎΠ΄Π° Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€Π° p0f -> BPF. Π’ статията Introducing the p0f BPF compiler Ρ‚Π΅ Ρ€Π°Π·ΠΊΠ°Π·Π²Π°Ρ‚ ΠΊΠ°ΠΊΠ²ΠΎ Π΅ 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,
...

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

cls_bpf

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

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

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

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

Π‘Π±ΠΎΠ³ΡƒΠ²Π°Π½Π΅ с класичСския BPF

Π Π°Π·Π³Π»Π΅Π΄Π°Ρ…ΠΌΠ΅ Π½Π°Ρ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΠΉΡ‚ΠΎ тСхнологията BPF, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π΅Π½Π° Π² Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° дСвСтдСсСттС, ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ прСТивя Ρ‡Π΅Ρ‚Π²ΡŠΡ€Ρ‚ Π²Π΅ΠΊ ΠΈ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π° Π΄Π° Π½Π°ΠΌΠΈΡ€Π° Π½ΠΎΠ²ΠΈ прилоТСния. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ Π½Π° ΠΏΡ€Π΅Ρ…ΠΎΠ΄Π° ΠΎΡ‚ стСкови машини към RISC, ΠΊΠΎΠΉΡ‚ΠΎ Π΄Π°Π΄Π΅ старт Π½Π° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° класичСския BPF, Π² Π½Π°Ρ‡Π°Π»ΠΎΡ‚ΠΎ Π½Π° 2000-Ρ‚Π΅ Π³ΠΎΠ΄ΠΈΠ½ΠΈ Π½Π°ΡΡ‚ΡŠΠΏΠΈ ΠΏΡ€Π΅Ρ…ΠΎΠ΄ΡŠΡ‚ ΠΎΡ‚ 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 and 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 Tool: 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