BPF do na cinn beag, cuid nialais: BPF clasaiceach

Is teicneolaíocht eithne Linux é Berkeley Packet Filters (BPF) atá ar leathanaigh tosaigh na bhfoilseachán teicneolaíochta Béarla le roinnt blianta anuas. Líontar comhdhálacha le tuarascálacha ar úsáid agus ar fhorbairt BPF. Glaonn David Miller, cothaitheoir fochórais líonra Linux, a chuid cainte ag Linux Pluiméirí 2018 “Ní faoi XDP atá an chaint seo” (Is cás úsáide amháin é XDP do BPF). Tugann Brendan Gregg cainteanna dar teideal Sárchumhachtaí BPF Linux. Toke Høiland-Jørgensen gáirígo bhfuil an eithne anois microkernel. Cuireann Thomas Graf an smaoineamh chun cinn go Is javascript é BPF don eithne.

Níl aon tuairisc chórasach ar BPF ar Habré fós, agus mar sin i sraith alt déanfaidh mé iarracht labhairt faoi stair na teicneolaíochta, cur síos a dhéanamh ar na huirlisí ailtireachta agus forbartha, agus breac-chuntas a dhéanamh ar na réimsí feidhme agus cleachtais a bhaineann le húsáid BPF. Insíonn an t-alt seo, náid, sa tsraith, stair agus ailtireacht BPF clasaiceach, agus nochtann sé freisin rúin a phrionsabail oibriúcháin. tcpdump, seccomp, strace, agus i bhfad níos mó.

Tá forbairt BPF á rialú ag an bpobal líonraithe Linux, baineann príomhfheidhmchláir reatha BPF le líonraí agus mar sin, le cead @eucariot, Thug mé “BPF do na cinn bheaga” ar an tsraith, in ómós don tsraith iontach "Líonraí do na cinn beag".

Gearrchúrsa i stair BPF(c)

Is leagan feabhsaithe agus leathnaithe den sean-theicneolaíocht leis an ainm céanna é teicneolaíocht nua-aimseartha BPF, ar a dtugtar BPF clasaiceach anois chun mearbhall a sheachaint. Cruthaíodh áirgiúlacht aitheanta bunaithe ar an BPF clasaiceach tcpdump, meicníocht seccomp, chomh maith le modúil nach bhfuil mórán aithne orthu xt_bpf le haghaidh iptables agus aicmitheora cls_bpf. I Linux nua-aimseartha, aistrítear cláir BPF clasaiceach go huathoibríoch isteach sa bhfoirm nua, áfach, ó thaobh an úsáideora de, tá an API fós i bhfeidhm agus tá úsáidí nua le haghaidh BPF clasaiceach, mar a fheicfimid san Airteagal seo, fós á aimsiú. Ar an gcúis seo, agus freisin mar gheall ar tar éis stair fhorbairt BPF clasaiceach i Linux, beidh sé níos soiléire conas agus cén fáth a d'athraigh sé ina fhoirm nua-aimseartha, chinn mé tosú le halt faoi BPF clasaiceach.

Ag deireadh na n-ochtóidí den chéid seo caite, chuir innealtóirí ón Saotharlann cáiliúil Lawrence Berkeley spéis sa cheist maidir le conas paicéid líonra a scagadh i gceart ar chrua-earraí a bhí nua-aimseartha go déanach sna hochtóidí den chéid seo caite. Ba é bunsmaoineamh an scagtha, a cuireadh i bhfeidhm ar dtús i dteicneolaíocht CSPF (CMU/Stanford Packet Filter), ná paicéid neamhriachtanacha a scagadh chomh luath agus is féidir, i.e. sa spás eithne, toisc go seachnaíonn sé seo sonraí nach bhfuil gá leo a chóipeáil isteach sa spás úsáideora. Chun slándáil ama rite a sholáthar chun cód úsáideora a rith sa spás eithne, baineadh úsáid as meaisín fíorúil bosca gainimh.

Mar sin féin, dearadh na meaisíní fíorúla le haghaidh scagairí a bhí ann cheana féin chun oibriú ar mheaisíní stack-bhunaithe agus níor rith siad chomh héifeachtach ar mheaisíní RISC níos nuaí. Mar thoradh air sin, trí iarrachtaí na n-innealtóirí ó Berkeley Labs, forbraíodh teicneolaíocht nua BPF (Berkeley Packet Filters), a dearadh ailtireacht an mheaisín fíorúil bunaithe ar phróiseálaí Motorola 6502 - capall oibre táirgí aitheanta mar Apple IINES. Mhéadaigh an meaisín fíorúil nua feidhmíocht scagaire na mílte uair i gcomparáid leis na réitigh atá ann cheana féin.

BPF ailtireacht meaisín

Cuirfimid aithne ar an ailtireacht ar bhealach oibre, ag déanamh anailíse ar shamplaí. Ar dtús, áfach, déarfaimis go raibh dhá chlár 32-giotán ag an meaisín a raibh rochtain ag an úsáideoir orthu, carnadóir A agus clár innéacs X, 64 beart cuimhne (16 fhocal), ar fáil lena scríobh agus lena léamh ina dhiaidh sin, agus córas beag orduithe chun oibriú leis na réada seo. Bhí treoracha léime maidir le habairtí coinníollach a chur i bhfeidhm ar fáil sna cláir freisin, ach chun críochnú tráthúil an chláir a chinntiú, ní fhéadfaí ach léimeanna a dhéanamh ar aghaidh, i.e., go háirithe, bhí cosc ​​ar lúba a chruthú.

