BPF maka ụmụntakịrị, akụkụ efu: BPF kpochapụwo

Berkeley Packet Filters (BPF) bụ teknụzụ kernel Linux dị n'ihu ihu akwụkwọ teknụzụ Bekee kemgbe ọtụtụ afọ ugbu a. Mgbakọ jupụtara na akụkọ gbasara ojiji na mmepe nke BPF. David Miller, onye na-ahụ maka netwọkụ netwọkụ Linux, na-akpọ okwu ya na Linux Plumbers 2018 "Okwu a abụghị maka XDP" (XDP bụ otu ihe eji eme BPF). Brendan Gregg na-ekwu okwu isiokwu ya Linux BPF Superpowers. Toke Høiland-Jørgensen na-achị ọchịna kernel bụzi microkernel. Thomas Graf na-akwalite echiche ahụ BPF bụ javascript maka kernel.

Enweghị nkọwa nhazi nke BPF na Habré, ya mere, n'ọtụtụ isiokwu, m ga-agbalị ikwu banyere akụkọ ihe mere eme nke nkà na ụzụ, kọwaa ihe owuwu na ngwá ọrụ mmepe, ma kọwaa akụkụ nke ngwa na omume nke iji BPF. Edemede a, efu, na usoro a, na-akọ akụkọ ihe mere eme na ihe owuwu nke BPF kpochapụwo, ma na-ekpughekwa ihe nzuzo nke ụkpụrụ ọrụ ya. tcpdump, seccomp, strace, na ọtụtụ ndị ọzọ.

Ndị ọrụ netwọk Linux na-achịkwa mmepe nke BPF, ngwa ndị bụ isi nke BPF metụtara netwọk na ya mere, na ikike. @eucariot, Akpọrọ m usoro "BPF maka ụmụntakịrị", na-asọpụrụ nnukwu usoro "Networks maka ụmụaka".

Obere nkuzi na akụkọ ihe mere eme nke BPF(c)

Nkà na ụzụ BPF ọgbara ọhụrụ bụ ụdị teknụzụ ochie emelitere na gbasaara otu aha, nke a na-akpọ BPF kpochapụwo ugbu a iji zere ọgba aghara. Emepụtara ngwa amaara nke ọma dabere na BPF kpochapụrụ tcpdump, usoro seccomp, yana modul mara nke ọma xt_bpf n'ihi na iptables na classifier cls_bpf. Na Linux nke oge a, a na-asụgharị mmemme BPF kpochapụwo na-akpaghị aka n'ụdị ọhụrụ, Otú ọ dị, site n'echiche onye ọrụ, API nọgidere na-adị na ojiji ọhụrụ maka BPF kpochapụwo, dị ka anyị ga-ahụ n'isiokwu a, ka na-achọta. N'ihi nke a, nakwa n'ihi na ịgbaso akụkọ ihe mere eme nke mmepe nke oge gboo BPF na Linux, ọ ga-edokwuo anya otú na ihe mere o si malite n'ime ya ọgbara ọhụrụ ụdị, M kpebiri na-amalite na isiokwu banyere oge gboo BPF.

Na njedebe nke narị afọ asatọ nke narị afọ gara aga, ndị injinia sitere na ụlọ nyocha Lawrence Berkeley a ma ama nwere mmasị na ajụjụ banyere otu esi enyocha ngwugwu netwọkụ nke ọma na ngwaike nke dị ugbu a na ngwụcha iri asatọ nke narị afọ gara aga. Echiche bụ isi nke nzacha, nke etinyere na teknụzụ CSPF (CMU/Stanford Packet Filter), bụ iji nyochaa ngwugwu na-adịghị mkpa ozugbo enwere ike, ya bụ. na oghere kernel, ebe nke a na-ezere iṅomi data na-adịghị mkpa n'ime oghere onye ọrụ. Iji weta nchekwa oge ọsọ maka ịgba ọsọ koodu onye ọrụ na oghere kernel, ejiri igwe mebere nke nwere igbe aja.

Agbanyeghị, igwe mebere maka ihe nzacha ndị dị adị ka emebere ka ọ na-agba n'igwe ndị dabere na stack na anaghị arụ ọrụ nke ọma na igwe RISC ọhụrụ. N'ihi ya, site na mbọ nke injinia si Berkeley Labs, e mepụtara ọhụrụ BPF (Berkeley Packet Filters) technology, mebere igwe ije nke e mere dabere na Motorola 6502 processor - workhorse nke ndị a maara nke ọma ngwaahịa dị ka. Apple II ma ọ bụ NES. Igwe mebere ọhụrụ ahụ mụbara arụmọrụ nzacha ugboro iri na-atụnyere ihe ngwọta dị adị.

BPF igwe ije

Anyị ga-amata ụkpụrụ ụlọ n'ụzọ ọrụ, na-enyocha ihe atụ. Agbanyeghị, iji malite, ka anyị kwuo na igwe ahụ nwere ndekọ abụọ 32-bit nwere ike ịnweta onye ọrụ, onye na-akwakọba. A na ndekọ ndekọ X, 64 bytes nke ebe nchekwa (okwu 16), dị maka ide na ịgụ akwụkwọ na-esote, yana obere usoro iwu maka ịrụ ọrụ na ihe ndị a. Ntuziaka jumps maka mmejuputa okwu ọnọdụ dị na mmemme ahụ, mana iji kwe nkwa mmecha nke mmemme ahụ n'oge, a ga-eme ka jumps ga-aga n'ihu, ya bụ, karịsịa, a machibidoro iwu ịmepụta loops.

Atụmatụ izugbe maka ịmalite igwe bụ nke a. Onye ọrụ na-emepụta mmemme maka ụlọ ọrụ BPF na, na-eji ụfọdụ Usoro kernel (dị ka oku sistemụ), na-ebu ma jikọọ mmemme na nye ụfọdụ na ihe na-emepụta ihe omume na kernel (dịka ọmụmaatụ, ihe omume bụ mbata nke ngwugwu ọzọ na kaadị netwọk). Mgbe ihe omume mere, kernel na-eme mmemme (dịka ọmụmaatụ, na ntụgharị okwu), ebe nchekwa igwe dabara na ya. nye ụfọdụ mpaghara ebe nchekwa kernel (dịka ọmụmaatụ, data nke ngwugwu mbata).

Ihe dị n'elu ga-ezuru anyị ịmalite ilele ihe atụ: anyị ga-amata usoro na usoro iwu dị ka ọ dị mkpa. Ọ bụrụ na ịchọrọ ịmụ ngwa ngwa usoro iwu nke igwe mebere ma mụta banyere ike ya niile, mgbe ahụ ị nwere ike ịgụ akụkọ mbụ. Ihe nzacha BSD na/ma ọ bụ ọkara mbụ nke faịlụ ahụ Documentation/networking/filter.txt site na akwụkwọ kernel. Na mgbakwunye, ị nwere ike ịmụ ihe ngosi libpcap: Usoro nhazi na njikarịcha maka ijide ngwugwu, nke McCanne, otu n'ime ndị edemede nke BPF, na-ekwu maka akụkọ ihe mere eme nke okike libpcap.

Ugbu a anyị na-aga n'ihu ịtụle ihe atụ niile dị mkpa nke iji BPF kpochapụwo na Linux: tcpdump (libpcap), nke abụọ, xt_bpf, cls_bpf.

cma

Emere mmepe nke BPF n'otu n'otu na mmepe nke frontend maka nzacha ngwugwu - ihe a ma ama. tcpdump. Ma, ebe nke a bụ ihe atụ kacha ochie na ama ama nke iji BPF kpochapụwo, dị na ọtụtụ sistemụ arụmọrụ, anyị ga-eji ya malite ọmụmụ ihe gbasara teknụzụ.

