BPF เบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ, เบชเปˆเบงเบ™เบชเบนเบ™: BPF เบ„เบฅเบฒเบชเบชเบดเบ

Berkeley Packet Filters (BPF) เป€เบ›เบฑเบ™เป€เบ—เบเป‚เบ™เป‚เบฅเบเบต kernel Linux เบ—เบตเปˆเป„เบ”เป‰เบขเบนเปˆเปƒเบ™เบซเบ™เป‰เบฒเบ”เป‰เบฒเบ™เบซเบ™เป‰เบฒเบ‚เบญเบ‡เบชเบดเปˆเบ‡เบžเบดเบกเป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบตเบžเบฒเบชเบฒเบญเบฑเบ‡เบเบดเบ”เบชเปเบฒเบฅเบฑเบšเป€เบงเบฅเบฒเบซเบผเบฒเบเบ›เบตเปเบฅเป‰เบง. เบเบญเบ‡เบ›เบฐเบŠเบธเบกเปเบกเปˆเบ™เป€เบ•เบฑเบกเป„เบ›เบ”เป‰เบงเบเบšเบปเบ”เบฅเบฒเบเบ‡เบฒเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปเบฅเบฐเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ BPF. David Miller, เบœเบนเป‰เบฎเบฑเบเบชเบฒเบฅเบฐเบšเบปเบšเบเปˆเบญเบเป€เบ„เบทเบญเบ‚เปˆเบฒเบ Linux, เป‚เบ—เบซเบฒเบเบฒเบ™เบชเบปเบ™เบ—เบฐเบ™เบฒเบ‚เบญเบ‡เบฅเบฒเบงเบขเบนเปˆเบ—เบตเปˆ Linux Plumbers 2018 "เบเบฒเบ™เบชเบปเบ™เบ—เบฐเบ™เบฒเบ™เบตเป‰เบšเปเปˆเปเบกเปˆเบ™เบเปˆเบฝเบงเบเบฑเบš XDP" (XDP เปเบกเปˆเบ™เบเปเบฅเบฐเบ™เบตเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบซเบ™เบถเปˆเบ‡เบชเปเบฒเบฅเบฑเบš BPF). Brendan Gregg เปƒเบซเป‰โ€‹เบเบฒเบ™โ€‹เป€เบˆโ€‹เบฅเบฐโ€‹เบˆเบฒโ€‹เบ—เบตเปˆโ€‹เบกเบตโ€‹เบชเบดเบ” Linux BPF Superpowers. Toke Hรธiland-Jรธrgensen เบซเบปเบงเบงเปˆเบฒ kernel เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เป€เบ›เบฑเบ™ microkernel. Thomas Graf เบชเบปเปˆเบ‡เป€เบชเบตเบกเบ„เบงเบฒเบกเบ„เบดเบ”เบ—เบตเปˆเบงเปˆเบฒ BPF เปเบกเปˆเบ™ javascript เบชเปเบฒเบฅเบฑเบš kernel.

เบเบฑเบ‡เบšเปเปˆเบ—เบฑเบ™เบกเบตเบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ—เบตเปˆเป€เบ›เบฑเบ™เบฅเบฐเบšเบปเบšเบ‚เบญเบ‡ BPF เปƒเบ™Habrรฉ, เปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เปƒเบ™เบŠเบธเบ”เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบˆเบฐเบžเบฐเบเบฒเบเบฒเบกเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบ›เบฐเบซเบงเบฑเบ”เบชเบฒเบ”เบ‚เบญเบ‡เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบต, เบญเบฐเบ—เบดเบšเบฒเบเบเปˆเบฝเบงเบเบฑเบšเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปเบฅเบฐเป€เบ„เบทเปˆเบญเบ‡เบกเบทเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ, เปเบฅเบฐเบเปเบฒเบ™เบปเบ”เบ‚เบญเบšเป€เบ‚เบ”เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปเบฅเบฐเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ BPF. เบšเบปเบ”เบ‚เบฝเบ™เบ™เบตเป‰, เบชเบนเบ™, เปƒเบ™เบŠเบธเบ”, เบšเบญเบเบ›เบฐเบซเบงเบฑเบ”เบชเบฒเบ”เปเบฅเบฐเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเบ‚เบญเบ‡ BPF เบ„เบฅเบฒเบชเบชเบดเบ, เปเบฅเบฐเบเบฑเบ‡เป€เบ›เบตเบ”เป€เบœเบตเบเบ„เบงเบฒเบกเบฅเบฑเบšเบ‚เบญเบ‡เบซเบผเบฑเบเบเบฒเบ™เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ‚เบญเบ‡เบกเบฑเบ™. tcpdump, seccomp, strace, เปเบฅเบฐเบญเบทเปˆเบ™เป†เบญเบตเบ.

เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ BPF เปเบกเปˆเบ™เบ„เบงเบšเบ„เบธเบกเป‚เบ”เบเบŠเบธเบกเบŠเบปเบ™เป€เบ„เบทเบญเบ‚เปˆเบฒเบ Linux, เบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเบ—เบตเปˆเบกเบตเบขเบนเปˆเบ•เบปเป‰เบ™เบ•เปเบ‚เบญเบ‡ BPF เปเบกเปˆเบ™เบเปˆเบฝเบงเบ‚เป‰เบญเบ‡เบเบฑเบšเป€เบ„เบทเบญเบ‚เปˆเบฒเบเปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”. @eucariot, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบญเบตเป‰เบ™เบŠเบธเบ” "BPF เบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ", เป€เบžเบทเปˆเบญเบเบฝเบ”เบชเบฑเบเบชเบตเบ‚เบญเบ‡เบŠเบธเบ”เบ—เบตเปˆเบเบดเปˆเบ‡เปƒเบซเบเปˆ "เป€เบ„เบทเบญเบ‚เปˆเบฒเบเบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ".

เบซเบผเบฑเบเบชเบนเบ”เป„เบฅเบเบฐเบชเบฑเป‰เบ™เปƒเบ™เบ›เบฐเบซเบงเบฑเบ”เบชเบฒเบ”เบ‚เบญเบ‡ BPF (c)

เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบต BPF เบ—เบตเปˆเบ—เบฑเบ™เบชเบฐเป„เบซเบกเปเบกเปˆเบ™เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡เปเบฅเบฐเบ‚เบฐเบซเบเบฒเบเบ‚เบญเบ‡เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบตเป€เบเบปเปˆเบฒเบ—เบตเปˆเบกเบตเบŠเบทเปˆเบ”เบฝเบงเบเบฑเบ™, เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เป€เบญเบตเป‰เบ™เบงเปˆเบฒ BPF เบ„เบฅเบฒเบชเบชเบดเบเป€เบžเบทเปˆเบญเบซเบผเบตเบเป€เบงเบฑเป‰เบ™เบเบฒเบ™เบชเบฑเบšเบชเบปเบ™. เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เบ—เบตเปˆเบกเบตเบŠเบทเปˆเบชเบฝเบ‡เป„เบ”เป‰เบ–เบทเบเบชเป‰เบฒเบ‡เบ‚เบทเป‰เบ™เป‚เบ”เบเบญเบตเบ‡เปƒเบชเปˆ BPF เบ„เบฅเบฒเบชเบชเบดเบ tcpdump, เบเบปเบ™เป„เบ seccomp, เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบ™เบเบฑเบšเป‚เบกเบ”เบนเบ™เบ—เบตเปˆเบฎเบนเป‰เบˆเบฑเบเบซเบ™เป‰เบญเบ xt_bpf เบเบฒเบ™ iptables เปเบฅเบฐเบเบฒเบ™เบˆเบฑเบ”เบ›เบฐเป€เบžเบ” cls_bpf. เปƒเบ™ Linux เบ—เบตเปˆเบ—เบฑเบ™เบชเบฐเป„เบซเบก, เป‚เบ„เบ‡เบเบฒเบ™ BPF เบ„เบฅเบฒเบชเบชเบดเบเบ–เบทเบเปเบ›เป‚เบ”เบเบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เปƒเบ™เบฎเบนเบšเปเบšเบšเปƒเบซเบกเปˆ, เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบˆเบฒเบเบ—เบฑเบ”เบชเบฐเบ™เบฐเบ‚เบญเบ‡เบœเบนเป‰เปƒเบŠเป‰, API เบเบฑเบ‡เบ„เบปเบ‡เบขเบนเปˆเปƒเบ™เบชเบฐเบ–เบฒเบ™เบ—เบตเปˆเปเบฅเบฐเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปƒเบซเบกเปˆเบชเปเบฒเบฅเบฑเบš BPF เบ„เบฅเบฒเบชเบชเบดเบ, เบ”เบฑเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบซเบฑเบ™เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰, เบเบฑเบ‡เบ–เบทเบเบžเบปเบšเป€เบซเบฑเบ™. เบชเปเบฒเบฅเบฑเบšเป€เบซเบ”เบœเบปเบ™เบ™เบตเป‰, เปเบฅเบฐเบเป‰เบญเบ™เบงเปˆเบฒเบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบฒเบกเบ›เบฐเบซเบงเบฑเบ”เบชเบฒเบ”เบ‚เบญเบ‡เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ BPF เบ„เบฅเบฒเบชเบชเบดเบเปƒเบ™ Linux, เบกเบฑเบ™เบˆเบฐเบเบฒเบเป€เบ›เบฑเบ™เบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™เบเบงเปˆเบฒเบงเบดเบ—เบตเบเบฒเบ™เปเบฅเบฐเป€เบซเบ”เบœเบปเบ™เบ—เบตเปˆเบกเบฑเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเป„เบ›เบชเบนเปˆเบฎเบนเบšเปเบšเบšเบ—เบตเปˆเบ—เบฑเบ™เบชเบฐเป„เบซเบก, เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบ•เบฑเบ”เบชเบดเบ™เปƒเบˆเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบเบšเบปเบ”เบ„เบงเบฒเบกเบเปˆเบฝเบงเบเบฑเบš BPF เบ„เบฅเบฒเบชเบชเบดเบ.

เปƒเบ™เบ•เบญเบ™เบ—เป‰เบฒเบเบ‚เบญเบ‡เปเบ›เบ”เบชเบดเบšเบ‚เบญเบ‡เบชเบฐเบ•เบฐเบงเบฑเบ”เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ, เบงเบดเบชเบฐเบงเบฐเบเบญเบ™เบˆเบฒเบเบซเป‰เบญเบ‡เบ—เบปเบ”เบฅเบญเบ‡ Lawrence Berkeley เบ—เบตเปˆเบกเบตเบŠเบทเปˆเบชเบฝเบ‡เป„เบ”เป‰เบกเบตเบ„เบงเบฒเบกเบชเบปเบ™เปƒเบˆเปƒเบ™เบ„เปเบฒเบ–เบฒเบกเบเปˆเบฝเบงเบเบฑเบšเบงเบดเบ—เบตเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เป€เบ„เบทเบญเบ‚เปˆเบฒเบเบขเปˆเบฒเบ‡เบ–เบทเบเบ•เป‰เบญเบ‡เบเปˆเบฝเบงเบเบฑเบšเบฎเบฒเบ”เปเบงเบ—เบตเปˆเบ—เบฑเบ™เบชเบฐเป„เบซเบกเปƒเบ™เบ—เป‰เบฒเบเบชเบฐเบ•เบฐเบงเบฑเบ”เบ—เบตเปˆเปเบ›เบ”เบชเบดเบšเบ‚เบญเบ‡เบชเบฐเบ•เบฐเบงเบฑเบ”เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ. เปเบ™เบงเบ„เบงเบฒเบกเบ„เบดเบ”เบžเบทเป‰เบ™เบ–เบฒเบ™เบ‚เบญเบ‡เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡, เปƒเบ™เป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™เป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เปƒเบ™เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบต CSPF (CMU / Stanford Packet Filter), เปเบกเปˆเบ™เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เบ—เบตเปˆเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เป„เบงเป€เบ—เบปเปˆเบฒเบ—เบตเปˆเบˆเบฐเป„เบงเป„เบ”เป‰, i.e. เปƒเบ™เบžเบทเป‰เบ™เบ—เบตเปˆ kernel, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบ™เบตเป‰เบซเบผเบตเบเป€เบงเบฑเป‰เบ™เบเบฒเบ™เบ„เบฑเบ”เบฅเบญเบเบ‚เปเป‰เบกเบนเบ™เบ—เบตเปˆเบšเปเปˆเบˆเปเบฒเป€เบ›เบฑเบ™เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบžเบทเป‰เบ™เบ—เบตเปˆเบœเบนเป‰เปƒเบŠเป‰. เป€เบžเบทเปˆเบญเบชเบฐเบซเบ™เบญเบ‡เบ„เบงเบฒเบกเบ›เบญเบ”เป„เบž runtime เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เปเบฅเปˆเบ™เบฅเบฐเบซเบฑเบ”เบœเบนเป‰เปƒเบŠเป‰เบขเบนเปˆเปƒเบ™เบžเบทเป‰เบ™เบ—เบตเปˆเปเบเปˆเบ™, เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ virtual sandboxed เป„เบ”เป‰เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰.

เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ virtual เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบกเบตเบขเบนเปˆเปเบฅเป‰เบงเป„เบ”เป‰เบ–เบทเบเบญเบญเบเปเบšเบšเป€เบžเบทเปˆเบญเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ stack-based เปเบฅเบฐเบšเปเปˆเป„เบ”เป‰เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบขเปˆเบฒเบ‡เบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเปƒเบ™เป€เบ„เบทเปˆเบญเบ‡ RISC เบฎเบธเปˆเบ™เปƒเบซเบกเปˆ. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เป‚เบ”เบเบœเปˆเบฒเบ™เบ„เบงเบฒเบกเบžเบฐเบเบฒเบเบฒเบกเบ‚เบญเบ‡เบงเบดเบชเบฐเบงเบฐเบเบญเบ™เบˆเบฒเบ Berkeley Labs, เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบต BPF (Berkeley Packet Filters) เปƒเบซเบกเปˆเป„เบ”เป‰เบ–เบทเบเบžเบฑเบ”เบ—เบฐเบ™เบฒ, เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ virtual เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบ—เบตเปˆเบ–เบทเบเบญเบญเบเปเบšเบšเป‚เบ”เบเบญเบตเบ‡เปƒเบชเปˆเป‚เบ›เป€เบŠเบ”เป€เบŠเบต Motorola 6502 - workhorse เบ‚เบญเบ‡เบœเบฐเบฅเบดเบ”เบ•เบฐเบžเบฑเบ™เบ—เบตเปˆเบกเบตเบŠเบทเปˆเบชเบฝเบ‡เป€เบŠเบฑเปˆเบ™: Apple II เบซเบผเบท NES. เป€เบ„เบทเปˆเบญเบ‡ virtual เปƒเบซเบกเปˆเป„เบ”เป‰เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบซเบผเบฒเบเบชเบดเบšเป€เบ—เบทเปˆเบญเป€เบกเบทเปˆเบญเบ—เบฝเบšเบเบฑเบšเบเบฒเบ™เปเบเป‰เป„เบ‚เบ—เบตเปˆเบกเบตเบขเบนเปˆ.

เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเป€เบ„เบทเปˆเบญเบ‡ BPF

เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป„เบ”เป‰เบฎเบนเป‰เบˆเบฑเบเบเบฑเบšเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเปƒเบ™เบงเบดเบ—เบตเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบ, เบเบฒเบ™เบงเบดเป€เบ„เบฒเบฐเบ•เบปเบงเบขเปˆเบฒเบ‡. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เป€เบžเบทเปˆเบญเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ”เป‰เบงเบ, เปƒเบซเป‰เป€เบงเบปเป‰เบฒเบงเปˆเบฒเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบกเบตเบชเบญเบ‡เบ—เบฐเบšเบฝเบ™ 32-bit เบ—เบตเปˆเบชเบฒเบกเบฒเบ”เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบœเบนเป‰เปƒเบŠเป‰เป„เบ”เป‰, เป€เบ„เบทเปˆเบญเบ‡เบชเบฐเบชเบปเบก. A เปเบฅเบฐเบ—เบฐเบšเบฝเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต X, 64 bytes เบ‚เบญเบ‡เบซเบ™เปˆเบงเบเบ„เบงเบฒเบกเบˆเปเบฒ (16 เบ„เปเบฒ), เบกเบตเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ‚เบฝเบ™เปเบฅเบฐเบเบฒเบ™เบญเปˆเบฒเบ™เบ•เปเปˆเบกเบฒ, เปเบฅเบฐเบฅเบฐเบšเบปเบšเบ‚เบฐเบซเบ™เบฒเบ”เบ™เป‰เบญเบเบ‚เบญเบ‡เบ„เปเบฒเบชเบฑเปˆเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบงเบฑเบ”เบ–เบธเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰. เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบเบฒเบ™เป‚เบ”เบ”เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบเบ•เบฒเบกเป€เบ‡เบทเปˆเบญเบ™เป„เบ‚เบเปเปˆเบกเบตเบขเบนเปˆเปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™, เปเบ•เปˆเป€เบžเบทเปˆเบญเบฎเบฑเบšเบ›เบฐเบเบฑเบ™เบเบฒเบ™เบชเปเบฒเป€เบฅเบฑเบ”เบ•เบฒเบกเป€เบงเบฅเบฒเบ‚เบญเบ‡เป‚เบ„เบ‡เบเบฒเบ™, เบเบฒเบ™เบเบฐเป‚เบ”เบ”เบžเบฝเบ‡เปเบ•เปˆเบชเบฒเบกเบฒเบ”เบเป‰เบฒเบงเป„เบ›เบ‚เป‰เบฒเบ‡เบซเบ™เป‰เบฒ, i.e. เป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐ, เบกเบฑเบ™เบ–เบทเบเบซเป‰เบฒเบกเบšเปเปˆเปƒเบซเป‰เบชเป‰เบฒเบ‡ loops.

