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

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

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

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

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

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

Π’ края Π½Π° осСмдСсСттС Π³ΠΎΠ΄ΠΈΠ½ΠΈ Π½Π° миналия Π²Π΅ΠΊ ΠΈΠ½ΠΆΠ΅Π½Π΅Ρ€ΠΈ ΠΎΡ‚ извСстната лаборатория Π›ΠΎΡ€ΡŠΠ½Ρ Π‘ΡŠΡ€ΠΊΠ»ΠΈ сС заинтСрСсуваха ΠΎΡ‚ Π²ΡŠΠΏΡ€ΠΎΡΠ° ΠΊΠ°ΠΊ ΠΏΡ€Π°Π²ΠΈΠ»Π½ΠΎ Π΄Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Ρ‚ ΠΌΡ€Π΅ΠΆΠΎΠ²ΠΈΡ‚Π΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° Ρ…Π°Ρ€Π΄ΡƒΠ΅Ρ€, ΠΊΠΎΠΉΡ‚ΠΎ бСшС ΠΌΠΎΠ΄Π΅Ρ€Π΅Π½ Π² края Π½Π° осСмдСсСттС Π³ΠΎΠ΄ΠΈΠ½ΠΈ Π½Π° миналия Π²Π΅ΠΊ. ΠžΡΠ½ΠΎΠ²Π½Π°Ρ‚Π° идСя Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ, ΠΏΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π° Π² тСхнологията 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: ΠœΠ΅Ρ‚ΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΡ Π·Π° Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° ΠΈ оптимизация Π·Π° улавянС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ, Π² ΠΊΠΎΠΉΡ‚ΠΎ 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 (Ρ‚ΠΈΠΏ ΠΎΠΏΠ°ΠΊΠΎΠ²ΠΊΠ°) c 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 ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ. БравнявамС ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° с 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 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
...

На ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ Π΄Π²Π° Ρ€Π΅Π΄Π° Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π° създавамС Π½Π΅ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π΅Π½ сокСт Π·Π° Ρ‡Π΅Ρ‚Π΅Π½Π΅ Π½Π° всички 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.

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

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

ΠšΠ»Π°ΡΠΈΡ‡Π΅ΡΠΊΠΈ БНЀ ΠΈ XNUMX Π²Π΅ΠΊ

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

ΠšΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€ΡŠΡ‚ JIT бСшС ΠΏΡŠΡ€Π²ΠΈΡΡ‚ във Π²Π΅Ρ€ΠΈΠ³Π°Ρ‚Π° ΠΎΡ‚ ΠΏΡ€ΠΎΠΌΠ΅Π½ΠΈ: ΠΏΡ€Π΅Π· 2012 Π³ сС появи Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ Π·Π° писанС Π½Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° seccomp, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ BPF, ΠΏΡ€Π΅Π· януари 2013 Π³. имашС Π΄ΠΎΠ±Π°Π²Π΅Π½ΠΎ ΠΌΠΎΠ΄ΡƒΠ» xt_bpf, ΠΊΠΎΠ΅Ρ‚ΠΎ Π²ΠΈ позволява Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° iptables с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° БНЀ, Π° ΠΏΡ€Π΅Π· ΠΎΠΊΡ‚ΠΎΠΌΠ²Ρ€ΠΈ 2013 Π³. бСшС Π΄ΠΎΠ±Π°Π²Π΅Π½ΠΎ ΡΡŠΡ‰ΠΎ ΠΈ ΠΌΠΎΠ΄ΡƒΠ» cls_bpf, ΠΊΠΎΠ΅Ρ‚ΠΎ Π²ΠΈ позволява Π΄Π° ΠΏΠΈΡˆΠ΅Ρ‚Π΅ класификатори Π½Π° Ρ‚Ρ€Π°Ρ„ΠΈΠΊ с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° BPF.

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

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

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

   16    8    8     32
| code | 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))

ΠŸΠΈΡΠ°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ ΠΏΠΎΠ΄ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° Π½Π° машинни ΠΊΠΎΠ΄ΠΎΠ²Π΅ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ понякога Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° отстраняванС Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ, създаванС Π½Π° ΠΌΠΎΠ΄ΡƒΠ»Π½ΠΈ тСстовС, писанС Π½Π° статии Π½Π° HabrΓ© ΠΈ ​​др.). Π—Π° улСснСниС във Ρ„Π°ΠΉΠ»Π° <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

По ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ Π°ΡΠ΅ΠΌΠ±Π»Π΅Ρ€ΡŠΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° ΠΊΠΎΠ΄ във Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° <количСство инструкций>,<code1> <jt1> <jf1> <k1>,..., Π·Π° нашия ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с 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 Ρ‚Π΅Π·ΠΈ нСстандартни Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΡ са Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈ, Π·Π° Π΄Π° осигурят Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈΡ†ΠΈ Π½Π° ядрото Π·Π° Π΄ΠΎΡΡ‚ΡŠΠΏ Π΄ΠΎ ΠΏΠ°ΠΌΠ΅Ρ‚, структури ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΡΡŠΠ±ΠΈΡ‚ΠΈΡ.) Π•Ρ‚ΠΎ Π΅Π΄ΠΈΠ½ интСрСсСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° Ρ„ΠΈΠ»Ρ‚ΡŠΡ€, Π² ΠΊΠΎΠΉΡ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€Π°ΠΌΠ΅ само Π·Π°Π³Π»Π°Π²ΠΊΠΈ Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π² потрСбитСлското пространство с ΠΏΠΎΠΌΠΎΡ‰Ρ‚Π° Π½Π° Ρ€Π°Π·ΡˆΠΈΡ€Π΅Π½ΠΈΠ΅Ρ‚ΠΎ poff, отмСстванС Π½Π° ΠΏΠΎΠ»Π΅Π·Π΅Π½ Ρ‚ΠΎΠ²Π°Ρ€:

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.) Π’Ρ€ΡŠΠ·ΠΊΠΈ към Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½Π° докумСнтация ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° Π±ΡŠΠ΄Π°Ρ‚ Π½Π°ΠΌΠ΅Ρ€Π΅Π½ΠΈ Π² края Π½Π° статията.

Π˜ΠΌΠ°ΠΉΡ‚Π΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄, Ρ‡Π΅ Π²Π΅Ρ‡Π΅ ΠΈΠΌΠ° статии Π² Ρ†Π΅Π½Ρ‚ΡŠΡ€Π° Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° 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, Ρ‚.Π΅. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠ° Π½Π° БНЀ.

Как сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π°Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ‚Π΅ Π·Π° 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
Bad system call

ΡƒΠΏΠΎΡ‚Ρ€Π΅Π±Π° 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} ---
+++ killed by SIGSYS (core dumped) +++
Bad system call

ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ, Ρ‡Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ‚Π° Π΅ Π±ΠΈΠ»Π° ΠΏΡ€Π΅ΠΊΡ€Π°Ρ‚Π΅Π½Π° ΠΏΠΎΡ€Π°Π΄ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π½Π΅Π·Π°ΠΊΠΎΠ½Π½ΠΎ систСмно ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½Π΅ 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 Π½Π΅ Π΅ Ρ€Π°Π²Π΅Π½ 0x29. Няма Π΄Π° Π½Π°Π²Π»ΠΈΠ·Π°ΠΌ Π² подробности, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π²Π΅Ρ‡Π΅ Π΅ ясно, Ρ‡Π΅ писанСто Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° ΠΏΡ€Π°Π²ΠΈΠ»Π° Π½Π° Ρ€ΡŠΠΊΠ° Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎ. Π’ статията BPF - забравСният Π±Π°ΠΉΡ‚ ΠΊΠΎΠ΄, ΠΈΠΌΠ° няколко Π²Ρ€ΡŠΠ·ΠΊΠΈ с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΏΡ€Π°Π²ΠΈΠ»Π° Π·Π° 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 Π°Ρ‚Π°ΠΊΠΈ. Π’ статията ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡΠΌΠ΅ Π²ΠΈ 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" ΠΈ Ρ‚.Π½.

Малко ΠΏΠΎ-късно Cloudfare ΠΏΡƒΠ±Π»ΠΈΠΊΡƒΠ²Π° ΠΊΠΎΠ΄Π° Π½Π° ΠΊΠΎΠΌΠΏΠΈΠ»Π°Ρ‚ΠΎΡ€Π° 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,
...

Π’ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π²Π΅Ρ‡Π΅ Π½Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Cloudfare xt_bpf, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚Π΅ сС прСмСстиха Π² XDP - Π΅Π΄Π½Π° ΠΎΡ‚ ΠΎΠΏΡ†ΠΈΠΈΡ‚Π΅ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Π½ΠΎΠ²Π°Ρ‚Π° вСрсия Π½Π° BPF, Π²ΠΈΠΆΡ‚Π΅. L4Drop: XDP DDoS смСкчаванС.

cls_bpf

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

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

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

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

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

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

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

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

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

ΠŸΠΎΠ·ΠΎΠ²Π°Π²Π°Π½Π΅Ρ‚ΠΎ

  1. Π‘Ρ‚ΠΈΠ²ΡŠΠ½ Маккан ΠΈ Π’Π°Π½ Π”ΠΆΠ΅ΠΉΠΊΡŠΠ±ΡΡŠΠ½, β€žΠŸΠ°ΠΊΠ΅Ρ‚Π½ΠΈΡΡ‚ Ρ„ΠΈΠ»Ρ‚ΡŠΡ€ BSD: Нова Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π° Π·Π° улавянС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈ Π½Π° Π½ΠΈΠ²ΠΎ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»β€œ, https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Π‘Ρ‚ΠΈΠ²ΡŠΠ½ Маккан, β€žlibpcap: АрхитСктура ΠΈ мСтодология Π·Π° оптимизация Π·Π° улавянС Π½Π° ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈβ€œ, https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. Π£Ρ€ΠΎΠΊ Π·Π° съвпадСниС Π½Π° IPtable U32.
  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/

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

ДобавянС Π½Π° Π½ΠΎΠ² ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€