BPF ho an'ny madinika, ampahany aotra: BPF mahazatra

Berkeley Packet Filters (BPF) dia teknolojia kernel Linux izay efa tao amin'ny pejy voalohan'ny famoahana teknolojia amin'ny teny anglisy nandritra ny taona maro izao. Ny fihaonambe dia feno tatitra momba ny fampiasana sy ny fampandrosoana ny BPF. David Miller, mpitantana ny subsystem tambajotra Linux, dia niantso ny lahateniny tao amin'ny Linux Plumbers 2018 “Tsy momba ny XDP ity resaka ity” (XDP dia tranga iray ampiasaina amin'ny BPF). Brendan Gregg manao lahateny mitondra ny lohateny hoe Linux BPF Superpowers. Toke Høiland-Jørgensen mihomehyfa ny kernel izao dia microkernel. Thomas Graf dia mampiroborobo ny hevitra hoe BPF dia javascript ho an'ny kernel.

Mbola tsy misy famaritana rafitra momba ny BPF ao amin'ny Habré, ary noho izany amin'ny andian-dahatsoratra dia hiezaka hiresaka momba ny tantaran'ny teknolojia aho, hamaritana ny maritrano sy ny fitaovana fampandrosoana, ary hanoritra ny sehatra fampiharana sy fampiharana ny fampiasana BPF. Ity lahatsoratra ity, aotra, ao amin'ny andian-dahatsoratra, dia milaza ny tantara sy ny maritrano mahazatra BPF, ary koa manambara ny tsiambaratelon'ny fitsipiky ny asa. tcpdump, seccomp, strace, sy ny maro hafa.

Ny fampandrosoana ny BPF dia fehezin'ny vondrom-piarahamonina tambajotra Linux, ny fampiharana lehibe indrindra an'ny BPF dia mifandray amin'ny tambajotra ary noho izany, nahazoana alalana. @eucariot, Nantsoiko hoe "BPF ho an'ny ankizy madinika" ilay andian-dahatsoratra, ho fanomezam-boninahitra ny andiany lehibe "Tambajotra ho an'ny madinika".

Fianarana fohy amin'ny tantaran'ny BPF (c)

Ny teknolojia BPF maoderina dia dikan-teny nohatsaraina sy nitarina amin'ny teknolojia taloha miaraka amin'ny anarana mitovy, antsoina ankehitriny BPF mahazatra mba hisorohana ny fisafotofotoana. Ny fitaovana malaza iray dia noforonina mifototra amin'ny BPF mahazatra tcpdump, mekanika seccomp, ary koa ny modules tsy dia fantatra loatra xt_bpf ho an'ny iptables ary classifier cls_bpf. Ao amin'ny Linux maoderina, ny programa BPF mahazatra dia adika ho azy amin'ny endrika vaovao, na izany aza, amin'ny fomba fijerin'ny mpampiasa, ny API dia nijanona teo amin'ny toerany ary ny fampiasana vaovao ho an'ny BPF mahazatra, araka ny ho hitantsika ato amin'ity lahatsoratra ity, dia mbola hita. Noho izany antony izany, ary koa satria manaraka ny tantaran'ny fivoaran'ny BPF klasika amin'ny Linux, dia hazava kokoa ny fomba sy ny antony nivoahany ho amin'ny endriny maoderina, dia nanapa-kevitra ny hanomboka amin'ny lahatsoratra momba ny BPF klasika aho.

Tamin'ny faran'ny eighties tamin'ny taonjato farany, injeniera avy amin'ny malaza Lawrence Berkeley Laboratory lasa liana amin'ny fanontaniana ny fomba hanivana tsara ny tambajotra fonosana amin'ny fitaovana maoderina tamin'ny faramparan'ny eighties tamin'ny taonjato farany. Ny hevitra fototra momba ny sivana, izay nampiharina tamin'ny teknolojia CSPF (CMU/Stanford Packet Filter) tany am-boalohany, dia ny hanivana ireo fonosana tsy ilaina araka izay tratra, izany hoe. amin'ny habaka kernel, satria misoroka ny kopia data tsy ilaina amin'ny habaka mpampiasa izany. Mba hanomezana fiarovana amin'ny fotoana fampandehanana ny kaody mpampiasa amin'ny habaka kernel, dia nampiasaina ny milina virtoaly sandboxed.

Na izany aza, ny milina virtoaly ho an'ny sivana efa misy dia natao hihazakazaka amin'ny milina mifototra amin'ny stack ary tsy mandeha tsara amin'ny milina RISC vaovao kokoa. Vokatr'izany, tamin'ny alàlan'ny ezaky ny injeniera avy amin'ny Berkeley Labs, dia nisy teknolojia BPF (Berkeley Packet Filters) vaovao novolavolaina, ny maritrano milina virtoaly izay natao miorina amin'ny processeur Motorola 6502 - ny soavalin'ny vokatra fanta-daza toy izany. Apple II na nes. Ny milina virtoaly vaovao dia nampitombo ny fahombiazan'ny sivana im-polo raha oharina amin'ny vahaolana efa misy.

BPF milina architecture

Hifankazatra amin'ny maritrano amin'ny fomba miasa isika, mamakafaka ohatra. Na izany aza, mba hanombohana, andao lazaina fa ny milina dia manana rejisitra 32-bit roa azon'ny mpampiasa idirana, accumulator. A ary ny rejisitra index X, fitadidiana 64 bytes (teny 16), azo soratana sy vakina manaraka, ary rafitra kely misy baiko hiasa amin'ireo zavatra ireo. Ny toromarika hitsambikina amin'ny fampiharana ny fanehoan-kevitra misy fepetra dia nisy ihany koa tao amin'ny programa, fa mba hiantohana ny fahavitan'ny fandaharana ara-potoana dia azo atao ny mitsambikina, izany hoe, indrindra fa voarara ny mamorona tadivavarana.

Ny rafitra ankapobeny amin'ny fanombohana ny milina dia toy izao manaraka izao. Ny mpampiasa dia mamorona programa ho an'ny maritrano BPF ary mampiasa SASANY kernel (toy ny antso an-tariby), mameno sy mampifandray ny programa amin'ny amin'ny sasany mankany amin'ny mpamorona hetsika ao amin'ny kernel (ohatra, ny hetsika dia ny fahatongavan'ny fonosana manaraka amin'ny karatra tambajotra). Rehefa misy zava-mitranga, ny kernel dia mampandeha ny programa (ohatra, amin'ny mpandika teny), ary ny fitadidian'ny milina dia mifanaraka amin'ny amin'ny sasany faritra fitadidiana kernel (ohatra, angon-drakitra momba ny fonosana miditra).

Ireo voalaza etsy ambony ireo dia ho ampy ho antsika hanomboka hijery ohatra: hifankazatra amin'ny rafitra sy ny format baiko isika raha ilaina. Raha te hianatra avy hatrany ny rafitra baikon'ny milina virtoaly ianao ary hianatra momba ny fahaizany rehetra, dia azonao atao ny mamaky ny lahatsoratra tany am-boalohany Ny BSD Packet Filter ary/na ny tapany voalohany amin'ny rakitra Documentation/networking/filter.txt avy amin'ny antontan-taratasy kernel. Ankoatra izany, azonao atao ny mianatra ny famelabelarana libpcap: Fomba Famoronana sy fanatsarana ho an'ny fakàna fonosana, izay i McCanne, iray amin'ireo mpanoratra ny BPF, dia miresaka momba ny tantaran'ny famoronana libpcap.

Miroso amin'ny fandinihana ireo ohatra manan-danja rehetra amin'ny fampiasana BPF mahazatra amin'ny Linux isika izao: tcpdump (libpcap), seccom, xt_bpf, cls_bpf.

tcpdump

Ny fampandrosoana ny BPF dia natao mifanaraka amin'ny fampandrosoana ny frontend ho an'ny sivana fonosana - fitaovana malaza. tcpdump. Ary, satria ity no ohatra tranainy indrindra sy malaza indrindra amin'ny fampiasana BPF mahazatra, azo alaina amin'ny rafitra fiasa maro, dia hanomboka ny fandalinantsika ny teknolojia miaraka aminy isika.

(Nihazakazaka ny ohatra rehetra tao amin'ity lahatsoratra ity momba ny Linux aho 5.6.0-rc6. Ny famoahana ny baiko sasany dia novana mba ho mora kokoa ny mamaky azy.)

Ohatra: mijery ny fonosana IPv6

Andeha hojerentsika fa te hijery ny fonosana IPv6 rehetra amin'ny interface iray isika eth0. Mba hanaovana izany dia afaka mihazakazaka ny programa tcpdump miaraka amin'ny sivana tsotra ip6:

$ sudo tcpdump -i eth0 ip6

Noho izany tcpdump manangona ny sivana ip6 ao amin'ny bytecode architecture BPF ary alefaso any amin'ny kernel (jereo ny antsipiriany ao amin'ny fizarana Tcpdump: loading). Ny sivana feno entana dia halefa isaky ny fonosana mandalo amin'ny interface eth0. Raha mamerina sanda tsy aotra ny sivana n, dia hatramin'ny n Ny bytes amin'ny fonosana dia hadika amin'ny habaka mpampiasa ary ho hitantsika ao amin'ny vokatra tcpdump.

BPF ho an'ny madinika, ampahany aotra: BPF mahazatra

Hita fa afaka mahita mora foana izay bytecode nalefa tany amin'ny kernel tcpdump miaraka amin'ny fanampian'ny tcpdump, raha ataontsika miaraka amin'ny safidy -d:

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

Amin'ny andalana aotra no ataontsika ny baiko ldh [12], izay midika hoe “load into register A antsasaky ny teny (16 bits) hita ao amin'ny adiresy 12" ary ny hany fanontaniana dia inona no karazana fahatsiarovana resahina? Ny valiny dia hoe amin'ny x manomboka (x+1)th byte amin'ny fonosan'ny tambazotra nodinihina. Mamaky fonosana avy amin'ny interface Ethernet izahay eth0, ary ity dia midika hoefa toy izao ny packet (ho an'ny fahatsorana dia heverinay fa tsy misy marika VLAN ao anaty fonosana):

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

Ka rehefa avy nanatanteraka ny baiko ldh [12] ao amin'ny rejisitra A hisy saha Ether Type - ny karazana fonosana ampitaina amin'ity frame Ethernet ity. Amin'ny andalana 1 dia mampitaha ny votoatin'ny rejisitra A (karazana fonosana) c 0x86dd, ary ity ary manana Ny karazana mahaliana anay dia IPv6. Ao amin'ny andalana 1, ankoatra ny baiko fampitahana, dia misy tsanganana roa hafa - jt 2 и jf 3 - marika tokony halehanao raha mahomby ny fampitahana (A == 0x86dd) ary tsy nahomby. Noho izany, amin'ny tranga mahomby (IPv6) dia mankany amin'ny andalana 2 isika, ary amin'ny tranga tsy mahomby - amin'ny andalana 3. Amin'ny andalana 3 dia mifarana amin'ny code 0 ny programa (aza mandika ny fonosana), amin'ny andalana 2 dia mifarana amin'ny code ny programa. 262144 (adikao amiko ny fonosana 256 kilobytes ambony indrindra).

Ohatra sarotra kokoa: mijery ny fonosana TCP amin'ny seranan-tsambo

Andeha hojerentsika ny endriky ny sivana izay mandika ny fonosana TCP rehetra miaraka amin'ny seranan-tsambo 666. Hodinihintsika ny tranga IPv4, satria tsotra kokoa ny tranga IPv6. Rehefa avy nianatra ity ohatra ity ianao dia afaka mijery ny sivana IPv6 ho toy ny fanazaran-tena (ip6 and tcp dst port 666) ary sivana ho an'ny tranga ankapobeny (tcp dst port 666). Noho izany, ny sivana mahaliana antsika dia toy izao:

$ 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

Efa fantatsika ny ataon'ny andalana 0 sy 1. Ao amin'ny andalana 2 dia efa nanamarina izahay fa ity dia fonosana IPv4 (Ether Type = 0x800) ary ampidiro ao amin'ny rejisitra A 24th byte amin'ny fonosana. Toa ny fonosanay

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

izany hoe miditra ao anaty rejisitra isika A ny saha Protocol an'ny lohatenin'ny IP, izay lojika, satria ny fonosana TCP ihany no tiana atao. Mampitaha Protocol amin'ny 0x6 (IPPROTO_TCP) andalana 3.

Amin'ny andalana faha-4 sy faha-5 dia mameno ny antsasaky ny teny ao amin'ny adiresy 20 izahay ary mampiasa ny baiko jset jereo raha napetraka ny iray amin'izy telo flags - manao ny saron-tava navoaka jset voafafa ireo bitika telo manan-danja indrindra. Ny roa amin'ireo bitika telo dia milaza amintsika raha anisan'ny fonosana IP voazarazara ilay fonosana, ary raha izany, na io no sombiny farany. Ny bit fahatelo dia voatokana ary tsy maintsy aotra. Tsy te-hijery ny fonosana tsy feno na tapaka izahay, ka manamarina ny bitika telo.

Ny andalana 6 no mahaliana indrindra amin'ity lisitra ity. maneho Hevitra ldxb 4*([14]&0xf) midika hoe miditra ao amin'ny rejisitra isika X ny bits efatra manan-danja indrindra amin'ny byte fahadimy ambin'ny folo amin'ny fonosana ampitomboina amin'ny 4. Ny bitika efatra manan-danja indrindra amin'ny byte fahadimy ambin'ny folo dia ny saha. Internet Header Length Lohateny IPv4, izay mitahiry ny halavan'ny lohapejy amin'ny teny, ka mila ampitomboinao amin'ny 4. Mahaliana fa ny fitenenana 4*([14]&0xf) dia fanendrena ho an'ny rafitra adiresy manokana izay tsy azo ampiasaina afa-tsy amin'ity endrika ity ary ho an'ny rejisitra ihany X, i.e. tsy afaka miteny koa izahay ldb 4*([14]&0xf) na ldxb 5*([14]&0xf) (tsy afaka mamaritra afa-tsy offset hafa isika, ohatra, ldxb 4*([16]&0xf)). Mazava ho azy fa nampidirina tao amin'ny BPF io tetik'asa fiatrehana io mba hahazoana X (Rejistra fanondro) halavan'ny lohapejy IPv4.

Noho izany amin'ny andalana faha-7 dia manandrana mameno ny antsasaky ny teny izahay (X+16). Tsarovy fa 14 bytes no ipetrahan'ny lohatenin'ny Ethernet, ary X misy ny halavan'ny lohapejy IPv4, azontsika fa ao A Ny seranan-tsambon'ny TCP dia feno:

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

Farany, amin'ny andalana 8 isika dia mampitaha ny seranan-tsambo amin'ny sanda irina ary amin'ny andalana 9 na 10 dia mamerina ny valiny - na handika ny fonosana na tsia.

Tcpdump: loading

Ao amin'ireo ohatra teo aloha, dia tsy nieritreritra manokana momba ny fomba fametahana BPF bytecode ao anaty kernel ho an'ny sivana fonosana. Amin'ny ankapobeny, tcpdump nafindra tany amin'ny rafitra maro sy mba hiasa amin'ny sivana tcpdump mampiasa ny tranomboky libpcap. Fohy, hametraka sivana amin'ny interface iray mampiasa libpcap, mila manao izao manaraka izao ianao:

Mba hahitana ny fomba fiasa pcap_setfilter ampiasaina amin'ny Linux, ampiasainay strace (nesorina ny andalana sasany):

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

Amin'ny andalana roa voalohany amin'ny famoahana dia mamorona isika socket manta hamaky ny frame Ethernet rehetra ary hamatotra azy amin'ny interface eth0. avy amin'ny ohatra voalohany ho antsika fantatsika fa ny sivana ip dia ahitana torolalana BPF efatra, ary amin'ny andalana fahatelo dia hitantsika ny fomba fampiasana ny safidy SO_ATTACH_FILTER antso rafitra setsockopt apetrakay ary ampifandraiso ny sivana amin'ny halavany 4. Ity no sivanay.

Tsara ny manamarika fa amin'ny BPF mahazatra, ny fametrahana sy ny fampifandraisana ny sivana dia mitranga foana amin'ny asa atao atomika, ary amin'ny dikan-teny vaovao an'ny BPF, ny fametrahana ny programa sy ny famatorana azy amin'ny mpamokatra hetsika dia misaraka amin'ny fotoana.

Fahamarinana miafina

Ny dikan-teny feno kokoa amin'ny famoahana dia toy izao:

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

Araka ny voalaza etsy ambony, dia mametaka sy mampifandray ny sivana amin'ny socket amin'ny andalana 5 isika, fa inona no mitranga amin'ny andalana 3 sy 4? Hay io libpcap mikarakara antsika - mba tsy ahitana fonosana tsy mahafa-po azy ny fivoahan'ny sivanantsika, ny tranomboky mampifandray sivana dummy ret #0 (atsaharo ny fonosana rehetra), mamadika ny faladia ho amin'ny fomba tsy manakana ary manandrana manala ny fonosana rehetra mety hijanona amin'ny sivana teo aloha.

Amin'ny fitambarany, mba hanivana ny fonosana amin'ny Linux amin'ny fampiasana BPF mahazatra dia mila manana sivana amin'ny endrika rafitra toy izany ianao struct sock_fprog ary faladia misokatra, aorian'izay dia azo ampifandraisina amin'ny socket ny sivana amin'ny alàlan'ny antso an-tariby setsockopt.

Mahaliana fa ny sivana dia azo apetaka amin'ny socket rehetra fa tsy manta fotsiny. Eto ohatra programa manapaka ny rehetra afa-tsy ny roa voalohany amin'ny angona UDP rehetra miditra. (Nampiako hevitra tao amin'ny kaody aho mba tsy hanakorontana ny lahatsoratra.)

Fanazavana bebe kokoa momba ny fampiasana setsockopt ho an'ny fampifandraisana sivana, jereo socket (7), fa momba ny fanoratana ny sivanao manokana toy ny struct sock_fprog tsy misy fanampiana tcpdump hiresaka amin'ny fizarana isika Programming BPF mampiasa ny tananay manokana.

Classic BPF sy ny taonjato faha-21

Ny BPF dia nampidirina tao amin'ny Linux tamin'ny taona 1997 ary nijanona ho mpiasan'ny asa nandritra ny fotoana ela libpcap tsy misy fiovana manokana (fanovana manokana amin'ny Linux, mazava ho azy, izany no, nefa tsy nanova ny sary maneran-tany izy ireo). Ny famantarana lehibe voalohany fa hivoatra ny BPF dia tonga tamin'ny 2011, rehefa nanolotra soso-kevitra i Eric Dumazet damba, izay manampy Just In Time Compiler amin'ny kernel - mpandika teny hanovana ny BPF bytecode ho an'ny teratany x86_64 code.

JIT compiler no voalohany tamin'ny rojo fanovana: tamin'ny 2012 niseho fahafahana manoratra sivana ho an'ny seccom, mampiasa BPF, tamin'ny Janoary 2013 dia nisy nanampy Module xt_bpf, izay ahafahanao manoratra fitsipika momba ny iptables miaraka amin'ny fanampian'ny BPF, ary tamin'ny Oktobra 2013 dia nanampy koa module cls_bpf, izay ahafahanao manoratra fanasokajiana fifamoivoizana amin'ny fampiasana BPF.

Hojerentsika amin'ny antsipiriany bebe kokoa ireo ohatra rehetra ireo tsy ho ela, fa ilaina aloha ny mianatra manoratra sy manangona programa tsy misy dikany ho an'ny BPF, satria ny fahaiza-manao omen'ny tranomboky. libpcap voafetra (ohatra tsotra: sivana vokarina libpcap afaka mamerina sanda roa ihany - 0 na 0x40000) na amin'ny ankapobeny, toy ny amin'ny seccom, dia tsy azo ampiharina.

Programming BPF mampiasa ny tananay manokana

Andao hifankazatra amin'ny endrika binary amin'ny torolàlana BPF, tena tsotra izany:

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

Ny torolalana tsirairay dia manana 64 bits, izay ny 16 bits voalohany dia ny kaody fampianarana, avy eo misy indents valo-bit roa, jt и jf, ary 32 bits ho an'ny argument K, ny tanjon'izany dia miovaova arakaraka ny baiko. Ohatra, ny baiko ret, izay mamarana ny programa dia manana ny code 6, ary ny sanda miverina dia alaina amin'ny tsy miova K. Ao amin'ny C, ny fampianarana BPF tokana dia aseho ho rafitra

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

ary ny programa manontolo dia miendrika rafitra

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

Noho izany, efa afaka manoratra programa isika (ohatra, fantatsika ny kaody fampianarana avy amin'ny [1]). Toy izao no ho endriky ny sivana ip6 avy amin'ny ohatra voalohany ho antsika:

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

FANDAHARAM-POTOANA prog azontsika ampiasaina ara-dalàna amin'ny antso

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

Ny fanoratana programa amin'ny endriky ny kaody milina dia tsy dia mety loatra, fa indraindray ilaina izany (ohatra, amin'ny debugging, mamorona fitsapana unit, manoratra lahatsoratra momba ny Habré, sns.). Ho an'ny fanamorana, ao anaty rakitra <linux/filter.h> Ny macros mpanampy dia voafaritra - ny ohatra mitovy amin'ny etsy ambony dia azo averina soratana toy ny

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

Na izany aza, ity safidy ity dia tsy dia mety loatra. Izany no nasain'ireo mpandrindra kernel Linux, ary noho izany dia tao amin'ny lahatahiry tools/bpf kernel dia azonao atao ny mahita assembler sy debugger amin'ny fiasana amin'ny BPF mahazatra.

Ny fiteny fivoriambe dia tena mitovy amin'ny famoahana debug tcpdump, fa ho fanampin'izany dia afaka mamaritra marika an'ohatra isika. Ohatra, ity misy programa manary ny fonosana rehetra afa-tsy TCP/IPv4:

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

Amin'ny alàlan'ny default, ny assembler dia mamorona code amin'ny endrika <количество инструкций>,<code1> <jt1> <jf1> <k1>,..., ho ohatra amin'ny TCP izany

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

Ho fanamorana ny mpandrindra C, dia azo ampiasaina ny endrika famoahana hafa:

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

Ity lahatsoratra ity dia azo adika amin'ny famaritana rafitra karazana struct sock_filter, tahaka ny nataontsika tany am-piandohan’ity fizarana ity.

Linux sy netsniff-ng extensions

Ankoatra ny BPF mahazatra, Linux ary tools/bpf/bpf_asm fanohanana ary napetraka tsy manara-penitra. Amin'ny ankapobeny, ny toromarika dia ampiasaina hidirana amin'ny sahan'ny rafitra iray struct sk_buff, izay mamaritra fonosana tambajotra ao amin'ny kernel. Na izany aza, misy ihany koa ny karazana toromarika mpanampy hafa, ohatra ldw cpu dia hampiditra ao amin'ny rejisitra A vokatry ny fampandehanana asa kernel raw_smp_processor_id(). (Ao amin'ny dika vaovaon'ny BPF, ireo fanitarana tsy manara-penitra ireo dia nitarina mba hanomezana programa miaraka amin'ny andiana mpanampy amin'ny kernel ho an'ny fidirana amin'ny fitadidiana, ny rafitra ary ny famoronana hetsika.) Ity misy ohatra iray mahaliana momba ny sivana izay tsy adika afa-tsy ny lohapejy fonosana amin'ny habaka mpampiasa mampiasa ny fanitarana poff, offset enta-mavesatra:

ld poff
ret a

Tsy azo ampiasaina ny fanitarana BPF tcpdump, fa izany no antony tsara hahafantarana ny fonosana fampiasa netsniff-ng, izay, ankoatry ny zavatra hafa, dia misy programa mandroso netsniff-ng, izay, ankoatra ny fanivanana amin'ny fampiasana BPF, dia misy ihany koa mpamokatra fifamoivoizana mahomby, ary mandroso kokoa noho ny tools/bpf/bpf_asm, assembler BPF antsoina bpfc. Ny fonosana dia misy antontan-taratasy amin'ny antsipiriany, jereo koa ny rohy any amin'ny faran'ny lahatsoratra.

seccom

Noho izany, efa fantatsika ny fomba hanoratana programa BPF amin'ny fahasarotana tsy misy dikany ary vonona ny hijery ohatra vaovao, ny voalohany amin'izany dia ny teknolojia seccomp, izay mamela, amin'ny fampiasana sivana BPF, mitantana ny fametrahana sy ny fametrahana ny tohan-kevitry ny antso an-tariby misy dingana nomena sy ny taranany.

Ny dikan-teny voalohany amin'ny seccomp dia nampidirina tao amin'ny kernel tamin'ny taona 2005 ary tsy dia malaza loatra, satria tsy nanome afa-tsy safidy tokana izy io - mba hamerana ny antson'ny rafitra misy amin'ny dingana iray amin'ireto manaraka ireto: read, write, exit и sigreturn, ary ny dingana izay nandika ny fitsipika dia novonoina tamin'ny fampiasana SIGKILL. Na izany aza, tamin'ny taona 2012, ny seccomp dia nanampy ny fahafahana mampiasa sivana BPF, mamela anao hamaritra andiana antson'ny rafitra navela ary hanamarina mihitsy aza ny tohan-kevitr'izy ireo. (Mahaliana fa ny Chrome dia iray amin'ireo mpampiasa voalohany an'io fampiasa io, ary ny olona Chrome dia mamolavola rafitra KRSI mifototra amin'ny dikan-teny BPF vaovao ary mamela ny fanamboarana ny Linux Security Modules.) Misy rohy mankany amin'ny antontan-taratasy fanampiny hita any amin'ny farany. ny lahatsoratra.

Mariho fa efa nisy lahatsoratra tao amin'ny hub momba ny fampiasana seccom, angamba misy olona te hamaky azy ireo alohan'ny (na raha tokony) hamaky ireto fizarana manaraka ireto. Ao amin'ny lahatsoratra Kaontenera sy fiarovana: seccomp manome ohatra amin'ny fampiasana seccomp, na ny version 2007 na ny version mampiasa BPF (ny sivana dia novokarina tamin'ny libseccomp), miresaka momba ny fifandraisan'ny seccomp amin'ny Docker, ary manome rohy mahasoa maro ihany koa. Ao amin'ny lahatsoratra Mitokana ny daemon miaraka amin'ny systemd na "tsy mila Docker ianao amin'izany!" Izy io dia mirakitra, indrindra, ny fomba hanampiana lisitra mainty na lisitra fotsy amin'ny antson'ny rafitra ho an'ny daemons mandeha systemd.

Ho hitantsika manaraka ny fomba hanoratana sy hametahana sivana seccomp amin'ny bara C ary mampiasa ny tranomboky libseccomp ary inona no tombotsoa sy lafy ratsin'ny safidy tsirairay, ary farany, andeha hojerentsika ny fomba fampiasan'ny programa seccomp strace.

Manoratra sy mampiditra sivana ho an'ny seccom

Efa haintsika ny manoratra programa BPF, ka andeha hojerentsika aloha ny seccom programming interface. Azonao atao ny mametraka sivana eo amin'ny sehatry ny dingana, ary ny fizotran'ny ankizy rehetra dia handova ny fameperana. Izany dia atao amin'ny fampiasana antso an-tariby seccomp(2):

seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)

izay &filter - fanondroana rafitra efa mahazatra antsika izany struct sock_fprog, i.e. Programa BPF.

Inona no maha samy hafa ny programa ho an'ny seccom amin'ny programa ho an'ny sockets? contexte nampitaina. Raha ny sockets dia nomena faritra fitadidiana misy ny fonosana izahay, ary amin'ny seccom dia nomena rafitra toy ny

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

izany nr dia ny laharan'ny antson'ny rafitra hatomboka, arch - Architecture ankehitriny (bebe kokoa momba ity eto ambany ity), args - hatramin'ny enina rafitra antso hevitra, ary instruction_pointer dia tondro mankany amin'ny toromarika momba ny habaka mpampiasa izay nanao ny antson'ny rafitra. Noho izany, ohatra, hampiditra ny nomeraon'ny antso an-tariby ao amin'ny rejisitra A tsy maintsy miteny isika

ldw [0]

Misy endri-javatra hafa ho an'ny programa seccom, ohatra, ny contexte dia tsy azo idirana afa-tsy amin'ny alàlan'ny alignment 32-bit ary tsy afaka mametaka ny antsasaky ny teny na byte ianao - rehefa manandrana mampiditra sivana. ldh [0] antso rafitra seccomp hiverina EINVAL. Ny asa dia manamarina ny sivana feno entana seccomp_check_filter() voany. (Ny mampihomehy dia, tao amin'ny commit tany am-boalohany izay nanampy ny fampiasa seccomp, hadinon'izy ireo ny nanampy alalana hampiasa ny torolàlana amin'ity fiasa ity. mod (sisa fizarana) ary tsy azo ampiasaina amin'ny programa BPF seccom, hatramin'ny nampiana azy ho tapaka ABI.)

Amin'ny ankapobeny, efa fantatsika ny zava-drehetra hanoratana sy hamakiana programa seccom. Matetika ny lojikan'ny programa dia voalamina ho lisitra fotsy na mainty amin'ny antso an-tariby, ohatra ny programa

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

manamarina lisitra mainty misy antso an-tariby efatra misy laharana 304, 176, 239, 279. Inona avy ireo antso an-tariby ireo? Tsy afaka milaza marina isika, satria tsy fantatsika hoe inona no rafitra nanoratana ny programa. Noho izany, ny mpanoratra ny seccom tolotra manomboka ny programa rehetra miaraka amin'ny fanamarinana maritrano (ny rafitra ankehitriny dia aseho amin'ny teny manodidina ho toy ny saha arch rafitra struct seccomp_data). Raha jerena ny maritrano, ny fiandohan'ny ohatra dia ho toy izao:

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

ary avy eo dia hahazo sanda sasany ny laharan'ny antso an-tariby.

Manoratra sy mampiditra sivana ho an'ny fampiasana seccom izahay libseccomp

Ny fanoratana sivana amin'ny kaody teratany na ao amin'ny fivorian'ny BPF dia ahafahanao mifehy tanteraka ny vokatra, saingy amin'ny fotoana iray ihany, dia tsara kokoa indraindray ny manana kaody portable sy/na azo vakiana. Hanampy antsika amin’izany ny tranomboky libseccomp, izay manome interface tsara ho an'ny fanoratana sivana mainty na fotsy.

Andeha, ohatra, hanoratra programa iray izay mitantana rakitra mimari-droa amin'ny safidin'ny mpampiasa, efa nametraka lisitra mainty misy antso an-tariby avy amin'ny rafitra. ny lahatsoratra etsy ambony (Nohamafisina ny programa mba ho mora vakina kokoa, azo jerena ny dikan-teny feno eto):

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

Voalohany dia mamaritra ny array isika sys_numbers amin'ny laharana antso an-tariby 40+ hosakanana. Avy eo, manomboka ny contexte ctx ary lazao amin'ny tranomboky izay tiantsika avela (SCMP_ACT_ALLOW) ny antso rehetra amin'ny rafitra rehetra (mora kokoa ny manangana lisitra mainty). Avy eo, ampidirintsika tsirairay ny antson'ny rafitra rehetra avy amin'ny lisitra mainty. Ho valin'ny antso an-tariby avy amin'ny lisitra dia mangataka izahay SCMP_ACT_TRAP, amin'ity tranga ity dia handefa famantarana ny seccom amin'ny dingana SIGSYS miaraka amin'ny famaritana izay antsoin'ny rafitra nandika ny fitsipika. Farany, ampidirintsika ao anaty kernel ny programa amin'ny fampiasana seccomp_load, izay hanangona ny programa ary hamatotra azy amin'ny dingana amin'ny alàlan'ny antso an-tariby seccomp(2).

Mba hahazoana fahombiazana, ny programa dia tsy maintsy mifandray amin'ny tranomboky libseccomp, ohatra:

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

Ohatra amin'ny fandefasana mahomby:

$ ./seccomp_lib echo ok
ok

Ohatra amin'ny antson'ny rafitra voasakana:

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

Ampiasainay straceho an'ny antsipiriany:

$ 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

ahoana no ahafantarantsika fa tapaka ny programa noho ny fampiasana antso an-tariby tsy ara-dalàna mount(2).

Noho izany, nanoratra sivana izahay tamin'ny fampiasana ny tranomboky libseccomp, mametraka fehezan-dalàna tsy misy dikany ho andalana efatra. Ao amin'ny ohatra etsy ambony, raha be dia be ny antso an-tariby, ny fotoana famonoana dia mety hihena, satria ny fanamarinana dia lisitry ny fampitahana fotsiny. Ho an'ny fanatsarana, libseccomp vao haingana misy patch, izay manampy fanohanana ny toetra sivana SCMP_FLTATR_CTL_OPTIMIZE. Ny fametrahana ity toetra ity ho 2 dia hanova ny sivana ho programa fikarohana binary.

Raha te-hahita ny fomba fiasan'ny sivana fikarohana binary ianao dia jereo ny script tsotra, izay mamorona programa toy izany ao amin'ny BPF assembler amin'ny alàlan'ny fiantsoana ny laharan'ny antso an-tariby, ohatra:

$ 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

Tsy azo atao ny manoratra zavatra haingana kokoa, satria ny programa BPF dia tsy afaka manao fitsangantsanganana indentation (tsy afaka manao izany isika, ohatra, jmp A na jmp [label+X]) ary noho izany ny fifindrana rehetra dia static.

seccom sy strace

Fantatry ny rehetra ny utility strace dia fitaovana tena ilaina amin'ny fandalinana ny fihetsiky ny fizotran'ny Linux. Na izany aza, maro ihany koa no nandre momba izany olana momba ny fampisehoana rehefa mampiasa ity utility ity. Ny zava-misy dia izany strace ampiharina amin'ny fampiasana ptrace(2), ary amin'ity mekanika ity dia tsy afaka mamaritra hoe inona ny rafitra antso no ilaintsika hampitsaharana ny dingana, izany hoe, ohatra, baiko.

$ 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

dia karakaraina ao anatin'ny fotoana mitovy, na dia amin'ny tranga faharoa aza dia tiantsika ny hanara-maso antso an-tariby tokana.

Safidy vaovao --seccomp-bpf, ampiana amin'ny strace version 5.3, dia ahafahanao manafaingana ny dingana im-betsaka ary ny fotoana fanombohana eo ambanin'ny antson'ny rafitra iray dia efa azo oharina amin'ny fotoana fanombohana mahazatra:

$ 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

(Eto, mazava ho azy, misy fitaka kely amin'ny tsy fanarahana ny antson'ny rafitra fototra amin'ity baiko ity. newfsstat, then strace hisedra mafy toy ny tsy misy --seccomp-bpf.)

Ahoana no fiasan'ity safidy ity? Raha tsy misy azy strace mifandray amin'ny dingana ary manomboka mampiasa izany PTRACE_SYSCALL. Rehefa misy dingana voatantanana mamoaka antso an-tariby (izay) dia afindra any amin'ny rafitra ny fanaraha-maso strace, izay mijery ny tohan-kevitry ny antson'ny rafitra ary mampandeha azy PTRACE_SYSCALL. Rehefa afaka kelikely, dia mamita ny antson'ny rafitra ny dingana ary rehefa mivoaka izany dia afindra indray ny fanaraha-maso strace, izay mijery ny sanda miverina ary manomboka ny dingana mampiasa PTRACE_SYSCALL, sy ny sisa.

BPF ho an'ny madinika, ampahany aotra: BPF mahazatra

Miaraka amin'ny seccom, na izany aza, ity dingana ity dia azo amboarina araka izay tiantsika. Izany hoe, raha tsy te hijery afa-tsy ny antso rafitra X, dia afaka manoratra sivana BPF izay ho an'ny X mamerina sanda SECCOMP_RET_TRACE, ary ho an'ny antso izay tsy mahaliana antsika - SECCOMP_RET_ALLOW:

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

Amin'ity tranga ity strace manomboka ny dingana toy ny PTRACE_CONT, ny sivanay dia karakaraina isaky ny antso an-tariby, raha tsy misy ny antso an-tariby X, dia mitohy ny dingana, fa raha izao X, dia hamindra ny fanaraha-maso ny seccom straceizay hijery ny tohan-kevitra ary hanomboka ny dingana toy ny PTRACE_SYSCALL (satria tsy manana fahafahana mampandeha programa amin'ny fivoahana amin'ny antso an-tariby ny seccomp). Rehefa miverina ny antson'ny rafitra, strace dia hamerina ny dingana mampiasa PTRACE_CONT ary hiandry hafatra vaovao avy amin'ny seccom.

BPF ho an'ny madinika, ampahany aotra: BPF mahazatra

Rehefa mampiasa ny safidy --seccomp-bpf misy fameperana roa. Voalohany, tsy azo atao ny miditra amin'ny dingana efa misy (safidy -p fandaharana strace), satria tsy tohanan'ny seccom. Faharoa, tsy misy azo atao tsy jereo ny fizotran'ny ankizy, satria ny sivana seccom dia nolovain'ny fizotry ny ankizy rehetra tsy misy fahafahana manafoana izany.

Fanazavana fanampiny momba ny fomba marina strace miasa miaraka amin'ny seccomp azo jerena avy amin'ny tatitra vao haingana. Ho anay, ny zava-misy mahaliana indrindra dia ny BPF mahazatra asehon'ny seccomp dia mbola ampiasaina ankehitriny.

xt_bpf

Andeha isika hiverina amin'ny tontolon'ny tambajotra.

Fitohizan'ny hafatra : efa hatry ny ela, tamin'ny 2007, ny fototra nanampy Module xt_u32 ho an'ny netfilter. Izy io dia nosoratana tamin'ny alàlan'ny fanoharana miaraka amin'ny fanasokajiana fifamoivoizana tranainy kokoa cls_u32 ary namela anao hanoratra fitsipika mimari-droa tsy misy dikany ho an'ny iptables amin'ny fampiasana ireto asa tsotra manaraka ireto: mametaka 32 bits avy amin'ny fonosana iray ary manatanteraka andiana asa arithmetika amin'izy ireo. Ohatra,

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

Ampidiro ny bitika 32 amin'ny lohatenin'ny IP, manomboka amin'ny padding 6, ary asio saron-tava amin'izy ireo. 0xFF (alao ny byte ambany). Ity saha ity protocol Lohateny IP ary ampitahainay amin'ny 1 (ICMP). Amin'ny fitsipika iray dia azonao atao ny manambatra ny fanamarinana maro, ary azonao atao koa ny manatanteraka ny mpandraharaha @ — mamindra X bytes miankavanana. Ohatra, ny fitsipika

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

manamarina raha tsy mitovy ny laharana TCP Sequence 0x29. Tsy hiditra amin'ny antsipiriany bebe kokoa aho, satria efa mazava fa tsy dia mety loatra ny fanoratana fitsipika toy izany amin'ny tanana. Ao amin'ny lahatsoratra BPF - ny bytecode hadino, misy rohy maromaro misy ohatra momba ny fampiasana sy famoronana fitsipika momba ny xt_u32. Jereo koa ireo rohy any amin'ny faran'ity lahatsoratra ity.

Nanomboka tamin'ny 2013 ny module fa tsy ny module xt_u32 Azonao atao ny mampiasa module BPF xt_bpf. Na iza na iza namaky an'ity lavitra ity dia tokony ho efa mazava tsara ny fitsipiky ny fampandehanana azy: mihazakazaka BPF bytecode ho fitsipika iptables. Afaka mamorona fitsipika vaovao ianao, ohatra, toy izao:

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

eto <байткод> - ity no code amin'ny format assembler output bpf_asm amin'ny default, ohatra,

$ 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

Amin'ity ohatra ity dia manivana ny fonosana UDP rehetra izahay. Toe-javatra ho an'ny programa BPF amin'ny module xt_bpf, mazava ho azy, manondro ny angona fonosana, amin'ny tranga iptables, mankany amin'ny fiandohan'ny lohapejy IPv4. Sanda miverina avy amin'ny programa BPF booleanizay false midika fa tsy nifanaraka ny fonosana.

Mazava fa ny module xt_bpf manohana sivana sarotra kokoa noho ny ohatra etsy ambony. Andeha hojerentsika ny tena ohatra avy amin'ny Cloudfare. Hatramin'ny vao haingana izy ireo dia nampiasa ny module xt_bpf mba hiarovana amin'ny fanafihana DDoS. Ao amin'ny lahatsoratra Fampidirana ny BPF Tools manazava ny fomba (ary nahoana) izy ireo no mamokatra sivana BPF ary mamoaka rohy mankany amin'ny vondron'asa iray hamoronana sivana toy izany. Ohatra, mampiasa ny utility bpfgen afaka mamorona programa BPF ianao izay mifanandrify amin'ny fangatahana DNS ho an'ny anarana iray 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

Ao amin'ny programa dia miditra ao amin'ny rejisitra voalohany isika X adiresin'ny andalana x04habrx03comx00 ao anaty datagram UDP ary jereo ny fangatahana: 0x04686162 <-> "x04hab" sy ny sisa.

Fotoana fohy taty aoriana, namoaka ny p0f -> BPF compiler code ny Cloudfare. Ao amin'ny lahatsoratra Fampidirana ny p0f BPF compiler miresaka momba ny atao hoe p0f sy ny fomba hamadihana ny sonia p0f ho BPF izy ireo:

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

Tsy mampiasa Cloudfare intsony amin'izao fotoana izao xt_bpf, satria nifindra tany XDP izy ireo - iray amin'ireo safidy amin'ny fampiasana ny BPF vaovao, jereo. L4Drop: XDP DDoS Mitigations.

cls_bpf

Ny ohatra farany amin'ny fampiasana BPF mahazatra amin'ny kernel dia ny classifier cls_bpf ho an'ny subsystem fanaraha-maso ny fifamoivoizana amin'ny Linux, nampidirina tamin'ny Linux tamin'ny faran'ny taona 2013 ary nanolo ny taloha taloha. cls_u32.

Tsy hilazalaza ny asa anefa isika izao cls_bpf, satria avy amin'ny fomba fijerin'ny fahalalana momba ny BPF mahazatra dia tsy hanome antsika na inona na inona izany - efa mahazatra antsika ny fiasa rehetra. Ho fanampin'izany, amin'ny lahatsoratra manaraka miresaka momba ny BPF Extended, dia hihaona amin'ity mpanasokajy ity mihoatra ny indray mandeha isika.

Antony iray hafa tsy tokony hiresahana momba ny fampiasana BPF c cls_bpf Ny olana dia, raha ampitahaina amin'ny Extended BPF, ny sakan'ny fampiharana amin'ity tranga ity dia tena tery: ny programa klasika dia tsy afaka manova ny votoatin'ny fonosana ary tsy afaka mamonjy fanjakana eo anelanelan'ny antso.

Ka izao no fotoana hanaovana veloma ny BPF mahazatra ary hibanjina ny ho avy.

Veloma amin'ny BPF mahazatra

Nijery ny fomba niainan'ny teknolojia BPF tany am-piandohan'ny nineties izahay nandritra ny ampahefatry ny taonjato ary hatramin'ny farany dia nahita fampiharana vaovao. Na izany aza, mitovy amin'ny fifindrana avy amin'ny milina stack mankany RISC, izay nanosika ny fampandrosoana ny BPF mahazatra, tamin'ny taona 32 dia nisy ny fifindrana avy amin'ny milina 64-bit mankany XNUMX-bit ary ny BPF mahazatra dia nanomboka lany andro. Ankoatr'izay, ny fahaizan'ny BPF mahazatra dia tena voafetra, ary ankoatra ny maritrano efa lany andro - tsy manana fahafahana mamonjy fanjakana eo anelanelan'ny antso amin'ny programa BPF izahay, tsy misy ny mety hisian'ny fifandraisana mivantana amin'ny mpampiasa, tsy misy ny fahafahana mifandray. miaraka amin'ny kernel, afa-tsy ny famakiana sahan'ny rafitra voafetra sk_buff ary manomboka ny asa mpanampy tsotra indrindra, tsy afaka manova ny votoatin'ny fonosana ianao ary mamindra azy ireo.

Raha ny marina, amin'izao fotoana izao ny sisa amin'ny BPF mahazatra ao amin'ny Linux dia ny interface API, ary ao anatin'ny kernel ny programa mahazatra rehetra, na sivana socket na sivana seccomp, dia adika ho azy amin'ny endrika vaovao, Extended BPF. (Horesahintsika ao amin’ny lahatsoratra manaraka hoe ahoana marina no hitrangan’izany.)

Nanomboka tamin'ny 2013 ny fifindrana ho amin'ny maritrano vaovao, rehefa nanolotra drafitra fanavaozana BPF i Alexey Starovoitov. Tamin'ny taona 2014 ny paty mifanaraka amin'izany nanomboka niseho amin'ny fotony. Raha ny fahazoako azy, ny drafitra voalohany dia ny fanatsarana ny maritrano sy ny compiler JIT mba hampandeha tsara kokoa amin'ny milina 64-bit, fa kosa ireo fanatsarana ireo dia nanamarika ny fiandohan'ny toko vaovao amin'ny fampandrosoana Linux.

Ny lahatsoratra fanampiny amin'ity andiany ity dia handrakotra ny maritrano sy ny fampiharana ny teknolojia vaovao, fantatra tamin'ny voalohany hoe BPF anatiny, avy eo dia miitatra BPF, ary BPF tsotra izao.

soratra masina

  1. Steven McCanne sy Van Jacobson, "The BSD Packet Filter: Architecture New for User-level Packet Capture", https://www.tcpdump.org/papers/bpf-usenix93.pdf
  2. Steven McCanne, "libpcap: Metodôlôjia ara-drafitra sy fanatsarana ho an'ny fisamborana fonosana", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
  3. tcpdump, libpcap: https://www.tcpdump.org/
  4. IPtable U32 Match Tutorial.
  5. BPF - ny bytecode hadino: https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
  6. Fampidirana ny BPF Tool: https://blog.cloudflare.com/introducing-the-bpf-tools/
  7. bpf_cls: http://man7.org/linux/man-pages/man8/tc-bpf.8.html
  8. Fijerena seccom: https://lwn.net/Articles/656307/
  9. https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
  10. habr: Kaontenera sy fiarovana: seccom
  11. habr: Mitokana ny daemon miaraka amin'ny systemd na "tsy mila Docker ianao amin'izany!"
  12. Paul Chaignon, "strace --seccomp-bpf: fijery eo ambanin'ny satroka", https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
  13. netsniff-ng: http://netsniff-ng.org/

Source: www.habr.com

Add a comment