เป‚เบ„เบ‡เบเบฒเบ™เบ—เบปเปˆเบงเป„เบ›เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เป€เบ„เบทเปˆเบญเบ‡เปเบกเปˆเบ™เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰. เบœเบนเป‰เปƒเบŠเป‰เบชเป‰เบฒเบ‡เป‚เบ„เบ‡เบเบฒเบ™เบชเปเบฒเบฅเบฑเบšเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ BPF เปเบฅเบฐ, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ เบšเบฒเบ‡ เบเบปเบ™เป„เบ kernel (เป€เบŠเบฑเปˆเบ™: เบเบฒเบ™เป‚เบ—เบซเบฒเบฅเบฐเบšเบปเบš), เป‚เบซเบผเบ”เปเบฅเบฐเป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเป‚เบ„เบ‡เบเบฒเบ™เบเบฑเบš เบเบฑเบšเบšเบฒเบ‡ เป„เบ›เบซเบฒเบ•เบปเบงเบชเป‰เบฒเบ‡เป€เบซเบ”เบเบฒเบ™เปƒเบ™ kernel (เบ•เบปเบงเบขเปˆเบฒเบ‡, เป€เบซเบ”เบเบฒเบ™เปเบกเปˆเบ™เบเบฒเบ™เบกเบฒเบฎเบญเบ”เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เบ•เปเปˆเป„เบ›เปƒเบ™เบšเบฑเบ”เป€เบ„เบทเบญเบ‚เปˆเบฒเบ). เป€เบกเบทเปˆเบญเป€เบซเบ”เบเบฒเบ™เป€เบเบตเบ”เบ‚เบถเป‰เบ™, kernel เบ”เปเบฒเป€เบ™เบตเบ™เป‚เบ„เบ‡เบเบฒเบ™ (เบ•เบปเบงเบขเปˆเบฒเบ‡, เปƒเบ™เบ•เบปเบงเปเบ›), เปเบฅเบฐเบซเบ™เปˆเบงเบเบ„เบงเบฒเบกเบˆเปเบฒเบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเบˆเบฐเบเบปเบ‡เบเบฑเบš. เบเบฑเบšเบšเบฒเบ‡ เบžเบฒเบเบžเบทเป‰เบ™เบซเบ™เปˆเบงเบเบ„เบงเบฒเบกเบˆเปเบฒ kernel (เบ•เบปเบงเบขเปˆเบฒเบ‡, เบ‚เปเป‰เบกเบนเบ™เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เบ—เบตเปˆเป€เบ‚เบปเป‰เบฒเบกเบฒ).

เบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡เบˆเบฐเบžเบฝเบ‡เบžเปเบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบฎเบปเบฒเบ—เบตเปˆเบˆเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เป€เบšเบดเปˆเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡: เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบฎเบนเป‰เบˆเบฑเบเบเบฑเบšเบฅเบฐเบšเบปเบšเปเบฅเบฐเบฎเบนเบšเปเบšเบšเบ„เปเบฒเบชเบฑเปˆเบ‡เบ•เบฒเบกเบ„เบงเบฒเบกเบˆเปเบฒเป€เบ›เบฑเบ™. เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เบชเบถเบเบชเบฒเบฅเบฐเบšเบปเบšเบ„เปเบฒเบชเบฑเปˆเบ‡เบ‚เบญเบ‡เป€เบ„เบทเปˆเบญเบ‡ virtual เบ—เบฑเบ™เบ—เบตเปเบฅเบฐเบฎเบฝเบ™เบฎเบนเป‰เบเปˆเบฝเบงเบเบฑเบšเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบ‚เบญเบ‡เบกเบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบญเปˆเบฒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ•เบปเป‰เบ™เบชเบฐเบšเบฑเบš. BSD Packet Filter เปเบฅเบฐ/เบซเบผเบทเป€เบ„เบดเปˆเบ‡เบ—เบณเบญเบดเบ”เบ‚เบญเบ‡เป„เบŸเบฅเปŒ Documentation/networking/filter.txt เบˆเบฒเบเป€เบญเบเบฐเบชเบฒเบ™ kernel. เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเบถเบเบชเบฒเบเบฒเบ™เบ™เปเบฒเบชเบฐเป€เบซเบ™เบต libpcap: เป€เบ›เบฑเบ™เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ เปเบฅเบฐเบงเบดเบ—เบตเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบˆเบฑเบšเปเบžเบฑเบเป€เบเบฑเบ”, เปƒเบ™เบ—เบตเปˆ McCanne, เบซเบ™เบถเปˆเบ‡เปƒเบ™เบœเบนเป‰เบ‚เบฝเบ™เบ‚เบญเบ‡ BPF, เป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบ›เบฐเบซเบงเบฑเบ”เบชเบฒเบ”เบ‚เบญเบ‡เบเบฒเบ™เบชเป‰เบฒเบ‡ libpcap.

เบžเบงเบเป€เบฎเบปเบฒเบชเบทเบšเบ•เปเปˆเบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ BPF เบ„เบฅเบฒเบชเบชเบดเบเปƒเบ™ Linux: tcpdump (libpcap), seccomp, xt_bpf, cls_bpf.

tcpdump

เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ‚เบญเบ‡ BPF เป„เบ”เป‰เบ–เบทเบเบ›เบฐเบ•เบดเบšเบฑเบ”เปƒเบ™เบ‚เบฐเบซเบ™เบฒเบ™เบเบฑเบšเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ‚เบญเบ‡ frontend เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบŠเบญเบ‡ - เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เบ—เบตเปˆเบกเบตเบŠเบทเปˆเบชเบฝเบ‡. tcpdump. เปเบฅเบฐ, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเป€เบเบปเปˆเบฒเปเบเปˆเบ—เบตเปˆเบชเบธเบ”เปเบฅเบฐเบกเบตเบŠเบทเปˆเบชเบฝเบ‡เบ—เบตเปˆเบชเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ BPF เบ„เบฅเบฒเบชเบชเบดเบ, เบ—เบตเปˆเบกเบตเบขเบนเปˆเปƒเบ™เบซเบผเบฒเบเป†เบฅเบฐเบšเบปเบšเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบเบฒเบ™เบชเบถเบเบชเบฒเป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบตเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบเบฑเบšเบกเบฑเบ™.

(เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เปเบฅเปˆเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰เบเปˆเบฝเบงเบเบฑเบš Linux 5.6.0-rc6. เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบ‚เบญเบ‡เบšเบฒเบ‡เบ„เปเบฒเบชเบฑเปˆเบ‡เป„เบ”เป‰เบ–เบทเบเบ”เบฑเบ”เปเบเป‰เป€เบžเบทเปˆเบญเปƒเบซเป‰เบชเบฒเบกเบฒเบ”เบญเปˆเบฒเบ™เป„เบ”เป‰เบ”เบตเบ‚เบถเป‰เบ™.)

เบ•เบปเบงเบขเปˆเบฒเบ‡: เบเบฒเบ™เบชเบฑเบ‡เป€เบเบ”เปเบžเบฑเบเป€เบเบฑเบ” IPv6

เปƒเบซเป‰เบˆเบดเบ™เบ•เบฐเบ™เบฒเบเบฒเบ™เบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบšเบดเปˆเบ‡เบŠเบธเบ” IPv6 เบ—เบฑเบ‡เบซเบกเบปเบ”เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš eth0. เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบชเบดเปˆเบ‡เบ™เบตเป‰, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เป‚เบ„เบ‡เบเบฒเบ™ tcpdump เบ”เป‰เบงเบเบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบ ip6:

$ sudo tcpdump -i eth0 ip6

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบˆเบถเปˆเบ‡ tcpdump เบฅเบงเบšเบฅเบงเบกเบ•เบปเบงเบเบญเบ‡ ip6 เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™ bytecode เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐ BPF เปเบฅเบฐเบชเบปเปˆเบ‡เบกเบฑเบ™เป„เบ›เบซเบฒ kernel (เป€เบšเบดเปˆเบ‡เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เปƒเบ™เบžเบฒเบ Tcpdump: เบเบณเบฅเบฑเบ‡เป‚เบซเบผเบ”). เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเป‚เบซเบฅเบ”เบˆเบฐเบ–เบทเบเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบชเปเบฒเบฅเบฑเบšเบ—เบธเบเป†เปเบžเบฑเบเป€เบเบฑเบ”เบ—เบตเปˆเบœเปˆเบฒเบ™เบญเบดเบ™เป€เบ•เบตเป€เบŸเบ” eth0. เบ–เป‰เบฒเบ•เบปเบงเบเบญเบ‡เบชเบปเปˆเบ‡เบ„เบทเบ™เบ„เปˆเบฒเบ—เบตเปˆเบšเปเปˆเปเบกเปˆเบ™เบชเบนเบ™ n, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เป€เบ–เบดเบ‡ n bytes เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เบˆเบฐเบ–เบทเบเบ„เบฑเบ”เบฅเบญเบเปƒเบชเปˆเบžเบทเป‰เบ™เบ—เบตเปˆเบœเบนเป‰เปƒเบŠเป‰เปเบฅเบฐเบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบซเบฑเบ™เบกเบฑเบ™เบขเบนเปˆเปƒเบ™เบœเบปเบ™เบœเบฐเบฅเบดเบ” tcpdump.

BPF เบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ, เบชเปˆเบงเบ™เบชเบนเบ™: BPF เบ„เบฅเบฒเบชเบชเบดเบ

เบกเบฑเบ™ turns เปƒเบซเป‰ เป€เบซเบฑเบ™ เบงเปˆเบฒ เบžเบงเบ เป€เบฎเบปเบฒ เป„เบ”เป‰ เบขเปˆเบฒเบ‡ เบ‡เปˆเบฒเบ เบ”เบฒเบ เบชเบฒ เบกเบฒเบ” เบŠเบญเบ เบซเบฒ เบ—เบตเปˆ bytecode เบ–เบทเบ เบชเบปเปˆเบ‡ เป„เบ› เบซเบฒ kernel 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)th byte เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เป€เบ„เบทเบญเบ‚เปˆเบฒเบเบงเบดเป€เบ„เบฒเบฐ. เบžเบงเบเป€เบฎเบปเบฒเบญเปˆเบฒเบ™เปเบžเบฑเบเป€เบเบฑเบ”เบˆเบฒเบเบญเบดเบ™เป€เบ•เบตเป€เบŸเบ”เบญเบตเป€เบ—เบตเป€เบ™เบฑเบ” eth0เปเบฅเบฐเบ™เบตเป‰ เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒpacket เป€เบšเบดเปˆเบ‡เบ„เบทเบงเปˆเบฒเบ™เบตเป‰ (เบชเปเบฒเบฅเบฑเบšเบ„เบงเบฒเบกเบ‡เปˆเบฒเบเบ”เบฒเบ, เบžเบงเบเป€เบฎเบปเบฒเบชเบปเบกเบกเบธเบ”เบงเปˆเบฒเบšเปเปˆเบกเบตเปเบ—เบฑเบ VLAN เปƒเบ™เปเบžเบฑเบเป€เบเบฑเบ”):

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

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบซเบผเบฑเบ‡เบˆเบฒเบเบ›เบฐเบ•เบดเบšเบฑเบ”เบ„เปเบฒเบชเบฑเปˆเบ‡ ldh [12] เบขเบนเปˆเปƒเบ™เบ—เบฐเบšเบฝเบ™ A เบˆเบฐเบกเบตเบžเบฒเบเบชเบฐเบซเบ™เบฒเบก Ether Type โ€” เบ›เบฐโ€‹เป€เบžเบ”โ€‹เบ‚เบญเบ‡โ€‹เบŠเบญเบ‡โ€‹เบชเบปเปˆเบ‡โ€‹เปƒเบ™โ€‹เบเบญเบš Ethernet เบ™เบตเป‰โ€‹. เปƒเบ™เปเบ–เบงเบ—เบต 1 เบžเบงเบเป€เบฎเบปเบฒเบ›เบฝเบšเบ—เบฝเบšเป€เบ™เบทเป‰เบญเปƒเบ™เบ‚เบญเบ‡เบ—เบฐเบšเบฝเบ™ A (เบ›เบฐเป€เบžเบ”เบŠเบธเบ”) เบ„ 0x86ddเปเบฅเบฐเบ™เบตเป‰ เปเบฅเบฐเบกเบต เบ›เบฐเป€เบžเบ”เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเบปเบ™เปƒเบˆเปเบกเปˆเบ™ IPv6. เปƒเบ™เปเบ–เบงเบ—เบต 1, เบ™เบญเบเป€เบซเบ™เบทเบญเบˆเบฒเบเบ„เปเบฒเบชเบฑเปˆเบ‡เบ›เบฝเบšเบ—เบฝเบš, เบเบฑเบ‡เบกเบตเบชเบญเบ‡เบ–เบฑเบ™เบ•เบทเปˆเบกเบญเบตเบ - jt 2 ะธ jf 3 โ€” เป€เบ„เบทเปˆเบญเบ‡โ€‹เบซเบกเบฒเบโ€‹เบ—เบตเปˆโ€‹เบ—เปˆเบฒเบ™โ€‹เบˆเปเบฒโ€‹เป€เบ›เบฑเบ™โ€‹เบ•เป‰เบญเบ‡โ€‹เป„เบ›โ€‹เบ–เป‰เบฒโ€‹เบซเบฒเบโ€‹เบงเปˆเบฒโ€‹เบเบฒเบ™โ€‹เบ›เบฝเบšโ€‹เบ—เบฝเบšโ€‹เบชเบปเบšโ€‹เบœเบปเบ™โ€‹เบชเปเบฒโ€‹เป€เบฅเบฑเบ” (A == 0x86dd) เปเบฅเบฐโ€‹เบšเปเปˆโ€‹เบชเปเบฒโ€‹เป€เบฅเบฑเบ”โ€‹. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ—เบตเปˆเบชเปเบฒเป€เบฅเบฑเบ”เบœเบปเบ™ (IPv6) เบžเบงเบเป€เบฎเบปเบฒเป„เบ›เปเบ–เบง 2, เปเบฅเบฐเปƒเบ™เบเปเบฅเบฐเบ™เบตเบ—เบตเปˆเบšเปเปˆเบชเปเบฒเป€เบฅเบฑเบ” - เป„เบ›เปเบ–เบง 3. เปƒเบ™เปเบ–เบงเบ—เบต 3 เป‚เบ›เบฃเปเบเบฃเบกเบชเบดเป‰เบ™เบชเบธเบ”เบฅเบปเบ‡เบ”เป‰เบงเบเบฅเบฐเบซเบฑเบ” 0 (เบขเปˆเบฒเบ„เบฑเบ”เบฅเบญเบเปเบžเบฑเบเป€เบเบฑเบ”), เปƒเบ™เปเบ–เบงเบ—เบต 2 เป‚เบ›เบฃเปเบเบฃเบกเบˆเบฐเบชเบดเป‰เบ™เบชเบธเบ”เบ”เป‰เบงเบเบฅเบฐเบซเบฑเบ”. 262144 (เบ„เบฑเบ”เบฅเบญเบเบ‚เป‰เบญเบเบชเบนเบ‡เบชเบธเบ”เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ” 256 เบเบดเป‚เบฅเป„เบš).

เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบชเบฑเบšเบชเบปเบ™เบเบงเปˆเบฒ: เบžเบงเบเป€เบฎเบปเบฒเป€เบšเบดเปˆเบ‡เปเบžเบฑเบเป€เบเบฑเบ” TCP เป‚เบ”เบเบžเบญเบ”เบ›เบฒเบเบ—เบฒเบ‡

เบ‚เปเปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบ•เบปเบงเบเบญเบ‡เบกเบตเบฅเบฑเบเบชเบฐเบ™เบฐเปƒเบ”เบ—เบตเปˆเบ„เบฑเบ”เบฅเบญเบเบŠเบธเบ” TCP เบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเบกเบตเบžเบญเบ”เบ›เบฒเบเบ—เบฒเบ‡ 666. เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบžเบดเบˆเบฒเบฅเบฐเบ™เบฒเบเปเบฅเบฐเบ™เบต IPv4, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบเปเบฅเบฐเบ™เบต IPv6 เปเบกเปˆเบ™เบ‡เปˆเบฒเบเบ”เบฒเบเบเบงเปˆเบฒ. เบซเบผเบฑเบ‡เบˆเบฒเบเบเบฒเบ™เบชเบถเบเบชเบฒเบ•เบปเบงเบขเปˆเบฒเบ‡เบ™เบตเป‰, เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ„เบปเป‰เบ™เบซเบฒเบ•เบปเบงเบเบญเบ‡ IPv6 เบ•เบปเบงเบ—เปˆเบฒเบ™เป€เบญเบ‡เป€เบ›เบฑเบ™เบเบฒเบ™เบญเบญเบเบเปเบฒเบฅเบฑเบ‡เบเบฒเบ (ip6 and tcp dst port 666) เปเบฅเบฐเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบชเปเบฒเบฅเบฑเบšเบเปเบฅเบฐเบ™เบตเบ—เบปเปˆเบงเป„เบ› (tcp dst port 666). เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเบปเบ™เปƒเบˆเป€เบšเบดเปˆเบ‡เบ„เบทเบ”เบฑเปˆเบ‡เบ™เบตเป‰:

$ sudo tcpdump -i eth0 -d ip and tcp dst port 666
(000) ldh      [12]
(001) jeq      #0x800           jt 2    jf 10
(002) ldb      [23]
(003) jeq      #0x6             jt 4    jf 10
(004) ldh      [20]
(005) jset     #0x1fff          jt 10   jf 6
(006) ldxb     4*([14]&0xf)
(007) ldh      [x + 16]
(008) jeq      #0x29a           jt 9    jf 10
(009) ret      #262144
(010) ret      #0

เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เปเบฅเป‰เบงเบงเปˆเบฒเบชเบฒเบ 0 เปเบฅเบฐ 1 เป€เบฎเบฑเบ”เบซเบเบฑเบ‡เปเบ”เปˆ. เปƒเบ™เปเบ–เบงเบ—เบต 2 เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบเบงเบ”เป€เบšเบดเปˆเบ‡เปเบฅเป‰เบงเบงเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบŠเบธเบ” IPv4 (Ether Type = 0x800) เปเบฅเบฐโ€‹เป‚เบซเบผเบ”โ€‹เบกเบฑเบ™โ€‹เป€เบ‚เบปเป‰เบฒโ€‹เป„เบ›โ€‹เปƒเบ™โ€‹เบเบฒเบ™โ€‹เบˆเบปเบ”โ€‹เบ—เบฐโ€‹เบšเบฝเบ™โ€‹ A 24 byte เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”. เบŠเบธเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเป€เบšเบดเปˆเบ‡เบ„เบทเบงเปˆเบฒ

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

เบŠเบถเปˆเบ‡เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ”เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เบฐเบšเบฝเบ™ A เบžเบฒเบเบชเบฐเบซเบ™เบฒเบก Protocol เบ‚เบญเบ‡เบซเบปเบง IP, เบ—เบตเปˆเบกเบตเป€เบซเบ”เบœเบปเบ™, เป€เบžเบฒเบฐเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ„เบฑเบ”เบฅเบญเบเบžเบฝเบ‡เปเบ•เปˆเปเบžเบฑเบเป€เบเบฑเบ” TCP. เบžเบงเบเป€เบฎเบปเบฒเบ›เบฝเบšเบ—เบฝเบšเบญเบฐเบ™เบธเบชเบฑเบ™เบเบฒเบเบฑเบš 0x6 (IPPROTO_TCP) เปƒเบ™โ€‹เป€เบชเบฑเป‰เบ™ 3โ€‹.

