Horumarinta BPF waxaa gacanta ku haya bulshada isku xirka Linux, codsiyada ugu weyn ee jira ee BPF waxay la xiriiraan shabakadaha, sidaas darteed, ogolaansho. @eucariot, Waxaan ugu yeeray taxanaha "BPF ee kuwa yaryar", oo lagu sharfayo taxanaha weyn "Shabakadaha carruurta yaryar".
Koorso gaaban oo taariikhda BPF ahc)
Tiknoolajiyada casriga ah ee BPF waa nooc la wanaajiyey oo la ballaariyey oo ah tignoolajiyada hore ee isla magaca, hadda loo yaqaan BPF classic si looga fogaado jahawareer. Utility si fiican loo yaqaan ayaa la sameeyay iyadoo lagu salaynayo BPF-ga caadiga ah tcpdump, farsamaynta seccomp, iyo sidoo kale qaybo yar oo la yaqaan xt_bpf si ay u iptables iyo kalasaar cls_bpf. Linux-ka casriga ah, barnaamijyada BPF-ga caadiga ah ayaa si toos ah loogu tarjumaa qaabka cusub, si kastaba ha ahaatee, marka laga eego aragtida isticmaalaha, API-gu wuu sii jirayaa iyo isticmaalka cusub ee BPF-ga caadiga ah, sida aan ku arki doono maqaalkan, weli waa la helayaa. Sababtan awgeed, iyo sidoo kale iyadoo la raacayo taariikhda horumarinta BPF ee Linux, waxay noqon doontaa mid cad sida iyo sababta ay u kobcisay qaabkeeda casriga ah, waxaan go'aansaday inaan ku bilaabo maqaal ku saabsan BPF-ga caadiga ah.
Dhammaadkii siddeetameeyadii qarnigii la soo dhaafay, injineerada ka socda Shaybaadhka caanka ah ee Lawrence Berkeley ayaa xiiseynaya su'aasha ah sida saxda ah ee loo shaandheeyo xirmooyinka shabakada ee qalabka casriga ah ee dabayaaqadii siddeetameeyadii qarnigii la soo dhaafay. Fikradda aasaasiga ah ee shaandhaynta, oo asal ahaan lagu hirgeliyay tignoolajiyada CSPF (CMU/Stanford Packet Filter), waxay ahayd in la shaandheeyo baakadaha aan loo baahnayn sida ugu dhaqsaha badan, i.e. meel bannaan oo kernel ah, maadaama tani ay ka fogaanayso in xogta aan loo baahnayn lagu koobiyeeyo booska isticmaalaha. Si loo helo badbaadada runtime ee ku socodsiinta koodka isticmaalaha booska kernel-ka, mashiinka farsamada gacanta ayaa la isticmaalay.
Si kastaba ha ahaatee, mishiinada casriga ah ee filtarrada jira waxaa loogu talagalay inay ku shaqeeyaan mishiinada ku salaysan is dulsaarka oo si hufan ugumay shaqayn mashiinada RISC ee cusub. Natiijo ahaan, iyada oo loo marayo dadaalka injineerada Berkeley Labs, tignoolajiyada cusub ee BPF (Berkeley Packet Filters) ayaa la sameeyay, qaab dhismeedka mashiinka farsamada kaas oo loo qaabeeyey iyadoo lagu saleynayo processor-ka Motorola 6502 - faraska shaqada ee alaabooyinka caanka ah sida Apple II ama NES. Mashiinka casriga ah ee cusub wuxuu kordhiyey waxqabadka shaandhada tobanaan jeer marka la barbar dhigo xalalka jira.
Nashqada mashiinka BPF
Waxaan u baran doonaa qaab-dhismeedka qaab shaqo, anagoo falanqaynayna tusaalooyinka. Si kastaba ha ahaatee, si aan ku bilowno, aynu nidhaahno mashiinku wuxuu lahaa laba diiwaan oo 32-bit ah oo ay heli karaan isticmaaluhu, accumulator. A iyo diiwaanka tusmada X. Tilmaamaha boodboodka ee hirgelinta tibaaxaha shuruudaha ayaa sidoo kale laga heli karaa barnaamijyada, laakiin si loo dammaanad qaado dhamaystirka wakhtiga barnaamijka, boodada waxaa la samayn karaa oo kaliya, tusaale ahaan, gaar ahaan, waxaa mamnuuc ah in la abuuro wareegyo.
Nidaamka guud ee bilaabista mishiinka waa sida soo socota. Isticmaaluhu wuxuu u abuuraa barnaamij qaab dhismeedka BPF iyo, isagoo isticmaalaya qaar habka kernel-ka (sida nidaamka wicista), wuxuu ku shubaa oo ku xidhaa barnaamijka qaarna koronto dhaliyaha ku jira kernel-ka (tusaale ahaan, dhacdo waa imaatinka xirmada xiga ee kaadhka shabakada). Marka ay dhacdo dhacdo, kernel-ku waxa uu wadaa barnaamijka (tusaale ahaan, turjumaanka), xusuusta mishiinkuna waxa ay u dhigantaa qaarna Gobolka xusuusta kernel (tusaale, xogta xirmada soo socota).
Kuwa kore ayaa nagu filnaan doona inaan bilowno fiirinta tusaalooyinka: waxaan baran doonaa nidaamka iyo qaabka amarka sida loo baahdo. Haddii aad rabto inaad si dhakhso ah u barato nidaamka amarka mashiinka farsamada oo aad wax ka barato dhammaan awoodaheeda, markaa waxaad akhrin kartaa maqaalka asalka ah Shaandhaynta Xirmada BSD iyo/ama qaybta hore ee faylka Dukumeenti/shabakad/filter.txt laga bilaabo dukumentiyada kernel-ka. Intaa waxaa dheer, waxaad baran kartaa bandhigga libpcapHabka Dhismaha iyo Wanaajinta ee Qabashada Xidhmada, kaas oo McCanne, oo ka mid ah qorayaasha BPF, uu kaga hadlayo taariikhda abuurista libpcap.
Hadda waxaan u dhaqaaqnay inaan tixgelinno dhammaan tusaalooyinka muhiimka ah ee isticmaalka BPF-ga caadiga ah ee Linux: tcpdump (libpcap), labaad, xt_bpf, cls_bpf.
tcpdump
Horumarinta BPF waxaa lagu fuliyay si la mid ah horumarinta hore ee shaandhaynta baakadaha - utility si fiican loo yaqaan. tcpdump. Iyo, maadaama kani yahay tusaalaha ugu da'da weyn uguna caansan ee isticmaalka BPF-ga caadiga ah, oo laga heli karo habab badan oo hawlgal ah, waxaan ku bilaabi doonaa daraasaddeena tignoolajiyada iyada.
(Waxaan ku orday dhammaan tusaalooyinka maqaalkan Linux 5.6.0-rc6. Soo saarida amarada qaar ayaa loo tafatiray si loo akhriyo si ka wanaagsan.)
Tusaale: la socoshada xirmooyinka IPv6
Aynu qiyaasno inaan rabno inaan eegno dhammaan baakadaha IPv6 ee interface-ka eth0. Si taas loo sameeyo waxaan socodsiin karnaa barnaamijka tcpdump oo leh filtar fudud ip6:
$ sudo tcpdump -i eth0 ip6
Sayidka tcpdump wuxuu ururiyaa filtarka ip6 geli BPF bytecode qaab dhismeedka oo u dir kernel-ka (eeg faahfaahinta qaybta Tcpdump: rarista). Filterka la raray waxaa loo maamuli doonaa baakad kasta oo dhexmarta interface-ka eth0. Haddii filtarku soo celiyo qiime aan eber ahayn n, ka dibna ilaa n Bayt ee xirmada waxaa lagu koobiyeynayaa booska isticmaalaha waxaana ku arki doonaa wax soo saarka tcpdump.
Waxaa soo baxday in aan si fudud u ogaan karno bytecode loo soo diray kernel-ka tcpdump iyadoo gacan laga helayo tcpdump, haddii aan ku maamulno ikhtiyaarka -d:
$ sudo tcpdump -i eth0 -d ip6
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 3
(002) ret #262144
(003) ret #0
Eber khadka ah waxaan ku wadnaa amarka ldh [12], oo u taagan "load into record A nus kelmad (16 bits) oo ku yaala ciwaanka 12" su'aasha kaliya ayaa ah xasuus noocee ah ayaan ka hadlaynaa? Jawaabtu waa taas x bilaabmaa (x+1)th byte ee xirmada shabakada la falanqeeyay. Waxaan akhrinay baakado ka yimid interface Ethernet eth0, iyo kan macnaheedu waain baakidhku sidan u ekaado (fududnaanta, waxaanu u qaadanaynaa in aanay xidhmada ku jirin calaamado VLAN):
6 6 2
|Destination MAC|Source MAC|Ether Type|...|
Markaa kadib fulinta amarka ldh [12] diiwaanka ku jira A waxaa jiri doona beer Ether Type - nooca baakooyinka lagu kala qaado qaabkan Ethernet. Sadarka 1 waxaan is barbar dhigeynaa waxa ku jira diiwaanka A (nooc xirmo) c 0x86dd, iyo kan waxaana jira Nooca aan xiiseyneyno waa IPV6. Sadarka 1, marka lagu daro amarka isbarbardhigga, waxaa jira laba tiir oo kale - jt 2 ΠΈ jf 3 - calaamado aad u baahan tahay inaad tagto haddii isbarbardhigga lagu guuleysto (A == 0x86dd) oo aan guulaysan. Sidaa darteed, kiis guuleysta (IPv6) waxaan u tagnaa safka 2, iyo kiis aan guulaysan - ilaa 3. Sadarka 3 barnaamijku wuxuu ku joojinayaa code 0 (ha koobiyn baakidhka), khadka 2 barnaamijku wuxuu ku joojinayaa koodka. 262144 (i koobbi ugu badnaan xirmo 256 kilobytes ah).
Tusaalo aad u adag: waxaan ku eegeynaa baakadaha TCP ee dekada loo socdo
Aynu aragno sida filtarku u eg yahay nuqullada dhammaan baakadaha TCP ee leh dekedda 666. Waxaan tixgelin doonaa kiiska IPV4, maadaama kiis IPV6 uu ka fudud yahay. Ka dib markaad barato tusaalahan, waxaad naftaada u sahamin kartaa shaandhada IPv6 sida jimicsi (ip6 and tcp dst port 666iyo shaandhaynta kiiska guud (tcp dst port 666). Haddaba, filtarka aanu xiisaynaynaa wuxuu u eg yahay sidan:
$ 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
Waxaan horey u ognahay waxa ay sameeyaan sadarrada 0 iyo 1. Sadarka 2 waxaan mar hore ku hubinnay in kani yahay xirmo IPv4 ah (Ether Type = 0x800) oo ku shub diiwaanka A 24th byte ee xirmada. Xidhmadayadu waxay u egtahay
taas oo macnaheedu yahay in aanu ku shubanay diiwaanka A goobta Protocol-ka ee cinwaanka IP-ga, taas oo macquul ah, sababtoo ah waxaan rabnaa in aan nuqul ka sameysanno kaliya xirmooyinka TCP. Waxaan is barbar dhignaa Protocol-ka 0x6 (IPPROTO_TCP) line 3.
Sadarka 4 iyo 5 waxaan ku shubnaa ereyada kala bar ee ku yaal ciwaanka 20 waxaana isticmaalnaa amarka jset hubi haddii mid ka mid ah saddexda la dhigay calanka - xidhashada maaskaro la soo saaray jset saddexda qaybood ee ugu muhiimsan waa la nadiifiyaa. Laba ka mid ah saddexda bits ayaa noo sheegaya in baakidhku yahay qayb ka mid ah baakidh IP ah oo jajaban, iyo haddii ay sidaas tahay, inay tahay jajabkii ugu dambeeyay. Qaybta saddexaad waa la xafiday waana inay eber noqotaa. Ma rabno inaan hubinno baakooyinka aan dhameystirneyn ama jaban, marka waxaan hubineynaa dhammaan seddexda jajab.
Sadarka 6 waa kan ugu xiisaha badan liiskan. Odhaahda ldxb 4*([14]&0xf) macneheedu waxa weeye in aanu galno diiwaanka X Afarta ugu yar ee baytka shan iyo tobnaad ee baakidhka lagu dhufto 4. Afarta ugu yar ee muhiimka ah ee byte shan iyo tobnaad waa garoonka Dhererka Madaxa Internetka Madaxa IPV4, kaas oo ku kaydiya dhererka madaxa ereyada, markaa waxaad u baahan tahay inaad ku dhufato 4. Waxa xiiso leh, odhaahda 4*([14]&0xf) waa habayn loogu talagalay qorshe ciwaan gaar ah oo loo isticmaali karo kaliya foomkan oo keliya diiwaan-gelinta X, i.e. midna ma dhihi karno ldb 4*([14]&0xf) iyo sidoo kale ldxb 5*([14]&0xf) (waxaanu qeexi karnaa kaliya dhimis ka duwan, tusaale ahaan, ldxb 4*([16]&0xf)). Way caddahay in nidaamkan wax ka qabashada lagu daray BPF si sax ah si loo helo X (diiwaanka tusmada) IPV4 dhererka madaxa.
Markaa safka 7 waxaan isku dayeynaa inaan ku shubno kelmad kala bar (X+16). Xusuusnow in 14 bytes uu ku jiro madaxa Ethernet, iyo X waxaa ku jira dhererka madaxa IPV4, waan fahamsanahay in A Deked u socota TCP waa la rartay:
14 X 2 2
|ethernet header|ip header|source port|destination port|
Ugu dambeyntii, sadarka 8 waxaan isbarbar dhig ku sameyneynaa dekedda ku socota qiimaha la rabo iyo xariiqyada 9 ama 10 waxaan ku celineynaa natiijada - haddii la koobiyo baakidhka iyo haddii kale.
Tcpdump: rarista
Tusaalooyinka hore, gaar ahaan si faahfaahsan ugamaanaan hadlin sida saxda ah ee aan ugu shubno BPF bytecode kernel si loo shaandheeyo baakadaha. Guud ahaan, tcpdump loo gudbiyay habab badan iyo la shaqaynta filtarrada tcpdump adeegsada maktabadda libpcap. Si kooban, si aad shaandhada ugu dhejiso interface-ka adigoo isticmaalaya libpcap, waxaad u baahan tahay inaad sameyso waxyaabaha soo socda:
samee nooc tilmaame pcap_t laga bilaabo magaca interface: pcap_create,
Labada xariiq ee ugu horreeya ee wax soo saarka waxaan abuurnaa godad ceeriin si aad u akhrido dhammaan fiilooyinka Ethernet oo aad ku xidho interface-ka eth0. Ka Tusaalahayaga ugu horreeya waxaan ognahay in filtarka ip Waxay ka koobnaan doontaa afar tilmaamood oo BPF ah, iyo xariiqda saddexaad waxaan aragnaa sida loo isticmaalo ikhtiyaarka SO_ATTACH_FILTER nidaamka call setsockopt waanu ku shubnaa oo isku xidhaa filtar dhererkeedu yahay 4. Tani waa shaandhayntayada.
Waxaa xusid mudan in BPF-ga caadiga ah, rarista iyo isku xirka shaandhada ay had iyo jeer u dhacdo sida hawlgalka atomikada, iyo nooca cusub ee BPF, ku xidhida barnaamijka iyo ku xidhida koronto-dhaliyaha dhacdada ayaa la kala saaraa waqtiga.
Xaqiiqda Dahsoon
Nuqul ka yara dhammaystiran ee wax-soo-saarka ayaa u eg sidan:
Sida kor ku xusan, waxaan ku shubaneynaa oo ku xireynaa shaandhadayada godka 5-aad, laakiin maxaa ku dhacaya sadarrada 3 iyo 4? Waxaa soo baxday in tani libpcap na daryeela - si wax-soo-saarka shaandhayntayadu aanay ku jirin baakado aan ku qancin, maktabadda isku xira shaandhaynta dhumucda ret #0 (dhamaan baakadaha oo dhan), u beddela godka qaabka aan xannibin oo isku dayaa inuu ka gooyo dhammaan baakadaha ka hadhi kara filtarrada hore.
Isku soo wada duuboo, si aad u shaandhayso baakooyinka Linux adoo isticmaalaya BPF-ga caadiga ah, waxaad u baahan tahay inaad haysato shaandhayn qaab dhismeed ah oo kale ah struct sock_fprog iyo godad furan, ka dib shaandhada waxaa lagu dhejin karaa godka iyadoo la isticmaalayo nidaamka wicitaanka setsockopt.
Waxa xiiso leh, filtarka ayaa lagu dhejin karaa godad kasta, ma aha oo kaliya ceeriin. Halkan Tusaale barnaamij ka jaraya dhammaan marka laga reebo labada bytes ee ugu horreeya dhammaan xogta UDP ee soo socota. (Waxaan ku daray faallooyinka koodka si aysan u qasin maqaalka.)
BPF waxaa lagu soo daray Linux 1997 waxayna sii ahaan jirtay faras shaqo muddo dheer libpcap iyada oo aan wax isbeddel ah oo gaar ah lahayn (isbeddellada Linux-gaar ah, dabcan, Waxa ay ahayd, laakiin ma aysan beddelin sawirka caalamiga ah). Calaamadihii ugu horreeyay ee halista ah ee BPF ay soo baxayso waxay yimaaddeen 2011, markii Eric Dumazet uu soo jeediyay balastar, kaas oo ku daraya Just In Time Compiler kernel-ka oo ah tarjumaha u beddelaya bytecode BPF x86_64 code.
Isku-duwaha JIT wuxuu ahaa kii ugu horreeyay ee silsiladda isbeddellada: 2012 muuqday kartida u qorida filtarrada seccop, iyadoo la adeegsanayo BPF, Janaayo 2013 waxaa jiray ku daray moduleka xt_bpf, kaas oo kuu ogolaanaya inaad u qorto xeerar iptables iyadoo la kaashanayo BPF, iyo October 2013 ahaa ku daray sidoo kale module ah cls_bpf, kaas oo kuu ogolaanaya inaad qorto kala-soocidda taraafikada adoo isticmaalaya BPF.
Waxaan eegi doonaa dhammaan tusaalooyinkan si faahfaahsan dhawaan, laakiin marka hore waxay noo noqon doontaa faa'iido inaan barano sida loo qoro oo loo ururiyo barnaamijyada aan sharciga ahayn ee BPF, maaddaama awoodaha ay bixiso maktabaddu libpcap xaddidan (tusaale fudud: filtar ayaa la sameeyay libpcap soo celin karaa oo kaliya laba qiyamka - 0 ama 0x40000) ama guud ahaan, sida kiiska seccomp, ma khuseyso.
Ku barnaamijyada BPF gacmaheena
Aynu barano qaabka binary ee tilmaamaha BPF, aad bay u fududahay:
16 8 8 32
| code | jt | jf | k |
Tilmaam kastaa wuxuu ka kooban yahay 64 bits, kaas oo 16-ka ugu horreeya ee XNUMX-bit ay yihiin koodhka tilmaamaha, ka dibna waxaa jira laba siddeed-bits, jt ΠΈ jf, iyo 32 bits ee doodda K, ujeeddaduna way ku kala duwan tahay amarka. Tusaale ahaan, amarka ret, kaas oo joojiya barnaamijka ayaa leh koodka 6, iyo qiimaha soo celinta waxaa laga soo qaatay joogtada ah K. C, hal tilmaam oo BPF ah ayaa u taagan qaab dhismeed ahaan
Si kastaba ha ahaatee, doorashadani maaha mid aad u habboon. Tani waa waxa ay ku sababeeyeen barnaamij-bixiyeyaasha kernel-ka Linux, oo markaa ku jira buugga tools/bpf kernels waxaad ka heli kartaa isku-duwaha iyo cilladaha si aad ula shaqeyso BPF-ga caadiga ah.
Luuqadda golaha waxa ay aad ula mid tahay soo saarista cilladaha tcpdump, laakiin marka lagu daro waxaan qeexi karnaa calaamado calaamad ah. Tusaale ahaan, halkan waa barnaamij daadiya dhammaan baakadaha marka laga reebo TCP/IPv4:
$ cat /tmp/tcp-over-ipv4.bpf
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0
Sida caadiga ah, ururiyaha ayaa soo saaraya kood qaabka <ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΉ>,<code1> <jt1> <jf1> <k1>,..., tusaale ahaan TCP waxay noqon doontaa
Qoraalkan waxa lagu koobiyn karaa qaabka qeexidda qaab-dhismeedka struct sock_filter, sidii aan ku samaynay bilowgii qaybtan.
Linux iyo netsniff-ng kordhinta
Intaa waxaa dheer BPF caadiga ah, Linux iyo tools/bpf/bpf_asm taageero iyo set aan caadi ahayn. Asal ahaan, tilmaamaha waxaa loo isticmaalaa in lagu galo goobaha dhismaha struct sk_buff, kaas oo qeexaya baakad shabakadeed oo ku jirta kernel. Si kastaba ha ahaatee, waxa kale oo jira noocyo kale oo tilmaamo caawiye ah, tusaale ahaan ldw cpu ku shubi doona diiwaanka A natiijada socodsiinta shaqada kernel raw_smp_processor_id(). (Nooca cusub ee BPF, kuwan kordhinta aan caadiga ahayn ayaa la kordhiyay si ay u bixiyaan barnaamijyo leh qalab caawiyayaasha kernel si ay u helaan xusuusta, qaababka, iyo dhacdooyinka soo saarista madax xirmo galay booska isticmaalaha isticmaalaya kordhinta poff, dhimista rarka:
ld poff
ret a
Kordhinta BPF looma isticmaali karo gudaha tcpdump, laakiin tani waa sabab wanaagsan oo lagu baran karo xirmada tamarta netsniff-ng, kaas oo, iyo waxyaabo kale, ka kooban yahay barnaamij horumarsan netsniff-ng, kaas oo, marka lagu daro shaandhaynta isticmaalaya BPF, sidoo kale ka kooban yahay dhaliye taraafikada wax ku ool ah, oo ka horumarsan marka loo eego tools/bpf/bpf_asm, isku-duwaha BPF ee loo yaqaan bpfc. Xirmada waxaa ku jira dukumeenti aad u faahfaahsan, sidoo kale eeg xiriirinta dhamaadka maqaalka.
seccop
Sidaa darteed, waxaan horeyba u ognahay sida loo qoro barnaamijyada BPF ee kakanaanta aan macquul ahayn waxayna diyaar u yihiin inay eegaan tusaalooyin cusub, marka hore waa tignoolajiyada seccomp, taas oo u oggolaanaysa, iyadoo la adeegsanayo filtarrada BPF, si loo maareeyo go'aanka iyo nidaamka doodaha wacitaanka ee la heli karo hab la siiyey iyo farcankiisa.
Nooca ugu horreeya ee seccomp waxaa lagu daray kernel 2005 oo aan caan ahayn, maadaama ay bixisay hal ikhtiyaar oo keliya - si loo xaddido wicitaannada nidaamka ee loo heli karo geeddi-socodka kuwan soo socda: read, write, exit ΠΈ sigreturn, iyo habka ku xadgudubka xeerarka waa la dilay iyadoo la adeegsanayo SIGKILL. Si kastaba ha noqotee, 2012, seccomp wuxuu ku daray awoodda isticmaalka filtarrada BPF, taasoo kuu oggolaaneysa inaad qeexdo go'an wicitaannada nidaamka la oggol yahay oo xitaa sameyso hubinno doodooda. (Waxa xiiso leh, Chrome wuxuu ahaa mid ka mid ah isticmaalayaasha ugu horreeya ee shaqadan, dadka Chrome-ka waxay hadda horumarinayaan habka KRSI ee ku salaysan nooca cusub ee BPF iyo u oggolaanaya habeynta Modules Security Linux.) Xiriirinta dukumeenti dheeraad ah ayaa laga heli karaa dhamaadka ee maqaalka.
Ogsoonow in ay jireen maqaallo ku saabsan xuddunta oo ku saabsan isticmaalka seccomp, laga yaabee in qof doonayo inuu akhriyo ka hor (ama halkii) akhrinta qaybaha soo socda. In maqaalka Konteenarada iyo amniga: seccomp waxay bixisaa tusaalooyin isticmaalka seccomp, labadaba nooca 2007 iyo nooca iyadoo la adeegsanayo BPF (filiyaasha waxaa la soo saaray iyadoo la adeegsanayo libseccomp), waxay ka hadlaysaa isku xirka seccomp ee Docker, iyo sidoo kale waxay bixisaa xiriiro badan oo faa'iido leh. In maqaalka Go'doominta daemons-ka leh systemd ama "Uma baahnid Docker kan!" Waxay dabooshaa, gaar ahaan, sida loogu daro liiska madow ama liisaska cad ee wicitaanada nidaamka daemons ee ku shaqeeya systemd.
Marka xigta waxaan arki doonaa sida loo qoro oo loo raro filtarrada seccomp oo qaawan C iyo isticmaalka maktabadda libseccomp iyo waa maxay faa'iidooyinka iyo khasaaraha ikhtiyaar kasta, iyo ugu dambeyntii, aan aragno sida seccomp loo isticmaalo barnaamijka strace.
Qorista iyo rarista filtarrada ee seccomp
Waxaan hore u naqaannay sida loo qoro barnaamijyada BPF, marka aan marka hore eegno barnaamijka seccomp interface interface. Waxaad dejin kartaa shaandhada heerka habsocodka, dhammaan hababka ilmahu waxay dhaxli doonaan xannibaadaha. Tan waxaa lagu sameeyaa iyadoo la isticmaalayo nidaamka wicitaanka seccomp(2):
seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)
halkaas oo &filter - tani waxay tilmaan u tahay qaab-dhismeedkii horeba aannu naqaannay struct sock_fprog, i.e. Barnaamijka BPF.
Sidee bay barnaamijyada seccomp uga duwan yihiin barnaamijyada saldhigyada? Macnaha la kala qaado. Dhinaca saldhigyada, waxa nala siiyay meel xusuus ah oo baakidhku ku jiro, halka seccomp-na nala siiyay qaab dhismeed oo kale ah.
waa nr waa lambarka nidaamka wicitaanka ee la bilaabayo, arch - qaab dhismeedka hadda (wax badan oo ku saabsan kan hoose), args - ilaa lix hab dood call, iyo instruction_pointer waa tilmaame tilmaame booska isticmaalaha kaas oo sameeyay wicitaanka nidaamka. Sidaas darteed, tusaale ahaan, si aad ugu shubto nambarka wac nidaamka diiwaanka A waa inaan dhahnaa
ldw [0]
Waxaa jira sifooyin kale oo loogu talagalay barnaamijyada seccomp, tusaale ahaan, macnaha guud waxaa lagu geli karaa oo keliya 32-bit alignment mana awoodid inaad ku shubto nus kelmad ama byte - markaad isku dayeyso inaad rarayso shaandhada ldh [0] nidaamka call seccomp soo laaban doona EINVAL. Shaqadu waxay hubisaa filtarrada raran seccomp_check_filter() kernels. (Arrinta qosolka leh ayaa ah, ballan-qaadkii asalka ahaa ee ku daray shaqeynta seccomp, waxay illoobeen inay ku daraan oggolaanshaha si ay u adeegsadaan tilmaamaha shaqadan mod (qaybinta hadhaaga) oo hadda lama heli karo barnaamijyada seccomp BPF, tan iyo markii lagu daray jabi doona ABI.)
Asal ahaan, waxaan horay u naqaanay wax walba oo lagu qoro oo aan akhriyo barnaamijyada seccomp. Caadi ahaan macquulka barnaamijka waxaa loo habeeyaa sida liiska cad ama madow ee wicitaanada nidaamka, tusaale ahaan barnaamijka
ld [0]
jeq #304, bad
jeq #176, bad
jeq #239, bad
jeq #279, bad
good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
bad: ret #0
Wuxuu hubiyaa liiska madow ee afar hab oo la wacay oo lambarkiisu yahay 304, 176, 239, 279. Waa maxay wicitaannada nidaamkan? Dhab ahaan ma odhan karno, maadaama aynaan garanayn naqshadda barnaamijka loo qoray. Sidaa darteed, qorayaasha seccomp bixinta ku bilow dhammaan barnaamijyada adiga oo ku eegaya qaab-dhismeedka (nashqadaha hadda jira waxa lagu tilmaamay goob ahaan arch dhismayaasha struct seccomp_data). Iyada oo la hubiyay qaab-dhismeedka, bilowga tusaaluhu wuxuu u ekaan lahaa:
ld [4]
jne #0xc000003e, bad_arch ; SCMP_ARCH_X86_64
ka dibna nambarada wicitaanka nidaamkayaga waxay heli lahaayeen qiyam gaar ah.
Waxaan qornaa oo ku shubnaa filtarrada si loo isticmaalo seccomp libseccomp
Qorista filtarrada ee koodka asalka ah ama golaha BPF wuxuu kuu ogolaanayaa inaad si buuxda u maamusho natiijada, laakiin isla mar ahaantaana, waxaa mararka qaarkood la door bidaa inaad haysato kood la qaadi karo iyo/ama la akhriyi karo. Maktabadu waxay naga caawin doontaa tan libseccomp, kaas oo bixiya interface caadiga ah ee qorista filtarrada madow ama caddaanka ah.
Aynu, tusaale ahaan, qorno barnaamij socodsiiya faylka binary ee xulashada isticmaaluhu, isagoo hore ugu rakibay liis madow oo wicitaannada nidaamka ah maqaalka kore (barnaamijka waa la fududeeyay si loo akhriyo, nooca buuxa waa la heli karaa halkan):
$ 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
Suurtagal maaha in si degdeg ah wax loo qoro, maadaama barnaamijyada BPF aysan samayn karin boodada boodboodka (ma samayn karno, tusaale ahaan, jmp A ama jmp [label+X]) oo sidaas darteed dhammaan isbeddellada ayaa ah kuwo taagan.
seccomp iyo xadhig
Qof kastaa wuu yaqaan utility strace waa qalab lagama maarmaan u ah barashada hab-dhaqanka hababka Linux. Si kastaba ha ahaatee, qaar badan ayaa sidoo kale maqlay arrimaha waxqabadka marka la isticmaalayo utility this. Xaqiiqdu waxay tahay strace la hirgeliyey iyadoo la isticmaalayo ptrace(2), iyo habkan kuma qeexi karno nooca nidaamka wicitaanada waxaan u baahanahay inaan joojino habka, tusaale ahaan, amarrada
$ 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
Waxa la farsameeyaa ku dhawaad ββisku wakhti, in kasta oo kiiska labaad aanu doonayno in aanu raad raacno hal wicitaan oo keliya.
Doorasho cusub --seccomp-bpf, lagu daray strace Nooca 5.3, wuxuu kuu ogolaanayaa inaad dardar geliso geeddi-socodka marar badan iyo wakhtiga bilowga ee hoos yimaada raadraaca hal wicitaan oo horeyba u dhigma wakhtiga bilowga caadiga ah:
$ 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
(Halkan, dabcan, waxaa jira khiyaano yar oo ah inaanan raadinayn nidaamka ugu muhiimsan ee amarkan. Haddii aan raadinaynay, tusaale ahaan, newfsstat, ka dibna strace jabi lahaa si la mid ah sida la'aanta --seccomp-bpf.)
Sidee doorashadani u shaqeysaa? La'aanteed strace wuxuu ku xiraa habka oo uu ku bilaabo isticmaalka PTRACE_SYSCALL. Marka habka la maareeyay uu soo saaro (mid kasta) wicitaanka nidaamka, xakamaynta ayaa loo wareejiyaa strace, kaas oo eegaya doodaha nidaamka wicitaanka oo ku shaqeeya isticmaalka PTRACE_SYSCALL. Muddo ka dib, nidaamku wuxuu dhamaystiraa wicitaanka nidaamka iyo marka laga baxo, xakamaynta ayaa mar kale la wareejiyaa strace, kaas oo eegaya qiyamka soo noqoshada oo bilaabaya habka isticmaalaya PTRACE_SYSCALL, iyo wixi la mida.
Si kastaba ha ahaatee, seccomp, si kastaba ha ahaatee, habkan waxaa loo hagaajin karaa sida aan rabno. Tusaale ahaan, haddii aan rabno inaan eegno kaliya wac nidaamka X, markaas waxaan u qori karnaa shaandhada BPF taas oo loogu talagalay X soo celisa qiimaha SECCOMP_RET_TRACE, iyo baaqyo aan dan noo ahayn - SECCOMP_RET_ALLOW:
ld [0]
jneq #X, ignore
trace: ret #0x7ff00000
ignore: ret #0x7fff0000
Xaaladdan strace marka hore waxay ku bilaabataa habka PTRACE_CONT, filter our waxaa loo habeeyey loogu talagalay wicitaan kasta oo nidaamka, haddii wicitaanka nidaamka ma aha X, ka dibna geeddi-socodku wuu sii socdaa, laakiin haddii tani X, ka dibna seccomp ayaa wareejin doona xakamaynta straceKaas oo eegi doona doodaha oo bilaabi doona habka sida PTRACE_SYSCALL (maadaama seccomp aanu lahayn awood uu ku socodsiiyo barnaamij ka bixitaanka nidaamka call). Marka nidaamka wicitaanku soo noqdo, strace dib u bilaabi doona habsocodka isticmaalaya PTRACE_CONT waxayna sugi doonaan fariimaha cusub ee seccomp.
Marka la isticmaalayo ikhtiyaarka --seccomp-bpf waxaa jira laba xayiraad. Marka hore, suurtogal ma noqon doonto in lagu biiro hanaan hore u jiray (ikhtiraac -p barnaamijyada strace), mar haddii tani aysan taageerin seccomp. Marka labaad, ma jirto wax suurtagal ah ma U fiirso hababka ilmaha, maadaama filtarrada seccomp ay dhaxlaan dhammaan hababka ilmaha iyaga oo aan awood u lahayn inay tan joojiyaan.
Faahfaahin yar oo ku saabsan sida saxda ah strace la shaqee seccomp waxaa laga heli karaa warbixin dhawaan. Annaga, xaqiiqda ugu xiisaha badan ayaa ah in BPF-ga caadiga ah ee uu matalo seccomp wali la isticmaalo maanta.
xt_bpf
Aynu hadda ku noqonno dunida shabakadaha.
Sooyaalka: wakhti dheer ka hor, 2007, xudunta u ahayd ku daray moduleka xt_u32 netfilter. Waxa loo qoray si isbarbardhig leh oo xitaa ka sii qadiimi ah kala soocida taraafikada cls_u32 wuxuuna kuu oggolaaday inaad u qorto xeerarka binary-ga ee iptables adigoo isticmaalaya hawlgalladan fudud ee soo socda: 32-bits ka soo qaado xirmo oo ku samee tiro hawlgallo xisaabeed ah. Tusaale ahaan,
Hadda ma isticmaaleyso Cloudfare xt_bpf, tan iyo markii ay u guureen XDP - mid ka mid ah fursadaha isticmaalka nooca cusub ee BPF, fiiri. L4Drop: XDP DDoS Yaraynta.
cls_bpf
Tusaalaha ugu dambeeya ee isticmaalka BPF-ga caadiga ah ee kernelka waa kala soocida cls_bpf nidaamka hoosaadka taraafikada ee Linux, oo lagu daray Linux dhamaadkii 2013 oo fikrad ahaan bedelaya kii hore cls_u32.
Si kastaba ha ahaatee, hadda ma qeexi doono shaqada cls_bpf, Tan iyo markii laga eego aragtida aqoonta ku saabsan BPF-ga caadiga ah tani waxba naguma siin doonto - waxaan horeyba u barannay dhammaan shaqeynta. Intaa waxaa dheer, maqaallada soo socda ee ka hadlaya Extended BPF, waxaan la kulmi doonaa kala-soociddan in ka badan hal mar.
Sabab kale oo aan looga hadlin isticmaalka caadiga ah ee BPF c cls_bpf Dhibaatadu waxay tahay, marka la barbar dhigo Extended BPF, baaxadda ku habboonaanta kiiskan si weyn ayaa loo soo koobay: barnaamijyada qadiimiga ah ma beddeli karaan waxa ku jira xirmooyinka mana badbaadin karaan gobolka u dhexeeya wicitaannada.
Markaa waa waqtigii lagu macsalaamayn lahaa BPF-ga caadiga ah oo la eegi lahaa mustaqbalka.
Nabadgelyo BPF-ga caadiga ah
Waxaan eegnay sida tignoolajiyada BPF, oo la sameeyay horraantii sagaashamaadkii, si guul leh u noolaatay rubuc qarni iyo ilaa dhamaadka laga helay codsiyo cusub. Si kastaba ha ahaatee, waxay la mid tahay ka gudubka mishiinada qashinka ilaa RISC, kaas oo u adeegay sidii dhiirigelinta horumarinta BPF-ga caadiga ah, 32-meeyadii waxaa jiray isbeddel ka yimid 64-bit ilaa XNUMX-bit machines iyo BPF-ga caadiga ah waxay bilaabeen inay noqdaan kuwo duugoobay. Intaa waxaa dheer, awoodaha BPF ee caadiga ah aad ayey u xaddidan yihiin, marka lagu daro qaab dhismeedka duugoobay - ma lihin awood aan ku badbaadino gobolka u dhexeeya wicitaannada barnaamijyada BPF, ma jirto suurtogalnimada isdhexgalka tooska ah ee isticmaalaha, ma jirto wax suurtagal ah oo isdhexgalka. la kernel-ka, marka laga reebo akhrinta tiro xaddidan ee goobaha qaab-dhismeedka sk_buff iyo bilaabista hawlaha caawiye ee ugu fudud, ma bedeli kartid waxa ku jira baakadaha oo dib u habayn kartid.
Dhab ahaantii, hadda waxa haray oo dhan BPF-ga caadiga ah ee Linux waa interface API, iyo gudaha kernel dhammaan barnaamijyada caadiga ah, ha ahaadaan filtarrada godka ama filtarrada seccomp, ayaa si toos ah loogu tarjumay qaab cusub, BPF Dheeraad ah. (Waxaan uga hadli doonaa sida saxda ah ee ay tani u dhacdo maqaalka soo socda.)
U gudubka qaab dhismeedka cusub wuxuu bilaabmay 2013, markii Alexey Starovoitov soo jeediyay nidaamka cusboonaysiinta BPF. 2014-ka balastar u dhigma bilaabay inuu soo muuqdo xudunta u ah. Ilaa hadda inta aan fahmayo, qorshaha asalka ah wuxuu ahaa kaliya in la hagaajiyo qaab-dhismeedka iyo isku-dariyeyaasha JIT si ay si hufan ugu shaqeeyaan mashiinnada 64-bit, laakiin taa beddelkeeda hagaajintaani waxay calaamad u tahay bilowga cutub cusub oo horumarinta Linux ah.
Maqaalo dheeri ah oo taxanahan ah ayaa dabooli doona qaab dhismeedka iyo codsiyada tignoolajiyada cusub, oo markii hore loo yaqaan BPF gudaha, ka dibna BPF la kordhiyay, oo hadda si fudud BPF.
tixraacyada
Steven McCanne iyo Van Jacobson, "Shandhaynta Xirmada BSD: Nashqada Cusub ee Xidhmada Heerka Adeegsiga", https://www.tcpdump.org/papers/bpf-usenix93.pdf
Steven McCanne, "libpcap: Habka Dhismaha iyo Wanaajinta ee Qabashada Xidhmada", https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf