小さな子䟛のための BPF、パヌト XNUMX: 叀兞的な BPF

Berkeley Packet Filters (BPF) は、数幎前から英語の技術出版物の衚玙を食っおいる Linux カヌネル テクノロゞです。 カンファレンスでは、BPF の䜿甚ず開発に関する報告が数倚く行われたす。 Linux ネットワヌク サブシステム メンテナの David Miller 氏が Linux Plumbers 2018 で講挔 「この話は XDP に関するものではありたせん」 (XDP は BPF の䜿甚䟋の XNUMX ぀です)。 ブレンダン・グレッグが次のタむトルで講挔 Linux BPF のスヌパヌパワヌ。 トヌケ・ホむランドペルゲンセン 笑うカヌネルがマむクロカヌネルになっおいるずいうこずです。 トヌマス・グラフは次のような考えを掚進しおいたす。 BPFはカヌネル甚のJavaScriptです.

Habré に関する BPF の䜓系的な説明はただありたせん。そのため、䞀連の蚘事で、このテクノロゞヌの歎史に぀いお説明し、アヌキテクチャず開発ツヌルに぀いお説明し、BPF の䜿甚の応甚分野ず実践の抂芁を説明しようず思いたす。 シリヌズのこの蚘事れロでは、叀兞的な BPF の歎史ずアヌキテクチャを説明し、その動䜜原理の秘密も明らかにしたす。 tcpdump, seccomp, strace、ОЌМПгПеЎругПе。

BPF の開発は Linux ネットワヌク コミュニティによっお管理されおおり、BPF の既存の䞻なアプリケヌションはネットワヌクに関連しおいるため、蚱可を埗おいたす。 @ナヌカリオット、玠晎らしいシリヌズに敬意を衚しお、私はこのシリヌズを「小さなもののためのBPF」ず名付けたした。 「小さな子どもたちのネットワヌク」.

BPF の歎史の短いコヌス(c)

最新の BPF テクノロゞは、同じ名前の叀いテクノロゞを改良および拡匵したバヌゞョンであり、珟圚は混乱を避けるためにクラシック BPF ず呌ばれおいたす。 有名なナヌティリティは叀兞的な BPF に基づいお䜜成されたした tcpdump、メカニズム seccomp、あたり知られおいないモゞュヌルも xt_bpf のために iptables ず分類子 cls_bpf。 最新の Linux では、クラシック BPF プログラムは自動的に新しい圢匏に倉換されたすが、ナヌザヌの芳点から芋るず、API はそのたた残されおおり、この蚘事で説明するように、クラシック BPF の新しい甚途がただ芋぀かっおいたす。 この理由から、たた、Linux での叀兞的な BPF の開発の歎史をたどるず、それがどのように、そしおなぜ珟代の圢に進化したのかがより明確になるため、私は叀兞的な BPF に関する蚘事から始めるこずにしたした。

前䞖玀の XNUMX 幎代の終わりに、有名なロヌレンス バヌクレヌ研究所の゚ンゞニアは、前䞖玀の XNUMX 幎代埌半には最新だったハヌドりェア䞊でネットワヌク パケットを適切にフィルタリングする方法の問題に興味を持ちたした。 もずもず CSPF (CMU/Stanford Packet Filter) テクノロゞヌで実装されたフィルタリングの基本的な考え方は、䞍芁なパケットをできるだけ早くフィルタリングするこずでした。 これにより、䞍芁なデヌタがナヌザヌ空間にコピヌされるこずが回避されるためです。 カヌネル空間でナヌザヌ コヌドを実行するためのランタむム セキュリティを提䟛するために、サンドボックス仮想マシンが䜿甚されたした。

ただし、既存のフィルタヌの仮想マシンはスタックベヌスのマシンで実行されるように蚭蚈されおおり、新しい RISC マシンではそれほど効率的に実行されたせんでした。 その結果、バヌクレヌ研究所の゚ンゞニアの努力により、新しい BPF (バヌクレヌ パケット フィルタヌ) テクノロゞヌが開発されたした。その仮想マシン アヌキテクチャは、以䞋のようなよく知られた補品の䞻力である Motorola 6502 プロセッサに基づいお蚭蚈されたした。 アップルII たたは NES。 新しい仮想マシンは、既存の゜リュヌションず比范しおフィルタヌのパフォヌマンスを数十倍向䞊させたした。

BPF マシンのアヌキテクチャ

事䟋を分析しながら、実践的な方法で建築に぀いお孊びたす。 ただし、たず、マシンにナヌザヌがアクセスできる 32 ぀の XNUMX ビット レゞスタ、぀たりアキュムレヌタがあったずしたす。 A ずむンデックスレゞスタ X、曞き蟌みずその埌の読み取りに䜿甚できる 64 バむトのメモリ (16 ワヌド)、およびこれらのオブゞェクトを操䜜するための小芏暡なコマンド システム。 条件匏を実装するためのゞャンプ呜什もプログラム内で䜿甚できたしたが、プログラムのタむムリヌな完了を保蚌するために、ゞャンプは前方にのみ行うこずができ、特にルヌプを䜜成するこずは犁止されおいたした。

マシンを起動するための䞀般的なスキヌムは次のずおりです。 ナヌザヌは、BPF アヌキテクチャ甚のプログラムを䜜成し、 いく぀か カヌネルメカニズム (システムコヌルなど)、プログラムをロヌドしお接続したす。 䞀郚の人に カヌネル内のむベント ゞェネレヌタヌに送信されたす (たずえば、むベントはネットワヌク カヌド䞊の次のパケットの到着です)。 むベントが発生するず、カヌネルはプログラムを実行したずえばむンタヌプリタ内で、マシンのメモリは 䞀郚の人に カヌネル メモリ領域 (受信パケットのデヌタなど)。

䟋を芋お始めるには䞊蚘で十分です。必芁に応じおシステムずコマンドの圢匏に぀いお理解しおいきたす。 仮想マシンのコマンド システムをすぐに調べお、そのすべおの機胜に぀いお知りたい堎合は、元の蚘事を読むこずができたす。 BSDパケットフィルタヌ および/たたはファむルの前半 ドキュメント/ネットワヌク/filter.txt カヌネルのドキュメントから。 たた、プレれンテヌションの勉匷もできたす libpcap: パケット キャプチャのアヌキテクチャず最適化手法、BPF の著者の XNUMX 人であるマッキャンが創造の歎史に぀いお語りたす。 libpcap.

次に、Linux でのクラシック BPF の䜿甚に関する重芁な䟋をすべお怜蚎しおいきたす。 tcpdump (libpcap)、セコンプ、 xt_bpf, cls_bpf.

tcpdump

BPF の開発は、よく知られたナヌティリティであるパケット フィルタリングのフロント゚ンドの開発ず䞊行しお行われたした。 tcpdump。 これは、倚くのオペレヌティング システムで利甚できるクラシック BPF を䜿甚する最も叀く、最も有名な䟋であるため、これを䜿甚しおテクノロゞの研究を開始したす。

(この蚘事のすべおの䟋は Linux 䞊で実行したした 5.6.0-rc6。 䞀郚のコマンドの出力は、読みやすくするために線集されおいたす。)

䟋: IPv6 パケットの芳察

むンタヌフェむス䞊のすべおの IPv6 パケットを調べたいず想像しおみたしょう。 eth0。 これを行うには、プログラムを実行したす tcpdump 簡単なフィルタヌを䜿っお ip6:

$ sudo tcpdump -i eth0 ip6

この堎合、 tcpdump フィルタヌをコンパむルしたす ip6 BPF アヌキテクチャのバむトコヌドに倉換しおカヌネルに送信したす (セクションの詳现を参照) Tcpdump:読み蟌み䞭。 ロヌドされたフィルタは、むンタヌフェむスを通過するすべおのパケットに察しお実行されたす。 eth0。 フィルタヌがれロ以倖の倀を返した堎合 n、その埌、たで n パケットのバむトがナヌザヌ空間にコピヌされ、出力に衚瀺されたす。 tcpdump.

小さな子䟛のための BPF、パヌト XNUMX: 叀兞的な BPF

どのバむトコヌドがカヌネルに送信されたかを簡単に知るこずができるこずがわかりたした。 tcpdump の助けを借りお tcpdump、オプションを付けお実行するず -d:

$ sudo tcpdump -i eth0 -d ip6
(000) ldh      [12]
(001) jeq      #0x86dd          jt 2    jf 3
(002) ret      #262144
(003) ret      #0

XNUMX行目でコマンドを実行したす ldh [12]、これは「レゞスタぞのロヌド」を衚したす。 A アドレス 16 にある半ワヌド (12 ビット) ですが、唯䞀の問題は、どのような皮類のメモリをアドレス指定しおいるのかずいうこずです。 答えは、 x 始たる (x+1)分析されたネットワヌクパケットの第 XNUMX バむト。 むヌサネットむンタヌフェむスからパケットを読み取りたす eth0そしおこれ 手段パケットは次のようになりたす (簡単にするために、パケット内に VLAN タグがないず仮定したす)。

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

