Berkeley Packet Filters (BPF) β ΡΡΠΎ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ ΡΠ΄ΡΠ° Linux, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π΅ ΡΡ
ΠΎΠ΄ΠΈΡ Ρ ΠΏΠ΅ΡΠ²ΡΡ
ΠΏΠΎΠ»ΠΎΡ Π°Π½Π³Π»ΠΎΡΠ·ΡΡΠ½ΡΡ
ΡΠ΅Ρ
Π½ΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΈΠ·Π΄Π°Π½ΠΈΠΉ Π²ΠΎΡ ΡΠΆΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π»Π΅Ρ ΠΏΠΎΠ΄ΡΡΠ΄. ΠΠΎΠ½ΡΠ΅ΡΠ΅Π½ΡΠΈΠΈ Π·Π°Π±ΠΈΡΡ Π΄ΠΎΠΊΠ»Π°Π΄Π°ΠΌΠΈ ΠΏΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΡ BPF. David Miller, ΠΌΠ°Π½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΠ΅ΡΠ΅Π²ΠΎΠΉ ΠΏΠΎΠ΄ΡΠΈΡΡΠ΅ΠΌΡ Linux, Π½Π°Π·ΡΠ²Π°Π΅Ρ ΡΠ²ΠΎΠΉ Π΄ΠΎΠΊΠ»Π°Π΄ Π½Π° Linux Plumbers 2018
ΠΠ° Π₯Π°Π±ΡΠ΅ Π΄ΠΎ ΡΠΈΡ
ΠΏΠΎΡ Π½Π΅Ρ ΡΠΈΡΡΠ΅ΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ BPF, ΠΈ ΠΏΠΎΡΡΠΎΠΌΡ Ρ Π² ΡΠ΅ΡΠΈΠΈ ΡΡΠ°ΡΠ΅ΠΉ ΠΏΠΎΡΡΠ°ΡΠ°ΡΡΡ ΡΠ°ΡΡΠΊΠ°Π·Π°ΡΡ ΠΏΡΠΎ ΠΈΡΡΠΎΡΠΈΡ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, ΠΎΠΏΠΈΡΠ°ΡΡ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ ΠΈ ΡΡΠ΅Π΄ΡΡΠ²Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ, ΠΎΡΠ΅ΡΡΠΈΡΡ ΠΎΠ±Π»Π°ΡΡΠΈ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΈ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ BPF. Π ΡΡΠΎΠΉ, Π½ΡΠ»Π΅Π²ΠΎΠΉ, ΡΡΠ°ΡΡΠ΅ ΡΠΈΠΊΠ»Π° ΡΠ°ΡΡΠΊΠ°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΈΡΡΠΎΡΠΈΡ ΠΈ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF, Π° ΡΠ°ΠΊΠΆΠ΅ ΡΠ°ΡΠΊΡΡΠ²Π°ΡΡΡΡ ΡΠ°ΠΉΠ½Ρ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΎΠ² ΡΠ°Π±ΠΎΡΡ tcpdump
, seccomp
, strace
, ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄ΡΡΠ³ΠΎΠ΅.
Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° BPF ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΡΠ΅ΡΡΡ ΡΠ΅ΡΠ΅Π²ΡΠΌ ΡΠΎΠΎΠ±ΡΠ΅ΡΡΠ²ΠΎΠΌ Linux, ΠΎΡΠ½ΠΎΠ²Π½ΡΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ BPF ΡΠ²ΡΠ·Π°Π½Ρ Ρ ΡΠ΅ΡΡΠΌΠΈ ΠΈ ΠΏΠΎΡΡΠΎΠΌΡ, Ρ ΠΏΠΎΠ·Π²ΠΎΠ»Π΅Π½ΠΈΡ
ΠΡΠ°ΡΠΊΠΈΠΉ ΠΊΡΡΡ ΠΈΡΡΠΎΡΠΈΠΈ BPF(c)
Π‘ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ BPF β ΡΡΠΎ ΡΠ»ΡΡΡΠ΅Π½Π½Π°Ρ ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½Π½Π°Ρ Π²Π΅ΡΡΠΈΡ ΡΡΠ°ΡΠΎΠΉ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Ρ ΡΠ΅ΠΌ ΠΆΠ΅ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ, Π½Π°Π·ΡΠ²Π°Π΅ΠΌΠΎΠΉ Π½ΡΠ½ΡΠ΅, Π²ΠΎ ΠΈΠ·Π±Π΅ΠΆΠ°Π½ΠΈΠ΅ ΠΏΡΡΠ°Π½ΠΈΡΡ, classic BPF. ΠΠ° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF Π±ΡΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½Ρ Π²ΡΠ΅ΠΌ ΠΈΠ·Π²Π΅ΡΡΠ½Π°Ρ ΡΡΠΈΠ»ΠΈΡΠ° tcpdump
, ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌ seccomp
, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΌΠ΅Π½Π΅Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠ΅ ΠΌΠΎΠ΄ΡΠ»Ρ xt_bpf
Π΄Π»Ρ iptables
ΠΈ ΠΊΠ»Π°ΡΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ cls_bpf
. Π ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΌ Linux ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ BPF Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠ°Π½ΡΠ»ΠΈΡΡΡΡΡΡ Π² Π½ΠΎΠ²ΡΡ ΡΠΎΡΠΌΡ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠΉ ΡΠΎΡΠΊΠΈ Π·ΡΠ΅Π½ΠΈΡ, API ΠΎΡΡΠ°Π»ΡΡ Π½Π° ΠΌΠ΅ΡΡΠ΅ ΠΈ Π½ΠΎΠ²ΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF, ΠΊΠ°ΠΊ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ Π² ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅, Π½Π°Ρ
ΠΎΠ΄ΡΡΡΡ Π΄ΠΎ ΡΠΈΡ
ΠΏΠΎΡ. ΠΠΎ ΡΡΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½Π΅, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΡΠΎΠΌΡ, ΡΡΠΎ ΡΠ»Π΅Π΄ΡΡ Π·Π° ΠΈΡΡΠΎΡΠΈΠ΅ΠΉ ΡΠ°Π·Π²ΠΈΡΠΈΡ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠΉ BPF Π² Linux, ΡΡΠ°Π½Π΅Ρ ΡΡΠ½Π΅Π΅ ΠΊΠ°ΠΊ ΠΈ ΠΏΠΎΡΠ΅ΠΌΡ ΠΎΠ½Π° ΡΠ²ΠΎΠ»ΡΡΠΈΠΎΠ½ΠΈΡΠΎΠ²Π°Π»Π° Π² ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠΎΡΠΌΡ, Ρ ΡΠ΅ΡΠΈΠ» Π½Π°ΡΠ°ΡΡ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΠΎ ΡΡΠ°ΡΡΠΈ ΠΏΡΠΎ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ BPF.
Π ΠΊΠΎΠ½ΡΠ΅ Π²ΠΎΡΡΠΌΠΈΠ΄Π΅ΡΡΡΡΡ Π³ΠΎΠ΄ΠΎΠ² ΠΏΡΠΎΡΠ»ΠΎΠ³ΠΎ Π²Π΅ΠΊΠ° ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΡ ΠΈΠ· Π·Π½Π°ΠΌΠ΅Π½ΠΈΡΠΎΠΉ Lawrence Berkeley Laboratory Π·Π°ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠΎΠ²Π°Π»ΠΈΡΡ Π²ΠΎΠΏΡΠΎΡΠΎΠΌ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΡΠΈΠ»ΡΡΡΠΎΠ²Π°ΡΡ ΡΠ΅ΡΠ΅Π²ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ Π½Π° ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΌ Π΄Π»Ρ ΠΊΠΎΠ½ΡΠ° Π²ΠΎΡΡΠΌΠΈΠ΄Π΅ΡΡΡΡΡ Π³ΠΎΠ΄ΠΎΠ² ΠΏΡΠΎΡΠ»ΠΎΠ³ΠΎ Π²Π΅ΠΊΠ° ΠΆΠ΅Π»Π΅Π·Π΅. ΠΠ°Π·ΠΎΠ²Π°Ρ ΠΈΠ΄Π΅Ρ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ, ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Π°Ρ ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΠΎ Π² ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ CSPF (CMU/Stanford Packet Filter), ΡΠΎΡΡΠΎΡΠ»Π° Π² ΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΡΠΈΠ»ΡΡΡΠΎΠ²Π°ΡΡ Π»ΠΈΡΠ½ΠΈΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π½ΡΡΠ΅, Ρ.Π΅. Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΡΠ΄ΡΠ°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π΅ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ Π»ΠΈΡΠ½ΠΈΠ΅ Π΄Π°Π½Π½ΡΠ΅ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ. Π§ΡΠΎΠ±Ρ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΡΠ΄ΡΠ°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»Π°ΡΡ Π²ΠΈΡΡΡΠ°Π»ΡΠ½Π°Ρ ΠΌΠ°ΡΠΈΠ½Π° β ΠΏΠ΅ΡΠΎΡΠ½ΠΈΡΠ°.
ΠΠ΄Π½Π°ΠΊΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠ΅ ΠΌΠ°ΡΠΈΠ½Ρ Π΄Π»Ρ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π²ΡΠΈΡ
ΡΠΈΠ»ΡΡΡΠΎΠ² Π±ΡΠ»ΠΈ ΡΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½Ρ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π½Π° ΠΌΠ°ΡΠΈΠ½Π°Ρ
ΡΠΎ ΡΡΠ΅ΠΊΠΎΠ²ΠΎΠΉ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠΎΠΉ ΠΈ Π½Π° Π½ΠΎΠ²ΡΡ
RISC ΠΌΠ°ΡΠΈΠ½Π°Ρ
ΡΠ°Π±ΠΎΡΠ°Π»ΠΈ Π½Π΅ ΡΠ°ΠΊ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎ. Π ΠΈΡΠΎΠ³Π΅ ΡΡΠΈΠ»ΠΈΡΠΌΠΈ ΠΈΠ½ΠΆΠ΅Π½Π΅ΡΠΎΠ² ΠΈΠ· Berkeley Labs Π±ΡΠ»Π° ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π° Π½ΠΎΠ²Π°Ρ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ BPF (Berkeley Packet Filters), Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ Π±ΡΠ»Π° ΡΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½Π° Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ° Motorola 6502 β ΡΠ°Π±ΠΎΡΠ΅ΠΉ Π»ΠΎΡΠ°Π΄ΠΊΠΈ ΡΠ°ΠΊΠΈΡ
ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ
ΠΏΡΠΎΠ΄ΡΠΊΡΠΎΠ² ΠΊΠ°ΠΊ
ΠΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΌΠ°ΡΠΈΠ½Ρ BPF
ΠΡ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠΌΡΡ Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠΎΠΉ ΠΏΠΎ-ΡΠ°Π±ΠΎΡΠ΅ΠΌΡ, ΡΠ°Π·Π±ΠΈΡΠ°Ρ ΠΏΡΠΈΠΌΠ΅ΡΡ. ΠΠ΄Π½Π°ΠΊΠΎ Π΄Π»Ρ Π½Π°ΡΠ°Π»Π° Π²ΡΠ΅ ΠΆΠ΅ ΡΠΊΠ°ΠΆΠ΅ΠΌ, ΡΡΠΎ Ρ ΠΌΠ°ΡΠΈΠ½Ρ Π±ΡΠ»ΠΎ Π΄Π²Π° Π΄ΠΎΡΡΡΠΏΠ½ΡΡ
Π΄Π»Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ 32-Π±ΠΈΡΠ½ΡΡ
ΡΠ΅Π³ΠΈΡΡΡΠ°, Π°ΠΊΠΊΡΠΌΡΠ»ΡΡΠΎΡ A
ΠΈ ΠΈΠ½Π΄Π΅ΠΊΡΠ½ΡΠΉ ΡΠ΅Π³ΠΈΡΡΡ X
, 64 Π±Π°ΠΉΡΠ° ΠΏΠ°ΠΌΡΡΠΈ (16 ΡΠ»ΠΎΠ²), Π΄ΠΎΡΡΡΠΏΠ½ΠΎΠΉ Π΄Π»Ρ Π·Π°ΠΏΠΈΡΠΈ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΡΠ΅Π½ΠΈΡ, ΠΈ Π½Π΅Π±ΠΎΠ»ΡΡΠ°Ρ ΡΠΈΡΡΠ΅ΠΌΠ° ΠΊΠΎΠΌΠ°Π½Π΄ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΡΡΠΈΠΌΠΈ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌΠΈ. Π ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°Ρ
Π±ΡΠ»ΠΈ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΈ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΈ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Π° Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΡΠ»ΠΎΠ²Π½ΡΡ
Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΠΎΠ΄Π½Π°ΠΊΠΎ Π΄Π»Ρ Π³Π°ΡΠ°Π½ΡΠΈΠΈ ΡΠ²ΠΎΠ΅Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠΊΠΎΠ½ΡΠ°Π½ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΡΠΎΠ»ΡΠΊΠΎ Π²ΠΏΠ΅ΡΠ΅Π΄, Ρ.Π΅., Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, Π·Π°ΠΏΡΠ΅ΡΠ°Π»ΠΎΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΈΠΊΠ»Ρ.
ΠΠ±ΡΠ°Ρ ΡΡ Π΅ΠΌΠ° Π·Π°ΠΏΡΡΠΊΠ° ΠΌΠ°ΡΠΈΠ½Ρ ΡΠ»Π΅Π΄ΡΡΡΠ°Ρ. ΠΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΎΠ·Π΄Π°Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΡ BPF ΠΈ, ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-ΡΠΎ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° ΡΠ΄ΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π°), Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΊ ΠΊΠ°ΠΊΠΎΠΌΡ-ΡΠΎ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡΡ ΡΠΎΠ±ΡΡΠΈΠΉ Π² ΡΠ΄ΡΠ΅ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠΎΠ±ΡΡΠΈΠ΅ β ΡΡΠΎ ΠΏΡΠΈΡ ΠΎΠ΄ ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅ΡΠ° Π½Π° ΡΠ΅ΡΠ΅Π²ΡΡ ΠΊΠ°ΡΡΡ). ΠΡΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ΡΠΎΠ±ΡΡΠΈΡ ΡΠ΄ΡΠΎ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΎΡΠ΅), ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΌΠ°ΡΠΈΠ½Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΠΊΠ°ΠΊΠΎΠΌΡ-ΡΠΎ ΡΠ΅Π³ΠΈΠΎΠ½Ρ ΠΏΠ°ΠΌΡΡΠΈ ΡΠ΄ΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π°Π½Π½ΡΠΌ ΠΏΡΠΈΡΠ΅Π΄ΡΠ΅Π³ΠΎ ΠΏΠ°ΠΊΠ΅ΡΠ°).
Π‘ΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Π²ΡΡΠ΅ Π½Π°ΠΌ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ Π½Π°ΡΠ°ΡΡ ΡΠ°Π·Π±ΠΈΡΠ°ΡΡ ΠΏΡΠΈΠΌΠ΅ΡΡ: ΠΌΡ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΠΌΡΡ Ρ ΡΠΈΡΡΠ΅ΠΌΠΎΠΉ ΠΈ ΡΠΎΡΠΌΠ°ΡΠΎΠΌ ΠΊΠΎΠΌΠ°Π½Π΄ ΠΏΠΎ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ. ΠΡΠ»ΠΈ ΠΆΠ΅ Π²Π°ΠΌ Ρ
ΠΎΡΠ΅ΡΡΡ ΡΡΠ°Π·Ρ ΠΈΠ·ΡΡΠΈΡΡ ΡΠΈΡΡΠ΅ΠΌΡ ΠΊΠΎΠΌΠ°Π½Π΄ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Ρ ΠΈ ΡΠ·Π½Π°ΡΡ ΠΏΡΠΎ Π²ΡΠ΅ Π΅Π΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ, ΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΡ ΡΡΠ°ΡΡΡ libpcap
: An Architecture and Optimization Methodology for Packet Capturelibpcap
.
ΠΡ ΠΆΠ΅ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΠΌ ΠΊ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½ΠΈΡ Π²ΡΠ΅Ρ
ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΡ
ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ² ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ 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 ΠΏΠ°ΠΊΠ΅ΡΡ. ΠΡ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅ΠΌ Protocol Ρ 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)
(ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π΄ΡΡΠ³ΠΎΠΉ offset, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, 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
.
ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, ΡΡΠΎ ΡΠΈΠ»ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΡΡΡ ΠΊ Π»ΡΠ±ΠΎΠΌΡ ΡΠΎΠΊΠ΅ΡΡ, Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΊ raw. ΠΠΎΡ
ΠΠΎΠ΄ΡΠΎΠ±Π½Π΅Π΅ ΠΏΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ setsockopt
Π΄Π»Ρ ΠΏΠΎΠ΄ΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ ΡΠΈΠ»ΡΡΡΠΎΠ² ΡΠΌ. Π² struct sock_fprog
Π±Π΅Π· ΠΏΠΎΠΌΠΎΡΠΈ tcpdump
ΠΌΡ ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ Π² ΡΠ°Π·Π΄Π΅Π»Π΅
ΠΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ BPF ΠΈ XXI Π²Π΅ΠΊ
BPF Π±ΡΠ» Π²ΠΊΠ»ΡΡΠ΅Π½ Π² Linux Π² 1997 Π³ΠΎΠ΄Ρ ΠΈ Π΄ΠΎΠ»Π³ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ ΠΎΡΡΠ°Π²Π°Π»ΡΡ ΡΠ°Π±ΠΎΡΠ΅ΠΉ Π»ΠΎΡΠ°Π΄ΠΊΠΎΠΉ libpcap
Π±Π΅Π· ΠΎΡΠΎΠ±ΡΡ
ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ (Linux-ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, x86_64
ΠΊΠΎΠ΄.
JIT compiler Π±ΡΠ» ΠΏΠ΅ΡΠ²ΡΠΌ Π² ΡΠ΅ΠΏΠΎΡΠΊΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ: Π² 2012 Π³ΠΎΠ΄Ρ xt_bpf
, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ ΠΏΠΈΡΠ°ΡΡ ΠΏΡΠ°Π²ΠΈΠ»Π° Π΄Π»Ρ iptables
ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ BPF, Π° Π² ΠΎΠΊΡΡΠ±ΡΠ΅ 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))
ΠΠΈΡΠ°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π² Π²ΠΈΠ΄Π΅ ΠΌΠ°ΡΠΈΠ½Π½ΡΡ
ΠΊΠΎΠ΄ΠΎΠ² Π½Π΅ ΠΎΡΠ΅Π½Ρ ΡΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ ΠΈΠ½ΠΎΠ³Π΄Π° ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΡΡΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄Π»Ρ ΠΎΡΠ»Π°Π΄ΠΊΠΈ, ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠ½ΠΈΡ-ΡΠ΅ΡΡΠΎΠ², Π½Π°ΠΏΠΈΡΠ°Π½ΠΈΡ ΡΡΠ°ΡΠ΅ΠΉ Π½Π° Ρ
Π°Π±ΡΠ΅ ΠΈ Ρ.ΠΏ.). ΠΠ»Ρ ΡΠ΄ΠΎΠ±ΡΡΠ²Π° Π² ΡΠ°ΠΉΠ»Π΅ <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 ΡΡΠΈ Π½Π΅ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ Π±ΡΠ»ΠΈ ΡΠ°ΡΡΠΈΡΠ΅Π½Ρ Π² Π²ΠΈΠ΄Π΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°ΠΌ Π½Π°Π±ΠΎΡΠ° kernel helpers Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΏΠ°ΠΌΡΡΠΈ, ΡΡΡΡΠΊΡΡΡΠ°ΠΌ, ΠΈ Π³Π΅Π½Π΅ΡΠ°ΡΠΈΠΈ ΡΠΎΠ±ΡΡΠΈΠΉ.) ΠΠΎΡ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ ΡΠΈΠ»ΡΡΡΠ°, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΌΡ ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΡΠΎΠ»ΡΠΊΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ poff
, payload offset:
ld poff
ret a
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ BPF Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² tcpdump
, Π½ΠΎ ΡΡΠΎ Ρ
ΠΎΡΠΎΡΠΈΠΉ ΠΏΠΎΠ²ΠΎΠ΄ ΠΏΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Ρ ΠΏΠ°ΠΊΠ΅ΡΠΎΠΌ ΡΡΠΈΠ»ΠΈΡ netsniff-ng
netsniff-ng
, ΠΊΠΎΡΠΎΡΠ°Ρ, ΠΊΡΠΎΠΌΠ΅ ΡΠΈΠ»ΡΡΡΠ°ΡΠΈΠΈ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ BPF ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΠ°ΠΊΠΆΠ΅ ΠΈ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠΉ Π³Π΅Π½Π΅ΡΠ°ΡΠΎΡ ΡΡΠ°ΡΠΈΠΊΠ°, ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠ΄Π²ΠΈΠ½ΡΡΡΠΉ, ΡΠ΅ΠΌ tools/bpf/bpf_asm
, Π°ΡΡΠ΅ΠΌΠ±Π»Π΅Ρ BPF ΠΏΠΎΠ΄ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ΠΌ bpfc
. ΠΠ°ΠΊΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΡΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ, ΡΠΌ. ΡΠ°ΠΊΠΆΠ΅ ΡΡΡΠ»ΠΊΠΈ Π² ΠΊΠΎΠ½ΡΠ΅ ΡΡΠ°ΡΡΠΈ.
seccomp
ΠΡΠ°ΠΊ, ΠΌΡ ΡΠΆΠ΅ ΡΠΌΠ΅Π΅ΠΌ ΠΏΠΈΡΠ°ΡΡ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΠΎΠΉ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΈ Π³ΠΎΡΠΎΠ²Ρ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ Π½Π° Π½ΠΎΠ²ΡΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΡ, ΠΏΠ΅ΡΠ²ΡΠΉ ΠΈΠ· ΠΊΠΎΡΠΎΡΡΡ β ΡΡΠΎ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΡ seccomp, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠ°Ρ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΡΠΈΠ»ΡΡΡΠΎΠ² BPF ΡΠΏΡΠ°Π²Π»ΡΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎΠΌ ΠΈ Π½Π°Π±ΠΎΡΠΎΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ Π²ΡΠ·ΠΎΠ²ΠΎΠ², Π΄ΠΎΡΡΡΠΏΠ½ΡΡ Π΄Π°Π½Π½ΠΎΠΌΡ ΠΏΡΠΎΡΠ΅ΡΡΡ ΠΈ Π΅Π³ΠΎ ΠΏΠΎΡΠΎΠΌΠΊΠ°ΠΌ.
ΠΠ΅ΡΠ²Π°Ρ Π²Π΅ΡΡΠΈΡ seccomp Π±ΡΠ»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π² ΡΠ΄ΡΠΎ Π² 2005 Π³ΠΎΠ΄Ρ ΠΈ Π½Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»Π°ΡΡ Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΎΡΡΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ»Π° Π»ΠΈΡΡ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ β ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ
Π²ΡΠ·ΠΎΠ²ΠΎΠ², Π΄ΠΎΡΡΡΠΏΠ½ΡΡ
ΠΏΡΠΎΡΠ΅ΡΡΡ, ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ: read
, write
, exit
ΠΈ sigreturn
, Π° ΠΏΡΠΎΡΠ΅ΡΡ, Π½Π°ΡΡΡΠΈΠ²ΡΠΈΠΉ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠ±ΠΈΠ²Π°Π»ΡΡ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ SIGKILL
. ΠΠ΄Π½Π°ΠΊΠΎ Π² 2012 Π³ΠΎΠ΄Ρ Π² seccomp Π±ΡΠ»Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π° Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ BPF ΡΠΈΠ»ΡΡΡΡ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½Π½ΡΡ
ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ
Π²ΡΠ·ΠΎΠ²ΠΎΠ² ΠΈ Π΄Π°ΠΆΠ΅ Π²ΡΠΏΠΎΠ»Π½ΡΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΠΈ Π½Π°Π΄ ΠΈΡ
Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ. (ΠΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, ΡΡΠΎ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΠΏΠ΅ΡΠ²ΡΡ
ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΉ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ ΡΠ²Π»ΡΠ»ΡΡ Chrome, Π° Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π»ΡΠ΄ΡΠΌΠΈ ΠΈΠ· Chrome ΡΠ°Π·ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΡΡΡ ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌ KRSI, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΡΠΉ Π½Π° Π½ΠΎΠ²ΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ BPF ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ ΠΊΠ°ΡΡΠΎΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Linux Security Modules.) Π‘ΡΡΠ»ΠΊΠΈ Π½Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ Π² ΠΊΠΎΠ½ΡΠ΅ ΡΡΠ°ΡΡΠΈ.
ΠΡΠΌΠ΅ΡΠΈΠΌ, ΡΡΠΎ Π½Π° Ρ
Π°Π±ΡΠ΅ ΡΠΆΠ΅ Π±ΡΠ»ΠΈ ΡΡΠ°ΡΡΠΈ ΠΏΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ seccomp, ΠΌΠΎΠΆΠ΅Ρ ΠΊΠΎΠΌΡ-ΡΠΎ Π·Π°Ρ
ΠΎΡΠ΅ΡΡΡ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ ΠΈΡ
Π΄ΠΎ (ΠΈΠ»ΠΈ Π²ΠΌΠ΅ΡΡΠΎ) ΡΡΠ΅Π½ΠΈΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΡ
ΠΏΠΎΠ΄ΡΠ°Π·Π΄Π΅Π»ΠΎΠ². Π ΡΡΠ°ΡΡΠ΅
ΠΠ°Π»ΡΡΠ΅ ΠΌΡ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ ΠΊΠ°ΠΊ ΠΏΠΈΡΠ°ΡΡ ΠΈ Π·Π°Π³ΡΡΠΆΠ°ΡΡ ΡΠΈΠ»ΡΡΡΡ Π΄Π»Ρ seccomp
Π½Π° Π³ΠΎΠ»ΠΎΠΌ C ΠΈ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ libseccomp
ΠΈ ΠΊΠ°ΠΊΠΈΠ΅ ΠΏΠ»ΡΡΡ ΠΈ ΠΌΠΈΠ½ΡΡΡ Π΅ΡΡΡ Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²Π°ΡΠΈΠ°Π½ΡΠ°, Π° Π½Π°ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠΊ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ ΠΊΠ°ΠΊ seccomp ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΎΠΉ strace
.
ΠΠΈΡΠ΅ΠΌ ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ ΡΠΈΠ»ΡΡΡΡ Π΄Π»Ρ seccomp
ΠΡ ΡΠΆΠ΅ ΡΠΌΠ΅Π΅ΠΌ ΠΏΠΈΡΠ°ΡΡ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΠΈ ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ ΡΠ½Π°ΡΠ°Π»Π° Π½Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ seccomp. Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠΈΠ»ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΠΏΡΠΈ ΡΡΠΎΠΌ Π²ΡΠ΅ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΡ Π±ΡΠ΄ΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ. ΠΠ΅Π»Π°Π΅ΡΡΡ ΡΡΠΎ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° seccomp(2)
seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)
Π³Π΄Π΅ &filter
β ΡΡΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΡΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡΡ Π½Π°ΠΌ ΡΡΡΡΠΊΡΡΡΡ struct sock_fprog
, Ρ.Π΅. ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ BPF.
Π§Π΅ΠΌ ΠΆΠ΅ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π΄Π»Ρ seccomp ΠΎΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ Π΄Π»Ρ ΡΠΎΠΊΠ΅ΡΠΎΠ²? ΠΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠΎΠΌ. Π ΡΠ»ΡΡΠ°Π΅ ΡΠΎΠΊΠ΅ΡΠΎΠ², Π½Π°ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π»Π°ΡΡ ΠΎΠ±Π»Π°ΡΡΡ ΠΏΠ°ΠΌΡΡΠΈ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠ°Ρ ΠΏΠ°ΠΊΠ΅Ρ, Π° Π² ΡΠ»ΡΡΠ°Π΅ seccomp Π½Π°ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ ΡΡΡΡΠΊΡΡΡΠ° Π²ΠΈΠ΄Π°
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
ΠΠ΄Π΅ΡΡ nr
β ΡΡΠΎ Π½ΠΎΠΌΠ΅Ρ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌΠΎΠ³ΠΎ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π°, arch
β ΡΠ΅ΠΊΡΡΠ°Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° (ΠΎΠ± ΡΡΠΎΠΌ Π½ΠΈΠΆΠ΅), args
β Π΄ΠΎ ΡΠ΅ΡΡΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π°, Π° instruction_pointer
β ΡΡΠΎ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΈΠ½ΡΡΡΡΠΊΡΠΈΡ Π² ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ΄Π΅Π»Π°Π»Π° Π΄Π°Π½Π½ΡΠΉ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠΉ Π²ΡΠ·ΠΎΠ². Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎΠ±Ρ Π·Π°Π³ΡΡΠ·ΠΈΡΡ Π½ΠΎΠΌΠ΅Ρ ΡΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° Π² ΡΠ΅Π³ΠΈΡΡΡ A
ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΊΠ°Π·Π°ΡΡ
ldw [0]
ΠΠ»Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ seccomp ΡΡΡΠ΅ΡΡΠ²ΡΡΡ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ΅Π½ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎ 32-Π±ΠΈΡΠ½ΠΎΠΌΡ Π²ΡΡΠ°Π²Π½ΠΈΠ²Π°Π½ΠΈΡ ΠΈ Π½Π΅Π»ΡΠ·Ρ Π·Π°Π³ΡΡΠΆΠ°ΡΡ ΠΏΠΎΠ»-ΡΠ»ΠΎΠ²Π° ΠΈΠ»ΠΈ Π±Π°ΠΉΡ β ΠΏΡΠΈ ΠΏΠΎΠΏΡΡΠΊΠ΅ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΡΠΈΠ»ΡΡΡ ldh [0]
ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠΉ Π²ΡΠ·ΠΎΠ² seccomp
Π²Π΅ΡΠ½Π΅Ρ EINVAL
. ΠΡΠΎΠ²Π΅ΡΠΊΡ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΡ
ΡΠΈΠ»ΡΡΡΠΎΠ² Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΡ seccomp_check_filter()
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 Sequence Number 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 ΠΈ Π·Π°Π³Π»ΡΠ½ΡΡΡ Π² Π±ΡΠ΄ΡΡΠ΅Π΅.
ΠΡΠΎΡΠ°Π½ΠΈΠ΅ Ρ classic BPF
ΠΡ ΠΏΠΎΡΠΌΠΎΡΡΠ΅Π»ΠΈ Π½Π° ΡΠΎ, ΠΊΠ°ΠΊ ΡΠ΅Ρ
Π½ΠΎΠ»ΠΎΠ³ΠΈΡ BPF, ΡΠ°Π·ΡΠ°Π±ΠΎΡΠ°Π½Π½Π°Ρ Π² Π½Π°ΡΠ°Π»Π΅ Π΄Π΅Π²ΡΠ½ΠΎΡΡΡΡ
ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΏΡΠΎΠΆΠΈΠ»Π° ΡΠ΅ΡΠ²Π΅ΡΡΡ Π²Π΅ΠΊΠ° ΠΈ Π΄ΠΎ ΠΊΠΎΠ½ΡΠ° Π½Π°Ρ
ΠΎΠ΄ΠΈΠ»Π° Π½ΠΎΠ²ΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ. ΠΠ΄Π½Π°ΠΊΠΎ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄Ρ ΡΠΎ ΡΡΠ΅ΠΊΠΎΠ²ΡΡ
ΠΌΠ°ΡΠΈΠ½ Π½Π° RISC, ΠΏΠΎΡΠ»ΡΠΆΠΈΠ²ΡΠ΅ΠΌΡ ΡΠΎΠ»ΡΠΊΠΎΠΌ ΠΊ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF, Π² Π΄Π²ΡΡ
ΡΡΡΡΡΠ½ΡΠ΅ ΡΠ»ΡΡΠΈΠ»ΡΡ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ Ρ 32-Π±ΠΈΡΠ½ΡΡ
Π½Π° 64-Π±ΠΈΡΠ½ΡΠ΅ ΠΌΠ°ΡΠΈΠ½Ρ ΠΈ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ BPF ΡΡΠ°Π» ΡΡΡΠ°ΡΠ΅Π²Π°ΡΡ. ΠΡΠΎΠΌΠ΅ ΡΡΠΎΠ³ΠΎ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF ΡΠΈΠ»ΡΠ½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Ρ ΠΈ ΠΏΠΎΠΌΠΈΠΌΠΎ ΡΡΡΠ°ΡΠ΅Π²ΡΠ΅ΠΉ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ β Ρ Π½Π°Ρ Π½Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠΎΡ
ΡΠ°Π½ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ·ΠΎΠ²Π°ΠΌΠΈ BPF ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌ, Π½Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΠΏΡΡΠΌΠΎΠ³ΠΎ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ, Π½Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΡΠ΄ΡΠΎΠΌ, ΠΊΡΠΎΠΌΠ΅ ΡΡΠ΅Π½ΠΈΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΏΠΎΠ»Π΅ΠΉ ΡΡΡΡΠΊΡΡΡΡ sk_buff
ΠΈ Π·Π°ΠΏΡΡΠΊΠ° ΠΏΡΠΎΡΡΠ΅ΠΉΡΠΈΡ
ΡΡΠ½ΠΊΡΠΈΠΉ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΎΠ², Π½Π΅Π»ΡΠ·Ρ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ² ΠΈ ΠΏΠ΅ΡΠ΅Π°Π΄ΡΠ΅ΡΠΎΠ²ΡΠ²Π°ΡΡ ΠΈΡ
.
ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅, Π² Π½Π°ΡΡΠΎΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ ΠΎΡ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ BPF Π² Linux ΠΎΡΡΠ°Π»ΡΡ ΡΠΎΠ»ΡΠΊΠΎ API ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ, Π° Π²Π½ΡΡΡΠΈ ΡΠ΄ΡΠ° Π²ΡΠ΅ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, Π±ΡΠ΄Ρ ΡΠΎ ΡΠΈΠ»ΡΡΡΡ ΡΠΎΠΊΠ΅ΡΠΎΠ² ΠΈΠ»ΠΈ ΡΠΈΠ»ΡΡΡΡ seccomp, Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠ°Π½ΡΠ»ΠΈΡΡΡΡΡΡ Π² Π½ΠΎΠ²ΡΠΉ ΡΠΎΡΠΌΠ°Ρ, Extended BPF. (ΠΡ ΡΠ°ΡΡΠΊΠ°ΠΆΠ΅ΠΌ ΠΏΡΠΎ ΡΠΎ ΠΊΠ°ΠΊ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΡΠΎ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π² ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ ΡΡΠ°ΡΡΠ΅.)
ΠΠ΅ΡΠ΅Ρ
ΠΎΠ΄ Π½Π° Π½ΠΎΠ²ΡΡ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ Π½Π°ΡΠ°Π»ΡΡ Π² 2013 Π³ΠΎΠ΄Ρ, ΠΊΠΎΠ³Π΄Π° ΠΠ»Π΅ΠΊΡΠ΅ΠΉ Π‘ΡΠ°ΡΠΎΠ²ΠΎΠΉΡΠΎΠ² ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΠ» ΡΡ
Π΅ΠΌΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ BPF. Π 2014 Π³ΠΎΠ΄Ρ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠ΅ ΠΏΠ°ΡΡΠΈ
ΠΠ°Π»ΡΠ½Π΅ΠΉΡΠΈΠ΅ ΡΡΠ°ΡΡΠΈ Π² ΡΡΠΎΠΉ ΡΠ΅ΡΠΈΠΈ ΡΠ°ΡΡΠΊΠ°ΠΆΡΡ ΠΎΠ± Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ΅ ΠΈ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡΡ Π½ΠΎΠ²ΠΎΠΉ ΡΠ΅Ρ Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ, ΠΈΠ·Π½Π°ΡΠ°Π»ΡΠ½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎΠΉ ΠΊΠ°ΠΊ internal BPF, Π·Π°ΡΠ΅ΠΌ extended BPF, Π° ΡΠ΅ΠΏΠ΅ΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΡΡΠΎ BPF.
Π‘ΡΡΠ»ΠΊΠΈ
- Steven McCanne and Van Jacobson, "The BSD Packet Filter: A New Architecture for User-level Packet Capture",
https://www.tcpdump.org/papers/bpf-usenix93.pdf
- Steven McCanne, "libpcap: An Architecture and Optimization Methodology for Packet Capture",
https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
tcpdump
,libpcap
:https://www.tcpdump.org/ IPtable U32 Match Tutorial .- BPF β the forgotten bytecode:
https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
- Introducing the BPF Tool:
https://blog.cloudflare.com/introducing-the-bpf-tools/
bpf_cls
:http://man7.org/linux/man-pages/man8/tc-bpf.8.html
- A seccomp overview:
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: a look under the hood",
https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
netsniff-ng
:http://netsniff-ng.org/
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com