Seo a leanas an scéim ghinearálta chun an meaisín a thosú. Cruthaíonn an t-úsáideoir clár don ailtireacht BPF agus, ag baint úsáide as roinnt meicníocht eithne (cosúil le glao córais), ualaí agus nascann an clár le a roinnt chuig an ngineadóir imeacht san eithne (mar shampla, is éard atá i gceist le himeacht ná teacht an chéad phaicéad eile ar an gcárta líonra). Nuair a tharlaíonn teagmhas, ritheann an eithne an clár (mar shampla, in ateangaire), agus comhfhreagraíonn cuimhne an mheaisín do a roinnt réigiún cuimhne eithne (mar shampla, sonraí paicéad isteach).

Is leor an méid thuas dúinn tosú ag féachaint ar shamplaí: cuirfimid aithne ar an gcóras agus ar fhormáid na n-orduithe de réir mar is gá. Más mian leat staidéar a dhéanamh láithreach ar chóras ordaithe meaisín fíorúil agus foghlaim faoi a chumais go léir, ansin is féidir leat an t-alt bunaidh a léamh An Scagaire Paicéad BSD agus/nó an chéad leath den chomhad Doiciméadú/líonrú/filter.txt ón doiciméadú eithne. Ina theannta sin, is féidir leat staidéar a dhéanamh ar an gcur i láthair libpcap: Modheolaíocht Ailtireachta agus Optamaithe le haghaidh Gabháil Paicéad, ina labhraíonn McCanne, duine d’údair BPF, faoi stair an chruthaithe libpcap.

Bogaimid ar aghaidh anois chun na samplaí suntasacha go léir a mheas maidir le BPF clasaiceach a úsáid ar Linux: tcpdump (libpcap), soic, xt_bpf, cls_bpf.

tcpdump

Rinneadh forbairt BPF i gcomhthráth le forbairt an tosaigh le haghaidh scagadh paicéid - fóntais a bhfuil aithne mhaith air tcpdump. Agus, ós rud é gurb é seo an sampla is sine agus is cáiliúla de BPF clasaiceach a úsáid, atá ar fáil ar go leor córais oibriúcháin, cuirfimid tús lenár staidéar ar an teicneolaíocht leis.

(Rith mé na samplaí go léir san alt seo ar Linux 5.6.0-rc6. Tá aschur roinnt orduithe curtha in eagar ar mhaithe le hinléiteacht níos fearr.)

Sampla: breathnú ar phaicéid IPv6

Samhlóimid gur mhaith linn breathnú ar gach paicéad IPv6 ar chomhéadan eth0. Chun seo a dhéanamh is féidir linn an clár a rith tcpdump le scagaire simplí ip6:

$ sudo tcpdump -i eth0 ip6

Sa chás seo, tcpdump thiomsaíonn an scagaire ip6 isteach i seachchód ailtireachta BPF agus seol chuig an eithne é (féach na sonraí sa rannán Tcpdump: luchtú). Reáchtálfar an scagaire luchtaithe do gach paicéad a théann tríd an gcomhéadan eth0. Má thugann an scagaire luach neamh-nialas ar ais n, ansin suas go dtí n déanfar bearta an phaicéid a chóipeáil go spás úsáideora agus feicfimid san aschur é tcpdump.

BPF do na cinn beag, cuid nialais: BPF clasaiceach

Tarlaíonn sé gur féidir linn a fháil amach go héasca cén bytecode a seoladh chuig an eithne tcpdump le cabhair ó na tcpdump, má rithimid é leis an rogha -d:

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

Ar líne nialais ritheann muid an t-ordú ldh [12], a sheasann do “load into register A leath fhocail (16 ghiotán) suite ag seoladh 12” agus is í an t-aon cheist ná cén cineál cuimhne a bhfuilimid ag tabhairt faoi? Is é an freagra go bhfuil ag x Tosaíonn (x+1)ú beart den phaicéad líonra anailísithe. Léimid paicéid ón gcomhéadan Ethernet eth0agus seo ciallaíonngo bhfuil cuma mar seo ar an bpaicéad (ar mhaithe le simplíocht, glacaimid leis nach bhfuil clibeanna VLAN sa phaicéad):

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

Mar sin, tar éis an t-ordú a fhorghníomhú ldh [12] sa chlár A beidh cluain ann Ether Type — an cineál paicéad a tharchuirtear sa fhráma Ethernet seo. Ar líne 1 déanaimid comparáid idir a bhfuil sa chlár A (cineál pacáiste) c 0x86ddagus seo agus tá Is é an cineál a bhfuil suim againn ann ná IPv6. Ar líne 1, chomh maith leis an ordú comparáide, tá dhá cholún eile - jt 2 и jf 3 — marcanna nach mór duit dul chucu má éiríonn leis an gcomparáid (A == 0x86dd) agus nár éirigh leo. Mar sin, i gcás rathúil (IPv6) téann muid go dtí líne 2, agus i gcás nár éirigh leis - go líne 3. Ar líne 3 críochnaíonn an clár le cód 0 (ná cóipeáil an paicéad), ar líne 2 críochnaíonn an clár le cód. 262144 (cóipeáil dom uasmhéid de 256 cilibheart pacáiste).

Sampla níos casta: féachaimid ar phaicéid TCP de réir calafoirt cinn scríbe

Feicfimid cad is cosúil le scagaire a dhéanann cóipeáil ar gach paicéad TCP le calafort ceann scríbe 666. Déanfaimid breithniú ar an gcás IPv4, ós rud é go bhfuil an cás IPv6 níos simplí. Tar éis duit an sampla seo a staidéar, is féidir leat an scagaire IPv6 a iniúchadh mar chleachtadh (ip6 and tcp dst port 666) agus scagaire don chás ginearálta (tcp dst port 666). Mar sin, tá an chuma ar an scagaire a bhfuil suim againn ann mar seo:

$ 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