เปƒเบ™เปเบ–เบงเบ—เบต 4 เปเบฅเบฐ 5 เบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ” halfwords เบ—เบตเปˆเบ•เบฑเป‰เบ‡เบขเบนเปˆเบ—เบตเปˆเบขเบนเปˆ 20 เปเบฅเบฐเปƒเบŠเป‰เบ„เปเบฒเบชเบฑเปˆเบ‡ jset เบเบงเบ”เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบซเบ™เบถเปˆเบ‡เปƒเบ™เบชเบฒเบกเปเบกเปˆเบ™เบ–เบทเบเบเปเบฒเบ™เบปเบ” เบ—เบธเบ‡ - เปƒเบชเปˆเปœเป‰เบฒเบเบฒเบเบญเบญเบ jset เบชเบฒเบก bits เบ—เบตเปˆเบชเปเบฒเบ„เบฑเบ™เบ—เบตเปˆเบชเบธเบ”เปเบกเปˆเบ™เป„เบ”เป‰เบ–เบทเบเป€เบเบฑเบšเบเบนเป‰. เบชเบญเบ‡เปƒเบ™เบชเบฒเบกเบšเบดเบ”เบšเบญเบเบžเบงเบเป€เบฎเบปเบฒเบงเปˆเบฒเปเบžเบฑเบเป€เบเบฑเบ”เปเบกเปˆเบ™เบชเปˆเบงเบ™เบซเบ™เบถเปˆเบ‡เบ‚เบญเบ‡เบŠเบธเบ” IP เบ—เบตเปˆเปเบ•เบเปเบเบ, เปเบฅเบฐเบ–เป‰เบฒเป€เบ›เบฑเบ™เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบšเปเปˆเบงเปˆเบฒเบˆเบฐเป€เบ›เบฑเบ™เบŠเบดเป‰เบ™เบชเบธเบ”เบ—เป‰เบฒเบ. เบšเบดเบ”เบ—เบตเบชเบฒเบกเบ–เบทเบเบชเบฐเบซเบ‡เบงเบ™เป„เบงเป‰ เปเบฅเบฐเบ•เป‰เบญเบ‡เป€เบ›เบฑเบ™เบชเบนเบ™. เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบšเปเปˆโ€‹เบ•เป‰เบญเบ‡โ€‹เบเบฒเบ™โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบเบงเบ”โ€‹เบชเบญเบšโ€‹เบ—เบฑเบ‡โ€‹เบซเบกเบปเบ”โ€‹เบšเปเปˆโ€‹เบ„เบปเบšโ€‹เบ–เป‰เบงเบ™โ€‹เบซเบผเบทโ€‹เปเบ•เบโ€‹, เบ”เบฑเปˆเบ‡โ€‹เบ™เบฑเป‰เบ™โ€‹เบžเบงเบโ€‹เป€เบฎเบปเบฒโ€‹เบเบงเบ”โ€‹เบชเบญเบšโ€‹เบ—เบฑเบ‡โ€‹เบชเบฒเบก bitsโ€‹.

เปเบ–เบงเบ—เบต 6 เปเบกเปˆเบ™เบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเบ—เบตเปˆเบชเบธเบ”เปƒเบ™เบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ™เบตเป‰. เบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบ ldxb 4*([14]&0xf) เบซเบกเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ”เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เบฐเบšเบฝเบ™ X เบชเบตเปˆเบšเบดเบ”เบ—เบตเปˆเบชเบณเบ„เบฑเบ™เปœเป‰เบญเบเบชเบธเบ”เบ‚เบญเบ‡เบชเบดเบšเบซเป‰เบฒเป„เบšเบ•เปŒเบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เบ„เบนเบ™เบ”เป‰เบงเบ 4. เบชเบตเปˆเบšเบดเบ”เบ—เบตเปˆเบชเบณเบ„เบฑเบ™เปœเป‰เบญเบเบชเบธเบ”เบ‚เบญเบ‡เป„เบšเบชเบดเบšเบซเป‰เบฒเปเบกเปˆเบ™เบŠเปˆเบญเบ‡เบ‚เปเป‰เบกเบนเบ™ เบ„เบงเบฒเบกเบเบฒเบงเบชเปˆเบงเบ™เบซเบปเบงเบญเบดเบ™เป€เบ•เบตเป€เบ™เบฑเบ” IPv4 header, เป€เบŠเบดเปˆเบ‡เป€เบเบฑเบšเบฎเบฑเบเบชเบฒเบ„เบงเบฒเบกเบเบฒเบงเบ‚เบญเบ‡ header เปƒเบ™เบ„เปเบฒเบชเบฑเบšเบ•เปˆเบฒเบ‡เป†, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบ„เบนเบ™เบ”เป‰เบงเบ 4. เบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆ, เบเบฒเบ™เบชเบฐเปเบ”เบ‡เบญเบญเบ. 4*([14]&0xf) เปเบกเปˆเบ™เบเบฒเบ™เบเปเบฒเบ™เบปเบ”เบชเปเบฒเบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเบขเบนเปˆเบžเบดเป€เบชเบ”เบ—เบตเปˆเบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰เป„เบ”เป‰เปƒเบ™เบฎเบนเบšเปเบšเบšเบ™เบตเป‰เปเบฅเบฐเบžเบฝเบ‡เปเบ•เปˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบฅเบปเบ‡เบ—เบฐเบšเบฝเบ™ X, i.e. เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบชเบฒเบกเบฒเบ”เป€เบงเบปเป‰เบฒเป„เบ”เป‰ ldb 4*([14]&0xf) neither ldxb 5*([14]&0xf) (เบžเบงเบเป€เบฎเบปเบฒเบžเบฝเบ‡เปเบ•เปˆเบชเบฒเบกเบฒเบ”เบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบŠเบปเบ”เป€เบŠเบตเบเบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบเบฑเบ™, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡, ldxb 4*([16]&0xf)). เบกเบฑเบ™เป€เบ›เบฑเบ™เบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™เบงเปˆเบฒเป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเบขเบนเปˆเบ™เบตเป‰เบ–เบทเบเป€เบžเบตเปˆเบกเปƒเบชเปˆ BPF เบขเปˆเบฒเบ‡เปเบ™เปˆเบ™เบญเบ™เป€เบžเบทเปˆเบญเบˆเบฐเป„เบ”เป‰เบฎเบฑเบš X (เบฅเบปเบ‡เบ—เบฐเบšเบฝเบ™เบ”เบฑเบ”เบชเบฐเบ™เบต) เบ„เบงเบฒเบกเบเบฒเบงเบชเปˆเบงเบ™เบซเบปเบง IPv4.

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เปƒเบ™เปเบ–เบงเบ—เบต 7 เบžเบงเบเป€เบฎเบปเบฒเบžเบฐเบเบฒเบเบฒเบกเป‚เบซเบฅเบ”เป€เบ„เบดเปˆเบ‡เบซเบ™เบถเปˆเบ‡เบ‚เบญเบ‡เบ„เปเบฒเบ—เบตเปˆ (X+16). เบˆเบทเปˆเป„เบงเป‰เบงเปˆเบฒ 14 เป„เบšเบ•เปŒเบ–เบทเบเบ„เบญเบšเบ„เบญเบ‡เป‚เบ”เบเบซเบปเบงเบญเบตเป€เบ—เบตเป€เบ™เบฑเบ”, เปเบฅเบฐ X เบกเบตเบ„เบงเบฒเบกเบเบฒเบงเบ‚เบญเบ‡เบซเบปเบงเบ‚เปเป‰ IPv4, เบžเบงเบเป€เบฎเบปเบฒเป€เบ‚เบปเป‰เบฒเปƒเบˆเบงเปˆเบฒเปƒเบ™ A เบœเบญเบ”เบ›เบฒเบเบ—เบฒเบ‡ TCP เบ–เบทเบเป‚เบซเบฅเบ”เปเบฅเป‰เบง:

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

เบชเบธเบ”เบ—เป‰เบฒเบ, เปƒเบ™เป€เบชเบฑเป‰เบ™ 8 เบžเบงเบเป€เบฎเบปเบฒเบ›เบฝเบšเบ—เบฝเบšเบžเบญเบ”เบ›เบฒเบเบ—เบฒเบ‡เบเบฑเบšเบ„เปˆเบฒเบ—เบตเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™เปเบฅเบฐเปƒเบ™เบชเบฒเบ 9 เบซเบผเบท 10 เบžเบงเบเป€เบฎเบปเบฒเบชเบปเปˆเบ‡เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบš - เบงเปˆเบฒเบˆเบฐเบ„เบฑเบ”เบฅเบญเบเปเบžเบฑเบเป€เบเบฑเบ”เบซเบผเบทเบšเปเปˆ.

Tcpdump: เบเบณเบฅเบฑเบ‡เป‚เบซเบผเบ”

เปƒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ, เบžเบงเบเป€เบฎเบปเบฒเป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐเบšเปเปˆเป„เบ”เป‰เบขเบนเปˆเปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบขเปˆเบฒเบ‡เปเบ™เปˆเบ™เบญเบ™เบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ” BPF bytecode เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™ kernel เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ packet. เป€เบงเบปเป‰เบฒเป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›, tcpdump ported เบเบฑเบšเบซเบผเบฒเบเบฅเบฐเบšเบปเบšเปเบฅเบฐเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ tcpdump เปƒเบŠเป‰เบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ” libpcap. เป‚เบ”เบเบซเบเปเป‰, เป€เบžเบทเปˆเบญเบงเบฒเบ‡เบ•เบปเบงเบเบญเบ‡เปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเป‚เบ”เบเปƒเบŠเป‰ libpcap, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เป€เบฎเบฑเบ”เบ”เบฑเปˆเบ‡เบ•เปเปˆเป„เบ›เบ™เบตเป‰:

  • เบชเป‰เบฒเบ‡เบ•เบปเบงเบญเบฐเบ—เบดเบšเบฒเบเบ›เบฐเป€เบžเบ” pcap_t เบˆเบฒเบเบŠเบทเปˆเบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš: pcap_create,
  • เบเบฐเบ•เบธเป‰เบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš: pcap_activate,
  • เบฅเบงเบšเบฅเบงเบกเบ•เบปเบงเบเบญเบ‡: pcap_compile,
  • เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ•เบปเบงเบเบญเบ‡: pcap_setfilter.

เป€เบžเบทเปˆเบญเป€เบšเบดเปˆเบ‡เบงเบดเบ—เบตเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบซเบ™เป‰เบฒ pcap_setfilter เบ›เบฐเบ•เบดเบšเบฑเบ”เปƒเบ™ Linux, เบžเบงเบเป€เบฎเบปเบฒเปƒเบŠเป‰ strace (เบšเบฒเบ‡เบชเบฒเบเป„เบ”เป‰เบ–เบทเบเป‚เบเบเบเป‰เบฒเบเบญเบญเบ):

$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768)        = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...

เปƒเบ™เบชเบญเบ‡เปเบ–เบงเบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบชเป‰เบฒเบ‡ เป€เบ•เบปเป‰เบฒเบฎเบฑเบšเบงเบฑเบ”เบ–เบธเบ”เบดเบš เป€เบžเบทเปˆเบญเบญเปˆเบฒเบ™เบ—เบธเบเป€เบŸเบฃเบก Ethernet เปเบฅเบฐเบœเบนเบเบกเบฑเบ”เบกเบฑเบ™เปƒเบชเปˆเปƒเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš eth0... เบ‚เบญเบ‡ เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบงเปˆเบฒเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ ip เบˆเบฐเบ›เบฐเบเบญเบšเบ”เป‰เบงเบเบชเบตเปˆเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒ BPF, เปเบฅเบฐเปƒเบ™เปเบ–เบงเบ—เบตเบชเบฒเบกเบžเบงเบเป€เบฎเบปเบฒเป€เบšเบดเปˆเบ‡เบงเบดเบ—เบตเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ—เบฒเบ‡เป€เบฅเบทเบญเบ SO_ATTACH_FILTER เป‚เบ—เบฅเบฐเบšเบปเบš setsockopt เบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบผเบ”เปเบฅเบฐเป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเบกเบตเบ„เบงเบฒเบกเบเบฒเบง 4. เบ™เบตเป‰เปเบกเปˆเบ™เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ.

เบกเบฑเบ™เป€เบ›เบฑเบ™เบกเบนเบ™เบ„เปˆเบฒเบ—เบตเปˆเบชเบฑเบ‡เป€เบเบ”เบงเปˆเบฒเปƒเบ™ BPF เบ„เบฅเบฒเบชเบชเบดเบ, เบเบฒเบ™เป‚เบซเบผเบ”เปเบฅเบฐเป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ•เบปเบงเบเบญเบ‡เบชเบฐเป€เบซเบกเบตเป€เบเบตเบ”เบ‚เบถเป‰เบ™เป€เบ›เบฑเบ™เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เบ›เบฐเบฅเปเบฒเบกเบฐเบ™เบน, เปเบฅเบฐเปƒเบ™เบฎเบธเปˆเบ™เปƒเบซเบกเปˆเบ‚เบญเบ‡ BPF, เบเบฒเบ™เป‚เบซเบผเบ”เป‚เบ›เบฅเปเบเบฅเบกเปเบฅเบฐเบเบฒเบ™เบœเบนเบเบกเบฑเบ”เบกเบฑเบ™เบเบฑเบšเป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เป€เบซเบ”เบเบฒเบ™เบ–เบทเบเปเบเบเบญเบญเบเบˆเบฒเบเป€เบงเบฅเบฒ.

เบ„เบงเบฒเบกเบˆเบดเบ‡เบ—เบตเปˆเป€เบŠเบทเปˆเบญเบ‡เป„เบงเป‰

เบฎเบธเปˆเบ™เบ—เบตเปˆเบชเบปเบกเบšเบนเบ™เบเบงเปˆเบฒเป€เบฅเบฑเบเบ™เป‰เบญเบเบ‚เบญเบ‡เบœเบปเบ™เบœเบฐเบฅเบดเบ”เป€เบšเบดเปˆเบ‡เบ„เบทเบงเปˆเบฒเบ™เบตเป‰:

$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768)        = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=1, filter=0xbeefbeefbeef}, 16) = 0
recvfrom(3, 0x7ffcad394257, 1, MSG_TRUNC, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...

เบ”เบฑเปˆเบ‡เบ—เบตเปˆเป„เบ”เป‰เบเปˆเบฒเบงเบกเบฒเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡, เบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ”เปเบฅเบฐเบ„เบฑเบ”เบ•เบดเบ”เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบเบฑเบšเป€เบ•เบปเป‰เบฒเบฎเบฑเบšเปƒเบ™เบชเบฒเบ 5, เปเบ•เปˆเบชเบดเปˆเบ‡เบ—เบตเปˆเป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เบชเบฒเบ 3 เปเบฅเบฐ 4? เบกเบฑเบ™ turns เปƒเบซเป‰ เป€เบซเบฑเบ™ เบงเปˆเบฒ เบ™เบตเป‰ libpcap เป€เบšเบดเปˆเบ‡เปเบเบ‡เบžเบงเบเป€เบฎเบปเบฒ - เป€เบžเบทเปˆเบญเปƒเบซเป‰เบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบฅเบงเบกเป€เบญเบปเบฒเบŠเบธเบ”เบ—เบตเปˆเบšเปเปˆเบžเปเปƒเบˆเบเบฑเบšเบกเบฑเบ™, เบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ” เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆ เบ•เบปเบงเบเบญเบ‡ dummy ret #0 (เบ–เบดเป‰เบกเปเบžเบฑเบเป€เบเบฑเบ”เบ—เบฑเบ‡เปเบปเบ”), เบชเบฐเบซเบผเบฑเบšเบŠเบฑเบญเบเป€เบเบฑเบ”เป€เบ›เบฑเบ™เป‚เปเบ”เบšเปเปˆเบ›เบดเบ”เบเบฑเป‰เบ™ เปเบฅเบฐเบžเบฐเบเบฒเบเบฒเบกเบฅเบปเบšเปเบžเบฑเบเป€เบเบฑเบ”เบ—เบฑเบ‡เปเบปเบ”เบ—เบตเปˆเบชเบฒเบกเบฒเบ”เบ„เบปเบ‡เบขเบนเปˆเบˆเบฒเบเบ•เบปเบงเบเบญเบ‡เบเปˆเบญเบ™เปœเป‰เบฒ.

เปƒเบ™เบˆเปเบฒเบ™เบงเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”, เป€เบžเบทเปˆเบญเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบŠเบธเบ”เปƒเบ™ Linux เป‚เบ”เบเปƒเบŠเป‰ BPF เบ„เบฅเบฒเบชเบชเบดเบ, เบ—เปˆเบฒเบ™เบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบกเบตเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เป€เบŠเบฑเปˆเบ™: struct sock_fprog เปเบฅเบฐเป€เบ•เบปเป‰เบฒเบชเบฝเบšเป€เบ›เบตเบ”, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ•เบปเบงเบเบญเบ‡เบชเบฒเบกเบฒเบ”เบ•เบดเบ”เบเบฑเบšเป€เบ•เบปเป‰เบฒเบฎเบฑเบšเป‚เบ”เบเปƒเบŠเป‰เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš setsockopt.

เบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆ, เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบชเบฒเบกเบฒเบ”เบ•เบดเบ”เบเบฑเบšเป€เบ•เบปเป‰เบฒเบชเบฝเบšเปƒเบ”เป†, เบšเปเปˆเบžเบฝเบ‡เปเบ•เปˆเบงเบฑเบ”เบ–เบธเบ”เบดเบš. เบ—เบตเปˆเบ™เบตเป‰ เบ•เบปเบงเบขเปˆเบฒเบ‡ เป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเบ•เบฑเบ”เบญเบญเบเบ—เบฑเบ‡เบซเบกเบปเบ”เปเบ•เปˆเบชเบญเบ‡ bytes เบ—เปเบฒเบญเบดเบ”เบˆเบฒเบเบ‚เปเป‰เบกเบนเบ™ UDP เบ‚เบฒเป€เบ‚เบปเป‰เบฒเบ—เบฑเบ‡เบซเบกเบปเบ”. (เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เป€เบžเบตเปˆเบกเบ„เปเบฒเป€เบซเบฑเบ™เปƒเบ™เบฅเบฐเบซเบฑเบ”เป€เบžเบทเปˆเบญเบšเปเปˆเปƒเบซเป‰ clutter เบšเบปเบ”เบ„เบงเบฒเบก.)

เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ setsockopt เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ•เบปเบงเบเบญเบ‡, เป€เบšเบดเปˆเบ‡ เป€เบ•เบปเป‰เบฒเบชเบฝเบš (7), เปเบ•เปˆเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เบ‚เบญเบ‡เบ—เปˆเบฒเบ™เป€เบญเบ‡เป€เบŠเบฑเปˆเบ™ struct sock_fprog เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบŠเปˆเบงเบเป€เบซเบผเบทเบญ tcpdump เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบชเบปเบ™เบ—เบฐเบ™เบฒเปƒเบ™เบžเบฒเบ เบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบก BPF เบ”เป‰เบงเบเบกเบทเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเป€เบญเบ‡.

BPF เบ„เบฅเบฒเบชเบชเบดเบเปเบฅเบฐเบชเบฐเบ•เบฐเบงเบฑเบ”เบ—เบต 21st

BPF เป„เบ”เป‰เบฅเบงเบกเบขเบนเปˆเปƒเบ™ Linux เปƒเบ™เบ›เบต 1997 เปเบฅเบฐเบเบฑเบ‡เบ„เบปเบ‡เป€เบ›เบฑเบ™ workhorse เป€เบ›เบฑเบ™เป€เบงเบฅเบฒเบ”เบปเบ™ libpcap เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบžเบดเป€เบชเบ”เปƒเบ”เป† (เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡เบชเบฐเป€เบžเบฒเบฐ Linux, เปเบ™เปˆเบ™เบญเบ™, เบกเบฑเบ™เปเบกเปˆเบ™, เปเบ•เปˆเบžเบงเบเป€เบ‚เบปเบฒเบšเปเปˆเป„เบ”เป‰เบ›เปˆเบฝเบ™เปเบ›เบ‡เบฎเบนเบšเบžเบฒเบšเบ—เบปเปˆเบงเป‚เบฅเบ). เบชเบฑเบ™เบเบฒเบ™เบ—เบตเปˆเบฎเป‰เบฒเบเปเบฎเบ‡เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆ BPF เบˆเบฐเบžเบฑเบ”เบ—เบฐเบ™เบฒเปเบกเปˆเบ™เป€เบเบตเบ”เบ‚เบทเป‰เบ™เปƒเบ™เบ›เบต 2011, เป€เบกเบทเปˆเบญ Eric Dumazet เบชเบฐเป€เบซเบ™เบต. patch, เป€เบŠเบดเปˆเบ‡เป€เบžเบตเปˆเบก Just In Time Compiler เบเบฑเบš kernel - เบ•เบปเบงเปเบ›เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ›เปˆเบฝเบ™ BPF bytecode เป€เบ›เบฑเบ™ native x86_64 เบฅเบฐเบซเบฑเบ”.

JIT compiler เปเบกเปˆเบ™เบ„เบฑเป‰เบ‡เบ—เปเบฒเบญเบดเบ”เปƒเบ™เบฅเบฐเบšเบปเบšเบ•เปˆเบญเบ‡เป‚เบชเป‰เบเบฒเบ™เบ›เปˆเบฝเบ™เปเบ›เบ‡: เปƒเบ™เบ›เบต 2012 เบ›เบฒเบเบปเบ”เบงเปˆเบฒ เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡ seccomp, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ BPF, เปƒเบ™เป€เบ”เบทเบญเบ™เบกเบฑเบ‡เบเบญเบ™ 2013 เบกเบต เป€เบžเบตเปˆเบก เป‚เบกเบ”เบนเบ™ xt_bpf, เป€เบŠเบดเปˆเบ‡เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบ‚เบฝเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบšเบชเปเบฒเบฅเบฑเบš iptables เบ”เป‰เบงเบเบเบฒเบ™เบŠเปˆเบงเบเป€เบซเบผเบทเบญเบ‚เบญเบ‡ BPF, เปเบฅเบฐเปƒเบ™เป€เบ”เบทเบญเบ™เบ•เบธเบฅเบฒ 2013 เปเบกเปˆเบ™ เป€เบžเบตเปˆเบก เป€เบ›เบฑเบ™เป‚เบกเบ”เบนเบ™ cls_bpf, เป€เบŠเบดเปˆเบ‡เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบ‚เบฝเบ™เบเบฒเบ™เบˆเบฑเบ”เบ›เบฐเป€เบžเบ”เบเบฒเบ™เบˆเบฐเบฅเบฒเบˆเบญเบ™เป‚เบ”เบเปƒเบŠเป‰ BPF.

เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบšเบดเปˆเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบฑเบ‡เบซเบกเบปเบ”เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเปƒเบ™เป„เบงเป†เบ™เบตเป‰, เปเบ•เปˆเบ—เปเบฒเบญเบดเบ”เบกเบฑเบ™เบˆเบฐเป€เบ›เบฑเบ™เบ›เบฐเป‚เบซเบเบ”เบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบฎเบปเบฒเบ—เบตเปˆเบˆเบฐเบฎเบฝเบ™เบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เปเบฅเบฐเบฅเบงเบšเบฅเบงเบกเบšเบฑเบ™เบ”เบฒเป‚เบ„เบ‡เบเบฒเบ™ arbitrary เบชเปเบฒเบฅเบฑเบš BPF, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบชเบฐเบซเบ™เบญเบ‡เปƒเบซเป‰เป‚เบ”เบเบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ”. libpcap เบˆเปเบฒเบเบฑเบ” (เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‡เปˆเบฒเบเป†: เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™ libpcap เบชเบฒเบกเบฒเบ”เบชเบปเปˆเบ‡เบ„เบทเบ™เบžเบฝเบ‡เปเบ•เปˆเบชเบญเบ‡เบ„เปˆเบฒ - 0 เบซเบผเบท 0x40000) เบซเบผเบทเป‚เบ”เบเบ—เบปเปˆเบงเป„เบ›, เป€เบŠเบฑเปˆเบ™เบ”เบฝเบงเบเบฑเบšเบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡ seccomp, เปเบกเปˆเบ™เบšเปเปˆเบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เป„เบ”เป‰.

เบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบก BPF เบ”เป‰เบงเบเบกเบทเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเป€เบญเบ‡

เปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบˆเบฑเบเบเบฑเบšเบฎเบนเบšเปเบšเบšเบ„เบนเปˆเบ‚เบญเบ‡เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒ BPF, เบกเบฑเบ™เบ‡เปˆเบฒเบเบ”เบฒเบเบซเบผเบฒเบ:

   16    8    8     32
| code | jt | jf |  k  |

เปเบ•เปˆเบฅเบฐเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบ„เบญเบšเบ„เบญเบ‡ 64 เบšเบดเบ”, เป€เบŠเบดเปˆเบ‡ 16 เบšเบดเบ”เบ—เปเบฒเบญเบดเบ”เปเบกเปˆเบ™เบฅเบฐเบซเบฑเบ”เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒ, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบกเบตเบชเบญเบ‡เบซเบเปเป‰เบซเบ™เป‰เบฒเปเบ›เบ”เบšเบดเบ”, jt ะธ jf, เปเบฅเบฐ 32 bits เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡ K, เบˆเบธเบ”เบ›เบฐเบชเบปเบ‡เบ—เบตเปˆเปเบ•เบเบ•เปˆเบฒเบ‡เบˆเบฒเบเบ„เปเบฒเบชเบฑเปˆเบ‡เป„เบ›เบซเบฒเบ„เปเบฒเบชเบฑเปˆเบ‡. เบชเปเบฒเบฅเบฑเบšเบ•เบปเบงเบขเปˆเบฒเบ‡, เบ„เปเบฒเบชเบฑเปˆเบ‡ ret, เป€เบŠเบดเปˆเบ‡เบชเบดเป‰เบ™เบชเบธเบ”เป‚เบ„เบ‡เบเบฒเบ™เบกเบตเบฅเบฐเบซเบฑเบ” 6, เปเบฅเบฐเบ„เปˆเบฒเบเบฑเบšเบ„เบทเบ™เปเบกเปˆเบ™เป€เบญเบปเบฒเบกเบฒเบˆเบฒเบเบ„เปˆเบฒเบ„เบปเบ‡เบ—เบตเปˆ K. เปƒเบ™ C, เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒ BPF เบ”เบฝเบงเปเบกเปˆเบ™เป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™เป€เบ›เบฑเบ™เป‚เบ„เบ‡เบชเป‰เบฒเบ‡

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

เปเบฅเบฐเป‚เบ„เบ‡เบเบฒเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เปเบกเปˆเบ™เบขเบนเปˆเปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡

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

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบกเป„เบ”เป‰เปเบฅเป‰เบง (เบ•เบปเบงเบขเปˆเบฒเบ‡, เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบฅเบฐเบซเบฑเบ”เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบˆเบฒเบ [1]). เบ™เบตเป‰เปเบกเปˆเบ™เบชเบดเปˆเบ‡เบ—เบตเปˆเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบˆเบฐเบกเบตเบฅเบฑเบเบชเบฐเบ™เบฐ ip6 เบˆเบฒเบเบ™เบฑเป‰เบ™ เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒ:

struct sock_filter code[] = {
        { 0x28, 0, 0, 0x0000000c },
        { 0x15, 0, 1, 0x000086dd },
        { 0x06, 0, 0, 0x00040000 },
        { 0x06, 0, 0, 0x00000000 },
};
struct sock_fprog prog = {
        .len = ARRAY_SIZE(code),
        .filter = code,
};

เป‚เบ„เบ‡เบเบฒเบ™ prog เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบ™เบณเปƒเบŠเป‰เบขเปˆเบฒเบ‡เบ–เบทเบเบเบปเบ”เปเบฒเบเปƒเบ™เบเบฒเบ™เป‚เบ—

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

เบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบกเปƒเบ™เบฎเบนเบšเปเบšเบšเบ‚เบญเบ‡เบฅเบฐเบซเบฑเบ”เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบเปเบกเปˆเบ™เบšเปเปˆเบชเบฐเบ”เบงเบเบซเบผเบฒเบ, เปเบ•เปˆเบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบกเบฑเบ™เป€เบ›เบฑเบ™เบชเบดเปˆเบ‡เบˆเปเบฒเป€เบ›เบฑเบ™ (เบ•เบปเบงเบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™: เบชเปเบฒเบฅเบฑเบš debugging, เบเบฒเบ™เบชเป‰เบฒเบ‡เบเบฒเบ™เบ—เบปเบ”เบชเบญเบšเบซเบ™เปˆเบงเบเบ‡เบฒเบ™, เบเบฒเบ™เบ‚เบฝเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบเปˆเบฝเบงเบเบฑเบšHabre, เปเบฅเบฐเบญเบทเปˆเบ™เป†). เป€เบžเบทเปˆเบญเบ„เบงเบฒเบกเบชเบฐเบ”เบงเบ, เปƒเบ™เป„เบŸเบฅเปŒ <linux/filter.h> macro เบœเบนเป‰เบŠเปˆเบงเบเปเบกเปˆเบ™เบ–เบทเบเบเปเบฒเบ™เบปเบ” - เบ•เบปเบงเบขเปˆเบฒเบ‡เบ”เบฝเบงเบเบฑเบ™เบเบฑเบšเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡เบชเบฒเบกเบฒเบ”เบ–เบทเบเบ‚เบฝเบ™เบ„เบทเบ™เปƒเบซเบกเปˆเป€เบ›เบฑเบ™

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 kernel เบชเบปเบกเป€เบซเบ”เบชเบปเบกเบœเบปเบ™, เปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบขเบนเปˆเปƒเบ™เป„เบ”เป€เบฅเบเบฐเบ—เปเบฅเบต tools/bpf kernels เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบŠเบญเบเบซเบฒ assembler เปเบฅเบฐ debugger เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบšเบ„เบฅเบฒเบชเบชเบดเบ BPF.

เบžเบฒโ€‹เบชเบฒโ€‹เบชเบฐโ€‹เบžเบฒโ€‹เปเบซเปˆเบ‡โ€‹เปเบกเปˆเบ™โ€‹เบ„เป‰เบฒเบโ€‹เบ„เบทโ€‹เบเบฑเบ™โ€‹เบซเบผเบฒเบโ€‹เบเบฑเบš debug outputโ€‹ 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, เป€เบŠเบดเปˆเบ‡เบญเบฐเบ—เบดเบšเบฒเบเบŠเบธเบ”เป€เบ„เบทเบญเบ‚เปˆเบฒเบเปƒเบ™ kernel. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบเบฑเบ‡เบกเบตเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบ‚เบญเบ‡เบœเบนเป‰เบŠเปˆเบงเบเบ›เบฐเป€เบžเบ”เบญเบทเปˆเบ™เป†, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡ ldw cpu เบˆเบฐเป‚เบซเบฅเบ”เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เบฐเบšเบฝเบ™ A เบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเบ‚เบญเบ‡เบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡ kernel raw_smp_processor_id(). (เปƒเบ™เบชเบฐเบšเบฑเบšเปƒเบซเบกเปˆเบ‚เบญเบ‡ BPF, เบเบฒเบ™เบ‚เบฐเบซเบเบฒเบเบ—เบตเปˆเบšเปเปˆเปเบกเปˆเบ™เบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™เป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เป„เบ”เป‰เบ–เบทเบเบ‚เบฐเบซเบเบฒเบเบญเบญเบเป€เบžเบทเปˆเบญเปƒเบซเป‰เป‚เบ„เบ‡เบเบฒเบ™เบ—เบตเปˆเบกเบตเบŠเบธเบ”เบ‚เบญเบ‡เบ•เบปเบงเบŠเปˆเบงเบ kernel เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เบซเบ™เปˆเบงเบเบ„เบงเบฒเบกเบˆเปเบฒ, เป‚เบ„เบ‡เบชเป‰เบฒเบ‡, เปเบฅเบฐเบเบฒเบ™เบชเป‰เบฒเบ‡เป€เบซเบ”เบเบฒเบ™.) เบ™เบตเป‰เปเบกเปˆเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเบ‚เบญเบ‡เบ•เบปเบงเบเบญเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ„เบฑเบ”เบฅเบญเบเบžเบฝเบ‡เปเบ•เปˆเบ•เบปเบงเบเบญเบ‡ packet headers เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบžเบทเป‰เบ™เบ—เบตเปˆเบœเบนเป‰เปƒเบŠเป‰เป‚เบ”เบเปƒเบŠเป‰เบชเปˆเบงเบ™เบ‚เบฐเบซเบเบฒเบ poff, เบ„เปˆเบฒเบŠเบปเบ”เป€เบŠเบตเบ payload:

ld poff
ret a

เบเบฒเบ™เบ‚เบฐเบซเบเบฒเบ BPF เบšเปเปˆเบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เปƒเบ™ tcpdump, เปเบ•เปˆเบ™เบตเป‰เปเบกเปˆเบ™เป€เบซเบ”เบœเบปเบ™เบ—เบตเปˆเบ”เบตเบ—เบตเปˆเบˆเบฐเบฎเบนเป‰เบˆเบฑเบเบเบฑเบšเบŠเบธเบ”เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ” netsniff-ng, เป€เบŠเบดเปˆเบ‡, เปƒเบ™เบšเบฑเบ™เบ”เบฒเบชเบดเปˆเบ‡เบญเบทเปˆเบ™เป†, เบ›เบฐเบเบญเบšเบ”เป‰เบงเบเป‚เบ„เบ‡เบเบฒเบ™เบ‚เบฑเป‰เบ™เบชเบนเบ‡ netsniff-ng, เป€เบŠเบดเปˆเบ‡, เบ™เบญเบเป€เบซเบ™เบทเบญเบˆเบฒเบเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เป‚เบ”เบเปƒเบŠเป‰ BPF, เบเบฑเบ‡เบกเบตเป€เบ„เบทเปˆเบญเบ‡เบเปเบฒเป€เบ™เบตเบ”เบเบฒเบ™เบˆเบฐเบฅเบฒเบˆเบญเบ™เบ—เบตเปˆเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบš, เปเบฅเบฐเบกเบตเบ„เบงเบฒเบกเบเป‰เบฒเบงเบซเบ™เป‰เบฒเบเบงเปˆเบฒ. tools/bpf/bpf_asm, เบœเบนเป‰เบ›เบฐเบเบญเบš BPF เป€เบญเบตเป‰เบ™เบงเปˆเบฒ bpfc. เบŠเบธเบ”เบ›เบฐเบเบญเบšเบ”เป‰เบงเบเป€เบญเบเบฐเบชเบฒเบ™เบ—เบตเปˆเบ‚เป‰เบญเบ™เบ‚เป‰เบฒเบ‡เบฅเบฐเบญเบฝเบ”, เป€เบšเบดเปˆเบ‡เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเปƒเบ™เบ•เบญเบ™เบ—เป‰เบฒเบเบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบก.

seccomp

เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบก BPF เบ‚เบญเบ‡เบ„เบงเบฒเบกเบชเบฑเบšเบชเบปเบ™เบ—เบตเปˆเบ•เบปเบ™เป€เบญเบ‡เบกเบฑเบเปเบฅเบฐเบžเป‰เบญเบกเบ—เบตเปˆเบˆเบฐเป€เบšเบดเปˆเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เปƒเบซเบกเปˆ, เบ—เปเบฒเบญเบดเบ”เปเบกเปˆเบ™เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบต seccomp, เป€เบŠเบดเปˆเบ‡เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ•เบปเบงเบเบญเบ‡ BPF, เป€เบžเบทเปˆเบญเบˆเบฑเบ”เบเบฒเบ™เบŠเบธเบ”เปเบฅเบฐเบŠเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบตเปˆเบกเบตเบขเบนเปˆ. เบ‚เบฐโ€‹เบšเบงเบ™โ€‹เบเบฒเบ™โ€‹เบ—เบตเปˆโ€‹เป„เบ”เป‰โ€‹เบฎเบฑเบšโ€‹เปเบฅเบฐโ€‹เบฅเบนเบโ€‹เบซเบฅเบฒเบ™โ€‹เบ‚เบญเบ‡โ€‹เบ•เบปเบ™โ€‹.

เบฎเบธเปˆเบ™เบ—เปเบฒเบญเบดเบ”เบ‚เบญเบ‡ seccomp เป„เบ”เป‰เบ–เบทเบเป€เบžเบตเปˆเบกเป€เบ‚เบปเป‰เบฒเปƒเบ™ kernel เปƒเบ™เบ›เบต 2005 เปเบฅเบฐเบšเปเปˆเป€เบ›เบฑเบ™เบ—เบตเปˆเบ™เบดเบเบปเบกเบซเบผเบฒเบ, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบกเบฑเบ™เบชเบฐเบซเบ™เบญเบ‡เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ”เบฝเบง - เป€เบžเบทเปˆเบญเบˆเปเบฒเบเบฑเบ”เบŠเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบตเปˆเบกเบตเบขเบนเปˆเปƒเบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ•เปเปˆเป„เบ›เบ™เบตเป‰: read, write, exit ะธ sigreturn, เปเบฅเบฐเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ—เบตเปˆเบฅเบฐเป€เบกเบตเบ”เบเบปเบ”เบฅเบฐเบšเบฝเบšเป„เบ”เป‰เบ–เบทเบเบ‚เป‰เบฒเบ•เบฒเบเป‚เบ”เบเปƒเบŠเป‰ SIGKILL. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เปƒเบ™เบ›เบต 2012, seccomp เป„เบ”เป‰เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ•เบปเบงเบเบญเบ‡ BPF, เบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบเปเบฒเบ™เบปเบ”เบŠเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบตเปˆเป„เบ”เป‰เบฎเบฑเบšเบญเบฐเบ™เบธเบเบฒเบ”เปเบฅเบฐเปเบกเป‰เบเบฐเบ—เบฑเป‰เบ‡เบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™เบเบงเบ”เบชเบญเบšเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบ‚เบปเบฒ. (เปœเป‰เบฒเบชเบปเบ™เปƒเบˆ, Chrome เปเบกเปˆเบ™เบซเบ™เบถเปˆเบ‡เปƒเบ™เบšเบฑเบ™เบ”เบฒเบœเบนเป‰เปƒเบŠเป‰เบ—เปเบฒเบญเบดเบ”เบ—เบตเปˆเป€เบฎเบฑเบ”เบงเบฝเบเบ™เบตเป‰, เปเบฅเบฐเบ›เบฐเบŠเบฒเบŠเบปเบ™ Chrome เบเปเบฒเบฅเบฑเบ‡เบžเบฑเบ”เบ—เบฐเบ™เบฒเบเบปเบ™เป„เบ KRSI เป‚เบ”เบเบญเบตเบ‡เปƒเบชเปˆ BPF เบฎเบธเปˆเบ™เปƒเบซเบกเปˆเปเบฅเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ›เบฑเบšเปเบ•เปˆเบ‡ Linux Security Modules.) เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบšเป€เบญเบเบฐเบชเบฒเบ™เป€เบžเบตเปˆเบกเป€เบ•เบตเบกเบชเบฒเบกเบฒเบ”เบžเบปเบšเป„เบ”เป‰เปƒเบ™เบ—เป‰เบฒเบ. เบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบก.

เปƒเบซเป‰เบชเบฑเบ‡เป€เบเบ”เบงเปˆเบฒเบกเบตเบšเบปเบ”เบ„เบงเบฒเบกเบขเบนเปˆเปƒเบ™เบชเบนเบ™เบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เปƒเบŠเป‰ seccomp เปเบฅเป‰เบง, เบšเบฒเบ‡เบ—เบตเบ„เบปเบ™เบญเบฒเบ”เบˆเบฐเบ•เป‰เบญเบ‡เบเบฒเบ™เบญเปˆเบฒเบ™เบกเบฑเบ™เบเปˆเบญเบ™ (เบซเบผเบทเปเบ—เบ™เบ—เบตเปˆเบˆเบฐ) เบญเปˆเบฒเบ™เบชเปˆเบงเบ™เบเปˆเบญเบเบ•เปเปˆเป„เบ›เบ™เบตเป‰. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก เบšเบฑเบ™เบˆเบธเปเบฅเบฐเบ„เบงเบฒเบกเบ›เบญเบ”เป„เบž: seccomp เบชเบฐเบซเบ™เบญเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰ seccomp, เบ—เบฑเบ‡เบชเบฐเบšเบฑเบš 2007 เปเบฅเบฐเบชเบฐเบšเบฑเบšเบ—เบตเปˆเปƒเบŠเป‰ BPF (เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบกเปˆเบ™เบชเป‰เบฒเบ‡เบ‚เบถเป‰เบ™เป‚เบ”เบเปƒเบŠเป‰ libseccomp), เป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ‚เบญเบ‡ seccomp เบเบฑเบš Docker, เปเบฅเบฐเบเบฑเบ‡เบชเบฐเบซเบ™เบญเบ‡เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบ—เบตเปˆเป€เบ›เบฑเบ™เบ›เบฐเป‚เบซเบเบ”เบซเบผเบฒเบ. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก เบเบฒเบ™เปเบเบ daemons เบ”เป‰เบงเบ systemd เบซเบผเบท "เบ—เปˆเบฒเบ™เบšเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™ Docker เบชเปเบฒเบฅเบฑเบšเบชเบดเปˆเบ‡เบ™เบตเป‰!" เบกเบฑเบ™เบเบงเบกเป€เบญเบปเบฒ, เป‚เบ”เบเบชเบฐเป€เบžเบฒเบฐ, เบงเบดเบ—เบตเบเบฒเบ™เป€เบžเบตเปˆเบกเบšเบฑเบ™เบŠเบตเบ”เปเบฒเบซเบผเบทเบšเบฑเบ™เบŠเบตเบ‚เบฒเบงเบ‚เบญเบ‡เบฅเบฐเบšเบปเบšเบเบฒเบ™เป‚เบ—เบชเปเบฒเบฅเบฑเบš daemons เปเบฅเปˆเบ™ systemd.

เบ•เปเปˆเป„เบ›เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบšเบดเปˆเบ‡เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เปเบฅเบฐเบเบฒเบ™เป‚เบซเบผเบ”เบ•เบปเบงเบเบญเบ‡เบชเปเบฒเบฅเบฑเบš seccomp เปƒเบ™ C เป€เบ›เบปเปˆเบฒเปเบฅเบฐเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ” libseccomp เปเบฅเบฐเบ‚เปเป‰เบ”เบตเปเบฅเบฐเบ‚เปเป‰เป€เบชเบเบ‚เบญเบ‡เปเบ•เปˆเบฅเบฐเบ—เบฒเบ‡เป€เบฅเบทเบญเบเปเบกเปˆเบ™เบซเบเบฑเบ‡, เปเบฅเบฐเบชเบธเบ”เบ—เป‰เบฒเบ, เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบงเปˆเบฒ seccomp เบ–เบทเบเปƒเบŠเป‰เป‚เบ”เบเป‚เบ„เบ‡เบเบฒเบ™เปเบ™เบงเปƒเบ” strace.

เบเบฒเบ™เบ‚เบฝเบ™เปเบฅเบฐเบเบฒเบ™เป‚เบซเบผเบ”เบ•เบปเบงเบเบญเบ‡เบชเปเบฒเบฅเบฑเบš seccomp

เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบงเบดเบ—เบตเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบก BPF เปเบฅเป‰เบง, เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบ—เปเบฒเบญเบดเบ”เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบเบฒเบ™เบ‚เบฝเบ™เป‚เบ›เบฅเปเบเบฅเบก seccomp. เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบเปเบฒเบ™เบปเบ”เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เปƒเบ™เบฅเบฐเบ”เบฑเบšเบ‚เบฐเบšเบงเบ™เบเบฒเบ™, เปเบฅเบฐเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป€เบ”เบฑเบเบ™เป‰เบญเบเบ—เบฑเบ‡เบซเบกเบปเบ”เบˆเบฐเบชเบทเบšเบ—เบญเบ”เบ‚เปเป‰เบˆเปเบฒเบเบฑเบ”. เบ™เบตเป‰เปเบกเปˆเบ™เป€เบฎเบฑเบ”เป„เบ”เป‰เป‚เบ”เบเปƒเบŠเป‰เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

เบšเปˆเบญเบ™เบ—เบตเปˆ &filter - เบ™เบตเป‰เปเบกเปˆเบ™เบ•เบปเบงเบŠเบตเป‰เป€เบ–เบดเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡เบ—เบตเปˆเบ„เบธเป‰เบ™เป€เบ„เบตเบเบเบฑเบšเบžเบงเบเป€เบฎเบปเบฒ struct sock_fprog, i.e. เป‚เบ„เบ‡เบเบฒเบ™ BPF.

เป‚เบ›เบฅเปเบเบฅเบกเบชเปเบฒเบฅเบฑเบš seccomp เปเบ•เบเบ•เปˆเบฒเบ‡เบˆเบฒเบเป‚เบ›เบผเปเบเบผเบกเบชเปเบฒเบฅเบฑเบš sockets เปเบ™เบงเปƒเบ”? เบชเบฐเบžเบฒเบšเบเบฒเบ™เบ–เปˆเบฒเบเบ—เบญเบ”. เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡ sockets, เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบšเบžเบทเป‰เบ™เบ—เบตเปˆเบ„เบงเบฒเบกเบŠเบปเบ‡เบˆเปเบฒเบ—เบตเปˆเบ›เบฐเบเบญเบšเบ”เป‰เบงเบ packet, เปเบฅเบฐเปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡ seccomp เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบฎเบฑเบšเป‚เบ„เบ‡เบชเป‰เบฒเบ‡เป€เบŠเบฑเปˆเบ™:

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

เบกเบฑเบ™เป€เบ›เบฑเบ™ nr เปเบกเปˆเบ™เบ•เบปเบงเป€เบฅเบเบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบตเปˆเบˆเบฐเป€เบ›เบตเบ”เบ•เบปเบง, arch - เบชเบฐโ€‹เบ–เบฒโ€‹เบ›เบฑเบ”โ€‹เบ•เบฐโ€‹เบ›เบฑเบ”โ€‹เบˆเบธโ€‹เบšเบฑเบ™ (เป€เบžเบตเปˆเบกโ€‹เป€เบ•เบตเบกโ€‹เบเปˆเบฝเบงโ€‹เบเบฑเบšโ€‹เบเบฒเบ™โ€‹เบ‚เป‰เบฒเบ‡โ€‹เบฅเบธเปˆเบกโ€‹เบ™เบตเป‰โ€‹)โ€‹, args - เป€เบ–เบดเบ‡เบซเบปเบเบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš, เปเบฅเบฐ instruction_pointer เปเบกเปˆเบ™เบ•เบปเบงเบŠเบตเป‰เป„เบ›เบซเบฒเบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเบžเบทเป‰เบ™เบ—เบตเปˆเบ‚เบญเบ‡เบœเบนเป‰เปƒเบŠเป‰เบ—เบตเปˆเป€เบฎเบฑเบ”เปƒเบซเป‰เบฅเบฐเบšเบปเบšเบเบฒเบ™เป‚เบ—. เบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡, เบเบฒเบ™เป‚เบซเบผเบ”เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เบฐเบšเบฝเบ™ A เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เป€เบงเบปเป‰เบฒ

ldw [0]

เบกเบตเบฅเบฑเบเบชเบฐเบ™เบฐเบญเบทเปˆเบ™เป†เบชเปเบฒเบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™ seccomp, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡, เบชเบฐเบžเบฒเบšเบเบฒเบ™เบชเบฒเบกเบฒเบ”เป€เบ‚เบปเป‰เบฒเป€เบ–เบดเบ‡เป„เบ”เป‰เป‚เบ”เบเบเบฒเบ™เบงเบฒเบ‡ 32-bit เปเบฅเบฐเบ—เปˆเบฒเบ™เบšเปเปˆเบชเบฒเบกเบฒเบ”เป‚เบซเบฅเบ”เป€เบ„เบดเปˆเบ‡เบซเบ™เบถเปˆเบ‡เบ„เปเบฒเบซเบผเบท byte - เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆเบžเบฐเบเบฒเบเบฒเบกเป‚เบซเบผเบ”เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡. ldh [0] เป‚เบ—เบฅเบฐเบšเบปเบš seccomp เบˆเบฐเบเบฑเบšเบ„เบทเบ™เบกเบฒ EINVAL. เบŸเบฑเบ‡เบŠเบฑเบ™เบเบงเบ”เบชเบญเบšเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเป‚เบซเบฅเบ” seccomp_check_filter() เปเบเปˆเบ™. (เบชเบดเปˆเบ‡เบ—เบตเปˆเบ•เบฐเบซเบฅเบปเบเปเบกเปˆเบ™, เปƒเบ™เบ„เปเบฒเบซเบกเบฑเป‰เบ™เบชเบฑเบ™เบเบฒเบ•เบปเป‰เบ™เบชเบฐเบšเบฑเบšเบ—เบตเปˆเป€เบžเบตเปˆเบกเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ‚เบญเบ‡ seccomp, เบžเบงเบเป€เบ‚เบปเบฒเบฅเบทเบกเป€เบžเบตเปˆเบกเบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ™เปเบฒเปƒเบŠเป‰เบ„เปเบฒเปเบ™เบฐเบ™เปเบฒเปƒเบ™เบซเบ™เป‰เบฒเบ—เบตเปˆเบ™เบตเป‰. mod (เบเบฒเบ™เปเบšเปˆเบ‡เบชเปˆเบงเบ™เบ—เบตเปˆเบเบฑเบ‡เป€เบซเบผเบทเบญ) เปเบฅเบฐเบ•เบญเบ™เบ™เบตเป‰เบšเปเปˆเบชเบฒเบกเบฒเบ”เปƒเบŠเป‰เป„เบ”เป‰เบชเบณเบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™ BPF seccomp, เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบเบฒเบ™เป€เบžเบตเปˆเบกเบ‚เบญเบ‡เบกเบฑเบ™ เบˆเบฐเปเบ•เบ ABI.)

เป‚เบ”เบเบžเบทเป‰เบ™เบ–เบฒเบ™เปเบฅเป‰เบง, เบžเบงเบเป€เบฎเบปเบฒเบฎเบนเป‰เบ—เบธเบเบชเบดเปˆเบ‡เบ—เบธเบเบขเปˆเบฒเบ‡เป€เบžเบทเปˆเบญเบ‚เบฝเบ™เปเบฅเบฐเบญเปˆเบฒเบ™เป‚เบ„เบ‡เบเบฒเบ™ seccomp. เบ›เบปเบเบเบฐเบ•เบดเปเบฅเป‰เบงเป€เบซเบ”เบœเบปเบ™เบ‚เบญเบ‡เป‚เบ›เบฅเปเบเบฅเบกเบ–เบทเบเบˆเบฑเบ”เป€เบ›เบฑเบ™เบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบชเบตเบ‚เบฒเบงเบซเบผเบทเบชเบตเบ”เปเบฒเบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš, เบ•เบปเบงเบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™เป‚เบ„เบ‡เบเบฒเบ™

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

เบเบงเบ”เป€เบšเบดเปˆเบ‡เบšเบฑเบ™เบŠเบตเบ”เปเบฒเบ‚เบญเบ‡เบชเบตเปˆเบฅเบฐเบšเบปเบšเบเบฒเบ™เป‚เบ—เป€เบฅเบ 304, 176, 239, 279. เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เปเบกเปˆเบ™เบซเบเบฑเบ‡? เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบชเบฒเบกเบฒเบ”เป€เบงเบปเป‰เบฒเป„เบ”เป‰เปเบ™เปˆเบ™เบญเบ™, เป€เบžเบฒเบฐเบงเปˆเบฒเบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบฎเบนเป‰เบงเปˆเบฒเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปƒเบ”เบ—เบตเปˆเป‚เบ„เบ‡เบเบฒเบ™เป„เบ”เป‰เบ–เบทเบเบ‚เบฝเบ™. เป€เบžเบฒเบฐเบชเบฐเบ™เบฑเป‰เบ™, เบœเบนเป‰เบ‚เบฝเบ™เบ‚เบญเบ‡ seccomp เบชเบฐเป€เบซเบ™เบต เป€เบฅเบตเปˆเบกเป‚เบ„เบ‡เบเบฒเบ™เบ—เบฑเบ‡เปเบปเบ”เบ”เป‰เบงเบเบเบฒเบ™เบเบงเบ”เบชเบญเบšเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเบณ (เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเบณเบ›เบฐเบˆเบธเบšเบฑเบ™เปเบกเปˆเบ™เบชเบฐเปเบ”เบ‡เบขเบนเปˆเปƒเบ™เบšเปเบฅเบดเบšเบปเบ”เป€เบ›เบฑเบ™เบŠเปˆเบญเบ‡เบ‚เปเป‰เบกเบนเบ™ arch เบเบฐเบ”เบฒเบ™เบชเบปเบ™เบ—เบฐเบ™เบฒ struct seccomp_data). เบ”เป‰เบงเบเบเบฒเบ™เบเบงเบ”เบเบฒเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ, เบˆเบธเบ”เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบˆเบฐเป€เบšเบดเปˆเบ‡เบ„เบทเบงเปˆเบฒ:

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

เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป„เบ”เป‰เบฎเบฑเบšเบ„เปˆเบฒเบ—เบตเปˆเปเบ™เปˆเบ™เบญเบ™.

เบžเบงเบเป€เบฎเบปเบฒเบ‚เบฝเบ™เปเบฅเบฐเป‚เบซเบฅเบ”เบ•เบปเบงเบเบญเบ‡เบชเปเบฒเบฅเบฑเบš seccomp เป‚เบ”เบเปƒเบŠเป‰ libseccomp

เบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เปƒเบ™เบฅเบฐเบซเบฑเบ”เบžเบทเป‰เบ™เป€เบกเบทเบญเบ‡เบซเบผเบทเปƒเบ™เบชเบฐเบžเบฒเปเบซเปˆเบ‡ BPF เบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ„เบงเบšเบ„เบธเบกเบœเบปเบ™เป„เบ”เป‰เบฎเบฑเบšเป„เบ”เป‰เบขเปˆเบฒเบ‡เป€เบ•เบฑเบกเบ—เบตเปˆ, เปเบ•เปˆเปƒเบ™เป€เบงเบฅเบฒเบ”เบฝเบงเบเบฑเบ™, เบšเบฒเบ‡เบ„เบฑเป‰เบ‡เบกเบฑเบ™เบเปเปˆเบ”เบตเบเบงเปˆเบฒเบ—เบตเปˆเบˆเบฐเบกเบตเบฅเบฐเบซเบฑเบ”เปเบšเบšเป€เบ„เบทเปˆเบญเบ™เบ—เบตเปˆเปเบฅเบฐ / เบซเบผเบทเบชเบฒเบกเบฒเบ”เบญเปˆเบฒเบ™เป„เบ”เป‰. เบซเป‰เบญเบ‡เบชเบฐเบซเบกเบธเบ”เบˆเบฐเบŠเปˆเบงเบเบžเบงเบเป€เบฎเบปเบฒเปƒเบ™เป€เบฅเบทเปˆเบญเบ‡เบ™เบตเป‰ libseccomp, เป€เบŠเบดเปˆเบ‡เบชเบฐเบซเบ™เบญเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบกเบฒเบ”เบ•เบฐเบ–เบฒเบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ‚เบฝเบ™เบ•เบปเบงเบเบญเบ‡เบชเบตเบ”เปเบฒเบซเบผเบทเบชเบตเบ‚เบฒเบง.

เบ•เบปเบงเบขเปˆเบฒเบ‡, เปƒเบซเป‰เบ‚เบฝเบ™เป‚เบ›เบผเปเบเบผเบกเบ—เบตเปˆเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เป„เบŸเบฅเปŒเบ„เบนเปˆเบ‚เบญเบ‡เบเบฒเบ™เป€เบฅเบทเบญเบเบ‚เบญเบ‡เบœเบนเป‰เปƒเบŠเป‰, เป‚เบ”เบเป„เบ”เป‰เบ•เบดเบ”เบ•เบฑเป‰เบ‡เบšเบฑเบ™เบŠเบตเบ”เปเบฒเบ‚เบญเบ‡เบฅเบฐเบšเบปเบšเบเบฒเบ™เป‚เบ—เบˆเบฒเบ. เบšเบปเบ”เบ„เบงเบฒเบกเบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡ (เป‚เบ›เบฅเปเบเบฅเบกเป„เบ”เป‰เบ–เบทเบเบ›เบฑเบšเบ›เบธเบ‡เปƒเบซเป‰เบ‡เปˆเบฒเบเบ‚เบถเป‰เบ™เป€เบžเบทเปˆเบญเปƒเบซเป‰เบชเบฒเบกเบฒเบ”เบญเปˆเบฒเบ™เป„เบ”เป‰เบซเบผเบฒเบเบ‚เบถเป‰เบ™, เบชเบฐเบšเบฑเบšเป€เบ•เบฑเบกเบชเบฒเบกเบฒเบ”เบžเบปเบšเป„เบ”เป‰ เบ—เบตเปˆเบ™เบตเป‰):

#include <seccomp.h>
#include <unistd.h>
#include <err.h>

static int sys_numbers[] = {
        __NR_mount,
        __NR_umount2,
       // ... ะตั‰ะต 40 ัะธัั‚ะตะผะฝั‹ั… ะฒั‹ะทะพะฒะพะฒ ...
        __NR_vmsplice,
        __NR_perf_event_open,
};

int main(int argc, char **argv)
{
        scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);

        for (size_t i = 0; i < sizeof(sys_numbers)/sizeof(sys_numbers[0]); i++)
                seccomp_rule_add(ctx, SCMP_ACT_TRAP, sys_numbers[i], 0);

        seccomp_load(ctx);

        execvp(argv[1], &argv[1]);
        err(1, "execlp: %s", argv[1]);
}