(M gbapụrụ ihe atụ niile dị n'isiokwu a na Linux 5.6.0-rc6. E deziela mmepụta nke ụfọdụ iwu maka ịgụpụta nke ọma.)

Ọmụmaatụ: na-ekiri ngwugwu IPv6

Ka anyị were ya na anyị chọrọ ilele ngwugwu IPv6 niile na interface eth0. Iji mee nke a, anyị nwere ike na-agba ọsọ mmemme tcpdump na nzacha dị mfe ip6:

$ sudo tcpdump -i eth0 ip6

N'ihi ya tcpdump na-achịkọta nzacha ip6 n'ime BPF architecture bytecode wee ziga ya na kernel (lee nkọwa na ngalaba Tcpdump: na-ebu). A ga-agba ọsọ nzacha ahụ maka ngwugwu ọ bụla na-agafe na interface ahụ eth0. Ọ bụrụ nzacha weghachi uru na-abụghị efu n, wee ruo n A ga-e copyomi bytes nke ngwugwu ahụ na oghere onye ọrụ ma anyị ga-ahụ ya na mmepụta tcpdump.

BPF maka ụmụntakịrị, akụkụ efu: BPF kpochapụwo

Ọ tụgharịrị na anyị nwere ike ịchọpụta ngwa ngwa nke bytecode ezigara na kernel tcpdump site n'enyemaka nke tcpdump, ma ọ bụrụ na anyị na-agba ọsọ ya na nhọrọ -d:

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

Na efu efu anyị na-agba iwu ldh [12], nke pụtara “load into register A ọkara okwu (16 bits) dị na adreesị 12" na naanị ajụjụ bụ ụdị ebe nchekwa anyị na-ekwu? Azịza ya bụ na x amalite (x+1)th byte nke ngwugwu netwọk nyochara. Anyị na-agụ ngwugwu sitere na interface Ethernet eth0, na nke a pụtarana ngwugwu ahụ dị ka nke a (maka ịdị mfe, anyị na-eche na enweghị mkpado VLAN na ngwugwu):

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

Yabụ mgbe ịmechara iwu ahụ ldh [12] na ndekọ A a ga-enwe ubi Ether Type - ụdị ngwugwu ebufere na etiti Ethernet a. Na ahịrị 1 anyị na-atụnyere ọdịnaya nke ndekọ ahụ A (ụdị ngwugwu) c 0x86dd, na nke a ma nwee Ụdị anyị nwere mmasị na ya bụ IPv6. Na ahịrị 1, na mgbakwunye na iwu ntụnyere, enwere ogidi abụọ ọzọ - jt 2 и jf 3 - akara nke ịchọrọ ịga ma ọ bụrụ na ntụnyere ahụ gara nke ọma (A == 0x86dd) na enweghị ihe ịga nke ọma. Ya mere, n'ọnọdụ na-aga nke ọma (IPv6) anyị na-aga na ahịrị 2, na ikpe na-emeghị nke ọma - n'ahịrị 3. N'ahịrị 3 ihe omume ahụ na-ejedebe na koodu 0 (e depụtala ngwugwu), na akara 2 usoro ihe omume ahụ kwụsịrị na koodu. 262144 (detuo m ihe kacha nke 256 kilobytes).

Ihe atụ gbagwojuru anya: anyị na-elele ngwugwu TCP site na ọdụ ụgbọ mmiri

Ka anyị hụ ihe nzacha dị ka nke ahụ na-ebipụta ngwugwu TCP niile na ọdụ ụgbọ mmiri 666. Anyị ga-atụle ikpe IPv4, ebe ọ bụ na ikpe IPv6 dị mfe. Mgbe ị gụsịrị ihe atụ a, ị nwere ike nyochaa nzacha IPv6 onwe gị dị ka mgbatị ahụ (ip6 and tcp dst port 666) na nzacha maka ikpe izugbe (tcp dst port 666). Yabụ, nzacha anyị nwere mmasị na ya dị ka nke a:

$ 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

Anyị amaralarị ihe ahịrị 0 na 1 na-eme. Na ahịrị 2 anyị enyochalarị na nke a bụ ngwugwu IPv4 (Etherdị Ether = 0x800) ma tinye ya na ndekọ A 24th byte nke ngwugwu. Ngwungwu anyị dị ka

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

nke pụtara na anyị na-ebuba n'ime ndekọ A ubi Protocol nke nkụnye eji isi mee IP, nke bụ ihe ezi uche dị na ya, n'ihi na anyị chọrọ idetu naanị ngwugwu TCP. Anyị na-atụnyere Protocol 0x6 (IPPROTO_TCP) n'ahịrị 3.

Na ahịrị 4 na 5 anyị na-ebunye ọkara okwu dị na adreesị 20 wee jiri iwu ahụ jset lelee ma edobere otu n'ime ha atọ ọkọlọtọ - iyi ihe mkpuchi e nyere jset a na-ekpochapụ ihe atọ kachasị mkpa. Abụọ n'ime ibe atọ ahụ na-agwa anyị ma ngwugwu a bụ akụkụ nke ngwugwu IP ekewapụrụ, ma ọ bụrụ otú ahụ, ma ọ bụ iberibe ikpeazụ. Edebere bit nke atọ na ọ ga-abụrịrị efu. Anyị achọghị ịlele ngwugwu ezughị ezu ma ọ bụ gbajiri agbaji, yabụ anyị na-elele ibe atọ ahụ.

Ahịrị 6 kacha amasị na ndepụta a. Nkwuputa ldxb 4*([14]&0xf) pụtara na anyị na-ebuba n'ime ndekọ X nke kacha nta dị ịrịba ama anọ nke byte nke iri na ise nke ngwugwu ahụ mụbara site na 4. Nke kacha nta dị ịrịba ama anọ nke byte nke iri na ise bụ ubi. Ogologo isi ihe ntanetị IPv4 nkụnye eji isi mee, nke na-echekwa ogologo nkụnye eji isi mee na okwu, ya mere, ị ga-mgbe ahụ mkpa ka mụbaa site 4. Na-akpali mmasị, okwu. 4*([14]&0xf) bụ aha maka atụmatụ okwu pụrụ iche nke enwere ike iji naanị n'ụdị a yana naanị maka ndebanye aha X, i.e. anyị enweghị ike ikwu ldb 4*([14]&0xf) abughikwa ldxb 5*([14]&0xf) (anyị nwere ike ịkọwapụta ụgwọ dị iche, dịka ọmụmaatụ, ldxb 4*([16]&0xf)). O doro anya na atụmatụ a na-agwa okwu agbakwunyere na BPF kpomkwem iji nweta X (ndebanye aha index) IPv4 nkụnye eji isi mee ogologo.

Yabụ na ahịrị 7 anyị na-agbalị ibu ọkara otu okwu na (X+16). Icheta na 14 bytes na-eji nkụnye eji isi mee Ethernet, na X nwere ogologo nke nkụnye eji isi mee IPv4, anyị ghọtara na n'ime A Ajuju ọdụ ụgbọ mmiri ebe TCP:

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

N'ikpeazụ, na ahịrị 8 anyị na-atụnyere ọdụ ụgbọ mmiri na-aga na uru achọrọ yana na ahịrị 9 ma ọ bụ 10 anyị na-eweghachi nsonaazụ - ma ọ ga-eṅomi ngwugwu ma ọ bụ na ọ bụghị.

Tcpdump: na-ebu

N'ihe atụ ndị gara aga, anyị etinyeghị nkọwa n'ụzọ zuru ezu ka anyị si ebubata bytecode BPF n'ime kernel maka nzacha ngwugwu. N'ikwu okwu n'ozuzu, tcpdump ported na ọtụtụ sistemụ yana maka ịrụ ọrụ na nzacha tcpdump na-eji ụlọ akwụkwọ libpcap. Na nkenke, idowe nzacha na interface iji libpcap, ịkwesịrị ịme ihe ndị a:

Ka ịhụ ka ọrụ pcap_setfilter etinyere na Linux, anyị na-eji strace (ewepụrụ ahịrị ụfọdụ):

$ 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
...

Na ahịrị abụọ mbụ nke mmepụta anyị na-emepụta raw oghere ka ịgụọ okpokolo agba Ethernet niile wee kechie ya na interface ahụ eth0. Site na ihe atụ mbụ anyị anyị maara na nyo ip ga-enwe ntuziaka BPF anọ, na ahịrị nke atọ anyị na-ahụ ka esi eji nhọrọ ahụ SO_ATTACH_FILTER oku usoro setsockopt anyị na-ebu ma jikọọ nzacha nke ogologo 4. Nke a bụ nzacha anyị.

Ọ bụ ihe kwesịrị ịrịba ama na na kpochapụwo BPF, loading na jikọọ a nyo na-eme mgbe niile dị ka ihe atọmịk ọrụ, na na ọhụrụ version nke BPF, loading omume na ejikọta ya na ihe omume generator na-ekewa n'ime oge.

Eziokwu zoro ezo

Ụdị mmepụta zuru oke dị ka nke a:

$ 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
...

Dịka e kwuru n'elu, anyị na-ebu ma jikọta nzacha anyị na oghere dị na ahịrị 5, mana gịnị na-eme na ahịrị 3 na 4? Ọ na-apụta na nke a libpcap na-elekọta anyị - nke mere na mmepụta nke nzacha anyị adịghị agụnye ngwugwu ndị na-adịghị eju ya afọ, ọbá akwụkwọ na-ejikọ nzacha nzacha ret #0 (dobe ngwugwu niile), gbanwee oghere ka ọ bụrụ ọnọdụ anaghị egbochi ma gbalịa iwepụ ngwugwu niile nwere ike ịdị na nzacha gara aga.

Na mkpokọta, iji nyochaa ngwugwu na Linux site na iji BPF kpochapụwo, ịkwesịrị ịnwe nzacha n'ụdị nhazi dịka struct sock_fprog na oghere mepere emepe, mgbe nke ahụ gasịrị enwere ike itinye nzacha na oghere site na iji oku usoro setsockopt.

N'ụzọ na-akpali mmasị, nzacha nwere ike itinye ya na oghere ọ bụla, ọ bụghị naanị raw. Ebe a ihe atụ mmemme nke na-ebipụ ihe niile ma ewezuga bytes abụọ mbụ na datagram UDP niile na-abata. (M gbakwunyere nkọwa na koodu ahụ ka ọ ghara ịchịkọta akụkọ ahụ.)

Nkọwa ndị ọzọ gbasara ojiji setsockopt maka ijikọ ihe nzacha, hụ oghere (7), mana banyere ide ihe nzacha nke gị dị ka struct sock_fprog na-enweghị enyemaka tcpdump anyị ga-ekwu na ngalaba Iji aka nke aka anyị were hazie BPF.

BPF kpochapụwo na narị afọ nke XNUMXst

BPF etinyere na Linux na 1997 ma nọgide na-arụ ọrụ ogologo oge libpcap enweghị mgbanwe ọ bụla pụrụ iche (mgbanwe pụrụ iche Linux, n'ezie, ọ bụ, ma ha agbanweghị ihe osise zuru ụwa ọnụ). Ihe ịrịba ama mbụ dị njọ na BPF ga-apụta na 2011, mgbe Eric Dumazet tụrụ aro kwachie, nke na-agbakwunye Just In Time Compiler na kernel - onye ntụgharị maka ịtụgharị BPF bytecode ka ọ bụrụ nwa amaala. x86_64 koodu.

JIT compiler bụ nke mbụ na yinye mgbanwe: na 2012 pụtara ike ide ihe nzacha maka sekọnd, iji BPF, na Jenụwarị 2013 enwere gbakwunyere na modul xt_bpf, nke na-enye gị ohere ide iwu maka iptables site n'enyemaka nke BPF, na October 2013 bụ gbakwunyere nakwa modul cls_bpf, nke na-enye gị ohere iji BPF dee ọkwa okporo ụzọ.

Anyị ga-elele ihe atụ ndị a niile n'ụzọ zuru ezu n'oge na-adịghị anya, mana nke mbụ ọ ga-abara anyị uru ịmụta ka esi ede na chịkọta mmemme aka ike maka BPF, ebe ọ bụ na ikike nke ụlọ akwụkwọ ahụ nyere. libpcap nwere oke (atụ atụ dị mfe: emepụtara nzacha libpcap nwere ike ịlaghachi naanị ụkpụrụ abụọ - 0 ma ọ bụ 0x40000) ma ọ bụ n'ozuzu, dị ka ọ dị n'ihe banyere seccomp, adịghị etinye ya.

Iji aka nke aka anyị were hazie BPF

Ka anyị mata usoro ọnụọgụ abụọ nke ntuziaka BPF, ọ dị mfe:

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

Ntuziaka ọ bụla nwere 64 ibe n'ibe, nke mbụ 16 ibe n'ibe bụ koodu ntụziaka, mgbe ahụ e nwere abụọ asatọ-bit indents, jt и jf, na 32 bit maka arụmụka K, nzube ya dịgasị iche site n'iwu ruo n'iwu. Dịka ọmụmaatụ, iwu ahụ ret, nke na-akwụsị mmemme nwere koodu 6, a na-ewepụkwa uru nlọghachi site na mgbe niile K. Na C, a na-anọchi anya otu ntụziaka BPF dị ka nhazi

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

na mmemme dum dị n'ụdị nhazi

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

Ya mere, anyị nwere ike dee mmemme (dịka ọmụmaatụ, anyị maara koodu ntụziaka site na [1]). Nke a bụ ihe nzacha ga-adị ka ip6 si ihe atụ mbụ anyị:

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,
};

Mmemme prog anyị nwere ike iji n'ụzọ iwu kwadoro na oku

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

Ide mmemme n'ụdị koodu igwe anaghị adabara nke ukwuu, mana mgbe ụfọdụ ọ dị mkpa (dịka ọmụmaatụ, maka nbipu, imepụta ule otu, ide akụkọ na Habré, wdg). Maka ịdị mma na faịlụ <linux/filter.h> Akọwapụtara macros inyeaka - enwere ike idegharị otu ihe atụ dị n'elu dị ka

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),
}