Tá a fhios againn cheana féin cad a dhéanann línte 0 agus 1. Ar líne 2 ní mór dúinn a sheiceáil cheana féin gur paicéad IPv4 é seo (Éitear Cineál = 0x800) agus é a luchtú isteach sa chlár A 24ú beart den phaicéad. Is cosúil ár bpacáiste

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

rud a chiallaíonn go ndéanaimid lódáil isteach sa chlár A réimse an Phrótacail den cheanntásc IP, atá loighciúil, toisc nach dteastaíonn uainn ach paicéid TCP a chóipeáil. Déanaimid comparáid idir Prótacal le 0x6 (IPPROTO_TCP) ar líne 3.

Ar línte 4 agus 5 luchtaimid na leathfhocail atá suite ag seoladh 20 agus úsáidimid an t-ordú jset seiceáil an bhfuil ceann de na trí cinn socraithe bratacha - ag caitheamh an masc a eisíodh jset glantar na trí ghiotán is suntasaí. Insíonn dhá cheann de na trí ghiotán dúinn an bhfuil an paicéad mar chuid de phaicéad IP ilroinnte, agus má tá, cé acu an blúire deiridh é. Tá an tríú giotán in áirithe agus ní mór a bheith nialas. Nílimid ag iarraidh paicéid neamhiomlána nó briste a sheiceáil, mar sin déanaimid seiceáil ar na trí ghiotán.

Is í Líne 6 an ceann is suimiúla sa liosta seo. Léiriú ldxb 4*([14]&0xf) ciallaíonn sé go lódálann muid isteach sa chlár X na ceithre ghiotán is lú suntasaí den chúigiú beart déag den phaicéad iolraithe faoi 4. Is é an réimse na ceithre ghiotán is lú suntasaí den chúigiú beart déag Fad Ceanntásca Idirlín Ceanntásc IPv4, a stórálann fad an cheanntásc i bhfocail, mar sin ní mór duit a iolrú faoi 4. Suimiúil go leor, an abairt 4*([14]&0xf) is ainmniúchán é do scéim seoltaí speisialta nach féidir a úsáid ach san fhoirm seo agus do chlár amháin X, i.e. ní féidir linn a rá ach an oiread ldb 4*([14]&0xf)ldxb 5*([14]&0xf) (ní féidir linn ach fritháireamh eile a shonrú, mar shampla, ldxb 4*([16]&0xf)). Is léir gur cuireadh an scéim seoltaí seo le BPF go beacht lena fháil X (clár innéacs) Fad ceanntásc IPv4.

Mar sin ar líne 7 déanaimid iarracht leath focal a lódáil ag (X+16). Ag cuimhneamh go bhfuil 14 bytes á áitiú ag an gceanntásc Ethernet, agus X ina bhfuil fad an cheannteidil IPv4, tuigimid go bhfuil i A Tá calafort ceann scríbe TCP luchtaithe:

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

Ar deireadh, ar líne 8 déanaimid comparáid idir an calafort ceann scríbe agus an luach atá ag teastáil agus ar línte 9 nó 10 cuirimid an toradh ar ais - cibé acu an paicéad a chóipeáil nó nach ea.

Tcpdump: luchtú

Sna samplaí roimhe seo, níor chuamar go mion faoi conas go díreach a luchtóimid seachchód BPF isteach san eithne le haghaidh scagadh paicéid. Go ginearálta, tcpdump a iompar chuig go leor córas agus chun oibriú le scagairí tcpdump úsáideann an leabharlann libpcap. Go hachomair, chun scagaire a chur ar chomhéadan ag baint úsáide as libpcap, ní mór duit na rudaí seo a leanas a dhéanamh:

A fheiceáil conas an fheidhm pcap_setfilter i bhfeidhm i Linux, úsáidimid strace (bainte roinnt línte):

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

Ar an gcéad dá líne aschuir cruthaímid soicéad amh gach fráma Ethernet a léamh agus é a cheangal leis an gcomhéadan eth0. Ó ár gcéad sampla tá a fhios againn go bhfuil an scagaire ip comhdhéanta de cheithre treoracha BPF, agus ar an tríú líne a fheicimid conas ag baint úsáide as an rogha SO_ATTACH_FILTER glao córais setsockopt luchtú agus nascaimid scagaire ar fad 4. Is é seo ár scagaire.

Is fiú a thabhairt faoi deara, i BPF clasaiceach, go dtarlaíonn luchtú agus nascadh scagaire i gcónaí mar oibríocht adamhach, agus sa leagan nua de BPF, déantar an clár a luchtú agus é a cheangal leis an gineadóir imeacht a scaradh in am.

Fírinne Cheilte

Breathnaíonn leagan beagán níos iomláine den aschur mar seo:

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

Mar a luadh thuas, déanaimid ár scagaire a luchtú agus a nascadh leis an soicéad ar líne 5, ach cad a tharlaíonn ar línte 3 agus 4? Tharlaíonn sé go raibh seo libpcap a thugann aire dúinn - ionas nach n-áirítear in aschur ár scagaire paicéid nach sásaíonn é, an leabharlann nascann scagaire Caochadán ret #0 (buail gach paicéad), aistríonn sé an soicéad go dtí mód neamh-bhloic agus déanann sé iarracht gach paicéad a d'fhéadfadh fanacht ó na scagairí roimhe seo a dhealú.

San iomlán, chun pacáistí a scagadh ar Linux ag baint úsáide as BPF clasaiceach, ní mór duit scagaire a bheith agat i bhfoirm struchtúir cosúil le struct sock_fprog agus soicéad oscailte, ina dhiaidh sin is féidir an scagaire a cheangal leis an soicéad ag baint úsáide as glao córais setsockopt.

Suimiúil go leor, is féidir an scagaire a cheangal le haon soicéad, ní hamháin amh. Anseo mar shampla clár a ghearrann amach gach beart seachas an chéad dá bheart ó gach datagram UDP a thagann isteach. (Chuir mé tráchtanna isteach sa chód ionas nach gcuirfí isteach ar an alt.)

Tuilleadh sonraí faoi úsáid setsockopt le haghaidh scagairí a nascadh, féach soicéad(7), ach faoi do chuid scagairí féin a scríobh mar struct sock_fprog gan chabhair tcpdump beidh muid ag caint sa rannóg BPF a ríomhchlárú lenár lámha féin.

BPF clasaiceach agus an XNUMXú haois

Áiríodh BPF le Linux i 1997 agus tá sé fós ina chapall oibre le fada an lá libpcap gan aon athruithe speisialta (athruithe a bhaineann go sonrach le Linux, ar ndóigh, Bhí muid, ach níor athraigh siad an pictiúr domhanda). Tháinig na chéad chomharthaí tromchúiseacha go dtiocfadh BPF chun cinn in 2011, nuair a mhol Eric Dumazet paiste, a chuireann Just In Time Compiler leis an eithne - aistritheoir chun seachchód BPF a thiontú go dúchais x86_64 cód.

Ba é tiomsaitheoir JIT an chéad cheann sa slabhra athruithe: in 2012 le feiceáil cumas chun scagairí a scríobh le haghaidh seccomp, ag baint úsáide as BPF, i mí Eanáir 2013 bhí curtha leis modúl xt_bpf, a ligeann duit rialacha a scríobh le haghaidh iptables le cabhair ó BPF, agus i mí Dheireadh Fómhair 2013 bhí curtha leis freisin modúl cls_bpf, a ligeann duit aicmitheoirí tráchta a scríobh ag baint úsáide as BPF.

Breathnóimid ar na samplaí seo go léir go mion go luath, ach ar dtús beidh sé úsáideach dúinn foghlaim conas cláir treallach a scríobh agus a thiomsú le haghaidh BPF, ós rud é go bhfuil na cumais a sholáthraíonn an leabharlann libpcap teoranta (mar shampla simplí: scagaire ginte libpcap is féidir ar ais ach dhá luach - 0 nó 0x40000) nó go ginearálta, mar atá i gcás seccomp, nach bhfuil infheidhme.

BPF a ríomhchlárú lenár lámha féin

Cuirimis aithne ar fhormáid dhénártha treoracha BPF, tá sé an-simplí:

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

Tá 64 giotán ag gach teagasc, ina bhfuil an chéad 16 ghiotán mar chód treorach, ansin tá dhá fhleasc ocht ngiotán, jt и jf, agus 32 giotán don argóint K, a athraíonn a chuspóir ó ordú go ceannas. Mar shampla, an t-ordú ret, a chuireann deireadh leis an gclár tá an cód 6, agus tógtar an luach tuairisceáin ón tairiseach K. In C, léirítear treoir BPF amháin mar struchtúr

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

agus tá an clár iomlán i bhfoirm struchtúir

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

Mar sin, is féidir linn cláir a scríobh cheana féin (mar shampla, tá na cóid treoracha ar eolas againn ó [1]). Seo an chuma a bheidh ar an scagaire ip6 de ár gcéad sampla:

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

clár prog is féidir linn a úsáid go dleathach i nglao

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

Níl sé an-áisiúil cláir a scríobh i bhfoirm cóid meaisín, ach uaireanta tá sé riachtanach (mar shampla, le haghaidh dífhabhtaithe, tástálacha aonaid a chruthú, scríobh altanna ar Habré, etc.). Ar mhaithe le caoithiúlacht, sa chomhad <linux/filter.h> Sainmhínítear macraí cúntóra - d'fhéadfaí an sampla céanna thuas a athscríobh mar

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

Mar sin féin, níl an rogha seo an-áisiúil. Seo é a réasúnaigh ríomhchláraitheoirí eithne Linux, agus mar sin san eolaire tools/bpf eithne is féidir leat teacht ar cóimeálaí agus dífhabhtóir chun oibriú le BPF clasaiceach.

Tá teanga an tionóil an-chosúil le haschur dífhabhtaithe tcpdump, ach ina theannta sin is féidir linn a shonrú lipéid siombalach. Mar shampla, seo clár a scaoileann gach paicéad seachas TCP/IPv4:

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

De réir réamhshocraithe, gineann an cóimeálaí cód san fhormáid <количество инструкций>,<code1> <jt1> <jf1> <k1>,..., mar shampla lenár TCP beidh sé

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

Ar mhaithe le háisiúlacht ríomhchláraitheoirí C, is féidir formáid aschuir dhifriúil a úsáid:

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

Is féidir an téacs seo a chóipeáil isteach sa sainmhíniú ar struchtúr cineáil struct sock_filter, mar a rinne muid ag tús an ailt seo.

Eisínteachtaí Linux agus netsniff-ng

Chomh maith le BPF caighdeánach, Linux agus tools/bpf/bpf_asm tacaíocht agus sraith neamhchaighdeánach. Go bunúsach, úsáidtear treoracha chun rochtain a fháil ar réimsí struchtúir struct sk_buff, a chuireann síos ar phaicéad líonra san eithne. Mar sin féin, tá cineálacha eile treoracha cúntóir ann freisin, mar shampla ldw cpu luchtú isteach sa chlár A thoradh ar fheidhm eithne a rith raw_smp_processor_id(). (Sa leagan nua de BPF, leathnaíodh na síntí neamhchaighdeánacha seo chun cláir a sholáthar le sraith cúntóirí eithne chun rochtain a fháil ar chuimhne, struchtúir, agus imeachtaí giniúna.) Seo sampla suimiúil de scagaire ina ndéanaimid cóip amháin den ceanntásca paicéad isteach sa spás úsáideora ag baint úsáide as an síneadh poff, fritháireamh ualaigh:

ld poff
ret a

Ní féidir síntí BPF a úsáid i tcpdump, ach is cúis mhaith é seo chun eolas a fháil ar an bpacáiste fóntais netsniff-ng, ina bhfuil, i measc rudaí eile, ardchlár netsniff-ng, a bhfuil, chomh maith le scagadh ag baint úsáide as BPF, freisin gineadóir tráchta éifeachtach, agus níos airde ná tools/bpf/bpf_asm, ar a dtugtar cóimeálaí BPF bpfc. Tá doiciméadú sách mionsonraithe sa phacáiste, féach freisin na naisc ag deireadh an ailt.

seccomp

Mar sin, tá a fhios againn cheana féin conas a scríobh cláir BPF de chastacht treallach agus go bhfuil siad réidh chun breathnú ar shamplaí nua, is é an chéad cheann acu an teicneolaíocht seccomp, a cheadaíonn, ag baint úsáide as scagairí BPF, a bhainistiú an leagan síos agus sraith na n-argóintí glaoch córais atá ar fáil do. próiseas tugtha agus a shliocht.

Cuireadh an chéad leagan de seccomp leis an eithne sa bhliain 2005 agus ní raibh an-tóir air, ós rud é nár chuir sé ach rogha amháin ar fáil - chun teorainn a chur le sraith na nglaonna córais atá ar fáil do phróiseas chuig an méid seo a leanas: read, write, exit и sigreturn, agus maraíodh an próiseas a sháraigh na rialacha ag baint úsáide as SIGKILL. Mar sin féin, in 2012, chuir seccomp leis an gcumas scagairí BPF a úsáid, rud a ligeann duit sraith de ghlaonna córais ceadaithe a shainiú agus fiú seiceálacha a dhéanamh ar a n-argóintí. (Suimiúil go leor, bhí Chrome ar cheann de na chéad úsáideoirí na feidhme seo, agus tá na daoine Chrome ag forbairt meicníocht KRSI faoi láthair bunaithe ar leagan nua de BPF agus a cheadaíonn saincheaptha Modúil Slándála Linux.) Is féidir naisc chuig doiciméadú breise a fháil ag an deireadh den alt.

Tabhair faoi deara go bhfuil ailt ar an mol cheana féin faoi úsáid a bhaint as seccomp, b'fhéidir go mbeidh duine ag iarraidh iad a léamh roimh (nó in ionad) na fo-ailt seo a leanas a léamh. San alt Coimeádáin agus slándáil: seccomp Soláthraíonn sé samplaí d'úsáid seccomp, idir leagan 2007 agus an leagan ag baint úsáide as BPF (gintear scagairí ag baint úsáide as libseccomp), labhraíonn sé faoi nasc seccomp le Docker, agus cuireann sé go leor naisc úsáideacha ar fáil freisin. San alt Deamhan a leithlisiú le systemd nó “níl Docker ag teastáil uait le haghaidh seo!” Clúdaíonn sé, go háirithe, conas liostaí dubha nó liostaí bána de ghlaonna córais a chur leis le haghaidh deamhan ag rith systemd.

Ansin feicfimid conas scagairí a scríobh agus a luchtú le haghaidh seccomp i lom C agus ag baint úsáide as an leabharlann libseccomp agus cad iad na buntáistí agus na míbhuntáistí a bhaineann le gach rogha, agus ar deireadh, feicfimid conas a úsáideann an clár seccomp strace.

Scagairí a scríobh agus a luchtú le haghaidh seccomp

Tá a fhios againn cheana féin conas cláir BPF a scríobh, mar sin déanaimis féachaint ar an gcomhéadan cláir seccomp ar dtús. Is féidir leat scagaire a shocrú ag leibhéal an phróisis, agus gheobhaidh gach próiseas leanbh na srianta le hoidhreacht. Déantar é seo trí ghlao córais a úsáid seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

i gcás &filter - is pointeoir é seo do struchtúr atá ar eolas againn cheana féin struct sock_fprog, i.e. Clár BPF.

Cén difríocht atá idir cláir seccomp agus cláir do shoicéid? Comhthéacs tarchurtha. I gcás soicéid, tugadh limistéar cuimhne dúinn ina raibh an paicéad, agus i gcás seccomp tugadh struchtúr cosúil le

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

Anseo nr an bhfuil uimhir an ghlao córais le seoladh, arch - ailtireacht reatha (tuilleadh air seo thíos), args - suas le sé argóint glaonna córais, agus instruction_pointer is pointeoir é don treoir spáis úsáideora a rinne an córas glao. Mar sin, mar shampla, uimhir ghlao an chórais a luchtú isteach sa chlár A caithfimid a rá

ldw [0]

Tá gnéithe eile le haghaidh ríomhchláir seccomp, mar shampla, ní féidir rochtain a fháil ar an gcomhthéacs ach trí ailíniú 32-giotán agus ní féidir leat leathfhocal nó beart a lódáil - agus tú ag iarraidh scagaire a luchtú ldh [0] glao córais seccomp fillfidh EINVAL. Seiceálann an fheidhm na scagairí luchtaithe seccomp_check_filter() eithne. (Rud greannmhar, sa bhunghealltanas a chuir an fheidhm seccomp leis, rinne siad dearmad cead a chur leis an teagasc a úsáid leis an bhfeidhm seo mod (fuílleach rannáin) agus níl sé ar fáil anois do chláir BPF seccomp, ó cuireadh leis é brisfidh ABI.)