เบเปˆเบญเบ™เบญเบทเปˆเบ™ เปเบปเบ” เบžเบงเบเป€เบฎเบปเบฒ เบเบณ เบ™เบปเบ” array sys_numbers เบ‚เบญเบ‡ 40+ เบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบตเปˆเบˆเบฐเบ•เบฑเบ™. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบชเบฐเบžเบฒเบšเบเบฒเบ™ ctx เปเบฅเบฐเบšเบญเบเบซเป‰เบญเบ‡เบชเบฐเปเบธเบ”เบชเบดเปˆเบ‡เบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰ (SCMP_ACT_ALLOW) เบเบฒเบ™โ€‹เป‚เบ—โ€‹เบฅเบฐโ€‹เบšเบปเบšโ€‹เบ—เบฑเบ‡โ€‹เบซเบกเบปเบ”โ€‹เป€เบ›เบฑเบ™โ€‹เบ„เปˆเบฒโ€‹เป€เบฅเบตเปˆเบกโ€‹เบ•เบปเป‰เบ™ (เบกเบฑเบ™โ€‹เบ‡เปˆเบฒเบโ€‹เบ‚เบถเป‰เบ™โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบชเป‰เบฒเบ‡โ€‹เบšเบฑเบ™โ€‹เบŠเบตโ€‹เบ”เปเบฒโ€‹)โ€‹. เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, เบซเบ™เบถเปˆเบ‡เป‚เบ”เบเบซเบ™เบถเปˆเบ‡, เบžเบงเบเป€เบฎเบปเบฒเป€เบžเบตเปˆเบกเบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบ—เบฑเบ‡เบซเบกเบปเบ”เบˆเบฒเบเบšเบฑเบ™เบŠเบตเบ”เปเบฒ. เปƒเบ™เบเบฒเบ™เบ•เบญเบšเบชเบฐเบซเบ™เบญเบ‡เบ•เปเปˆเบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบˆเบฒเบเบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆ, เบžเบงเบเป€เบฎเบปเบฒเบฎเป‰เบญเบ‡เบ‚เป SCMP_ACT_TRAP, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰ seccomp เบˆเบฐเบชเบปเปˆเบ‡เบชเบฑเบ™เบเบฒเบ™เบเบฑเบšเบ‚เบฐเบšเบงเบ™เบเบฒเบ™ SIGSYS เบกเบตเบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเปƒเบ”เบฅเบฐเป€เบกเบตเบ”เบเบปเบ”เบฅเบฐเบšเบฝเบš. เบชเบธเบ”เบ—เป‰เบฒเบ, เบžเบงเบเป€เบฎเบปเบฒเป‚เบซเบฅเบ”เป‚เบ„เบ‡เบเบฒเบ™เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™ kernel เป‚เบ”เบเปƒเบŠเป‰ 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, fitting เบฅเบฐเบซเบฑเบ”เบ—เบตเปˆเบšเปเปˆเปเบกเปˆเบ™ trivial เป€เบ›เบฑเบ™เบชเบตเปˆเปเบ–เบง. เปƒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡, เบ–เป‰เบฒเบกเบตเบˆเปเบฒเบ™เบงเบ™เบซเบฅเบฒเบเบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš, เป€เบงเบฅเบฒเบ›เบฐเบ•เบดเบšเบฑเบ”เบชเบฒเบกเบฒเบ”เบซเบผเบธเบ”เบฅเบปเบ‡เบขเปˆเบฒเบ‡เป€เบซเบฑเบ™เป„เบ”เป‰เบŠเบฑเบ”, เป€เบžเบฒเบฐเบงเปˆเบฒเบเบฒเบ™เบเบงเบ”เบชเบญเบšเปเบกเปˆเบ™เบžเบฝเบ‡เปเบ•เปˆเบšเบฑเบ™เบŠเบตเบฅเบฒเบเบŠเบทเปˆเบ‚เบญเบ‡เบเบฒเบ™เบ›เบฝเบšเบ—เบฝเบš. เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบš, libseccomp เบšเปเปˆเบ”เบปเบ™เบกเบฒเบ™เบตเป‰เบกเบต เบฅเบงเบก patch, เป€เบŠเบดเปˆเบ‡เป€เบžเบตเปˆเบกเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบชเปเบฒเบฅเบฑเบšเบ„เบธเบ™เบฅเบฑเบเบชเบฐเบ™เบฐเบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ SCMP_FLTATR_CTL_OPTIMIZE. เบเบฒเบ™เบ•เบฑเป‰เบ‡เบ„เปˆเบฒเบ„เบธเบ™เบฅเบฑเบเบชเบฐเบ™เบฐเบ™เบตเป‰เป€เบ›เบฑเบ™ 2 เบˆเบฐเบ›เปˆเบฝเบ™เบ•เบปเบงเบเบญเบ‡เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบ„เบปเป‰เบ™เบซเบฒเบ–เบฒเบ™เบชเบญเบ‡.