したがっお、コマンドを実行した埌、 ldh [12] レゞスタヌにある A フィヌルドがあるでしょう Ether Type — このむヌサネット フレヌムで送信されるパケットのタむプ。 1 行目でレゞスタの内容を比范したす。 A (パッケヌゞタむプ) c 0x86ddそしおこれ そしおありたす 私たちが関心のあるタむプは IPv6 です。 1 行目には、比范コマンドに加えお、さらに XNUMX ぀の列がありたす。 jt 2 О jf 3 — 比范が成功した堎合に進む必芁があるマヌク (A == 0x86ddそしお倱敗したした。 したがっお、成功した堎合 (IPv6) は 2 行目に進み、倱敗した堎合は 3 行目に進みたす。 3 行目ではプログラムはコヌド 0 (パケットをコピヌしない) で終了し、2 行目ではプログラムはコヌドで終了したす。 262144 (最倧 256 キロバむトのパッケヌゞをコピヌしおください)。

より耇雑な䟋: 宛先ポヌトごずに TCP パケットを調べたす

宛先ポヌト 666 を持぀すべおの TCP パケットをコピヌするフィルタヌがどのようなものかを芋おみたしょう。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 IP ヘッダヌの Protocol フィヌルド。TCP パケットのみをコピヌするため、これは論理的です。 プロトコルを比范したす 0x6 (IPPROTO_TCP) 3 行目。

4 行目ず 5 行目で、アドレス 20 にあるハヌフワヌドをロヌドし、次のコマンドを䜿甚したす。 jset XNUMX ぀のうちの XNUMX ぀が蚭定されおいるかどうかを確認したす フラグ - 発行されたマスクの着甚 jset 最䞊䜍 XNUMX ビットはクリアされたす。 XNUMX ビットのうち XNUMX ビットは、パケットがフラグメント化された IP パケットの䞀郚であるかどうか、たた、フラグメント化されおいる堎合は最埌のフラグメントであるかどうかを瀺したす。 XNUMX 番目のビットは予玄されおおり、れロにする必芁がありたす。 敎数パケットも壊れたパケットもチェックしたくないので、XNUMX ビットすべおをチェックしたす。

このリストの䞭で最も興味深いのは行 6 です。 衚珟 ldxb 4*([14]&0xf) レゞスタにロヌドするこずを意味したす X パケットの 4 番目のバむトの䞋䜍 XNUMX ビットを XNUMX で乗算したもの。XNUMX 番目のバむトの䞋䜍 XNUMX ビットはフィヌルドです。 むンタヌネットヘッダヌの長さ IPv4 ヘッダヌ。ヘッダヌの長さをワヌドで保存するため、4 を掛ける必芁がありたす。興味深いこずに、匏は 4*([14]&0xf) は、この圢匏でのみ、たたレゞスタに察しおのみ䜿甚できる特別なアドレス指定スキヌムの指定です。 X、぀たり私たちにも蚀えたせん ldb 4*([14]&0xf) たた ldxb 5*([14]&0xf) (指定できるのは別のオフセットのみです。たずえば、 ldxb 4*([16]&0xf)。 このアドレス指定スキヌムが正確に受信するために BPF に远加されたこずは明らかです。 X (むンデックス レゞスタ) IPv4 ヘッダヌの長さ。

したがっお、7行目で半分の単語をロヌドしようずしたす (X+16)。 14 バむトがむヌサネット ヘッダヌによっお占められおいるこずを思い出しおください。 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
...

出力の最初の XNUMX 行で䜜成したす。 生の゜ケット すべおのむヌサネット フレヌムを読み取り、むンタヌフェむスにバむンドしたす。 eth0。 から 私たちの最初の䟋 私たちはフィルタヌがあるこずを知っおいたす ip は XNUMX ぀の BPF 呜什で構成され、XNUMX 行目ではオプションの䜿甚方法が瀺されおいたす。 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 (すべおのパケットをドロップ)、゜ケットを非ブロッキング モヌドに切り替え、以前のフィルタヌから残っおいる可胜性のあるすべおのパケットを枛算しようずしたす。

たずめるず、クラシック BPF を䜿甚しお Linux 䞊でパッケヌゞをフィルタリングするには、次のような構造の圢匏のフィルタが必芁です。 struct sock_fprog オヌプン゜ケット。その埌、システムコヌルを䜿甚しおフィルタヌを゜ケットに接続できたす。 setsockopt.

興味深いこずに、フィルタヌは生だけでなく、あらゆる゜ケットに接続できたす。 ここ 䟋 すべおの受信 UDP デヌタグラムから最初の XNUMX バむトを陀くすべおを切り取るプログラム。 (蚘事が煩雑にならないように、コヌドにコメントを远加したした。)

ご利甚に぀いお詳しくはこちら setsockopt フィルタヌの接続に぀いおは、を参照しおください。 ゜ケット7、ただし、次のような独自のフィルタヌを䜜成するこずに぀いおは、 struct sock_fprog 助けなしで tcpdump セクションで話したす 自分の手でBPFをプログラミングする.

叀兞的な BPF ず XNUMX 侖简

BPF は 1997 幎に Linux に組み蟌たれ、長い間䞻力であり続けたした。 libpcap 特別な倉曎はありたせん (もちろん Linux 固有の倉曎はありたす) た、しかし䞖界的な状況は倉わりたせんでした。 BPF が進化するずいう最初の深刻な兆候は、゚リック デュマれが提案した 2011 幎に起こりたした。 パッチこれにより、BPF バむトコヌドをネむティブに倉換するトランスレヌタヌである Just In Time Compiler がカヌネルに远加されたす。 x86_64 コヌド。

JIT コンパむラヌは䞀連の倉曎の最初のものでした: 2012 幎 出珟した フィルタを䜜成する機胜 セコンプ、BPF を䜿甚しお、2013 幎 XNUMX 月に 远加されたした モゞュヌル xt_bpf、これにより、次のルヌルを䜜成できたす。 iptables BPF の協力を埗お、2013 幎 XNUMX 月に 远加されたした モゞュヌルでもありたす cls_bpfこれにより、BPF を䜿甚しおトラフィック分類子を䜜成できるようになりたす。

これらすべおの䟋に぀いおは埌ほど詳しく芋おいきたすが、その前に、BPF 甚の任意のプログラムを䜜成しおコンパむルする方法を孊習するのが圹立ちたす。ラむブラリによっお提䟛される機胜があるためです。 libpcap 制限付き (簡単な䟋: フィルタヌが生成される) libpcap 0 ぀の倀 - 0 たたは 40000xXNUMX のみを返すこずができたす、たたは seccomp の堎合のように、䞀般的には適甚されたせん。

自分の手でBPFをプログラミングする

BPF 呜什のバむナリ圢匏を理解したしょう。それは非垞に簡単です。

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

各呜什は 64 ビットを占め、最初の 16 ビットが呜什コヌドで、その埌に XNUMX ビットのむンデントが XNUMX ぀ありたす。 jt О jf、匕数には 32 ビット K、その目的はコマンドごずに異なりたす。 たずえば、次のコマンドは ret、プログラムを終了するコヌドは次のずおりです 6、戻り倀は定数から取埗されたす K。 C では、単䞀の BPF 呜什は構造䜓ずしお衚されたす。

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

プログラム党䜓は構造䜓の圢匏になっおいたす

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

したがっお、私たちはすでにプログラムを曞くこずができたすたずえば、私たちは次の呜什コヌドを知っおいたす 【1]。 フィルタヌはこんな感じになりたす ip6 の 私たちの最初の䟋:

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

プログラム prog 通話䞭に合法的に䜿甚できたす

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

マシンコヌドの圢匏でプログラムを蚘述するのはあたり䟿利ではありたせんが、堎合によっおは必芁になりたす (たずえば、デバッグ、単䜓テストの䜜成、Habré に関する蚘事の執筆など)。 ファむル内の䟿宜䞊 <linux/filter.h> ヘルパヌ マクロが定矩されおいたす。䞊蚘ず同じ䟋は次のように曞き換えるこずができたす。

struct sock_filter code[] = {
        BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 12),
        BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ETH_P_IPV6, 0, 1),
        BPF_STMT(BPF_RET|BPF_K, 0x00040000),
        BPF_STMT(BPF_RET|BPF_K, 0),
}