Go bunúsach, tá gach rud ar eolas againn cheana féin chun cláir seccomp a scríobh agus a léamh. De ghnáth socraítear loighic an chláir mar liosta bán nó dubh de ghlaonna córais, mar shampla an clár

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

seiceálann sé liosta dubh de cheithre ghlao córais dar uimhreacha 304, 176, 239, 279. Cad iad na glaonna córais seo? Ní féidir linn a rá go cinnte, mar níl a fhios againn cén ailtireacht ar scríobhadh an clár di. Dá bhrí sin, údair seccomp tairiscint tús a chur le gach clár le seiceáil ailtireachta (léirítear an ailtireacht reatha sa chomhthéacs mar réimse arch an struchtúr struct seccomp_data). Agus an ailtireacht seiceáilte, bheadh ​​cuma ar thús an tsampla:

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

agus ansin gheobhadh ár n-uimhreacha glaonna córais luachanna áirithe.

Scríobhaimid agus lódálann muid scagairí le húsáid seccomp libseccomp

Má scríobhtar scagairí i gcód dúchais nó i dtionól BPF is féidir leat smacht iomlán a bheith agat ar an toradh, ach ag an am céanna, is fearr uaireanta cód iniompartha agus/nó inléite a bheith agat. Cabhróidh an leabharlann linn le seo libseccomp, a sholáthraíonn comhéadan caighdeánach chun scagairí dubh nó bán a scríobh.

Scríobhaimis, mar shampla, clár a ritheann comhad dhénártha de rogha an úsáideora, tar éis liosta dubh de ghlaonna córais a shuiteáil roimhe seo ó an t-alt thuas (tá an clár simplithe ar mhaithe le hinléiteacht níos fearr, is féidir an leagan iomlán a fháil anseo):

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

Ar dtús déanaimid sainmhíniú ar eagar sys_numbers de 40+ uimhreacha glaonna córais le blocáil. Ansin, cuir tús leis an gcomhthéacs ctx agus inis don leabharlann cad ba mhaith linn a cheadú (SCMP_ACT_ALLOW) gach glao córais de réir réamhshocraithe (tá sé níos éasca liostaí dubha a thógáil). Ansin, ceann ar cheann, cuirimid na glaonna córais go léir ón liosta dubh. Mar fhreagra ar ghlao córais ón liosta, iarraimid SCMP_ACT_TRAP, sa chás seo seolfaidh seccomp comhartha chuig an bpróiseas SIGSYS le cur síos ar cén glao córais a sháraigh na rialacha. Ar deireadh, luchtú muid an clár isteach san eithne ag baint úsáide as seccomp_load, a thiomsóidh an clár agus é a cheangal leis an bpróiseas ag baint úsáide as glao córais seccomp(2).

Chun go n-éireoidh le tiomsú, ní mór an clár a nascadh leis an leabharlann libseccomp, mar shampla:

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

Sampla de sheoladh rathúil:

$ ./seccomp_lib echo ok
ok

Sampla de ghlao córais blocáilte:

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

úsáidimid stracele haghaidh sonraí:

$ 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

conas is féidir a fhios againn gur cuireadh deireadh leis an gclár mar gheall ar ghlao córais mhídhleathach a úsáid mount(2).

Mar sin, scríobhamar scagaire ag baint úsáide as an leabharlann libseccomp, cód neamhfhánach a fheistiú i gceithre líne. Sa sampla thuas, má tá líon mór glaonna córais ann, is féidir an t-am forghníomhaithe a laghdú go suntasach, ós rud é nach bhfuil sa seiceáil ach liosta comparáidí. Chun leas iomlán a bhaint, bhí libseccomp le déanaí paiste san áireamh, a chuireann tacaíocht don tréith scagaire SCMP_FLTATR_CTL_OPTIMIZE. Má shocraítear an tréith seo go 2, déanfar an scagaire a thiontú ina ríomhchlár cuardaigh dénártha.

Más mian leat a fheiceáil conas a oibríonn scagairí cuardaigh dénártha, féach ar script simplí, a ghineann cláir den sórt sin i gcóimeálaí BPF trí ghlao-uimhreacha córais a dhiailiú, mar shampla:

$ 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

Tá sé dodhéanta aon rud a scríobh i bhfad níos tapúla, ós rud é nach féidir le cláir BPF léimeanna eangaithe a dhéanamh (ní féidir linn a dhéanamh, mar shampla, jmp Ajmp [label+X]) agus dá bhrí sin tá gach trasdul statach.

seccomp agus strace

Tá a fhios ag gach duine an fóntais strace Is uirlis fíor-riachtanach é chun staidéar a dhéanamh ar iompar na bpróiseas ar Linux. Mar sin féin, tá go leor cloiste freisin faoi saincheisteanna feidhmíochta agus an áirgiúlacht seo á úsáid agat. Is é fírinne an scéil go strace curtha i bhfeidhm ag baint úsáide as ptrace(2), agus sa mheicníocht seo ní féidir linn a shonrú cén sraith glaonna córais a theastaíonn uainn chun an próiseas a stopadh, i.e., mar shampla, orduithe

$ 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 phróiseáiltear thart ar an am céanna, cé gur mian linn sa dara cás gan ach glaoch córais amháin a rianú.

Rogha nua --seccomp-bpf, curtha le strace leagan 5.3, is féidir leat an próiseas a bhrostú go minic agus tá an t-am tosaithe faoi rian aon ghlao córais amháin inchomparáide cheana féin leis an am tosaithe rialta:

$ 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

(Seo, ar ndóigh, tá rud beag meallta sa mhéid is nach bhfuilimid ag lorg príomhghlao an chórais den ordú seo. Dá mbeimis ag rianú, mar shampla, newfsstatansin strace bheadh ​​coscán díreach chomh crua le gan --seccomp-bpf.)