Otú ọ dị, nhọrọ a adịghị mma. Nke a bụ ihe ndị mmemme kernel Linux chere, ya mere na ndekọ tools/bpf kernels ị nwere ike ịchọta onye na-agbakọta na debugger maka ịrụ ọrụ na BPF kpochapụwo.

Asụsụ mgbakọ dị nnọọ ka mmepụta ihe nbibi tcpdump, ma na mgbakwunye na anyị nwere ike ezipụta akara akara. Dịka ọmụmaatụ, ebe a bụ mmemme na-atụfu ngwugwu niile ma e wezụga TCP/IPv4:

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

Site na ndabara, onye na-agbakọta na-ewepụta koodu na usoro <количество инструкций>,<code1> <jt1> <jf1> <k1>,..., maka ihe atụ anyị na TCP ọ ga-abụ

$ 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,

Maka ịdị mma nke ndị mmemme C, enwere ike iji usoro mmepụta dị iche:

$ 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 },

Enwere ike iṅomi ederede a n'ime nkọwa nhazi ụdị struct sock_filter, dị ka anyị mere ná mmalite nkebi a.

Linux na netsniff-ng ndọtị

Na mgbakwunye na ọkọlọtọ BPF, Linux na tools/bpf/bpf_asm nkwado na na-abụghị ọkọlọtọ set. N'ụzọ bụ isi, a na-eji ntuziaka iji nweta ubi nke ihe owuwu struct sk_buff, nke na-akọwa ngwugwu netwọk na kernel. Otú ọ dị, e nwekwara ụdị ntụziaka enyemaka ndị ọzọ, dịka ọmụmaatụ ldw cpu ga-ebuba n'ime ndekọ A nsonaazụ nke ịrụ ọrụ kernel raw_smp_processor_id(). (N'ụdị ọhụrụ nke BPF, agbatịwo ndọtị ndị a na-abụghị ọkọlọtọ iji nye mmemme nwere ihe enyemaka kernel maka ịnweta ebe nchekwa, ihe owuwu na imepụta ihe omume.) Nke a bụ ihe atụ na-adọrọ mmasị nke nzacha nke anyị na-eṅomi naanị ihe nkụnye eji isi mee n'ime oghere onye ọrụ site na iji ndọtị poff, akwụ ụgwọ akwụ ụgwọ:

ld poff
ret a

Enweghị ike iji ndọtị BPF mee ihe na tcpdump, ma nke a bụ ezigbo ihe mere ị ga-eji mara ngwugwu ọrụ netsniff-ng, nke, n'etiti ihe ndị ọzọ, nwere mmemme dị elu netsniff-ng, nke, na mgbakwunye na nzacha site na iji BPF, nwekwara ihe na-emepụta ihe na-emepụta okporo ụzọ dị irè, ma dị elu karịa tools/bpf/bpf_asm, onye mgbakọ BPF kpọrọ bpfc. Ngwungwu ahụ nwere akwụkwọ zuru ezu, hụkwa njikọ ndị dị na njedebe nke akụkọ ahụ.

sekọnd

Ya mere, anyị na-ama mara otú e si dee BPF mmemme nke aka ike complexity na dị njikere anya ọhụrụ atụ, nke mbụ nke bụ seccomp technology, nke na-enye ohere, iji BPF nzacha, jikwaa set na set nke usoro oku arụmụka dị ka usoro enyere na ụmụ ya.

Agbakwunyere ụdị nke mbụ nke seccomp na kernel na 2005 ma ọ bụghị nke a ma ama, ebe ọ bụ na ọ na-enye naanị otu nhọrọ - iji kpachie usoro oku sistemụ dị na usoro ndị a: read, write, exit и sigreturn, na usoro nke mebiri iwu na-eji SIGKILL. Otú ọ dị, na 2012, seccomp gbakwunyere ikike iji ihe nzacha BPF, na-enye gị ohere ịkọwapụta otu usoro oku na-ekwe ka ọ na-eme ma mee nyocha na arụmụka ha. (N'ụzọ na-akpali mmasị, Chrome bụ otu n'ime ndị ọrụ mbụ nke ọrụ a, na ndị Chrome na-emepụta usoro KRSI ugbu a dabere na ụdị ọhụrụ nke BPF na ikwe ka nhazi nke Linux Security Modules.) Enwere ike ịchọta njikọ na akwụkwọ ndị ọzọ na njedebe. nke isiokwu.

Rịba ama na enweelarị akụkọ na hub gbasara iji seccomp, ikekwe mmadụ ga-achọ ịgụ ha tupu (ma ọ bụ kama) ịgụ akụkụ ndị a. N'isiokwu Akpa na nchekwa: seccomp na-enye ihe atụ nke iji seccomp, ma ụdị 2007 na ụdị na-eji BPF (a na-emepụta ihe nzacha site na iji libseccomp), na-ekwu maka njikọ nke seccomp na Docker, ma na-enyekwa ọtụtụ njikọ bara uru. N'isiokwu Kewapụ daemons na sistemụ ma ọ bụ "ịchọghị Docker maka nke a!" Ọ na-ekpuchi, karịsịa, otu esi agbakwunye blacklists ma ọ bụ whitelists nke usoro oku maka daemons na-agba ọsọ systemd.

Ọzọ anyị ga-ahụ ka esi ede na ibu ihe nzacha maka seccomp na iferi C na iji ụlọ akwụkwọ libseccomp na kedu uru na ọghọm nke nhọrọ ọ bụla, na n'ikpeazụ, ka anyị hụ ka seccomp si eji mmemme eme ihe. strace.

Ide ihe na ntinye ihe nzacha maka sekọnd

Anyị amaralarị ka esi ede mmemme BPF, yabụ ka anyị buru ụzọ leba anya na interface mmemme nke seccomp. Ị nwere ike ịtọ nzacha na ọkwa usoro, na usoro ụmụaka niile ga-eketa ihe mgbochi. A na-eme nke a site na iji oku sistemụ seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

ebe &filter - Nke a bụ ihe ntụnye aka na usoro nke anyị maara nke ọma struct sock_fprog, i.e. Mmemme BPF.

Kedu ka mmemme maka seccomp si dị iche na mmemme maka sọket? Ọnọdụ ebufere. N'ihe banyere sọket, e nyere anyị ebe nchekwa nke nwere ngwugwu ahụ, na nke seccomp, e nyere anyị ihe owuwu dị ka.

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

ọ bụ nr bụ nọmba nke usoro oku a ga-ebido, arch - ihe owuwu ugbu a (karịa na nke a n'okpuru), args - ruo isii usoro oku arụmụka, na instruction_pointer bụ ntụnye aka na ntuziaka oghere onye ọrụ mere oku sistemụ. Ya mere, dịka ọmụmaatụ, ịkwanye nọmba oku usoro n'ime ndekọ A anyị ga-ekwu

ldw [0]

Enwere atụmatụ ndị ọzọ maka mmemme seccomp, dịka ọmụmaatụ, enwere ike ịnweta ọnọdụ ahụ naanị site na nhazi 32-bit ma ị nweghị ike ibu ọkara okwu ma ọ bụ byte - mgbe ị na-agbalị ịkwanye nzacha. ldh [0] oku usoro seccomp ga-alọghachi EINVAL. Ọrụ ahụ na-enyocha ihe nzacha ndị eburu seccomp_check_filter() ndụ. (Ihe na-atọ ọchị bụ, na ntinye mbụ nke gbakwunyere ọrụ seccomp, ha chefuru ịgbakwunye ikike iji ntuziaka maka ọrụ a. mod (nkewa fọdụrụ) ma ọ dịghị ugbu a maka mmemme BPF nke abụọ, kemgbe mgbakwunye ya ga-agbaji ABI.)

N'ụzọ bụ isi, anyị amaworị ihe niile iji dee na gụọ mmemme seccomp. Ọtụtụ mgbe, a na-ahazi usoro ihe omume ahụ dị ka ndepụta ọcha ma ọ bụ oji nke oku usoro, dịka ọmụmaatụ mmemme

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

na-enyocha ndetu ojii nke oku sistemu anọ dị 304, 176, 239, 279. Gịnị bụ oku sistemu ndị a? Anyị enweghị ike ikwu n'ezie, ebe ọ bụ na anyị amaghị ụlọ ọrụ e ji dee ihe omume ahụ. Ya mere, ndị na-ede akwụkwọ nke seccomp enye malite mmemme niile site na nyocha ihe owuwu (ihe owuwu ụlọ dị ugbu a ka egosipụtara n'ọnọdụ ya dị ka ubi arch ihe owuwu struct seccomp_data). Site na nyocha ụlọ, mmalite ihe atụ ga-adị ka:

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

na mgbe ahụ usoro anyị nọmba oku ga-enweta ụfọdụ ụkpụrụ.

Anyị na-ede ma na-ebu ihe nzacha maka iji seccomp libseccomp

Ide ihe nzacha na koodu obodo ma ọ bụ na nzuko BPF na-enye gị ohere ijikwa nsonaazụ ya, mana n'otu oge ahụ, ọ na-aka mma mgbe ụfọdụ inwe koodu mkpanaka na/ma ọ bụ enwere ike ịgụ. Ọbá akwụkwọ ga-enyere anyị aka na nke a libseccomp, nke na-enye ọkọlọtọ ọkọlọtọ maka ide ihe nzacha ojii ma ọ bụ ọcha.

Dịka ọmụmaatụ, ka anyị dee mmemme na-agba ọsọ faịlụ ọnụọgụ abụọ nke onye ọrụ na-ahọrọ, ebe etinyelarị ndetu ojii nke oku sistemụ. isiokwu dị n'elu (E meela ka mmemme ahụ dị mfe maka ịgụkwu akwụkwọ, enwere ike ịchọta ụdị zuru ezu ebe a):

#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]);
}

