Berkeley Packet Filters (BPF) Π΅ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ Π½Π° ΡΠ΄ΡΠΎΡΠΎ Π½Π° Linux, ΠΊΠΎΡΡΠΎ Π΅ Π½Π° ΠΏΡΡΠ²ΠΈΡΠ΅ ΡΡΡΠ°Π½ΠΈΡΠΈ Π½Π° Π°Π½Π³Π»ΠΎΠ΅Π·ΠΈΡΠ½ΠΈΡΠ΅ ΡΠ΅Ρ
Π½ΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΎΡ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π³ΠΎΠ΄ΠΈΠ½ΠΈ. ΠΠΎΠ½ΡΠ΅ΡΠ΅Π½ΡΠΈΠΈΡΠ΅ ΡΠ° ΠΏΡΠ»Π½ΠΈ Ρ Π΄ΠΎΠΊΠ»Π°Π΄ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ ΠΈ ΡΠ°Π·Π²ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° BPF. ΠΠ΅ΠΉΠ²ΠΈΠ΄ ΠΠΈΠ»ΡΡ, ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°Ρ ΠΌΡΠ΅ΠΆΠΎΠ²Π°ΡΠ° ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΠ° Π½Π° Linux, ΠΏΡΠΈΠ·ΠΎΠ²Π°Π²Π° ΡΠ²ΠΎΡΡΠ° ΡΠ΅Ρ Π½Π° Linux Plumbers 2018
ΠΡΠ΅ ΠΎΡΠ΅ Π½ΡΠΌΠ° ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠΈΡΠ½ΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° 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 - ΡΠ°Π±ΠΎΡΠ½ΠΈΡ ΠΊΠΎΠ½ Π½Π° ΡΠ°ΠΊΠΈΠ²Π° Π΄ΠΎΠ±ΡΠ΅ ΠΏΠΎΠ·Π½Π°ΡΠΈ ΠΏΡΠΎΠ΄ΡΠΊΡΠΈ ΠΊΠ°ΡΠΎ
BPF ΠΌΠ°ΡΠΈΠ½Π½Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°
Π©Π΅ ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΏΠΎ ΡΠ°Π±ΠΎΡΠ΅Π½ Π½Π°ΡΠΈΠ½, Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠ°ΠΉΠΊΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΈ. ΠΡΠΏΡΠ΅ΠΊΠΈ ΡΠΎΠ²Π°, ΠΊΠ°ΡΠΎ Π½Π°ΡΠ°Π»ΠΎ, Π½Π΅ΠΊΠ° ΠΊΠ°ΠΆΠ΅ΠΌ, ΡΠ΅ ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° ΠΈΠΌΠ° Π΄Π²Π° 32-Π±ΠΈΡΠΎΠ²ΠΈ ΡΠ΅Π³ΠΈΡΡΡΡΠ°, Π΄ΠΎΡΡΡΠΏΠ½ΠΈ Π·Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ, Π°ΠΊΡΠΌΡΠ»Π°ΡΠΎΡ A
ΠΈ ΠΈΠ½Π΄Π΅ΠΊΡΠ΅Π½ ΡΠ΅Π³ΠΈΡΡΡΡ X
, 64 Π±Π°ΠΉΡΠ° ΠΏΠ°ΠΌΠ΅Ρ (16 Π΄ΡΠΌΠΈ), Π΄ΠΎΡΡΡΠΏΠ½Π° Π·Π° Π·Π°ΠΏΠΈΡ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄Π²Π°ΡΠΎ ΡΠ΅ΡΠ΅Π½Π΅, ΠΈ ΠΌΠ°Π»ΠΊΠ° ΡΠΈΡΡΠ΅ΠΌΠ° ΠΎΡ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ ΡΠ΅Π·ΠΈ ΠΎΠ±Π΅ΠΊΡΠΈ. ΠΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ Π·Π° ΠΏΡΠ΅ΡΠΊΠ°ΡΠ°Π½Π΅ Π·Π° ΠΏΡΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° ΡΡΠ»ΠΎΠ²Π½ΠΈ ΠΈΠ·ΡΠ°Π·ΠΈ ΡΡΡΠΎ Π±ΡΡ
Π° Π½Π°Π»ΠΈΡΠ½ΠΈ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈΡΠ΅, Π½ΠΎ Π·Π° Π΄Π° ΡΠ΅ Π³Π°ΡΠ°Π½ΡΠΈΡΠ° Π½Π°Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΡΠΎ Π·Π°Π²ΡΡΡΠ²Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ°, ΡΠΊΠΎΠΊΠΎΠ²Π΅ ΠΌΠΎΠΆΠ΅Ρ
Π° Π΄Π° ΡΠ΅ ΠΏΡΠ°Π²ΡΡ ΡΠ°ΠΌΠΎ Π½Π°ΠΏΡΠ΅Π΄, Ρ.Π΅. ΠΏΠΎ-ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΎ Π±Π΅ΡΠ΅ Π·Π°Π±ΡΠ°Π½Π΅Π½ΠΎ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΡΠΈΠΊΠ»ΠΈ.
ΠΠ±ΡΠ°ΡΠ° ΡΡ Π΅ΠΌΠ° Π·Π° ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° Π΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ°. ΠΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΡ ΡΡΠ·Π΄Π°Π²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° BPF Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° Π½ΡΠΊΠΎΠΈ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΡΠΌ Π½Π° ΡΠ΄ΡΠΎΡΠΎ (ΠΊΠ°ΡΠΎ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅), Π·Π°ΡΠ΅ΠΆΠ΄Π° ΠΈ ΡΠ²ΡΡΠ·Π²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° ΠΊΡΠΌ Π·Π° Π½ΡΠΊΠΎΠΈ ΠΊΡΠΌ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡΠ° Π½Π° ΡΡΠ±ΠΈΡΠΈΡ Π² ΡΠ΄ΡΠΎΡΠΎ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΡΠ±ΠΈΡΠΈΠ΅ Π΅ ΠΏΡΠΈΡΡΠΈΠ³Π°Π½Π΅ΡΠΎ Π½Π° ΡΠ»Π΅Π΄Π²Π°ΡΠΈΡ ΠΏΠ°ΠΊΠ΅Ρ Π½Π° ΠΌΡΠ΅ΠΆΠΎΠ²Π°ΡΠ° ΠΊΠ°ΡΡΠ°). ΠΠΎΠ³Π°ΡΠΎ Π²ΡΠ·Π½ΠΈΠΊΠ½Π΅ ΡΡΠ±ΠΈΡΠΈΠ΅, ΡΠ΄ΡΠΎΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°ΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π² ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡ), Π° ΠΏΠ°ΠΌΠ΅ΡΡΠ° Π½Π° ΠΌΠ°ΡΠΈΠ½Π°ΡΠ° ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²Π° Π½Π° Π·Π° Π½ΡΠΊΠΎΠΈ ΡΠ΅Π³ΠΈΠΎΠ½ Π½Π° ΠΏΠ°ΠΌΠ΅ΡΡΠ° Π½Π° ΡΠ΄ΡΠΎΡΠΎ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π΄Π°Π½Π½ΠΈ Π·Π° Π²Ρ ΠΎΠ΄ΡΡ ΠΏΠ°ΠΊΠ΅Ρ).
ΠΠΎΡΠ½ΠΎΡΠΎ ΡΠ΅ Π±ΡΠ΄Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ, Π·Π° Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΠΌ Π΄Π° ΡΠ°Π·Π³Π»Π΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΈ: ΡΠ΅ ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΠΌ ΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠ° ΠΈ ΡΠΎΡΠΌΠ°ΡΠ° Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈΡΠ΅, Π°ΠΊΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ. ΠΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π²Π΅Π΄Π½Π°Π³Π° Π΄Π° ΠΈΠ·ΡΡΠΈΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°ΡΠ° ΡΠΈΡΡΠ΅ΠΌΠ° Π½Π° Π²ΠΈΡΡΡΠ°Π»Π½Π° ΠΌΠ°ΡΠΈΠ½Π° ΠΈ Π΄Π° Π½Π°ΡΡΠΈΡΠ΅ Π·Π° Π²ΡΠΈΡΠΊΠΈΡΠ΅ ΠΉ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ, ΡΠΎΠ³Π°Π²Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠΎΡΠ΅ΡΠ΅ΡΠ΅ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»Π½Π°ΡΠ° ΡΡΠ°ΡΠΈΡ libpcap
: ΠΠ΅ΡΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΡ Π·Π° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π·Π° ΡΠ»Π°Π²ΡΠ½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ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 Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΈ Π³ΠΎ ΠΈΠ·ΠΏΡΠ°ΡΠ΅ΡΠ΅ Π΄ΠΎ ΡΠ΄ΡΠΎΡΠΎ (Π²ΠΈΠΆΡΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ Π² ΡΠ°Π·Π΄Π΅Π»Π° eth0
. ΠΠΊΠΎ ΡΠΈΠ»ΡΡΡΡΡ Π²ΡΡΠ½Π΅ Π½Π΅Π½ΡΠ»Π΅Π²Π° ΡΡΠΎΠΉΠ½ΠΎΡΡ n
, ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° Π΄ΠΎ n
Π±Π°ΠΉΡΠΎΠ²Π΅ ΠΎΡ ΠΏΠ°ΠΊΠ΅ΡΠ° ΡΠ΅ Π±ΡΠ΄Π°Ρ ΠΊΠΎΠΏΠΈΡΠ°Π½ΠΈ Π² ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»ΡΠΊΠΎΡΠΎ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈ ΡΠ΅ Π³ΠΎ Π²ΠΈΠ΄ΠΈΠΌ Π² ΠΈΠ·Ρ
ΠΎΠ΄Π° tcpdump
.
ΠΠΊΠ°Π·Π²Π° ΡΠ΅, ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π»Π΅ΡΠ½ΠΎ Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΠΌ ΠΊΠΎΠΉ Π±Π°ΠΉΡ ΠΊΠΎΠ΄ Π΅ ΠΈΠ·ΠΏΡΠ°ΡΠ΅Π½ Π½Π° ΡΠ΄ΡΠΎΡΠΎ 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
, ΠΈ ΡΠΎΠ·ΠΈ
6 6 2
|Destination MAC|Source MAC|Ether Type|...|
Π’Π°ΠΊΠ° ΡΠ΅ ΡΠ»Π΅Π΄ ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° ldh [12]
Π² ΡΠ΅Π³ΠΈΡΡΡΡΠ° A
ΡΠ΅ ΠΈΠΌΠ° ΠΏΠΎΠ»Π΅ Ether Type
β Π²ΠΈΠ΄Π° Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠ°, ΠΏΡΠ΅Π΄Π°Π²Π°Π½ Π² ΡΠΎΠ·ΠΈ Ethernet ΠΊΠ°Π΄ΡΡ. ΠΠ° ΡΠ΅Π΄ 1 ΡΡΠ°Π²Π½ΡΠ²Π°ΠΌΠ΅ ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠ΅Π³ΠΈΡΡΡΡΠ° A
(ΡΠΈΠΏ ΠΎΠΏΠ°ΠΊΠΎΠ²ΠΊΠ°) c 0x86dd
, ΠΈ ΡΠΎΠ·ΠΈ 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
ΠΠ° ΡΠ΅Π΄ΠΎΠ²Π΅ 4 ΠΈ 5 Π·Π°ΡΠ΅ΠΆΠ΄Π°ΠΌΠ΅ ΠΏΠΎΠ»ΡΠ΄ΡΠΌΠΈΡΠ΅, Π½Π°ΠΌΠΈΡΠ°ΡΠΈ ΡΠ΅ Π½Π° Π°Π΄ΡΠ΅Ρ 20 ΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΡΠ° jset
ΠΏΡΠΎΠ²Π΅ΡΠ΅ΡΠ΅ Π΄Π°Π»ΠΈ Π΅ Π·Π°Π΄Π°Π΄Π΅Π½ΠΎ Π΅Π΄Π½ΠΎ ΠΎΡ ΡΡΠΈΡΠ΅ jset
ΡΡΠΈΡΠ΅ Π½Π°ΠΉ-Π·Π½Π°ΡΠΈΠΌΠΈ Π±ΠΈΡΠ° ΡΠ΅ ΠΈΠ·ΡΠΈΡΡΠ²Π°Ρ. ΠΠ²Π° ΠΎΡ ΡΡΠΈΡΠ΅ Π±ΠΈΡΠ° Π½ΠΈ ΠΊΠ°Π·Π²Π°Ρ Π΄Π°Π»ΠΈ ΠΏΠ°ΠΊΠ΅ΡΡΡ Π΅ ΡΠ°ΡΡ ΠΎΡ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠΈΡΠ°Π½ IP ΠΏΠ°ΠΊΠ΅Ρ ΠΈ Π°ΠΊΠΎ Π΅ ΡΠ°ΠΊΠ°, Π΄Π°Π»ΠΈ Π΅ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΡ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ. Π’ΡΠ΅ΡΠΈΡΡ Π±ΠΈΡ Π΅ Π·Π°ΠΏΠ°Π·Π΅Π½ ΠΈ ΡΡΡΠ±Π²Π° Π΄Π° Π±ΡΠ΄Π΅ Π½ΡΠ»Π°. ΠΠ΅ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ Π½ΠΈΡΠΎ Π½Π΅ΠΏΡΠ»Π½ΠΈ, Π½ΠΈΡΠΎ ΡΡΡΠΏΠ΅Π½ΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΈ, Π·Π°ΡΠΎΠ²Π° ΠΏΡΠΎΠ²Π΅ΡΡΠ²Π°ΠΌΠ΅ ΠΈ ΡΡΠΈΡΠ΅ Π±ΠΈΡΠ°.
Π Π΅Π΄ 6 Π΅ Π½Π°ΠΉ-ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΈΡΡ Π² ΡΠΎΠ·ΠΈ ΡΠΏΠΈΡΡΠΊ. ΠΠ·ΡΠ°Π·ΡΠ²Π°Π½Π΅ ldxb 4*([14]&0xf)
ΠΎΠ·Π½Π°ΡΠ°Π²Π°, ΡΠ΅ Π·Π°ΡΠ΅ΠΆΠ΄Π°ΠΌΠ΅ Π² ΡΠ΅Π³ΠΈΡΡΡΡΠ° X
Π½Π°ΠΉ-ΠΌΠ°Π»ΠΊΠΎ Π·Π½Π°ΡΠΈΠΌΠΈΡΠ΅ ΡΠ΅ΡΠΈΡΠΈ Π±ΠΈΡΠ° ΠΎΡ ΠΏΠ΅ΡΠ½Π°Π΄Π΅ΡΠ΅ΡΠΈΡ Π±Π°ΠΉΡ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠ°, ΡΠΌΠ½ΠΎΠΆΠ΅Π½ΠΈ ΠΏΠΎ 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
...
ΠΠ° ΠΏΡΡΠ²ΠΈΡΠ΅ Π΄Π²Π° ΡΠ΅Π΄Π° Π½Π° ΠΈΠ·Ρ
ΠΎΠ΄Π° ΡΡΠ·Π΄Π°Π²Π°ΠΌΠ΅ 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
.
ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎΡΠΎ Π΅, ΡΠ΅ ΡΠΈΠ»ΡΡΡΡΡ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΏΡΠΈΠΊΡΠ΅ΠΏΠ΅Π½ ΠΊΡΠΌ Π²ΡΡΠΊΠ° Π³Π½Π΅Π·Π΄ΠΎ, Π½Π΅ ΡΠ°ΠΌΠΎ ΡΡΡΠΎΠ²ΠΎ. Π’ΡΠΊ
ΠΠΎΠ²Π΅ΡΠ΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ Π·Π° ΡΠΏΠΎΡΡΠ΅Π±Π°ΡΠ° setsockopt
Π·Π° ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ Π½Π° ΡΠΈΠ»ΡΡΠΈ Π²ΠΈΠΆΡΠ΅ struct sock_fprog
Π±Π΅Π· ΠΏΠΎΠΌΠΎΡ tcpdump
ΡΠ΅ Π³ΠΎΠ²ΠΎΡΠΈΠΌ Π² ΡΠ°Π·Π΄Π΅Π»Π°
ΠΠ»Π°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΠΠ€ ΠΈ XNUMX Π²Π΅ΠΊ
BPF Π±Π΅ΡΠ΅ Π²ΠΊΠ»ΡΡΠ΅Π½ Π² Linux ΠΏΡΠ΅Π· 1997 Π³. ΠΈ ΠΎΡΡΠ°Π½Π° ΡΠ°Π±ΠΎΡΠ΅Π½ ΠΊΠΎΠ½ Π·Π° Π΄ΡΠ»Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅ libpcap
Π±Π΅Π· Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ ΡΠΏΠ΅ΡΠΈΠ°Π»Π½ΠΈ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ (ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΠΈ Π·Π° Linux ΠΏΡΠΎΠΌΠ΅Π½ΠΈ, ΡΠ°Π·Π±ΠΈΡΠ° ΡΠ΅, x86_64
ΠΊΠΎΠ΄.
ΠΠΎΠΌΠΏΠΈΠ»Π°ΡΠΎΡΡΡ JIT Π±Π΅ΡΠ΅ ΠΏΡΡΠ²ΠΈΡΡ Π²ΡΠ² Π²Π΅ΡΠΈΠ³Π°ΡΠ° ΠΎΡ ΠΏΡΠΎΠΌΠ΅Π½ΠΈ: ΠΏΡΠ΅Π· 2012 Π³ 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;
}
Π’Π°ΠΊΠ° Π²Π΅ΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΈΡΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ Π·Π½Π°Π΅ΠΌ ΠΊΠΎΠ΄ΠΎΠ²Π΅ΡΠ΅ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈΡΠ΅ ΠΎΡ 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
ΠΡΠ΅ΠΌΠ±Π»Π΅ΡΠ½ΠΈΡΡ Π΅Π·ΠΈΠΊ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π΅Π½ Π½Π° ΠΈΠ·Ρ
ΠΎΠ΄Π° Π·Π° ΠΎΡΡΡΡΠ°Π½ΡΠ²Π°Π½Π΅ Π½Π° Π³ΡΠ΅ΡΠΊΠΈ 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
Π² Π³ΠΎΠ» 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()
mod
(ΠΎΡΡΠ°ΡΡΠΊ ΠΏΡΠΈ Π΄Π΅Π»Π΅Π½ΠΈΠ΅) ΠΈ ΡΠ΅Π³Π° Π΅ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π·Π° seccomp BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ ΡΠ»Π΅Π΄ Π΄ΠΎΠ±Π°Π²ΡΠ½Π΅ΡΠΎ ΠΌΡ
ΠΠΎ ΠΏΡΠΈΠ½ΡΠΈΠΏ Π²Π΅ΡΠ΅ Π·Π½Π°Π΅ΠΌ Π²ΡΠΈΡΠΊΠΎ Π·Π° ΠΏΠΈΡΠ°Π½Π΅ ΠΈ ΡΠ΅ΡΠ΅Π½Π΅ Π½Π° 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 Π°ΡΠ΅ΠΌΠ±Π»ΠΈΡΠ°Π½Π΅ Π²ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ²Π° Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΠΏΡΠ»Π΅Π½ ΠΊΠΎΠ½ΡΡΠΎΠ» Π²ΡΡΡ
Ρ ΡΠ΅Π·ΡΠ»ΡΠ°ΡΠ°, Π½ΠΎ Π² ΡΡΡΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅ ΠΏΠΎΠ½ΡΠΊΠΎΠ³Π° Π΅ Π·Π° ΠΏΡΠ΅Π΄ΠΏΠΎΡΠΈΡΠ°Π½Π΅ Π΄Π° ΠΈΠΌΠ°ΡΠ΅ ΠΏΡΠ΅Π½ΠΎΡΠΈΠΌ ΠΈ/ΠΈΠ»ΠΈ ΡΠ΅ΡΠΈΠΌ ΠΊΠΎΠ΄. ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΠ΅ Π½ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ Ρ ΡΠΎΠ²Π°
ΠΠ΅ΠΊΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ°, ΠΊΠΎΡΡΠΎ ΠΈΠ·ΠΏΡΠ»Π½ΡΠ²Π° Π΄Π²ΠΎΠΈΡΠ΅Π½ ΡΠ°ΠΉΠ» ΠΏΠΎ ΠΈΠ·Π±ΠΎΡ Π½Π° ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»Ρ, ΠΊΠ°ΡΠΎ ΠΏΡΠ΅Π΄ΠΈ ΡΠΎΠ²Π° Π΅ ΠΈΠ½ΡΡΠ°Π»ΠΈΡΠ°Π» ΡΠ΅ΡΠ΅Π½ ΡΠΏΠΈΡΡΠΊ ΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½ΠΈΡ ΠΎΡ
#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 ΡΠ΅ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ²Π° ΡΠΈΠ»ΡΡΡΠ° Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠ° Π·Π° Π΄Π²ΠΎΠΈΡΠ½ΠΎ ΡΡΡΡΠ΅Π½Π΅.
ΠΠΊΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΡΡ Π΄Π²ΠΎΠΈΡΠ½ΠΈΡΠ΅ ΡΠΈΠ»ΡΡΠΈ Π·Π° ΡΡΡΡΠ΅Π½Π΅, ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅
$ 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
, ΠΈ ΡΠ°ΠΊΠ° Π½Π°ΡΠ°ΡΡΠΊ.
Π‘ΡΡ 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.
ΠΡΠΈ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ΠΎΠΏΡΠΈΡΡΠ° --seccomp-bpf
ΠΈΠΌΠ° Π΄Π²Π΅ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ. ΠΡΡΠ²ΠΎ, Π½ΡΠΌΠ° Π΄Π° Π΅ Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΏΡΠΈΡΡΠ΅Π΄ΠΈΠ½ΠΈΡΠ΅ ΠΊΡΠΌ Π²Π΅ΡΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ²Π°Ρ ΠΏΡΠΎΡΠ΅Ρ (ΠΎΠΏΡΠΈΡ -p
ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΈ strace
), ΡΡΠΉ ΠΊΠ°ΡΠΎ ΡΠΎΠ²Π° Π½Π΅ ΡΠ΅ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ° ΠΎΡ seccomp. ΠΡΠΎΡΠΎ, Π½ΡΠΌΠ° Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ Π½Π΅ ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΡΠ΅ Π΄ΡΡΠ΅ΡΠ½ΠΈΡΠ΅ ΠΏΡΠΎΡΠ΅ΡΠΈ, ΡΡΠΉ ΠΊΠ°ΡΠΎ seccomp ΡΠΈΠ»ΡΡΠΈΡΠ΅ ΡΠ΅ Π½Π°ΡΠ»Π΅Π΄ΡΠ²Π°Ρ ΠΎΡ Π²ΡΠΈΡΠΊΠΈ Π΄ΡΡΠ΅ΡΠ½ΠΈ ΠΏΡΠΎΡΠ΅ΡΠΈ Π±Π΅Π· Π²ΡΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠ° Π΄Π° Π΄Π΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΡΠ΅ ΡΠΎΠ²Π°.
ΠΠ°Π»ΠΊΠΎ ΠΏΠΎ-ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΠΊΠ°ΠΊ ΡΠΎΡΠ½ΠΎ strace
ΡΠ°Π±ΠΎΡΠΈ Ρ 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
. ΠΡΠΌΠ° Π΄Π° Π½Π°Π²Π»ΠΈΠ·Π°ΠΌ Π² ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎΡΡΠΈ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π²Π΅ΡΠ΅ Π΅ ΡΡΠ½ΠΎ, ΡΠ΅ ΠΏΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΡΠ°ΠΊΠΈΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»Π° Π½Π° ΡΡΠΊΠ° Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ. Π ΡΡΠ°ΡΠΈΡΡΠ° 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 Π°ΡΠ°ΠΊΠΈ. Π ΡΡΠ°ΡΠΈΡΡΠ° 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. Π ΡΡΠ°ΡΠΈΡΡΠ°
$ ./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, Π²ΠΈΠΆΡΠ΅.
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 Π³. ΡΡΠΎΡΠ²Π΅ΡΠ½ΠΈΡΠ΅ ΠΊΠΎΡΠ΅ΠΊΡΠΈΠΈ
ΠΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΡΡΠ°ΡΠΈΠΈ Π² ΡΠ°Π·ΠΈ ΠΏΠΎΡΠ΅Π΄ΠΈΡΠ° ΡΠ΅ ΠΏΠΎΠΊΡΠΈΡΡ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°ΡΠ° ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡΠ° Π½Π° Π½ΠΎΠ²Π°ΡΠ° ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ, ΠΏΡΡΠ²ΠΎΠ½Π°ΡΠ°Π»Π½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½Π° ΠΊΠ°ΡΠΎ Π²ΡΡΡΠ΅ΡΠ΅Π½ BPF, ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° ΡΠ°Π·ΡΠΈΡΠ΅Π½ BPF ΠΈ ΡΠ΅Π³Π° ΠΏΡΠΎΡΡΠΎ BPF.
ΠΠΎΠ·ΠΎΠ²Π°Π²Π°Π½Π΅ΡΠΎ
- Π‘ΡΠΈΠ²ΡΠ½ ΠΠ°ΠΊΠΊΠ°Π½ ΠΈ ΠΠ°Π½ ΠΠΆΠ΅ΠΉΠΊΡΠ±ΡΡΠ½, βΠΠ°ΠΊΠ΅ΡΠ½ΠΈΡΡ ΡΠΈΠ»ΡΡΡ BSD: ΠΠΎΠ²Π° Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° Π·Π° ΡΠ»Π°Π²ΡΠ½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈ Π½Π° Π½ΠΈΠ²ΠΎ ΠΏΠΎΡΡΠ΅Π±ΠΈΡΠ΅Π»β,
https://www.tcpdump.org/papers/bpf-usenix93.pdf
- Π‘ΡΠΈΠ²ΡΠ½ ΠΠ°ΠΊΠΊΠ°Π½, βlibpcap: ΠΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ»ΠΎΠ³ΠΈΡ Π·Π° ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π·Π° ΡΠ»Π°Π²ΡΠ½Π΅ Π½Π° ΠΏΠ°ΠΊΠ΅ΡΠΈβ,
https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
tcpdump
,libpcap
:https://www.tcpdump.org/ Π£ΡΠΎΠΊ Π·Π° ΡΡΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ Π½Π° IPtable U32 .- BPF - Π·Π°Π±ΡΠ°Π²Π΅Π½ΠΈΡΡ Π±Π°ΠΉΡ ΠΊΠΎΠ΄:
https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
- ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΠΌΠ΅ Π²ΠΈ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½ΡΠ° BPF:
https://blog.cloudflare.com/introducing-the-bpf-tools/
bpf_cls
:http://man7.org/linux/man-pages/man8/tc-bpf.8.html
- ΠΠ±Ρ ΠΏΡΠ΅Π³Π»Π΅Π΄ Π½Π° seccomp:
https://lwn.net/Articles/656307/
https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
habr: ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΈ ΠΈ ΡΠΈΠ³ΡΡΠ½ΠΎΡΡ: seccomp habr: ΠΠ·ΠΎΠ»ΠΈΡΠ°Π½Π΅ Π½Π° Π΄Π΅ΠΌΠΎΠ½ΠΈ ΡΡΡ systemd ΠΈΠ»ΠΈ βΠ½ΡΠΌΠ°ΡΠ΅ Π½ΡΠΆΠ΄Π° ΠΎΡ Docker Π·Π° ΡΠΎΠ²Π°!β - Paul Chaignon, βstrace --seccomp-bpf: ΠΏΠΎΠ³Π»Π΅Π΄ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠ°ΠΊΠ°β,
https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
netsniff-ng
:http://netsniff-ng.org/
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: www.habr.com