Conas a oibríonn an rogha seo? Sin í strace nascann sé leis an bpróiseas agus cuireann sé tús le húsáid PTRACE_SYSCALL. Nuair a eisíonn próiseas bainistithe glao córais (aon), aistrítear rialú chuig strace, a bhreathnaíonn ar argóintí an ghlao córais agus a ritheann sé ag baint úsáide as PTRACE_SYSCALL. Tar éis roinnt ama, críochnaíonn an próiseas glao an chórais agus nuair a scoirtear é, aistrítear an rialú arís strace, a bhreathnaíonn ar na luachanna tuairisceáin agus a thosaíonn an próiseas ag baint úsáide as PTRACE_SYSCALL, agus mar sin de.

BPF do na cinn beag, cuid nialais: BPF clasaiceach

Le seccomp, áfach, is féidir an próiseas seo a bharrfheabhsú díreach mar ba mhaith linn. Eadhon, más mian linn breathnú ar an nglao córais amháin X, ansin is féidir linn scagaire BPF a scríobh gur le haghaidh X luach ar ais SECCOMP_RET_TRACE, agus ar ghlaonna nach spéis linn - SECCOMP_RET_ALLOW:

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

Sa chás seo strace ar dtús a thosaíonn an próiseas mar PTRACE_CONT, próiseáiltear ár scagaire le haghaidh gach glao córais, mura bhfuil an glao córais X, ansin leanann an próiseas a rith, ach más rud é seo X, ansin déanfaidh seccomp rialú a aistriú stracea bhreathnóidh ar na hargóintí agus a chuirfidh tús leis an bpróiseas mar PTRACE_SYSCALL (ós rud é nach bhfuil an cumas ag seccomp clár a rith ar imeacht as glao córais). Nuair a fhilleann an glao córais, strace Beidh atosú ar an bpróiseas ag baint úsáide as PTRACE_CONT agus fanfaidh sé le teachtaireachtaí nua ó seccomp.

BPF do na cinn beag, cuid nialais: BPF clasaiceach

Nuair a bheidh an rogha á úsáid --seccomp-bpf tá dhá shrian ann. Ar an gcéad dul síos, ní bheidh sé indéanta dul isteach i bpróiseas atá ann cheana féin (rogha -p cláir strace), ós rud é nach dtacaíonn seccomp leis seo. Ar an dara dul síos, níl aon fhéidearthacht ann aon breathnú ar phróisis leanaí, ós rud é go bhfaigheann gach próiseas leanbh le hoidhreacht scagairí seccomp gan an cumas é seo a dhíchumasú.

Tá beagán níos mó sonraí ar conas go díreach strace oibríonn sé le seccomp le fáil ó tuairisc le déanaí. Maidir linne, is é an bhfíric is suimiúla ná go bhfuil an BPF clasaiceach arna ionadú ag seccomp fós in úsáid inniu.

xt_bpf

A ligean ar dul anois ar ais go dtí saol na líonraí.

Cúlra: i bhfad ó shin, i 2007, bhí an croí curtha leis modúl xt_u32 le haghaidh netfilter. Scríobhadh é de réir analaí le haicmitheoir tráchta níos ársa fós cls_u32 agus thug sé cead duit rialacha dénártha a scríobh le haghaidh iptables ag baint úsáide as na hoibríochtaí simplí seo a leanas: 32 giotán a luchtú ó phacáiste agus sraith oibríochtaí uimhríochta a dhéanamh orthu. Mar shampla,

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

Lódálann sé na 32 giotán den cheanntásc IP, ag tosú ag stuáil 6, agus cuireann sé masc orthu 0xFF (tóg an beart íseal). An réimse seo protocol Ceanntásc IP agus cuirimid i gcomparáid é le 1 (ICMP). Is féidir leat go leor seiceálacha a chomhcheangal i riail amháin, agus is féidir leat an t-oibreoir a fhorghníomhú freisin @ — bog X beart ar dheis. Mar shampla, an riail

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

seiceálacha mura bhfuil Uimhir Seicheamh TCP cothrom 0x29. Ní rachaidh mé isteach i sonraí a thuilleadh, ós rud é go bhfuil sé soiléir cheana féin nach bhfuil sé an-áisiúil rialacha den sórt sin a scríobh de láimh. San alt BPF - an bytecode dearmad, tá naisc éagsúla le samplaí úsáide agus giniúint rialacha do xt_u32. Féach freisin na naisc ag deireadh an ailt seo.

Ó 2013 i leith modúl in ionad an mhodúil xt_u32 is féidir leat modúl bunaithe ar BPF a úsáid xt_bpf. Ba cheart go mbeadh aon duine a bhfuil léite aige chomh fada seo soiléir faoi phrionsabal a oibríochta: rith bytecode BPF mar rialacha iptables. Is féidir leat riail nua a chruthú, mar shampla, mar seo:

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

anseo <байткод> - is é seo an cód i bhformáid aschuir cóimeálaí bpf_asm de réir réamhshocraithe, mar shampla,

$ 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

Sa sampla seo táimid ag scagadh gach paicéad UDP. Comhthéacs do chlár BPF i modúl xt_bpf, ar ndóigh, pointí ar na sonraí paicéad, i gcás iptables, go dtí tús an ceanntásc IPv4. An luach a thabhairt ar ais ón gclár BPF BooleI gcás ina false ciallaíonn sé nár mheaitseáil an paicéad.