Nke mbụ, anyị na-akọwa n'usoro sys_numbers nke 40+ nọmba usoro oku iji gbochie. Mgbe ahụ, malite ihe gbara ya gburugburu ctx ma gwa ọbá akwụkwọ ihe anyị chọrọ ikwe (SCMP_ACT_ALLOW) oku sistemu niile na ndabara (ọ dị mfe iji wuo ndetu ojii). Mgbe ahụ, n'otu n'otu, anyị na-agbakwunye oku sistemụ niile sitere na listi ojii. Na nzaghachi oku sistemụ sitere na ndepụta, anyị na-arịọ SCMP_ACT_TRAP, na nke a seccomp ga-ezite akara na usoro SIGSYS na nkọwa nke oku usoro mebiri iwu. N'ikpeazụ, anyị na-ebunye ihe omume ahụ n'ime kernel na-eji seccomp_load, nke ga-achịkọta mmemme ma tinye ya na usoro site na iji oku usoro seccomp(2).

Maka nchịkọta nke ọma, a ga-ejikọta mmemme ahụ na ọba akwụkwọ libseccomp, dịka ọmụmaatụ:

cc -std=c17 -Wall -Wextra -c -o seccomp_lib.o seccomp_lib.c
cc -o seccomp_lib seccomp_lib.o -lseccomp

Ọmụmaatụ nke mwepụta na-aga nke ọma:

$ ./seccomp_lib echo ok
ok

Ọmụmaatụ nke oku sistemụ akpọchiri:

$ sudo ./seccomp_lib mount -t bpf bpf /tmp
Bad system call

Anyị na-eji stracemaka nkọwa:

$ 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

kedu ka anyị ga-esi mara na a kwụsịrị mmemme ahụ n'ihi iji oku usoro iwu na-akwadoghị mount(2).

Yabụ, anyị na-eji nzacha wee dee nzacha libseccomp, dabara koodu na-abụghị obere n'ime ahịrị anọ. N'ihe atụ dị n'elu, ọ bụrụ na enwere ọnụ ọgụgụ dị ukwuu nke oku usoro, oge igbu oge nwere ike ibelata nke ọma, ebe ọ bụ na nlele bụ naanị ndepụta ntụnyere. Maka nkwalite, libseccomp nwere n'oge na-adịbeghị anya kwachie gụnyere, nke na-agbakwụnye nkwado maka njirimara nzacha SCMP_FLTATR_CTL_OPTIMIZE. Ịtọ n'ụdị a na 2 ga-atụgharị nzacha ka ọ bụrụ mmemme ọchụchọ ọnụọgụ abụọ.

Ọ bụrụ na ịchọrọ ịhụ ka nzacha ọchụchọ ọnụọgụ abụọ si arụ ọrụ, lelee anya edemede dị mfe, nke na-ebute mmemme dị otú ahụ na mgbakọ BPF site na ịpị nọmba oku usoro, dịka ọmụmaatụ:

$ 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

Ọ gaghị ekwe omume dee ihe ọ bụla ngwa ngwa, ebe ọ bụ na mmemme BPF enweghị ike ịme ihe nrịbama (anyị enweghị ike ime, dịka ọmụmaatụ, jmp A ma ọ bụ jmp [label+X]) ya mere mgbanwe niile na-agbanwe agbanwe.

seccomp na strace

Onye ọ bụla maara uru ahụ strace bụ ngwá ọrụ dị mkpa maka ịmụ omume nke usoro na Linux. Otú ọ dị, ọtụtụ anụwokwa banyere ya nsogbu arụmọrụ mgbe ị na-eji ngwa a. Nke bụ́ eziokwu bụ na strace emejuputa atumatu iji ptrace(2), na n'ime usoro a, anyị enweghị ike ịkọwapụta na ụdị usoro oku anyị kwesịrị ịkwụsị usoro ahụ, ya bụ, dịka ọmụmaatụ, iwu.

$ 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

A na-ahazi ya n'otu oge ahụ, n'agbanyeghị na n'ọnọdụ nke abụọ, anyị chọrọ ịchọta naanị otu oku usoro.

Nhọrọ ọhụrụ --seccomp-bpf, gbakwunyere na strace ụdị 5.3, na-enye gị ohere ịme ngwa ngwa usoro ahụ ọtụtụ oge na oge mmalite n'okpuru akara nke otu oku sistemụ adịlarị ka oge mmalite mmalite:

$ 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