ただし、このオプションはあたり䟿利ではありたせん。 これは、Linux カヌネル プログラマが掚論したものであり、したがっお、 tools/bpf カヌネルには、クラシック BPF を操䜜するためのアセンブラずデバッガが含たれおいたす。

アセンブリ蚀語はデバッグ出力ず非垞に䌌おいたす tcpdumpですが、さらにシンボリックラベルを指定するこずもできたす。 たずえば、TCP/IPv4 を陀くすべおのパケットをドロップするプログラムを次に瀺したす。

$ cat /tmp/tcp-over-ipv4.bpf
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0

デフォルトでは、アセンブラは次の圢匏でコヌドを生成したす。 <кПлОчествП ОМструкцОй>,<code1> <jt1> <jf1> <k1>,...、TCP の䟋では次のようになりたす。

$ tools/bpf/bpf_asm /tmp/tcp-over-ipv4.bpf
6,40 0 0 12,21 0 3 2048,48 0 0 23,21 0 1 6,6 0 0 4294967295,6 0 0 0,

C プログラマの䟿宜のために、別の出力圢匏を䜿甚できたす。

$ tools/bpf/bpf_asm -c /tmp/tcp-over-ipv4.bpf
{ 0x28,  0,  0, 0x0000000c },
{ 0x15,  0,  3, 0x00000800 },
{ 0x30,  0,  0, 0x00000017 },
{ 0x15,  0,  1, 0x00000006 },
{ 0x06,  0,  0, 0xffffffff },
{ 0x06,  0,  0, 0000000000 },

このテキストは型構造定矩にコピヌできたす。 struct sock_filter、このセクションの冒頭で行ったように。

Linux および netsniff-ng 拡匵機胜

暙準の BPF に加えお、Linux ず tools/bpf/bpf_asm サポヌトず 非暙準セット。 基本的に、呜什は構造䜓のフィヌルドにアクセスするために䜿甚されたす。 struct sk_buff、カヌネル内のネットワヌク パケットを蚘述したす。 ただし、他のタむプのヘルパヌ呜什もありたす。 ldw cpu レゞスタにロヌドされたす A カヌネル関数の実行結果 raw_smp_processor_id()。 (BPF の新しいバヌゞョンでは、これらの非暙準拡匵機胜が拡匵され、メモリ、構造䜓にアクセスし、むベントを生成するためのカヌネル ヘルパヌのセットをプログラムに提䟛したす。) 以䞋は、フィルタヌの興味深い䟋です。拡匵子を䜿甚しおパケットヘッダヌをナヌザヌ空間に送信したす poff、ペむロヌド オフセット:

ld poff
ret a

BPF 拡匵機胜は次の堎合には䜿甚できたせん。 tcpdumpただし、これはナヌティリティ パッケヌゞに぀いお知る十分な理由です。 netsniff-ng、特に高床なプログラムが含たれおいたす netsniff-ngこれには、BPF を䜿甚したフィルタリングに加えお、効果的なトラフィック ゞェネレヌタヌも含たれおおり、BPF よりも高床です。 tools/bpf/bpf_asmず呌ばれる BPF アセンブラ bpfc。 パッケヌゞには非垞に詳现なドキュメントが含たれおいたす。蚘事の最埌にあるリンクも参照しおください。

セコンプ

したがっお、任意の耇雑さの BPF プログラムを䜜成する方法はすでに知っおおり、新しい䟋を怜蚎する準備ができおいたす。その最初の䟋は seccomp テクノロゞヌです。これにより、BPF フィルタヌを䜿甚しお、BPF プログラムで利甚可胜な䞀連のシステム コヌル匕数を管理できたす。特定のプロセスずその子孫。

seccomp の最初のバヌゞョンは 2005 幎にカヌネルに远加されたしたが、プロセスで䜿甚できるシステム コヌルのセットを次のものに制限するずいう XNUMX ぀のオプションしか提䟛しおいなかったため、あたり人気がありたせんでした。 read, write, exit О sigreturn、ルヌルに違反したプロセスは次の方法で匷制終了されたした。 SIGKILL。 ただし、2012 幎に seccomp に BPF フィルタヌを䜿甚する機胜が远加され、蚱可されるシステム コヌルのセットを定矩したり、その匕数のチェックを実行したりできるようになりたした。 (興味深いこずに、Chrome はこの機胜の最初のナヌザヌの XNUMX ぀であり、Chrome 担圓者は珟圚、BPF の新しいバヌゞョンに基づいお KRSI メカニズムを開発し、Linux セキュリティ モゞュヌルのカスタマむズを可胜にしおいたす。) 远加のドキュメントぞのリンクは最埌にありたす。蚘事の。

ハブには seccomp の䜿甚に関する蚘事がすでに掲茉されおいるこずに泚意しおください。おそらく、次のサブセクションを読む前に (たたはその代わりに) 読んでおきたい人もいるでしょう。 蚘事の䞭で コンテナずセキュリティ: seccomp 2007 バヌゞョンず BPF を䜿甚するバヌゞョン (フィルタヌは libseccomp を䜿甚しお生成される) の䞡方の seccomp の䜿甚䟋を瀺し、seccomp ず Docker の接続に぀いお説明し、倚くの圹立぀リンクも提䟛したす。 蚘事の䞭で systemd でデヌモンを分離するか、「これには Docker は必芁ありたせん!」 特に、systemd を実行するデヌモンのシステム コヌルのブラックリストたたはホワむトリストを远加する方法に぀いお説明したす。

次に、フィルタを䜜成しおロヌドする方法を芋おいきたす。 seccomp 裞のCでラむブラリを䜿甚する libseccomp そしお、各オプションの長所ず短所は䜕か、そしお最埌に、プログラムで seccomp がどのように䜿甚されるかを芋おみたしょう。 strace.

seccomp のフィルタヌの䜜成ずロヌド

BPF プログラムの䜜成方法はすでに理解しおいるので、たず seccomp プログラミング むンタヌフェむスを芋おみたしょう。 プロセス レベルでフィルタヌを蚭定でき、すべおの子プロセスが制限を継承したす。 これはシステムコヌルを䜿甚しお行われたす seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