เบ–เป‰เบฒเบ—เปˆเบฒเบ™เบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบšเบดเปˆเบ‡เบงเปˆเบฒเบ•เบปเบงเบเบญเบ‡เบเบฒเบ™เบ„เบปเป‰เบ™เบซเบฒเบ„เบนเปˆเป€เบฎเบฑเบ”เบงเบฝเบเปเบ™เบงเปƒเบ”, เปƒเบซเป‰เป€เบšเบดเปˆเบ‡ script เบ‡เปˆเบฒเบเบ”เบฒเบ, เป€เบŠเบดเปˆเบ‡เบชเป‰เบฒเบ‡เป‚เบ„เบ‡เบเบฒเบ™เบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเปƒเบ™เบ•เบปเบงเบ›เบฐเบเบญเบš BPF เป‚เบ”เบเบเบฒเบ™เป‚เบ—เบซเบฒเบˆเปเบฒเบ™เบงเบ™เบเบฒเบ™เป‚เบ—เบ‚เบญเบ‡เบฅเบฐเบšเบปเบš, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡:

$ echo 1 3 6 8 13 | ./generate_bin_search_bpf.py
ld [0]
jeq #6, bad
jgt #6, check8
jeq #1, bad
jeq #3, bad
ret #0x7fff0000
check8:
jeq #8, bad
jeq #13, bad
ret #0x7fff0000
bad: ret #0

เบ—เปˆเบฒเบ™เบˆเบฐเบšเปเปˆเบชเบฒเบกเบฒเบ”เบ‚เบฝเบ™เบญเบฑเบ™เปƒเบ”เป„เบงเบ‚เบถเป‰เบ™เป„เบ”เป‰, เป€เบžเบฒเบฐเบงเปˆเบฒเป‚เบ›เบฃเปเบเบก BPF เบšเปเปˆเบชเบฒเบกเบฒเบ”เบ”เบณเป€เบ™เบตเบ™เบเบฒเบ™ indentation jumps เป„เบ”เป‰ (เบ•เบปเบงเบขเปˆเบฒเบ‡, เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบชเบฒเบกเบฒเบ”เป€เบฎเบฑเบ”เป„เบ”เป‰. jmp A เบซเบผเบท jmp [label+X]) เปเบฅเบฐเบ”เบฑเปˆเบ‡เบ™เบฑเป‰เบ™เบเบฒเบ™เบซเบฑเบ™เบ›เปˆเบฝเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เปเบกเปˆเบ™เบ„เบปเบ‡เบ—เบตเปˆ.

seccomp เปเบฅเบฐ strace

เบ—เบธเบเบ„เบปเบ™เบฎเบนเป‰เบˆเบฑเบเบ›เบฐเป‚เบซเบเบ” strace เป€เบ›เบฑเบ™เป€เบ„เบทเปˆเบญเบ‡เบกเบทเบ—เบตเปˆเบ‚เบฒเบ”เบšเปเปˆเป„เบ”เป‰เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเบถเบเบชเบฒเบžเบถเบ”เบ•เบดเบเปเบฒเบ‚เบญเบ‡เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เปƒเบ™ Linux. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบซเบผเบฒเบเบ„เบปเบ™เบเบฑเบ‡เป„เบ”เป‰เบเบดเบ™เบเปˆเบฝเบงเบเบฑเบš เบšเบฑเบ™เบซเบฒเบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ” เป€เบกเบทเปˆเบญเปƒเบŠเป‰เบ›เบฐเป‚เบซเบเบ”เบ™เบตเป‰. เบ„เบงเบฒเบกเบˆเบดเบ‡เปเบฅเป‰เบงเปเบกเปˆเบ™เบงเปˆเบฒ strace เบ›เบฐเบ•เบดเบšเบฑเบ”เป‚เบ”เบเบ™เปเบฒเปƒเบŠเป‰ ptrace(2), เปเบฅเบฐเปƒเบ™เบเบปเบ™เป„เบเบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบชเบฒเบกเบฒเบ”เบฅเบฐเบšเบธเป„เบ”เป‰เบงเปˆเบฒเบŠเบธเบ”เบ‚เบญเบ‡เบฅเบฐเบšเบปเบšเบเบฒเบ™เป‚เบ—เบซเบฒเบžเบงเบเป€เบฎเบปเบฒเบˆเปเบฒเป€เบ›เบฑเบ™เบ•เป‰เบญเบ‡เบขเบธเบ”เบ‚เบฐเบšเบงเบ™เบเบฒเบ™, i.e., เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡, เบ„เปเบฒเบชเบฑเปˆเบ‡.

$ time strace du /usr/share/ >/dev/null 2>&1

real    0m3.081s
user    0m0.531s
sys     0m2.073s

ะธ

$ time strace -e open du /usr/share/ >/dev/null 2>&1

real    0m2.404s
user    0m0.193s
sys     0m1.800s

เบ–เบทเบเบ›เบธเบ‡เปเบ•เปˆเบ‡เปƒเบ™เป€เบงเบฅเบฒเบ›เบฐเบกเบฒเบ™เบ”เบฝเบงเบเบฑเบ™, เป€เบ–เบดเบ‡เปเบกเปˆเบ™เบงเปˆเบฒเปƒเบ™เบเปเบฅเบฐเบ™เบตเบ—เบตเบชเบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เบ—เบตเปˆเบˆเบฐเบ•เบดเบ”เบ•เบฒเบกเบžเบฝเบ‡เปเบ•เปˆเบซเบ™เบถเปˆเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš.

เบ—เบฒเบ‡เป€เบฅเบทเบญเบเปƒเบซเบกเปˆ --seccomp-bpf, เป€เบžเบตเปˆเบกเปƒเบชเปˆ strace เบฎเบธเปˆเบ™ 5.3, เบŠเปˆเบงเบเปƒเบซเป‰เบ—เปˆเบฒเบ™เป€เบฅเบฑเปˆเบ‡เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบซเบผเบฒเบเบ„เบฑเป‰เบ‡เปเบฅเบฐเป€เบงเบฅเบฒเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบžเบฒเบเปƒเบ•เป‰เบเบฒเบ™เบ•เบดเบ”เบ•เบฒเบกเบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบซเบ™เบถเปˆเบ‡เปเบกเปˆเบ™เบ—เบฝเบšเบเบฑเบšเป€เบงเบฅเบฒเบ‚เบญเบ‡เบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ›เบปเบเบเบฐเบ•เบด:

$ time strace --seccomp-bpf -e open du /usr/share/ >/dev/null 2>&1

real    0m0.148s
user    0m0.017s
sys     0m0.131s

$ time du /usr/share/ >/dev/null 2>&1

real    0m0.140s
user    0m0.024s
sys     0m0.116s

(เปƒเบ™เบ—เบตเปˆเบ™เบตเป‰, เปเบ™เปˆเบ™เบญเบ™, เบกเบตเบเบฒเบ™เบซเบผเบญเบเบฅเบงเบ‡เป€เบฅเบฑเบเบ™เป‰เบญเบเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเป„เบ”เป‰เบ•เบดเบ”เบ•เบฒเบกเบเบฒเบ™เป€เบญเบตเป‰เบ™เบฅเบฐเบšเบปเบšเบซเบผเบฑเบเบ‚เบญเบ‡เบ„เปเบฒเบชเบฑเปˆเบ‡เบ™เบตเป‰. เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เบดเบ”เบ•เบฒเบก, เบชเปเบฒเบฅเบฑเบšเบ•เบปเบงเบขเปˆเบฒเบ‡, newfsstat, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™, strace เบˆเบฐเบซเป‰เบฒเบกเบฅเปเป‰เบžเบฝเบ‡เปเบ•เปˆเบเบฒเบเป€เบ›เบฑเบ™เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™ --seccomp-bpf.)

เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบ™เบตเป‰เป€เบฎเบฑเบ”เบงเบฝเบเปเบ™เบงเปƒเบ”? เป‚เบ”เบเบšเปเปˆเบกเบตเบเบฒเบ™เบ‚เบญเบ‡เบ™เบฒเบ‡ strace เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบšเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เปเบฅเบฐเป€เบฅเบตเปˆเบกเปƒเบŠเป‰เบกเบฑเบ™ PTRACE_SYSCALL. เป€เบกเบทเปˆเบญเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ—เบตเปˆเบกเบตเบเบฒเบ™เบ„เบธเป‰เบกเบ„เบญเบ‡เบญเบญเบเบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš (เปƒเบ”เป†), เบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบˆเบฐเบ–เบทเบเป‚เบญเบ™เป„เบ›เบซเบฒ strace, เป€เบŠเบดเปˆเบ‡เป€เบšเบดเปˆเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเปเบฅเบฐเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™เบเบฑเบš PTRACE_SYSCALL. เบซเบผเบฑเบ‡เบˆเบฒเบเป€เบงเบฅเบฒเปƒเบ”เบซเบ™เบถเปˆเบ‡, เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบชเปเบฒเป€เบฅเบฑเบ”เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเปเบฅเบฐเป€เบกเบทเปˆเบญเบญเบญเบเบˆเบฒเบเบกเบฑเบ™, เบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเป„เบ”เป‰เบ–เบทเบเป‚เบญเบ™เบญเบตเบเป€เบ—เบทเปˆเบญเบซเบ™เบถเปˆเบ‡ strace, เป€เบŠเบดเปˆเบ‡เป€เบšเบดเปˆเบ‡เบ„เปˆเบฒเบเบฑเบšเบ„เบทเบ™เปเบฅเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป‚เบ”เบเปƒเบŠเป‰ PTRACE_SYSCALL, เปเบฅเบฐเบญเบทเปˆเบ™เป†.

BPF เบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ, เบชเปˆเบงเบ™เบชเบนเบ™: BPF เบ„เบฅเบฒเบชเบชเบดเบ

เบ”เป‰เบงเบ seccomp, เปเบ™เบงเปƒเบ”เบเปเปˆเบ•เบฒเบก, เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ™เบตเป‰เบชเบฒเบกเบฒเบ”เบ–เบทเบเบ›เบฑเบšเปเบ•เปˆเบ‡เป„เบ”เป‰เบ•เบฒเบกเบ—เบตเปˆเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™. เบ„เบท, เบ–เป‰เบฒเบžเบงเบเป€เบฎเบปเบฒเบ•เป‰เบญเบ‡เบเบฒเบ™เป€เบšเบดเปˆเบ‡เบžเบฝเบ‡เปเบ•เปˆเบขเบนเปˆเปƒเบ™เบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบš X, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบžเบงเบเป€เบฎเบปเบฒเบชเบฒเบกเบฒเบ”เบ‚เบฝเบ™เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡ BPF เบงเปˆเบฒเบชเปเบฒเบฅเบฑเบš X เบ•เบญเบšเบ„เปˆเบฒ SECCOMP_RET_TRACE, เปเบฅเบฐเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป‚เบ—เบ—เบตเปˆเบšเปเปˆเบกเบตเบ„เบงเบฒเบกเบชเบปเบ™เปƒเบˆเบเบฑเบšเบžเบงเบเป€เบฎเบปเบฒ - SECCOMP_RET_ALLOW:

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

เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰ strace เปƒเบ™เป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป€เบ›เบฑเบ™ PTRACE_CONT, เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ‚เบญเบ‡เบžเบงเบเป€เบฎเบปเบฒเบ–เบทเบเบ›เบธเบ‡เปเบ•เปˆเบ‡เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เป‚เบ—เบซเบฒเบฅเบฐเบšเบปเบšเปเบ•เปˆเบฅเบฐเบ„เบปเบ™, เบ–เป‰เบฒเบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบšเปเปˆเปเบกเปˆเบ™ X, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบเบฑเบ‡เบชเบทเบšเบ•เปเปˆเบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™, เปเบ•เปˆเบ–เป‰เบฒเบซเบฒเบเบงเปˆเบฒเบ™เบตเป‰ X, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™ seccomp เบˆเบฐเป‚เบญเบ™เบเบฒเบ™เบ„เบงเบšเบ„เบธเบก straceเป€เบŠเบดเปˆเบ‡เบˆเบฐเป€เบšเบดเปˆเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ–เบฝเบ‡เปเบฅเบฐเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป€เบŠเบฑเปˆเบ™: PTRACE_SYSCALL (เป€เบ™เบทเปˆเบญเบ‡โ€‹เบˆเบฒเบ seccomp เบšเปเปˆโ€‹เบกเบตโ€‹เบ„เบงเบฒเบกโ€‹เบชเบฒโ€‹เบกเบฒเบ”โ€‹เบ—เบตเปˆโ€‹เบˆเบฐโ€‹เบ”เปเบฒโ€‹เป€เบ™เบตเบ™โ€‹เบเบฒเบ™โ€‹เป‚เบ„เบ‡โ€‹เบเบฒเบ™โ€‹เบเปˆเบฝเบงโ€‹เบเบฑเบšโ€‹เบเบฒเบ™โ€‹เบญเบญเบโ€‹เบˆเบฒเบโ€‹เบเบฒเบ™โ€‹เป‚เบ—โ€‹เบฅเบฐโ€‹เบšเบปเบšโ€‹)โ€‹. เป€เบกเบทเปˆเบญเบเบฒเบ™เป‚เบ—เบฅเบฐเบšเบปเบšเบเบฑเบšเบ„เบทเบ™เบกเบฒ, strace เบˆเบฐเป€เบฅเบตเปˆเบกเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ„เบทเบ™เปƒเปเปˆเป‚เบ”เบเปƒเบŠเป‰ PTRACE_CONT เปเบฅเบฐเบˆเบฐเบฅเปเบ–เป‰เบฒเบ‚เปเป‰เบ„เบงเบฒเบกเปƒเปเปˆเบˆเบฒเบ seccomp.

BPF เบชเปเบฒเบฅเบฑเบšเป€เบ”เบฑเบเบ™เป‰เบญเบ, เบชเปˆเบงเบ™เบชเบนเบ™: BPF เบ„เบฅเบฒเบชเบชเบดเบ

เป€เบกเบทเปˆเบญเปƒเบŠเป‰เบ—เบฒเบ‡เป€เบฅเบทเบญเบ --seccomp-bpf เบกเบตเบชเบญเบ‡เบ‚เปเป‰เบˆเปเบฒเบเบฑเบ”. เบเปˆเบญเบ™เบญเบทเปˆเบ™ เปเบปเบ”, เบกเบฑเบ™เบˆเบฐเบšเปเปˆเบชเบฒเบกเบฒเบ”เป€เบ‚เบปเป‰เบฒเบฎเปˆเบงเบกเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ—เบตเปˆเบกเบตเบขเบนเปˆเปเบฅเป‰เบงเป„เบ”เป‰ (เบ—เบฒเบ‡เป€เบฅเบทเบญเบ -p เบšเบฑเบ™เบ”เบฒเป‚เบ„เบ‡เบเบฒเบ™ strace), เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบ™เบตเป‰เบšเปเปˆเป„เบ”เป‰เบฎเบฑเบšเบเบฒเบ™เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เป‚เบ”เบ seccomp. เบญเบฑเบ™เบ—เบตเบชเบญเบ‡, เบšเปเปˆเบกเบตเบ„เบงเบฒเบกเป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰ เบšเปเปˆ เป€เบšเบดเปˆเบ‡เบ‚เบฐเบšเบงเบ™เบเบฒเบ™เบ‚เบญเบ‡เป€เบ”เบฑเบเบ™เป‰เบญเบ, เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบ•เบปเบงเบเบญเบ‡ seccomp เปเบกเปˆเบ™เบชเบทเบšเบ—เบญเบ”เป‚เบ”เบเบ‚เบฐเบšเบงเบ™เบเบฒเบ™เป€เบ”เบฑเบเบ™เป‰เบญเบเบ—เบฑเบ‡เบซเบกเบปเบ”เป‚เบ”เบเบšเปเปˆเบกเบตเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบ›เบดเบ”เบเบฒเบ™เปƒเบŠเป‰เบ‡เบฒเบ™เบ™เบตเป‰.

เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เป€เบฅเบฑเบเบ™เป‰เบญเบเบเปˆเบฝเบงเบเบฑเบšเบงเบดเบ—เบตเปเบ™เปˆเบ™เบญเบ™ strace เป€เบฎเบฑเบ”เบงเบฝเบเบเบฑเบš seccomp เบชเบฒเบกเบฒเบ”เบžเบปเบšเป„เบ”เป‰เบˆเบฒเบ เบšเบปเบ”เบฅเบฒเบเบ‡เบฒเบ™เบ—เบตเปˆเบœเปˆเบฒเบ™เบกเบฒ. เบชเปเบฒเบฅเบฑเบšเบžเบงเบเป€เบฎเบปเบฒ, เบ„เบงเบฒเบกเบˆเบดเบ‡เบ—เบตเปˆเบซเบ™เป‰เบฒเบชเบปเบ™เปƒเบˆเบซเบผเบฒเบเบ—เบตเปˆเบชเบธเบ”เปเบกเปˆเบ™เบงเปˆเบฒ BPF เบ„เบฅเบฒเบชเบชเบดเบเบ—เบตเปˆเป€เบ›เบฑเบ™เบ•เบปเบงเปเบ—เบ™เป‚เบ”เบ seccomp เบเบฑเบ‡เบ–เบทเบเบ™เปเบฒเปƒเบŠเป‰เปƒเบ™เบกเบทเป‰เบ™เบตเป‰.

xt_bpf

เบ•เบญเบ™เบ™เบตเป‰เปƒเบซเป‰เบเบฑเบšเบ„เบทเบ™เบชเบนเปˆเป‚เบฅเบเบ‚เบญเบ‡เป€เบ„เบทเบญเบ‚เปˆเบฒเบ.

เบ„เบงเบฒเบกโ€‹เป€เบ›เบฑเบ™โ€‹เบกเบฒโ€‹: เป€เบ›เบฑเบ™โ€‹เป€เบงโ€‹เบฅเบฒโ€‹เบ”เบปเบ™โ€‹เบ™เบฒเบ™โ€‹เบเปˆเบญเบ™โ€‹เบซเบ™เป‰เบฒโ€‹เบ™เบตเป‰โ€‹, เปƒเบ™โ€‹เบ›เบต 2007โ€‹, เบซเบผเบฑเบโ€‹เบเบฒเบ™โ€‹เปเบกเปˆเบ™โ€‹ เป€เบžเบตเปˆเบก เป‚เบกเบ”เบนเบ™ xt_u32 เบชเปเบฒเบฅเบฑเบš netfilter. เบกเบฑเบ™เบ–เบทเบเบ‚เบฝเบ™เป‚เบ”เบเบเบฒเบ™เบ›เบฝเบšเบ—เบฝเบšเบเบฑเบšเบ•เบปเบงเบˆเบฑเบ”เบ›เบฐเป€เบžเบ”เบเบฒเบ™เบˆเบฐเบฅเบฒเบˆเบญเบ™เบ—เบตเปˆเป€เบเบปเปˆเบฒเปเบเปˆเบเบงเปˆเบฒ cls_u32 เปเบฅเบฐเบญเบฐเบ™เบธเบเบฒเบ”เปƒเบซเป‰เบ—เปˆเบฒเบ™เบ‚เบฝเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบš binary arbitrary เบชเปเบฒเบฅเบฑเบš iptables เป‚เบ”เบเปƒเบŠเป‰เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ‡เปˆเบฒเบเป†เบ•เปเปˆเป„เบ›เบ™เบตเป‰: เป‚เบซเบฅเบ” 32 bits เบˆเบฒเบเบŠเบธเบ”เปเบฅเบฐเบ›เบฐเบ•เบดเบšเบฑเบ”เบŠเบธเบ”เบ‚เบญเบ‡เบเบฒเบ™เบ›เบฐเบ•เบดเบšเบฑเบ”เป€เบฅเบเบ„เบฐเบ™เบดเบ”เบชเบฒเบ”. เบเบปเบโ€‹เบ•เบปเบงโ€‹เบขเปˆเบฒเบ‡,

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

เป‚เบซเบฅเบ” 32 bits เบ‚เบญเบ‡เบซเบปเบง IP, เป€เบฅเบตเปˆเบกเบˆเบฒเบ padding 6, เปเบฅเบฐเบ™เปเบฒเปƒเบŠเป‰เบซเบ™เป‰เบฒเบเบฒเบเปƒเบซเป‰เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ. 0xFF (เป€เบญเบปเบฒ byte เบ•เปˆเปเบฒ). เบžเบฒเบเบชเบฐเบซเบ™เบฒเบกเบ™เบตเป‰ protocol เบซเบปเบง IP เปเบฅเบฐเบžเบงเบเป€เบฎเบปเบฒเบ›เบฝเบšเบ—เบฝเบšเบกเบฑเบ™เบเบฑเบš 1 (ICMP). เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเบปเบกเบ—เบปเบšเบเบฒเบ™เบเบงเบ”เบชเบญเบšเบˆเปเบฒเบ™เบงเบ™เบซเบผเบฒเบเปƒเบ™เบซเบ™เบถเปˆเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบš, เปเบฅเบฐเบ—เปˆเบฒเบ™เบเบฑเบ‡เบชเบฒเบกเบฒเบ”เบ›เบฐเบ•เบดเบšเบฑเบ”เบ•เบปเบงเบ›เบฐเบ•เบดเบšเบฑเบ”เบเบฒเบ™ @ โ€” เบเป‰เบฒเบ X bytes เป„เบ›เบ—เบฒเบ‡เบ‚เบงเบฒ. เบชเปเบฒเบฅเบฑเบšเบ•เบปเบงเบขเปˆเบฒเบ‡, เบเบปเบ”เบฅเบฐเบšเบฝเบš

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

เบเบงเบ”เป€เบšเบดเปˆเบ‡เบงเปˆเบฒ TCP Sequence Number เบšเปเปˆเป€เบ—เบปเปˆเบฒเบเบฑเบ™ 0x29. เบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเบˆเบฐเบšเปเปˆเป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบฅเบฒเบเบฅเบฐเบญเบฝเบ”เบ•เบทเปˆเบกเบญเบตเบ, เป€เบžเบฒเบฐเบงเปˆเบฒเบกเบฑเบ™เป€เบ›เบฑเบ™เบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™เปเบฅเป‰เบงเบงเปˆเบฒเบเบฒเบ™เบ‚เบฝเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบšเบ”เบฑเปˆเบ‡เบเปˆเบฒเบงเบ”เป‰เบงเบเบกเบทเปเบกเปˆเบ™เบšเปเปˆเบชเบฐเบ”เบงเบเบซเบผเบฒเบ. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก BPF - เบฅเบฐเบซเบฑเบ” byte เบฅเบทเบก, เบกเบตเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเป‚เบเบ‡เบซเบผเบฒเบเป†เบขเปˆเบฒเบ‡เบ—เบตเปˆเบกเบตเบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปเบฅเบฐเบเบฒเบ™เบชเป‰เบฒเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบšเบชเปเบฒเบฅเบฑเบš xt_u32. เป€เบšเบดเปˆเบ‡เบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเปƒเบ™เบ•เบญเบ™เบ—เป‰เบฒเบเบ‚เบญเบ‡เบšเบปเบ”เบ„เบงเบฒเบกเบ™เบตเป‰.

เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆ 2013 เป‚เบกเบ”เบนเบ™เปเบ—เบ™เบ—เบตเปˆเบˆเบฐเป€เบ›เบฑเบ™เป‚เบกเบ”เบนเบ™ xt_u32 เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบ™เปเบฒเปƒเบŠเป‰เป‚เบกเบ”เบนเบ™ BPF xt_bpf. เปƒเบœเบเปเปˆเบ•เบฒเบกเบ—เบตเปˆเป„เบ”เป‰เบญเปˆเบฒเบ™เบกเบฒเบ™เบตเป‰เปเบฅเป‰เบงเบ„เบงเบ™เบˆเบฐเบกเบตเบ„เบงเบฒเบกเบŠเบฑเบ”เป€เบˆเบ™เบเปˆเบฝเบงเบเบฑเบšเบซเบผเบฑเบเบเบฒเบ™เบ‚เบญเบ‡เบเบฒเบ™เบ”เปเบฒเป€เบ™เบตเบ™เบ‡เบฒเบ™เบ‚เบญเบ‡เบกเบฑเบ™: เบ”เปเบฒเป€เบ™เบตเบ™เบเบฒเบ™ BPF bytecode เป€เบ›เบฑเบ™เบเบปเบ”เบฅเบฐเบšเบฝเบš iptables. เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เบเบปเบ”เบฅเบฐเบšเบฝเบšเปƒเบซเบกเปˆ, เบ•เบปเบงเบขเปˆเบฒเบ‡เป€เบŠเบฑเปˆเบ™เบ™เบตเป‰:

iptables -A INPUT -m bpf --bytecode <ะฑะฐะนั‚ะบะพะด> -j LOG

เบ—เบตเปˆเบ™เบตเป‰ <ะฑะฐะนั‚ะบะพะด> - เบ™เบตเป‰เปเบกเปˆเบ™เบฅเบฐเบซเบฑเบ”เปƒเบ™เบฎเบนเบšเปเบšเบšเบœเบปเบ™เบœเบฐเบฅเบดเบ”เบ‚เบญเบ‡ assembler bpf_asm เป‚เบ”เบเบ„เปˆเบฒเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™, เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบเบปเบเบ•เบปเบงเบขเปˆเบฒเบ‡,

$ cat /tmp/test.bpf
ldb [9]
jneq #17, ignore
ret #1
ignore: ret #0

$ bpf_asm /tmp/test.bpf
4,48 0 0 9,21 0 1 17,6 0 0 1,6 0 0 0,

# iptables -A INPUT -m bpf --bytecode "$(bpf_asm /tmp/test.bpf)" -j LOG

เปƒเบ™เบ•เบปเบงเบขเปˆเบฒเบ‡เบ™เบตเป‰เบžเบงเบเป€เบฎเบปเบฒเบเปเบฒเบฅเบฑเบ‡เบเบฑเปˆเบ™เบ•เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ” UDP เบ—เบฑเบ‡เบซเบกเบปเบ”. เป€เบ™เบทเป‰เบญเปƒเบ™เบชเปเบฒเบฅเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™ BPF เปƒเบ™เป‚เบกเบ”เบนเบ™ xt_bpfเปเบ™เปˆเบ™เบญเบ™, เบŠเบตเป‰เปƒเบซเป‰เป€เบซเบฑเบ™เป€เบ–เบดเบ‡เบ‚เปเป‰เบกเบนเบ™เปเบžเบฑเบเป€เบเบฑเบ”, เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ‚เบญเบ‡ iptables, เป„เบ›เบซเบฒเบˆเบธเบ”เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เบซเบปเบง IPv4. เบเบฑเบšเบ„เบทเบ™เบกเบนเบ™เบ„เปˆเบฒเบˆเบฒเบเป‚เบ„เบ‡เบเบฒเบ™ BPF เบšเบนเบฅเบตเบ™เบšเปˆเบญเบ™เบ—เบตเปˆ false เปเบฒเบเบ„เบงเบฒเบกเบงเปˆเบฒเปเบžเบฑเบเป€เบเบฑเบ”เบšเปเปˆเบเบปเบ‡เบเบฑเบ™.

เบกเบฑเบ™เป€เบ›เบฑเบ™เบ—เบตเปˆเบŠเบฑเบ”เป€เบˆเบ™เบงเปˆเบฒเป‚เบกเบ”เบนเบ™ xt_bpf เบชเบฐเบซเบ™เบฑเบšเบชเบฐเบซเบ™เบนเบ™เบเบฒเบ™เบเบฑเปˆเบ™เบ•เบญเบ‡เบ—เบตเปˆเบชเบฑเบšเบชเบปเบ™เบซเบผเบฒเบเบเปˆเบงเบฒเบ•เบปเบงเบขเปˆเบฒเบ‡เบ‚เป‰เบฒเบ‡เป€เบ—เบดเบ‡. เปƒเบซเป‰เป€เบšเบดเปˆเบ‡เบ•เบปเบงเบขเปˆเบฒเบ‡เบ—เบตเปˆเปเบ—เป‰เบˆเบดเบ‡เบˆเบฒเบ Cloudfare. เบˆเบปเบ™เบเปˆเบงเบฒเบšเปเปˆเบ”เบปเบ™เบกเบฒเบ™เบตเป‰เบžเบงเบเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเป„เบ”เป‰เบ™เปเบฒเปƒเบŠเป‰เป‚เบกเบ”เบนเบ™ xt_bpf เป€เบžเบทเปˆเบญเบ›เป‰เบญเบ‡เบเบฑเบ™เบเบฒเบ™เป‚เบˆเบกเบ•เบต DDoS. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก เปเบ™เบฐเบ™เบณเป€เบ„เบทเปˆเบญเบ‡เบกเบท BPF เบžเบงเบเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบญเบฐเบ—เบดเบšเบฒเบเบงเบดเบ—เบตเบเบฒเบ™ (เปเบฅเบฐเป€เบ›เบฑเบ™เบซเบเบฑเบ‡) เบžเบงเบเป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒเบชเป‰เบฒเบ‡เบ•เบปเบงเบเบญเบ‡ BPF เปเบฅเบฐเป€เบœเบตเบเปเบœเปˆเบเบฒเบ™เป€เบŠเบทเปˆเบญเบกเบ•เปเปˆเบเบฑเบšเบŠเบธเบ”เบ‚เบญเบ‡เบœเบปเบ™เบ›เบฐเป‚เบซเบเบ”เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบชเป‰เบฒเบ‡เบ•เบปเบงเบเบญเบ‡เบ”เบฑเปˆเบ‡เบเปˆเบฒเบง. เบชเปเบฒเบฅเบฑเบšเบ•เบปเบงเบขเปˆเบฒเบ‡, เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบ›เบฐเป‚เบซเบเบ” bpfgen เบ—เปˆเบฒเบ™เบชเบฒเบกเบฒเบ”เบชเป‰เบฒเบ‡เป‚เบ„เบ‡เบเบฒเบ™ BPF เบ—เบตเปˆเบเบปเบ‡เบเบฑเบšเบ„เปเบฒเบ–เบฒเบก DNS เบชเปเบฒเบฅเบฑเบšเบŠเบทเปˆ habr.com:

$ ./bpfgen --assembly dns -- habr.com
ldx 4*([0]&0xf)
ld #20
add x
tax

lb_0:
    ld [x + 0]
    jneq #0x04686162, lb_1
    ld [x + 4]
    jneq #0x7203636f, lb_1
    ldh [x + 8]
    jneq #0x6d00, lb_1
    ret #65535

lb_1:
    ret #0

เปƒเบ™เป‚เบ„เบ‡เบเบฒเบ™เบžเบงเบเป€เบฎเบปเบฒเบ—เปเบฒเบญเบดเบ”เป‚เบซเบฅเบ”เป€เบ‚เบปเป‰เบฒเป„เบ›เปƒเบ™เบ—เบฐเบšเบฝเบ™ X เบ—เบตเปˆเบขเบนเปˆเป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เปเบ–เบง x04habrx03comx00 เบžเบฒเบเปƒเบ™ UDP datagram เปเบฅเบฐเบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบเบงเบ”เป€เบšเบดเปˆเบ‡เบ„เปเบฒเบฎเป‰เบญเบ‡เบ‚เป: 0x04686162 <-> "x04hab" เปเบฅเบฐเบญเบทเปˆเบ™เป†.