(N'ebe a, n'ezie, enwere ntakịrị aghụghọ na anyị anaghị achọpụta isi usoro oku nke iwu a. Ọ bụrụ na anyị na-achọpụta, dịka ọmụmaatụ, newfsstatmgbe ahụ strace ga-agbajikwa breeki siri ike dịka enweghị ya --seccomp-bpf.)

Kedu ka nhọrọ a si arụ ọrụ? Enweghị ya strace jikọọ na usoro ahụ wee malite iji ya PTRACE_SYSCALL. Mgbe usoro jisiri wepụta oku sistemụ (ọ bụla), a na-ebufe njikwa na ya strace, nke na-ele anya na arụmụka nke oku usoro ma na-agba ọsọ ya PTRACE_SYSCALL. Mgbe oge ụfọdụ gasịrị, usoro ahụ mezuru oku usoro ma mgbe ị na-apụ, a na-ebufe njikwa ọzọ strace, nke na-ele anya nloghachi ụkpụrụ wee malite usoro site na iji PTRACE_SYSCALL, were gabazie.

BPF maka ụmụntakịrị, akụkụ efu: BPF kpochapụwo

Na seccomp, Otú ọ dị, a ga-emezi usoro a kpọmkwem dị ka anyị ga-achọ. Ya bụ, ọ bụrụ na anyị chọrọ anya naanị na oku usoro X, mgbe ahụ anyị nwere ike dee nzacha BPF maka X alaghachi uru SECCOMP_RET_TRACE, na maka oku na-adịghị amasị anyị - SECCOMP_RET_ALLOW:

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

Na nke a strace ibido na-amalite usoro dị ka PTRACE_CONT, A na-edozi nzacha anyị maka oku usoro ọ bụla, ma ọ bụrụ na oku usoro abụghị X, mgbe ahụ, usoro ahụ na-aga n'ihu, ma ọ bụrụ na nke a X, mgbe ahụ, seccomp ga-ebufe njikwa stracenke ga-eleba anya na arụmụka ma malite usoro dịka PTRACE_SYSCALL (ebe ọ bụ na seccomp enweghị ike ịme mmemme na ọpụpụ na oku sistemụ). Mgbe oku sistemu laghachiri, strace ga-amalitegharịa usoro site na iji PTRACE_CONT ma ga-echere ozi ọhụrụ site na sekọnd.

BPF maka ụmụntakịrị, akụkụ efu: BPF kpochapụwo

Mgbe ị na-eji nhọrọ --seccomp-bpf enwere mgbochi abụọ. Nke mbụ, ọ gaghị ekwe omume ịbanye na usoro dị adị (nhọrọ -p mmemme strace), ebe ọ bụ na nke a anaghị akwado seccomp. Nke abuo, enweghi ike ime bụghị lelee usoro ụmụaka, ebe ọ bụ na a na-eketa ihe nzacha seccomp site na usoro ụmụaka niile na-enweghị ike gbanyụọ nke a.

A obere nkọwa na otú kpọmkwem strace na-arụ ọrụ na seccomp enwere ike ịchọta ya akụkọ na-adịbeghị anya. Maka anyị, eziokwu kachasị adọrọ mmasị bụ na BPF kpochapụwo nke seccomp nọchitere anya ka na-eji taa.

xt_bpf

Ka anyị laghachi azụ na ụwa nke netwọk.

Ihe ndabere: ogologo oge gara aga, na 2007, isi bụ gbakwunyere na modul xt_u32 maka netfilter. Edere ya site na ntụnyere ya na ihe nhazi oge ochie kariri okporo ụzọ cls_u32 ma nye gị ohere ide iwu ọnụọgụ abụọ maka iptables site na iji ọrụ ndị a dị mfe: buo 32 ibe n'ibe site na ngwugwu ma rụọ ọrụ usoro mgbakọ na mwepụ na ha. Ọmụmaatụ,

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

Na-eburu ibe 32 nke nkụnye eji isi mee IP, malite na padding 6, wee tinye ihe nkpuchi na ha. 0xFF (were obere byte). Ogige a protocol IP nkụnye eji isi mee na anyị na-atụnyere ya na 1 (ICMP). Ị nwere ike ijikọta ọtụtụ ndenye ego n'otu iwu, ma ị nwekwara ike igbu onye ọrụ @ - Bugharịa X bytes n'aka nri. Dịka ọmụmaatụ, iwu

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

na-enyocha ma ọ bụrụ na TCP Sequence Number abụghị nhata 0x29. Agaghị m abanye n'ime nkọwa ndị ọzọ, ebe ọ bụ na o doro anya na iji aka dee iwu ndị dị otú ahụ adịghị mma. N'isiokwu BPF - bytecode echefuru, e nwere ọtụtụ njikọ na ihe atụ nke ojiji na ọchịchị ọgbọ maka xt_u32. Hụkwa njikọ ndị dị na ngwụcha akụkọ a.

Ebe ọ bụ na 2013 modul kama modul xt_u32 Ị nwere ike iji modul dabeere na BPF xt_bpf. Onye ọ bụla gụrụ nke a ga-edo anya na ụkpụrụ nke ọrụ ya: gba ọsọ BPF bytecode dị ka iwu iptables. Ị nwere ike ịmepụta iwu ọhụrụ, dịka ọmụmaatụ, dịka nke a:

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

ebe a <байткод> - nke a bụ koodu na assembler mmepụta usoro bpf_asm na ndabara, ọmụmaatụ,

$ 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

N'ihe atụ a, anyị na-enyocha ngwugwu UDP niile. Okwu maka mmemme BPF na modul xt_bpf, n'ezie, na-arụtụ aka na data ngwugwu, n'ihe banyere iptables, na mmalite nke nkụnye eji isi mee IPv4. Weghachite uru site na mmemme BPF booleanebe false pụtara na ngwugwu ahụ adabaghị.

O doro anya na modul xt_bpf na-akwado nzacha dị mgbagwoju anya karịa ihe atụ dị n'elu. Ka anyị lelee ezigbo ọmụmaatụ sitere na Cloudfare. Ruo n'oge na-adịbeghị anya, ha na-eji modul xt_bpf iji chebe megide mwakpo DDoS. N'isiokwu Na-ewebata Ngwa BPF ha na-akọwa otu (na ihe kpatara) ha na-emepụta ihe nzacha BPF ma bipụta njikọ na otu ngwa maka ịmepụta ihe nzacha dị otú ahụ. Dịka ọmụmaatụ, na-eji akụrụngwa bpfgen ị nwere ike ịmepụta mmemme BPF nke dabara na ajụjụ DNS maka aha 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

Na mmemme anyị na-ebu ụzọ buru ibu n'ime ndekọ X mmalite nke adreesị ahịrị x04habrx03comx00 n'ime UDP datagram wee lelee arịrịọ: 0x04686162 <-> "x04hab" na ihe ndị ọzọ.

Obere oge ka e mesịrị, Cloudfare bipụtara p0f -> koodu nchịkọta BPF. N'isiokwu Na-ewebata p0f BPF compiler ha na-ekwu maka ihe p0f bụ yana otu esi agbanwe p0f mbinye aka na 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,
...

Ugbu a anaghịzi eji Cloudfare xt_bpf, ebe ọ bụ na ha kwagara XDP - otu n'ime nhọrọ maka iji ụdị ọhụrụ nke BPF, lee. L4Drop: Mbelata XDP DDoS.

cls_bpf

Ihe atụ ikpeazụ nke iji BPF kpochapụwo na kernel bụ classifier cls_bpf maka usoro nchịkwa okporo ụzọ na Linux, agbakwunyere na Linux na njedebe nke 2013 ma jiri echiche dochie anya ochie. cls_u32.

Agbanyeghị, anyị agaghị akọwa ọrụ ahụ ugbu a cls_bpf, ebe ọ bụ na site n'echiche nke ihe ọmụma banyere kpochapụwo BPF nke a agaghị enye anyị ihe ọ bụla - anyị amaralarị ọrụ niile. Na mgbakwunye, na edemede ndị na-esote na-ekwu maka Extended BPF, anyị ga-ezute ọkwa ọkwa a karịa otu ugboro.

Ihe ọzọ mere na-agaghị ekwu maka iji kpochapụwo BPF c cls_bpf Nsogbu bụ na, ma e jiri ya tụnyere Extended BPF, a na-ebelata ohere nke itinye n'ọrụ na nke a: mmemme oge gboo enweghị ike ịgbanwe ọdịnaya nke ngwugwu na enweghị ike ịchekwa steeti n'etiti oku.

Yabụ na ọ bụ oge ị ga-asị nke ọma na BPF kpochapụrụ wee lelee ọdịnihu.

Daalụ na BPF kpochapụwo

Anyị lere anya ka teknụzụ BPF, nke mepụtara na mmalite nineties, biri ndụ nke ọma maka otu ụzọ n'ụzọ anọ nke narị afọ na ruo mgbe ọgwụgwụ chọtara ngwa ọhụrụ. Otú ọ dị, dị ka mgbanwe site na igwe tojupụtara gaa na RISC, nke jere ozi dị ka ihe mkpali maka mmepe nke BPF kpochapụwo, na 32s enwere mgbanwe site na igwe 64-bit gaa na XNUMX-bit na BPF kpochapụwo malitere ịghọ ihe mgbe ochie. Na mgbakwunye, ike nke BPF kpochapụwo dị oke oke, yana mgbakwunye na ihe owuwu oge ochie - anyị enweghị ikike ịchekwa steeti n'etiti oku na mmemme BPF, ọ nweghị ike ịmekọrịta mmekọrịta onye ọrụ ozugbo, ọ nweghị ohere ịmekọrịta. ya na kernel, ma e wezụga maka ịgụ ọnụ ọgụgụ dị nta nke ngalaba nhazi sk_buff na ịmalite ọrụ enyemaka kacha mfe, ị nweghị ike ịgbanwe ọdịnaya nke ngwugwu ma redirect ha.

N'ezie, ugbu a ihe niile fọdụrụ na BPF kpochapụwo na Linux bụ interface API, na n'ime kernel niile mmemme kpochapụwo, ma ọ bụ ihe nzacha oghere ma ọ bụ ihe nzacha seccomp, na-atụgharị ya na-akpaghị aka ka ọ bụrụ usoro ọhụrụ, Extended BPF. (Anyị ga-ekwu kpọmkwem otú nke a si eme n’isiokwu na-esonụ.)

Ntughari na ihe owuwu ọhụrụ malitere na 2013, mgbe Alexey Starovoitov tụpụtara atụmatụ mmelite BPF. Na 2014 ndị kwekọrọ na patches malitere ịpụta na isi. Dị ka m ghọtara, atụmatụ mbụ bụ naanị ịkwalite ụlọ ọrụ na JIT compiler ka ọ na-arụ ọrụ nke ọma na igwe 64-bit, mana kama nke a, njikarịcha ndị a bụ akara mmalite nke isi ọhụrụ na mmepe Linux.

Akụkọ ndị ọzọ n'usoro isiokwu a ga-ekpuchi ihe owuwu na ngwa nke teknụzụ ọhụrụ, nke a maara na mbụ dị ka BPF ime, wee gbasaa BPF, ma ugbu a bụ BPF.

zoro

  1. Steven McCanne na Van Jacobson, "Ihe nzacha ngwugwu BSD: Nrụpụta ọhụrụ maka ijide ngwugwu ọkwa onye ọrụ", https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Steven McCanne, "libpcap: Usoro nhazi na njikarịcha maka ijide ngwugwu", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. Nkuzi Match U32 IPtable.
  5. BPF - bytecode echefuru: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. Na-ewebata Ngwa BPF: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. Nchịkọta nke abụọ: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: Akpa na nchekwa: seccomp
  11. habr: Kewapụ daemons na sistemu ma ọ bụ "ịchọghị Docker maka nke a!"
  12. Paul Chaignon, "strace --seccomp-bpf: anya n'okpuru mkpuchi", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

isi: www.habr.com

Tinye a comment