どこ &filter - これは私たちにすでに銎染みのある構造ぞのポむンタです struct sock_fprog、぀たりBPFプログラム。

seccomp のプログラムは゜ケットのプログラムずどう違うのですか? 送信されたコンテキスト。 ゜ケットの堎合はパケットを含むメモリ領域が䞎えられ、seccomp の堎合は次のような構造が䞎えられたした。

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

それは nr は起動されるシステムコヌルの番号です。 arch - 珟圚のアヌキテクチャ (詳现は埌述)、 args - 最倧 XNUMX ぀のシステムコヌル匕数、および instruction_pointer システムコヌルを行ったナヌザヌ空間呜什ぞのポむンタです。 したがっお、たずえば、システムコヌル番号をレゞスタにロヌドするには、 A 私たちは蚀わなければなりたせん

ldw [0]

seccomp プログラムには他にも機胜がありたす。たずえば、コンテキストには 32 ビット アラむンメントによっおのみアクセスでき、フィルタヌをロヌドしようずする堎合はハヌフワヌドたたはバむトをロヌドできたせん。 ldh [0] システムコヌル seccomp 戻りたす EINVAL。 この関数はロヌドされたフィルタヌをチェックしたす seccomp_check_filter() カヌネル。 (面癜いこずに、seccomp 機胜を远加した元のコミットでは、この関数に呜什を䜿甚する蚱可を远加するのを忘れおいたした。 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 ずいう番号が付いた XNUMX ぀のシステム コヌルのブラックリストをチェックしたす。これらのシステム コヌルは䜕ですか? プログラムがどのアヌキテクチャ向けに曞かれたのかがわからないため、確かなこずは蚀えたせん。 したがっお、seccomp の䜜成者は、 申し出 アヌキテクチャ チェックを䜿甚しおすべおのプログラムを開始したす (珟圚のアヌキテクチャはコンテキスト内でフィヌルドずしお瀺されたす) arch 構造 struct seccomp_data。 アヌキテクチャをチェックするず、䟋の冒頭は次のようになりたす。

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

そしお、システムコヌル番号は特定の倀を取埗したす。

次を䜿甚しお seccomp のフィルタヌを䜜成しおロヌドしたす。 libseccomp

ネむティブ コヌドたたは BPF アセンブリでフィルタヌを䜜成するず、結果を完党に制埡できたすが、同時に、移怍性のあるコヌドや読み取り可胜なコヌドを䜿甚するこずが望たしい堎合もありたす。 図曞通はこれを助けおくれたす libseccomp、黒たたは癜のフィルタヌを䜜成するための暙準むンタヌフェむスを提䟛したす。

たずえば、システム コヌルのブラック リストを事前にむンストヌルしお、ナヌザヌが遞択したバむナリ ファむルを実行するプログラムを䜜成しおみたしょう。 䞊の蚘事 (プログラムは読みやすくするために簡略化されおいたす。完党版はこちらでご芧いただけたす) ここで):

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

static int sys_numbers[] = {
        __NR_mount,
        __NR_umount2,
       // ... еще 40 сОстеЌМых вызПвПв ...
        __NR_vmsplice,
        __NR_perf_event_open,
};

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

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

        seccomp_load(ctx);

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

たず配列を定矩したす sys_numbers ブロックする 40 以䞊のシステム コヌル番号。 次に、コンテキストを初期化したす ctx そしおラむブラリに䜕を蚱可したいかを䌝えたす(SCMP_ACT_ALLOW) デフォルトですべおのシステムコヌル (ブラックリストを䜜成する方が簡単です)。 次に、すべおのシステム コヌルをブラックリストに XNUMX ぀ず぀远加したす。 リストからのシステムコヌルに応答しお、 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、自明ではないコヌドを XNUMX 行に収めたす。 䞊蚘の䟋では、倚数のシステム コヌルがある堎合、チェックは単なる比范のリストであるため、実行時間を倧幅に短瞮できたす。 最適化のために、libseccomp には最近、 パッチ付属これにより、フィルタヌ属性のサポヌトが远加されたす。 SCMP_FLTATR_CTL_OPTIMIZE。 この属性を 2 に蚭定するず、フィルタヌがバむナリ怜玢プログラムに倉換されたす。

二分怜玢フィルタヌがどのように機胜するかを確認したい堎合は、以䞋を参照しおください。 単玔なスクリプト、システム コヌル番号をダむダルするこずにより、BPF アセンブラでそのようなプログラムを生成したす。次に䟋を瀺したす。

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

BPF プログラムはむンデント ゞャンプを実行できないため、倧幅に高速に䜕かを曞くこずは䞍可胜です (たずえば、私たちはそれができたせん) jmp A たたは jmp [label+X]) したがっお、すべおの遷移は静的です。

seccomp ず strace

誰もがそのナヌティリティを知っおいたす strace Linux 䞊のプロセスの動䜜を研究するために䞍可欠なツヌルです。 しかし、倚くの人が聞いたこずがあるのは、 パフォヌマンスの問題 このナヌティリティを䜿甚するずき。 事実は、 strace を䜿甚しお実装されたした ptrace(2)そしお、このメカニズムでは、どのシステムコヌルのセットでプロセスを停止する必芁があるか、぀たりコマンドなどを指定するこずはできたせん。

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

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

О

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

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

はほが同時に凊理されたすが、XNUMX 番目のケヌスでは XNUMX ぀のシステム コヌルのみをトレヌスしたいず考えおいたす。

新しいオプション --seccomp-bpfに远加 strace バヌゞョン 5.3 では、プロセスを䜕倍にも高速化でき、XNUMX ぀のシステム コヌルのトレヌスでの起動時間はすでに通垞の起動時間ず同等になっおいたす。

$ 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、パヌト XNUMX: 叀兞的な 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、パヌト XNUMX: 叀兞的な BPF

オプション䜿甚時 --seccomp-bpf 制限が XNUMX ぀ありたす。 たず、既存のプロセスに参加するこずはできたせん (オプション) -p プログラム strace)、これは seccomp でサポヌトされおいないためです。 第二に、可胜性はありたせん ノヌ 子プロセスに泚目しおください。これは、seccomp フィルタがすべおの子プロセスに継承され、これを無効にする機胜がないためです。

正確な方法に぀いおもう少し詳しく説明するず、 strace で動䜜したす seccomp から芋぀けるこずができたす 最近の報告。 私たちにずっお最も興味深い事実は、seccomp に代衚される叀兞的な BPF が珟圚でも䜿甚されおいるこずです。

xt_bpf

さお、ネットワヌクの䞖界に戻りたしょう。

背景: ずっず前の 2007 幎、コアは 远加されたした モゞュヌル xt_u32 ネットフィルタヌ甚。 これは、さらに叀いトラフィック分類子ずの類掚によっお䜜成されたした。 cls_u32 たた、パッケヌゞから 32 ビットをロヌドし、それらに察しお䞀連の算術挔算を実行するずいう単玔な操䜜を䜿甚しお、iptables の任意のバむナリ ルヌルを䜜成できるようになりたした。 䟋えば、

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) ず比范したす。 XNUMX ぀のルヌルに倚くのチェックを結合でき、挔算子を実行するこずもできたす。 @ — X バむトを右に移動したす。 たずえば、次のようなルヌルがありたす。

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

TCP シヌケンス番号が等しくないかどうかを確認したす 0x29。 このようなルヌルを手曞きするのはあたり䟿利ではないこずはすでに明らかであるため、これ以䞊詳しくは説明したせん。 蚘事の䞭で BPF - 忘れられたバむトコヌド、䜿甚䟋ずルヌル生成の䟋を瀺したリンクがいく぀かありたす。 xt_u32。 この蚘事の最埌にあるリンクも参照しおください。

2013 幎以降、モゞュヌルの代わりにモゞュヌルになりたした xt_u32 BPFベヌスのモゞュヌルを䜿甚できたす xt_bpf。 ここたで読んだ人なら、BPF バむトコヌドを iptables ルヌルずしお実行するずいう動䜜原理をすでに理解しおいるはずです。 たずえば、次のように新しいルヌルを䜜成できたす。

iptables -A INPUT -m bpf --bytecode <байткПЎ> -j LOG

ここで <байткПЎ> - これはアセンブラ出力圢匏のコヌドです bpf_asm デフォルトでは、たずえば、

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

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

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

この䟋では、すべおの UDP パケットをフィルタリングしおいたす。 モゞュヌル内の BPF プログラムのコンテキスト xt_bpfもちろん、iptables の堎合はパケット デヌタ、IPv4 ヘッダヌの先頭を指したす。 BPF プログラムからの戻り倀 ブヌル倀どこ false パケットが䞀臎しなかったこずを意味したす。

モゞュヌルであるこずは明らかです xt_bpf は、䞊蚘の䟋よりも耇雑なフィルタヌをサポヌトしおいたす。 Cloudfare の実䟋を芋お​​みたしょう。 最近たで圌らはモゞュヌルを䜿甚しおいたした xt_bpf DDoS 攻撃から保護したす。 蚘事の䞭で BPF ツヌルの玹介 BPF フィルタヌを生成する方法 (およびその理由) を説明し、そのようなフィルタヌを䜜成するための䞀連のナヌティリティぞのリンクを公開したす。 たずえば、ナヌティリティを䜿甚するず、 bpfgen DNS ク゚リず名前を照合する BPF プログラムを䜜成できたす。 habr.com:

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

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

lb_1:
    ret #0

プログラムでは、たずレゞスタにロヌドしたす。 X 行頭アドレス x04habrx03comx00 UDP デヌタグラム内でリク゚ストを確認したす。 0x04686162 <-> "x04hab" 等

少し埌に、Cloudfare が p0f -> BPF コンパむラ コヌドを公開したした。 蚘事の䞭で p0f BPF コンパむラの玹介 圌らは、p0f ずは䜕か、および p0f 眲名を BPF に倉換する方法に぀いお話したす。

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

珟圚はクラりドフェアを䜿甚しおいたせん xt_bpf、新しいバヌゞョンの BPF を䜿甚するためのオプションの XNUMX ぀である XDP に移行したため、を参照しおください。 L4Drop: XDP DDoS 軜枛策.

cls_bpf

カヌネル内でクラシック BPF を䜿甚する最埌の䟋は、分類子です。 cls_bpf Linux のトラフィック制埡サブシステム甚。2013 幎末に Linux に远加され、抂念的に叀代のサブシステムを眮き換えたす。 cls_u32.

ただし、この䜜品に぀いおはここでは説明したせん cls_bpfなぜなら、叀兞的な BPF に関する知識の芳点からは、これは私たちに䜕も埗られないからです。私たちはすでにすべおの機胜に粟通しおいたす。 さらに、拡匵 BPF に぀いお説明する埌続の蚘事では、この分類子を耇数回取り䞊げたす。

叀兞的な BPF c の䜿甚に぀いお話さないもう XNUMX ぀の理由 cls_bpf 問題は、拡匵 BPF ず比范しお、この堎合の適甚範囲が倧幅に狭たっおいるこずです。埓来のプログラムはパッケヌゞの内容を倉曎できず、呌び出し間の状態を保存できたせん。

したがっお、叀兞的な BPF に別れを告げ、未来に目を向ける時が来たした。

叀兞的な BPF に別れを告げる

私たちは、32 幎代初頭に開発された BPF テクノロゞヌが四半䞖玀にわたっおどのように生き続け、最埌たで新たな甚途を芋぀けたのかを調べたした。 しかし、クラシック BPF 開発のきっかけずなったスタック マシンから RISC ぞの移行ず同様に、64 幎代には XNUMX ビット マシンから XNUMX ビット マシンぞの移行があり、クラシック BPF は時代遅れになり始めたした。 さらに、クラシック BPF の機胜は非垞に限られおおり、アヌキテクチャが叀いこずに加えお、BPF プログラムの呌び出しの間に状態を保存する機胜がなく、ナヌザヌずの盎接察話の可胜性がなく、盞互䜜甚する可胜性もありたせん。限られた数の構造䜓フィヌルドの読み取りを陀き、カヌネルを䜿甚 sk_buff 最も単玔なヘルパヌ関数を起動する堎合、パケットの内容を倉曎したり、パケットをリダむレクトしたりするこずはできたせん。

実際、珟圚、Linux のクラシック BPF に残っおいるのは API むンタヌフェむスだけであり、カヌネル内では、゜ケット フィルタヌであっおも seccomp フィルタヌであっおも、すべおのクラシック プログラムは新しい圢匏である拡匵 BPF に自動的に倉換されたす。 (これがどのように起こるのかに぀いおは、次の蚘事で詳しく説明したす。)

新しいアヌキテクチャぞの移行は、Alexey Starovoitov が BPF 曎新スキヌムを提案した 2013 幎に始たりたした。 2014 幎に察応するパッチ 珟れ始めた 栞心にある。 私の理解する限り、圓初の蚈画は 64 ビット マシンでより効率的に実行できるようにアヌキテクチャず JIT コンパむラを最適化するこずだけでしたが、代わりにこれらの最適化が Linux 開発の新しい章の始たりずなりたした。

このシリヌズの今埌の蚘事では、圓初は内郚 BPF、その埌拡匵 BPF、そしお珟圚は単に BPF ずしお知られおいる新しいテクノロゞヌのアヌキテクチャずアプリケヌションに぀いお説明したす。

リファレンス

  1. Steven McCanne および Van Jacobson、「BSD パケット フィルタヌ: ナヌザヌレベルのパケット キャプチャのための新しいアヌキテクチャ」、 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 - 忘れられたバむトコヌド: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. BPF ツヌルの玹介: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. seccomp の抂芁: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: コンテナずセキュリティ: seccomp
  11. habr: systemd でデヌモンを分離する、たたは「これには Docker は必芁ありたせん!」
  12. Paul Chaignon、「strace --seccomp-bpf: 内郚の様子」、 https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

出所 habr.com

コメントを远加したす