Is léir go bhfuil an modúl xt_bpf Tacaíonn scagairí níos casta ná an sampla thuas. Breathnaímid ar fhíorshamplaí ó Cloudfare. Go dtí le déanaí d'úsáid siad an modúl xt_bpf a chosaint ar ionsaithe DDoS. San alt Uirlisí BPF a thabhairt isteach míníonn siad conas (agus cén fáth) a ghineann siad scagairí BPF agus foilsíonn siad naisc chuig sraith fóntais chun na scagairí sin a chruthú. Mar shampla, ag baint úsáide as an fóntais bpfgen is féidir leat clár BPF a chruthú a mheaitseálann ceist DNS le haghaidh ainm 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

Sa chlár cuirimid isteach sa chlár ar dtús X seoladh tús líne x04habrx03comx00 laistigh de datagram UDP agus ansin seiceáil an t-iarratas: 0x04686162 <-> "x04hab" etc

Beagán níos déanaí, d'fhoilsigh Cloudfare an cód tiomsaitheora p0f -> BPF. San alt An tiomsaitheoir BPF p0f a thabhairt isteach labhraíonn siad faoi cad is p0f ann agus conas sínithe p0f a thiontú go 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,
...

Níl Cloudfare in úsáid a thuilleadh faoi láthair xt_bpf, ó bhog siad go XDP - ceann de na roghanna chun an leagan nua de BPF a úsáid, féach. L4Drop: Maoluithe XDP DDoS.

cls_bpf

Is é an sampla deireanach de BPF clasaiceach a úsáid san eithne ná an t-aicmitheoir cls_bpf don fhochóras rialaithe tráchta i Linux, curtha le Linux ag deireadh 2013 agus é a athsholáthar go coincheapúil cls_u32.

Mar sin féin, ní dhéanfaimid cur síos ar an obair anois cls_bpf, ós rud é ó thaobh an eolais faoi BPF clasaiceach ní thabharfaidh sé seo rud ar bith dúinn - ní mór dúinn a bheith eolach ar an bhfeidhmiúlacht go léir cheana féin. Ina theannta sin, in ailt ina dhiaidh sin ag caint faoi BPF Leathnaithe, buailfimid leis an aicmitheoir seo níos mó ná uair amháin.

Cúis eile gan labhairt faoi úsáid clasaiceach BPF c cls_bpf Is í an fhadhb atá ann, i gcomparáid le BPF Breisithe, go bhfuil raon feidhme na hinfheidhmeachta sa chás seo cúngaithe go mór: ní féidir le cláir chlasaiceacha inneachar na bpacáistí a athrú agus ní féidir leo an staid idir glaonna a shábháil.

Mar sin tá sé in am slán a fhágáil le BPF clasaiceach agus breathnú ar an todhchaí.

Slán le BPF clasaiceach

D'fhéachamar ar conas a d'éirigh le teicneolaíocht BPF, a forbraíodh go luath sna nóchaidí, maireachtáil ar feadh ceathrú céad bliain agus go dtí deireadh aimsíodh feidhmchláir nua. Mar sin féin, cosúil leis an aistriú ó mheaisíní cruachta go RISC, a bhí mar spreagadh d’fhorbairt BPF clasaiceach, sna 32í bhí aistriú ó mheaisíní 64-giotán go XNUMX-giotán agus thosaigh BPF clasaiceach ag dul i léig. Ina theannta sin, tá cumais BPF clasaiceach an-teoranta, agus sa bhreis ar an ailtireacht atá as dáta - níl an cumas againn staid a shábháil idir glaonna ar chláir BPF, níl aon fhéidearthacht ann idirghníomhú díreach leis an úsáideoir, níl aon fhéidearthacht ann idirghníomhú. leis an eithne, ach amháin le haghaidh léamh líon teoranta de réimsí struchtúir sk_buff agus na feidhmeanna cúntóra is simplí á seoladh agat, ní féidir leat a bhfuil sna paicéid a athrú agus iad a atreorú.

Go deimhin, faoi láthair níl fágtha den BPF clasaiceach i Linux ná an comhéadan API, agus taobh istigh den eithne aistrítear gach clár clasaiceach, bíodh sé ina scagairí soicéad nó ina scagairí seccomp, go formáid nua, BPF Breisithe. (Beidh muid ag caint faoi go díreach conas a tharlaíonn sé seo sa chéad alt eile.)

Thosaigh an t-aistriú chuig ailtireacht nua in 2013, nuair a mhol Alexey Starovoitov scéim nuashonraithe BPF. I 2014 na paistí comhfhreagracha thosaigh le feiceáil sa chroílár. Chomh fada agus a thuigim, ní raibh sa phlean tosaigh ach an ailtireacht agus an tiomsaitheoir JIT a bharrfheabhsú chun oibriú níos éifeachtaí ar mheaisíní 64-giotán, ach ina ionad sin ba é an leas iomlán a bhaint as na huasmhéaduithe seo tús caibidle nua i bhforbairt Linux.

Clúdóidh altanna breise sa tsraith seo ailtireacht agus feidhmeanna na teicneolaíochta nua, ar a dtugtar BPF inmheánach ar dtús, ansin BPF leathnaithe, agus anois go simplí BPF.

tagairtí

  1. Steven McCanne agus Van Jacobson, "An Scagaire Paicéad BSD: Ailtireacht Nua le haghaidh Gabháil Paicéad ag Leibhéal Úsáideora", https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Steven McCanne, "libpcap: Ailtireacht agus Modheolaíocht Optamaithe le haghaidh Gabháil Paicéad", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. Teagaisc Meaitseála IPtable U32.
  5. BPF - an bytecode dearmadta: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. Ag tabhairt isteach an Uirlis BPF: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. Forbhreathnú seccomp: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: Coimeádáin agus slándáil: seccomp
  11. habr: Deamhan á leithlisiú le systemd nó “níl Docker ag teastáil uait chuige seo!”
  12. Paul Chaignon, "strace --seccomp-bpf: cuma faoin gcochall", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

Foinse: will.com

Add a comment