เป€เบฅเบฑเบเบ™เป‰เบญเบเบ•เปเปˆเบกเบฒ, Cloudfare เป€เบœเบตเบเปเบœเปˆเบฅเบฐเบซเบฑเบ” p0f -> BPF compiler. เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบก เบ‚เปเปเบ™เบฐเบ™เปเบฒ p0f BPF compiler เบžเบงเบเป€เบ‚เบปเบฒเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบชเบดเปˆเบ‡เบ—เบตเปˆ p0f เปเบฅเบฐเบงเบดเบ—เบตเบเบฒเบ™เบ›เปˆเบฝเบ™เบฅเบฒเบเป€เบŠเบฑเบ™ p0f เป€เบ›เบฑเบ™ BPF:

$ ./bpfgen p0f -- 4:64:0:0:*,0::ack+:0
39,0 0 0 0,48 0 0 8,37 35 0 64,37 0 34 29,48 0 0 0,
84 0 0 15,21 0 31 5,48 0 0 9,21 0 29 6,40 0 0 6,
...

เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบšเปเปˆเป„เบ”เป‰เปƒเบŠเป‰ Cloudfare เบญเบตเบเบ•เปเปˆเป„เบ› xt_bpf, เบ™เบฑเบšเบ•เบฑเป‰เบ‡เปเบ•เปˆเบžเบงเบเป€เบ‚เบปเบฒเบเป‰เบฒเบเป„เบ› XDP - เบซเบ™เบถเปˆเบ‡เปƒเบ™เบ—เบฒเบ‡เป€เบฅเบทเบญเบเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เบชเบฐเบšเบฑเบšเปƒเบซเบกเปˆเบ‚เบญเบ‡ BPF, เป€เบšเบดเปˆเบ‡. L4Drop: XDP DDoS Mitigations.

cls_bpf

เบ•เบปเบงเบขเปˆเบฒเบ‡เบชเบธเบ”เบ—เป‰เบฒเบเบ‚เบญเบ‡เบเบฒเบ™เปƒเบŠเป‰ BPF เบ„เบฅเบฒเบชเบชเบดเบเปƒเบ™ kernel เปเบกเปˆเบ™เบ•เบปเบงเบˆเบฑเบ”เบ›เบฐเป€เบžเบ” cls_bpf เบชเปเบฒเบฅเบฑเบšเบฅเบฐเบšเบปเบšเบเปˆเบญเบเบเบฒเบ™เบ„เบงเบšเบ„เบธเบกเบเบฒเบ™เบˆเบฐเบฅเบฒเบˆเบญเบ™เปƒเบ™ Linux, เป€เบžเบตเปˆเบกเปƒเบชเปˆ Linux เปƒเบ™เบ—เป‰เบฒเบเบ›เบต 2013 เปเบฅเบฐเบ›เปˆเบฝเบ™เปเบ™เบงเบ„เบงเบฒเบกเบ„เบดเบ”เบ‚เบญเบ‡เบงเบฑเบ”เบ–เบธเบšเบนเบฎเบฒเบ™. cls_u32.

เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบšเปเปˆเบญเบฐเบ—เบดเบšเบฒเบเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบ cls_bpf, เป€เบ™เบทเปˆเบญเบ‡เบˆเบฒเบเบงเปˆเบฒเบˆเบฒเบเบ—เบฑเบ”เบชเบฐเบ™เบฐเบ‚เบญเบ‡เบ„เบงเบฒเบกเบฎเบนเป‰เบเปˆเบฝเบงเบเบฑเบš BPF เบ„เบฅเบฒเบชเบชเบดเบเบ™เบตเป‰เบˆเบฐเบšเปเปˆเปƒเบซเป‰เบžเบงเบเป€เบฎเบปเบฒเบซเบเบฑเบ‡ - เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เบเบฒเบเป€เบ›เบฑเบ™เบ„เบงเบฒเบกเบ„เบธเป‰เบ™เป€เบ„เบตเบเบเบฑเบšเบเบฒเบ™เป€เบฎเบฑเบ”เบงเบฝเบเบ—เบฑเบ‡เบซเบกเบปเบ”. เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ•เปเปˆเป„เบ›เบ—เบตเปˆเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบš Extended BPF, เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเบžเบปเบšเบเบฑเบšเบ•เบปเบงเบˆเบฑเบ”เบ›เบฐเป€เบžเบ”เบ™เบตเป‰เบซเบผเบฒเบเบเบงเปˆเบฒเบซเบ™เบถเปˆเบ‡เบ„เบฑเป‰เบ‡.

เป€เบซเบ”เบœเบปเบ™เบญเบทเปˆเบ™เบ—เบตเปˆเบˆเบฐเบšเปเปˆเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเบเบฒเบ™เปƒเบŠเป‰ BPF เบ„เบฅเบฒเบชเบชเบดเบ c cls_bpf เบšเบฑเบ™เบซเบฒเปเบกเปˆเบ™เบงเปˆเบฒ, เป€เบกเบทเปˆเบญเบ›เบฝเบšเบ—เบฝเบšเบเบฑเบš Extended BPF, เบ‚เบญเบšเป€เบ‚เบ”เบ‚เบญเบ‡เบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เปƒเบ™เบเปเบฅเบฐเบ™เบตเบ™เบตเป‰เปเบกเปˆเบ™เปเบ„เบšเบฅเบปเบ‡เบซเบผเบฒเบ: เป‚เบ„เบ‡เบเบฒเบ™เบ„เบฅเบฒเบชเบชเบดเบเบšเปเปˆเบชเบฒเบกเบฒเบ”เบ›เปˆเบฝเบ™เป€เบ™เบทเป‰เบญเปƒเบ™เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เปเบฅเบฐเบšเปเปˆเบชเบฒเบกเบฒเบ”เบšเบฑเบ™เบ—เบถเบเบชเบฐเบ–เบฒเบ™เบฐเบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เป‚เบ—.

เบชเบฐเบ™เบฑเป‰เบ™เบกเบฑเบ™เป€เบ–เบดเบ‡เป€เบงเบฅเบฒเบ—เบตเปˆเบˆเบฐเบšเบญเบเบฅเบฒเบเบฑเบš BPF เบ„เบฅเบฒเบชเบชเบดเบเปเบฅเบฐเป€เบšเบดเปˆเบ‡เบญเบฐเบ™เบฒเบ„เบปเบ”.

เบญเบณเบฅเบฒ BPF เบ„เบฅเบฒเบชเบชเบดเบ

เบžเบงเบเป€เบฎเบปเบฒเป„เบ”เป‰เป€เบšเบดเปˆเบ‡เบงเบดเบ—เบตเบเบฒเบ™เป€เบ—เบเป‚เบ™เป‚เบฅเบเบต BPF, เบžเบฑเบ”เบ—เบฐเบ™เบฒเปƒเบ™เบ•เบปเป‰เบ™ nineties, เบ›เบฐเบชเบปเบšเบœเบปเบ™เบชเปเบฒเป€เบฅเบฑเบ”เปƒเบ™เบซเบ™เบถเปˆเบ‡เบชเปˆเบงเบ™เบชเบตเปˆเบ‚เบญเบ‡เบชเบฐเบ•เบฐเบงเบฑเบ”เปเบฅเบฐเบˆเบปเบ™เบเปˆเบงเบฒเปƒเบ™เบ•เบญเบ™เบ—เป‰เบฒเบเบ‚เบญเบ‡เบเบฒเบ™เบ„เบปเป‰เบ™เบžเบปเบšเบ„เปเบฒเบฎเป‰เบญเบ‡เบชเบฐเบซเบกเบฑเบเปƒเบซเบกเปˆ. เบขเปˆเบฒเบ‡เปƒเบ”เบเปเบ•เบฒเบก, เบ„เป‰เบฒเบเบ„เบทเบเบฑเบ™เบเบฑเบšเบเบฒเบ™เบซเบฑเบ™เบ›เปˆเบฝเบ™เบˆเบฒเบเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ stack เบเบฑเบš RISC, เป€เบŠเบดเปˆเบ‡เป„เบ”เป‰เบฎเบฑเบšเบœเบดเบ”เบŠเบญเบšเป€เบ›เบฑเบ™เปเบฎเบ‡เบเบฐเบ•เบธเป‰เบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒเบ‚เบญเบ‡ BPF เบ„เบฅเบฒเบชเบชเบดเบ, เปƒเบ™เบŠเบธเบกเบ›เบต 32 เบกเบตเบเบฒเบ™เบซเบฑเบ™เบ›เปˆเบฝเบ™เบˆเบฒเบเป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ 64-bit เบเบฑเบš XNUMX-bit เปเบฅเบฐ BPF เบ„เบฅเบฒเบชเบชเบดเบเป„เบ”เป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ—เบตเปˆเบˆเบฐเบฅเป‰เบฒเบชเบฐเป„เบซเบก. เบ™เบญเบเบˆเบฒเบเบ™เบฑเป‰เบ™, เบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เบ‚เบญเบ‡ BPF เบ„เบฅเบฒเบชเบชเบดเบเปเบกเปˆเบ™เบˆเปเบฒเบเบฑเบ”เบซเบผเบฒเบ, เปเบฅเบฐเบ™เบญเบเป€เบซเบ™เบทเบญเบˆเบฒเบเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเบ—เบตเปˆเบฅเป‰เบฒเบชเบฐเป„เบซเบก - เบžเบงเบเป€เบฎเบปเบฒเบšเปเปˆเบกเบตเบ„เบงเบฒเบกเบชเบฒเบกเบฒเบ”เปƒเบ™เบเบฒเบ™เบŠเปˆเบงเบเบ›เบฐเบขเบฑเบ”เบฅเบฑเบ”เบฅเบฐเบซเบงเปˆเบฒเบ‡เบเบฒเบ™เป‚เบ—เบเบฑเบšเป‚เบ„เบ‡เบเบฒเบ™ BPF, เบšเปเปˆเบกเบตเบ„เบงเบฒเบกเป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบšเบœเบนเป‰เปƒเบŠเป‰เป‚เบ”เบเบเบปเบ‡, เบšเปเปˆเบกเบตเบ„เบงเบฒเบกเป€เบ›เบฑเบ™เป„เบ›เป„เบ”เป‰เบ‚เบญเบ‡เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš. เบเบฑเบš kernel, เบเบปเบเป€เบงเบฑเป‰เบ™เบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบญเปˆเบฒเบ™เบˆเปเบฒเบ™เบงเบ™เบˆเปเบฒเบเบฑเบ”เบ‚เบญเบ‡เบŠเปˆเบญเบ‡เป‚เบ„เบ‡เบชเป‰เบฒเบ‡ sk_buff เปเบฅเบฐเบเบฒเบ™เป€เบ›เบตเบ”เบ•เบปเบงเบซเบ™เป‰เบฒเบ—เบตเปˆเบœเบนเป‰เบŠเปˆเบงเบเบ—เบตเปˆเบ‡เปˆเบฒเบเบ”เบฒเบเบ—เบตเปˆเบชเบธเบ”, เบ—เปˆเบฒเบ™เบšเปเปˆเบชเบฒเบกเบฒเบ”เบ›เปˆเบฝเบ™เป€เบ™เบทเป‰เบญเปƒเบ™เบ‚เบญเบ‡เปเบžเบฑเบเป€เบเบฑเบ”เปเบฅเบฐเบ›เปˆเบฝเบ™เป€เบชเบฑเป‰เบ™เบ—เบฒเบ‡เปƒเบซเป‰เป€เบ‚เบปเบฒเป€เบˆเบปเป‰เบฒ.

เปƒเบ™เบ„เบงเบฒเบกเป€เบ›เบฑเบ™เบˆเบดเบ‡, เบ›เบฐเบˆเบธเบšเบฑเบ™เบ—เบฑเบ‡เบซเบกเบปเบ”เบ—เบตเปˆเบเบฑเบ‡เป€เบซเบผเบทเบญเบ‚เบญเบ‡ BPF เบ„เบฅเบฒเบชเบชเบดเบเปƒเบ™ Linux เปเบกเปˆเบ™เบเบฒเบ™เป‚เบ•เป‰เบ•เบญเบš API, เปเบฅเบฐเบžเบฒเบเปƒเบ™ kernel เบšเบฑเบ™เบ”เบฒเป‚เบ„เบ‡เบเบฒเบ™เบ„เบฅเบฒเบชเบชเบดเบ, เบšเปเปˆเบงเปˆเบฒเบˆเบฐเป€เบ›เบฑเบ™เบ•เบปเบงเบเบญเบ‡ socket เบซเบผเบทเบ•เบปเบงเบเบญเบ‡ seccomp, เบˆเบฐเบ–เบทเบเปเบ›เบญเบฑเบ”เบ•เบฐเป‚เบ™เบกเบฑเบ”เปƒเบ™เบฎเบนเบšเปเบšเบšเปƒเบซเบกเปˆ, Extended BPF. (เบžเบงเบเป€เบฎเบปเบฒเบˆเบฐเป€เบงเบปเป‰เบฒเบเปˆเบฝเบงเบเบฑเบšเป€เบฅเบทเปˆเบญเบ‡เบ™เบตเป‰เบขเปˆเบฒเบ‡เปเบ™เปˆเบ™เบญเบ™เปƒเบ™เบšเบปเบ”เบ„เบงเบฒเบกเบ•เปเปˆเป„เบ›.)

เบเบฒเบ™เบซเบฑเบ™เบ›เปˆเบฝเบ™เป„เบ›เบชเบนเปˆเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปƒเบซเบกเปˆเป„เบ”เป‰เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เปƒเบ™ 2013, เปƒเบ™เป€เบงเบฅเบฒเบ—เบตเปˆ Alexey Starovoitov เบชเบฐเป€เบซเบ™เบตเป‚เบ„เบ‡เบเบฒเบ™เบ›เบฑเบšเบ›เบธเบ‡ BPF. เปƒเบ™โ€‹เบ›เบต 2014 เบเบฒเบ™โ€‹เปเบเป‰โ€‹เป„เบ‚โ€‹เบ—เบตเปˆโ€‹เบชเบญเบ”โ€‹เบ„เป‰เบญเบ‡โ€‹เบเบฑเบ™โ€‹ เป€เบฅเบตเปˆเบกเบ›เบฒเบเบปเบ” เปƒเบ™เบซเบผเบฑเบ. เป€เบ—เบปเปˆเบฒเบ—เบตเปˆเบ‚เป‰เบฒเบžเบฐเป€เบˆเบปเป‰เบฒเป€เบ‚เบปเป‰เบฒเปƒเบˆ, เปเบœเบ™เบเบฒเบ™เป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™เปเบกเปˆเบ™เบžเบฝเบ‡เปเบ•เปˆเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบ‚เบญเบ‡เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปเบฅเบฐ JIT compiler เป€เบžเบทเปˆเบญเป€เบฎเบฑเบ”เบงเบฝเบเบ—เบตเปˆเบกเบตเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบซเบผเบฒเบเบ‚เบถเป‰เบ™เปƒเบ™เป€เบ„เบทเปˆเบญเบ‡เบˆเบฑเบ 64-bit, เปเบ•เปˆเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเป€เบซเบผเบปเปˆเบฒเบ™เบตเป‰เป€เบ›เบฑเบ™เบเบฒเบ™เป€เบฅเบตเปˆเบกเบ•เบปเป‰เบ™เบ‚เบญเบ‡เบšเบปเบ”เปƒเบซเบกเปˆเปƒเบ™เบเบฒเบ™เบžเบฑเบ”เบ—เบฐเบ™เบฒ Linux.

เบšเบปเบ”เบ„เบงเบฒเบกเป€เบžเบตเปˆเบกเป€เบ•เบตเบกเปƒเบ™เบŠเบธเบ”เบ™เบตเป‰เบˆเบฐเบเบงเบกเป€เบญเบปเบฒเบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปเบฅเบฐเบเบฒเบ™เบ™เปเบฒเปƒเบŠเป‰เป€เบ•เบฑเบเป‚เบ™เป‚เบฅเบขเบตเปƒเบซเบกเปˆ, เปƒเบ™เป€เบšเบทเป‰เบญเบ‡เบ•เบปเป‰เบ™เป€เบญเบตเป‰เบ™เบงเปˆเบฒ BPF เบžเบฒเบเปƒเบ™, เบซเบผเบฑเบ‡เบˆเบฒเบเบ™เบฑเป‰เบ™เบ‚เบฐเบซเบเบฒเบ BPF, เปเบฅเบฐเปƒเบ™เบ›เบฑเบ”เบˆเบธเบšเบฑเบ™เบžเบฝเบ‡เปเบ•เปˆ BPF.

เป€เบญเบเบฐเบชเบฒเบ™

  1. Steven McCanne เปเบฅเบฐ Van Jacobson, "BSD Packet Filter: เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒเปƒเบซเบกเปˆเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบˆเบฑเบš Packet เบฅเบฐเบ”เบฑเบšเบœเบนเป‰เปƒเบŠเป‰", https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Steven McCanne, "libpcap: เบชเบฐเบ–เบฒเบ›เบฑเบ”เบ•เบฐเบเบฐเบเปเบฒ เปเบฅเบฐเบงเบดเบ—เบตเบเบฒเบ™เป€เบžเบตเปˆเบกเบ›เบฐเบชเบดเบ”เบ—เบดเบžเบฒเบšเบชเปเบฒเบฅเบฑเบšเบเบฒเบ™เบˆเบฑเบšเปเบžเบฑเบเป€เบเบฑเบ”", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. เบเบฒเบ™เบชเบญเบ™เบเบฒเบ™เบˆเบฑเบšเบ„เบนเปˆ IPtable U32.
  5. BPF - เบฅเบฐเบซเบฑเบ” byte เบฅเบทเบก: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. เบเบฒเบ™โ€‹เบ™เปเบฒโ€‹เบชเบฐโ€‹เป€เบซเบ™เบตโ€‹เป€เบ„เบทเปˆเบญเบ‡โ€‹เบกเบท BPFโ€‹: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. เบžเบฒเบšโ€‹เบฅเบงเบก seccompโ€‹: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: เบšเบฑเบ™เบˆเบธเปเบฅเบฐเบ„เบงเบฒเบกเบ›เบญเบ”เป„เบž: seccomp
  11. habr: เบเบฒเบ™เปเบเบ daemons เบเบฑเบš systemd เบซเบผเบท "เบ—เปˆเบฒเบ™เบšเปเปˆเบ•เป‰เบญเบ‡เบเบฒเบ™ Docker เบชเปเบฒเบฅเบฑเบšเบชเบดเปˆเบ‡เบ™เบตเป‰!"
  12. Paul Chaignon, "strace --seccomp-bpf: a look under the hood", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

เปเบซเบผเปˆเบ‡เบ‚เปเป‰เบกเบนเบ™: www.habr.com

เป€เบžเบตเปˆเบกเบ„เบงเบฒเบกเบ„เบดเบ”เป€เบซเบฑเบ™