Berkeley Packet Filters (BPF) iLinux kernel tekinoroji yanga iri pamapeji ekutanga echiRungu-mutauro tech zvinyorwa kwemakore akati wandei ikozvino. Makonferensi akazadzwa nemishumo pamusoro pekushandiswa nekuvandudzwa kweBPF. David Miller, Linux network subsystem muchengeti, anodana hurukuro yake paLinux Plumbers 2018
Hapasati pasisina tsananguro yakarongeka yeBPF paHabrΓ©, uye naizvozvo munhevedzano yezvinyorwa ndichaedza kutaura nezvenhoroondo yetekinoroji, kutsanangura mavakirwo uye maturusi ebudiriro, uye kutsanangura nzvimbo dzekushandisa uye tsika yekushandisa BPF. Ichi chinyorwa, zero, munhevedzano, chinotaurira nhoroondo uye dhizaini yeBPF yekare, uye zvakare inoburitsa zvakavanzika zvemisimboti yayo yekushandisa. tcpdump
, seccomp
, strace
, nezvimwe zvakawanda.
Iko kuvandudza kweBPF kunodzorwa neLinux networking nharaunda, iwo makuru aripo maapplication eBPF ane hukama netiweki uye nekudaro, nemvumo.
Kosi pfupi munhoroondo yeBPF (c)
Tekinoroji yemazuva ano yeBPF ishanduro yakavandudzwa uye yakawedzerwa yetekinoroji yekare ine zita rimwechete, rava kunzi classic BPF kudzivirira kuvhiringika. Chishandiso chinozivikanwa chakagadzirwa zvichibva pane yekare BPF tcpdump
, michina seccomp
, pamwe chete nemamodule mashoma anozivikanwa xt_bpf
nokuti iptables
uye classifier cls_bpf
. MuLinux yazvino, mapurogiramu ekare eBPF anoshandurirwa otomatiki kuita fomu nyowani, zvisinei, kubva pakuona kwemushandisi, API yakaramba iripo uye kushandiswa kutsva kweBPF yekare, sezvatichaona muchinyorwa chino, kuchiri kuwanikwa. Nechikonzero ichi, uye zvakare nekuti kutevera nhoroondo yekuvandudzwa kwekirasi BPF muLinux, zvichanyatsojeka kuti sei uye nei yakashanduka kuita chimiro chayo chemazuva ano, ndakafunga kutanga nechinyorwa nezve classical BPF.
Pakupera kwemakumi masere ezana ramakore rapfuura, mainjiniya kubva kune yakakurumbira Lawrence Berkeley Laboratory akafarira mubvunzo wekuti ungasefa sei nemazvo mapeji etiweki pane Hardware yaive yazvino mukupera kwemakumi masere emakore apfuura. Pfungwa yekutanga yekusefa, yakatanga kushandiswa muCSPF (CMU/Stanford Packet Filter) tekinoroji, yaive yekusefa mapaketi asina basa nekukurumidza sezvinobvira, i.e. mu kernel space, sezvo izvi zvichidzivirira kukopa zvisina basa data munzvimbo yemushandisi. Kupa runtime chengetedzo yekumhanyisa mushandisi kodhi munzvimbo yekernel, sandboxed virtual muchina yakashandiswa.
Nekudaro, iwo chaiwo michina yemafirita aripo akagadzirwa kuti ashande pamakina-akavakirwa-muchina uye haana kumhanya nemazvo pamichina mitsva yeRISC. Nekuda kweizvozvo, kuburikidza nekuedza kwemainjiniya kubva kuBerkeley Labs, tekinoroji nyowani yeBPF (Berkeley Packet Filters) yakagadziridzwa, iyo chaiyo yemuchina yekuvaka iyo yakagadzirwa yakavakirwa paMotorola 6502 processor - horse yezvigadzirwa zvinozivikanwa zvakadai se.
BPF muchina architecture
Tichazojairana nemavakirwo nenzira inoshanda, tichiongorora mienzaniso. Nekudaro, kutanga, ngatiti muchina uyu waive nemarejista maviri e32-bit anowanikwa kumushandisi, accumulator. A
uye index register X
, 64 bytes of memory (16 mazwi), iripo pakunyora uye kuverenga kunotevera, uye diki system yemirairo yekushanda nezvinhu izvi. Jump mirairo yekuita mataurirwo ezvisungo zvaivepowo muzvirongwa, asi kuvimbisa kupera panguva yechirongwa, kusvetuka kwaigona kungoitwa kumberi, i.e., kunyanya, kwakarambidzwa kugadzira zvishwe.
Iyo general scheme yekutanga muchina ndeiyi inotevera. Mushandisi anogadzira chirongwa cheiyo BPF architecture uye, achishandisa vamwe kernel mechanism (senge system call), inotakura uye inobatanidza chirongwa ku kune vamwe kune jenareta yechiitiko mu kernel (somuenzaniso, chiitiko ndiko kusvika kwepakiti rinotevera pane network network). Kana chiitiko chikaitika, kernel inomhanyisa chirongwa (semuenzaniso, mumuturikiri), uye ndangariro yemuchina inoenderana kune vamwe kernel memory region (semuenzaniso, data yeinouya packet).
Izvo zviri pamusoro zvichave zvakakwana kuti isu titange kutarisa mienzaniso: isu tichajairana nehurongwa uye kuraira fomati sezvinodiwa. Kana iwe uchida kukurumidza kudzidza iyo yekuraira system yemuchina chaiwo uye kudzidza nezve ese kugona kwayo, saka unogona kuverenga yekutanga chinyorwa. libpcap
: An Architecture uye Optimization Methodology yePacket Capturelibpcap
.
Isu tinoenderera mberi nekufunga yese yakakosha mienzaniso yekushandisa yekare BPF paLinux: tcpdump
(libpcap
), seccomp, xt_bpf
, cls_bpf
.
tcpdump
Kuvandudzwa kweBPF kwakaitwa pamwe chete nekuvandudzwa kwepamberi yekusefa kwepaketi - chinhu chinozivikanwa chinoshandiswa. tcpdump
. Uye, sezvo uyu uri wekare uye wakakurumbira muenzaniso wekushandisa yekare BPF, inowanikwa pane akawanda masisitimu anoshanda, isu tichatanga kudzidza kwedu tekinoroji nayo.
(Ndakamhanya mienzaniso yese muchinyorwa ichi paLinux 5.6.0-rc6
. Kubuda kweimwe mirairo kwakagadziridzwa kuti iverengeke zvirinani.)
Muenzaniso: kutarisa IPv6 mapaketi
Ngatifungei kuti isu tinoda kutarisa ese IPv6 mapaketi pane interface eth0
. Kuti tiite izvi tinogona kumhanya purogiramu tcpdump
nesefa iri nyore ip6
:
$ sudo tcpdump -i eth0 ip6
saka tcpdump
inounganidza sefa ip6
muBPF architecture bytecode uye utumire kune kernel (ona ruzivo muchikamu eth0
. Kana sefa yakadzosa kukosha kusiri zero n
, ipapo kusvika n
ma byte epaketi anozoteedzerwa kunzvimbo yemushandisi uye isu tichazviona mune zvakabuda tcpdump
.
Zvinoitika kuti isu tinogona nyore kuona kuti ndeipi bytecode yakatumirwa ku kernel tcpdump
nerubatsiro rwe tcpdump
, kana tikaimhanyisa nesarudzo -d
:
$ sudo tcpdump -i eth0 -d ip6
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 3
(002) ret #262144
(003) ret #0
Pamutsara zero tinomhanya murairo ldh [12]
, izvo zvinomirira kuti βload into register A
hafu yezwi (16 bits) iri pakero 12β uye mubvunzo chete ndewekuti rudzii rwendangariro rwatiri kutaura? Mhinduro ndeyekuti pa x
anotanga (x+1)
th byte yeakaongororwa network packet. Isu tinoverenga mapaketi kubva kuEthernet interface eth0
uye izvi
6 6 2
|Destination MAC|Source MAC|Ether Type|...|
Saka mushure mekuita murairo ldh [12]
murejista A
pachava nemunda Ether Type
- mhando yepakiti inofambiswa mune iyi Ethernet furemu. Pamutsara 1 tinofananidza zviri mukati merejista A
(rudzi rwepakeji) c 0x86dd
uye izvi jt 2
ΠΈ jf 3
- mamakisi aunofanira kuenda nawo kana kuenzanisa kwabudirira (A == 0x86dd
) uye hazvina kubudirira. Saka, mune imwe nyaya yakabudirira (IPv6) tinoenda kumutsara 2, uye mune imwe nyaya isingabudiriri - kumutsara 3. Pamutsara 3 purogiramu inoguma nekodhi 0 (usakopa pakiti), pamutsara 2 purogiramu inoguma nekodhi. 262144 (ndikope pasuru inokwana 256 kilobytes).
Muenzaniso wakaoma: isu tinotarisa TCP mapaketi nenzvimbo yekuenda
Ngationei kuti sefa yakaita sei iyo inokopa ese TCP mapaketi ane nzvimbo yekuenda chiteshi 666. Tichafunga nezve IPv4 kesi, sezvo IPv6 kesi iri nyore. Mushure mekudzidza muenzaniso uyu, unogona kuongorora iyo IPv6 sefa iwe pachako sechiitwa (ip6 and tcp dst port 666
) uye sefa yenyaya yakajairwa (tcp dst port 666
) Saka, sefa yatiri kufarira inoita seizvi:
$ 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
Isu tinotoziva izvo mitsara 0 ne1 inoita. Pamutsara 2 takatotarisa kuti iyi IPv4 packet (Ether Type = 0x800
) woiisa murejista A
24th byte yepakiti. Pasuru yedu inoita senge
14 8 1 1
|ethernet header|ip fields|ttl|protocol|...|
zvinoreva kuti tinoisa murejista A
iyo Protocol munda weIP musoro, izvo zvine musoro, nekuti isu tinoda kukopa chete TCP mapaketi. Isu tinofananidza Protocol ne 0x6
(IPPROTO_TCP
Pamitsetse 4 uye 5 tinoisa hafu yemazwi ari pakero 20 uye toshandisa murairo jset
tarisa kana chimwe chezvitatu chaiswa jset
iwo matatu akakosha mabhiti akacheneswa. Mabhii maviri ematatu anotiudza kana packet iri chikamu cheyakatsemuka IP packet, uye kana zvirizvo, ingave iyo yekupedzisira chidimbu. Chikamu chechitatu chakachengetwa uye chinofanira kunge chiri zero. Hatidi kutarisa mapaketi asina kukwana kana akatyoka, saka tinotarisa ese matatu mabhiti.
Mutsetse wechitanhatu ndiwo unonyanya kunakidza mune iyi rondedzero. Kutaura ldxb 4*([14]&0xf)
zvinoreva kuti tinoisa murejista X
zvidiki zvidiki zvina zvebhaiti yegumi neshanu yepacket zvakapetwa ne 4. Mabhiti mana asinganyanyi kukosha ebhaiti yegumi neshanu ndiwo munda. 4*([14]&0xf)
izita rechirongwa chekero chakasarudzika chinogona kushandiswa chete mufomu iri uye rerejista chete X
, i.e. isu hatigone kutaurawo ldb 4*([14]&0xf)
kana ldxb 5*([14]&0xf)
(isu tinogona chete kutsanangura akasiyana offset, semuenzaniso, ldxb 4*([16]&0xf)
) Zviri pachena kuti chirongwa chekutaura ichi chakawedzerwa kuBPF chaizvo kuitira kuti tigamuchire X
(index rejista) IPv4 musoro wehurefu.
Saka pamutsetse wechinomwe tinoedza kurodha hafu yezwi pa (X+16)
. Kurangarira kuti 14 bytes anogarwa neEthernet musoro, uye X
ine hurefu hweiyo IPv4 musoro, tinonzwisisa kuti mukati A
TCP yekuenda chiteshi inotakurwa:
14 X 2 2
|ethernet header|ip header|source port|destination port|
Pakupedzisira, pamutsara wechisere tinofananidza chiteshi chechiteshi nemutengo unodiwa uye pamitsetse 8 kana 9 tinodzosera mhedzisiro - kana kukopa pakiti kana kwete.
Tcpdump: kurodha
Mumienzaniso yapfuura, isu hatina kugara zvakadzama pamusoro pemabatiro atinoita BPF bytecode mu kernel yekusefa kwepaketi. Kazhinji kutaura, tcpdump
inotakurwa kune akawanda masisitimu uye nekushanda nemasefa tcpdump
libpcap
libpcap
, iwe unoda kuita zvinotevera:
- gadzira mhando descriptor
pcap_t
kubva kuzita rekushandisa: ,pcap_create
- activate interface:
,pcap_activate
- unganidza sefa:
,pcap_compile
- batanidza sefa:
.pcap_setfilter
Kuti uone kuti inoshanda sei pcap_setfilter
yakaitwa muLinux, isu tinoshandisa strace
(mimwe mitsetse yakabviswa):
$ 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
...
Pamitsetse miviri yekutanga yekubuda tinogadzira eth0
. Of ip
ichave nemirairo mina yeBPF, uye pamutsetse wechitatu tinoona mashandisiro esarudzo SO_ATTACH_FILTER
setsockopt
tinotakura uye tinobatanidza sefa yehurefu 4. Iyi ndiyo sefa yedu.
Zvakakosha kucherechedza kuti muBPF yekare, kurodha nekubatanidza sefa nguva dzose kunoitika seatomu kushanda, uye mushanduro itsva yeBPF, kurodha purogiramu nekuisunga kune jenareta yechiitiko inoparadzaniswa nenguva.
Chokwadi Chakavanzika
Imwe vhezheni yakawedzera kuzara yezvakabuda inoita seizvi:
$ 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
...
Sezvambotaurwa pamusoro, tinotakura nekubatanidza sefa yedu kune socket pamutsetse wechishanu, asi chii chinoitika pamitsetse 5 ne3? Zvinoratidza kuti izvi libpcap
inotichengeta - kuitira kuti kubuda kwesefa yedu kusasanganise mapaketi asingaigutse, raibhurari. ret #0
(donhedza mapaketi ese), chinja socket kune isiri-blocking mode uye kuyedza kubvisa ese mapaketi anogona kusara kubva kune apfuura mafirita.
Pakazara, kusefa mapakeji paLinux uchishandisa yekare BPF, unofanirwa kuve nesefa muchimiro chechimiro chakadai struct sock_fprog
uye socket yakavhurika, mushure meiyo sefa inogona kusungirirwa kune socket uchishandisa system call setsockopt
.
Sezvineiwo, iyo sefa inogona kusungirirwa kune chero socket, kwete mbishi chete. Here
Mamwe mashoko pamusoro pekushandisa setsockopt
yekubatanidza masefa, maona struct sock_fprog
pasina rubatsiro tcpdump
tichataura muchikamu
Classic BPF uye yezana ramakore rechiXNUMX
BPF yakaverengerwa muLinux muna 1997 uye yakaramba ichiita basa kwenguva yakareba libpcap
pasina shanduko yakakosha (Linux-chaiyo shanduko, hongu, x86_64
code.
JIT compiler yaive yekutanga muketani yekuchinja: muna 2012 xt_bpf
, iyo inokubvumira kunyora mitemo ye iptables
nerubatsiro rweBPF, uye muna Gumiguru 2013 yaive cls_bpf
, iyo inokutendera kuti unyore traffic classifiers uchishandisa BPF.
Tichatarisa mienzaniso yese iyi zvakadzama munguva pfupi, asi kutanga zvichatibatsira kuti tidzidze kunyora uye kuunganidza zvirongwa zveBPF zvisina tsarukano, sezvo kugona kunopihwa neraibhurari. libpcap
shoma (muenzaniso wakapusa: sefa yakagadzirwa libpcap
inogona kudzosa maitiro maviri chete - 0 kana 0x40000) kana kazhinji, senge seccomp, haishande.
Kuronga BPF nemaoko edu
Ngatizivei neiyo binary fomati yeBPF mirairo, iri nyore kwazvo:
16 8 8 32
| code | jt | jf | k |
Murairo wega wega unotora 64 bits, umo mabhiti gumi nematanhatu ekutanga kodhi yekuraira, kozoita maviri masere-bit indents, jt
ΠΈ jf
, uye 32 bits yekupokana K
, chinangwa chacho chinosiyana kubva pakuraira kuenda kune kuraira. Somuenzaniso, murayiro ret
, iyo inogumisa purogiramu ine code 6
, uye kukosha kwekudzoka kunotorwa kubva kune nguva dzose K
. MuC, murayiridzo mumwe chete weBPF unomiririrwa sechimiro
struct sock_filter {
__u16 code;
__u8 jt;
__u8 jf;
__u32 k;
}
uye chirongwa chose chiri muchimiro chechimiro
struct sock_fprog {
unsigned short len;
struct sock_filter *filter;
}
Nokudaro, tinogona kutonyora mapurogiramu (somuenzaniso, tinoziva makodhi emirairo kubva ip6
kubva
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,
};
program prog
isu tinogona kushandisa zviri pamutemo mukufona
setsockopt(sk, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog))
Kunyora zvirongwa nenzira yemakodhi emuchina hazvina kunaka, asi dzimwe nguva zvinodikanwa (semuenzaniso, kugadzirisa, kugadzira bvunzo dzeyuniti, kunyora zvinyorwa paHabrΓ©, nezvimwewo). Kuti zvive nyore, mufaira <linux/filter.h>
mubatsiri macros anotsanangurwa - iwo muenzaniso wakafanana nepamusoro unogona kunyorwa zvakare se
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),
}
Zvisinei, iyi sarudzo haina kunyanya kunaka. Izvi ndizvo zvakafungwa neLinux kernel programmers, uye nekudaro mudhairekitori tools/bpf
Mutauro wegungano wakafanana zvakanyanya nekubuda kwedebug tcpdump
, asi nekuwedzera isu tinogona kutsanangura mavara ekufananidzira. Semuenzaniso, heino chirongwa chinodonhedza ese mapaketi kunze kweTCP/IPv4:
$ cat /tmp/tcp-over-ipv4.bpf
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0
Nekusagadzikana, iyo assembler inogadzira kodhi mufomati <ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΈΠ½ΡΡΡΡΠΊΡΠΈΠΉ>,<code1> <jt1> <jf1> <k1>,...
, semuenzaniso wedu neTCP zvichave
$ 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,
Kuti zvive nyore zveC programmers, imwe nzira yekubuda inogona kushandiswa:
$ 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 },
Ichi chinyorwa chinogona kukopwa mune tsananguro yemhando yechimiro struct sock_filter
, sezvatakaita pakutanga kwechikamu chino.
Linux uye netsniff-ng extensions
Mukuwedzera kune yakajairwa BPF, Linux uye tools/bpf/bpf_asm
rutsigiro uye struct sk_buff
, iyo inotsanangura network packet mu kernel. Zvisinei, kunewo mamwe marudzi emirairo yekubatsira, somuenzaniso ldw cpu
ichaisa murejista A
mhedzisiro yekumhanyisa kernel function raw_smp_processor_id()
. (Mushanduro itsva yeBPF, idzi dzisiri dzemhando dzekuwedzera dzakawedzerwa kuti dzipe zvirongwa zvine seti yevabatsiri kernel yekuwana ndangariro, zvimiro, nekugadzira zviitiko.) Heino muenzaniso unonakidza wesefa umo tinokopa chete packet headers munzvimbo yemushandisi uchishandisa kuwedzera poff
, payload offset:
ld poff
ret a
BPF yekuwedzera haigone kushandiswa mukati tcpdump
, asi ichi ndicho chikonzero chakanaka chekujairana neye utility package netsniff-ng
netsniff-ng
, iyo, kunze kwekusefa uchishandisa BPF, inewo inoshanda traffic jenareta, uye yakanyanya kupfuura tools/bpf/bpf_asm
, BPF yakaungana yakafona bpfc
. Iyo pasuru ine yakadzama magwaro, onawo zvinongedzo pakupera kwechinyorwa.
seccomp
Saka, isu tatoziva manyorerwo eBPF zvirongwa zvekunetsekana uye takagadzirira kutarisa mienzaniso mitsva, yekutanga iyo seccomp tekinoroji, iyo inobvumira, uchishandisa BPF mafirita, kutonga seti uye seti yehurongwa hwekufona nharo dziripo. nzira yakapiwa nevazukuru vayo.
Iyo yekutanga vhezheni ye seccomp yakawedzerwa kune kernel muna 2005 uye yakanga isinganyanyi kufarirwa, sezvo yaingopa imwe chete sarudzo - kudzikamisa seti yekufona system inowanikwa kune inotevera maitiro: read
, write
, exit
ΠΈ sigreturn
, uye nzira yaityora mitemo yakaurayiwa pachishandiswa SIGKILL
. Nekudaro, muna 2012, seccomp yakawedzera kugona kushandisa BPF mafirita, ichikubvumidza kuti utsanangure seti yeanobvumidzwa system mafoni uye kunyange kuita cheki panharo dzavo. (Sezvineiwo, Chrome yaive imwe yevashandisi vekutanga kweichi chiitiko, uye vanhu veChrome parizvino vari kugadzira nzira yeKRSI yakavakirwa pashanduro itsva yeBPF uye kubvumira kugadziridzwa kweLinux Security Modules.) Zvinongedzo kune mamwe magwaro zvinogona kuwanikwa pakupedzisira yechinyorwa.
Ziva kuti pakatove nezvinyorwa pahubhu nezve kushandisa seccomp, pamwe mumwe munhu angangoda kuzviverenga zvisati zvaitika (kana kuti panzvimbo) kuverenga zvikamu zvinotevera. Muchinyorwa
Tevere tichaona manyorero uye kurodha mafirita seccomp
isina C uye kushandisa raibhurari libseccomp
uye ndezvipi zvakanakira uye zvakaipira sarudzo yega yega, uye pakupedzisira, ngationei kuti seccomp inoshandiswa sei nechirongwa strace
.
Kunyora uye kurodha mafirita e seccomp
Isu tatoziva kunyora zvirongwa zveBPF, saka ngatitangei kutarisa seccomp programming interface. Iwe unogona kuseta sefa padanho rekuita, uye ese maitirwo emwana achagara nhaka zvirambidzo. Izvi zvinoitwa uchishandisa system call seccomp(2)
seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)
apo &filter
- ichi chinongedzo kune chimiro chatinoziva kare struct sock_fprog
, i.e. Chirongwa cheBPF.
Zvirongwa zve seccomp zvakasiyana sei nezvirongwa zvemasoketi? Transmitted context. Kana iri sockets, takapihwa memory area ine packet, kana iri seccomp takapihwa structure yakaita se.
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
zviri nr
ndiyo nhamba yekufona system ichatangwa, arch
- architecture yazvino (zvimwe pane izvi pazasi), args
- anosvika matanhatu system kudana nharo, uye instruction_pointer
inongedzo kune mushandisi nzvimbo yekuraira iyo yakaita iyo system kufona. Saka, semuenzaniso, kurodha iyo system yekufona nhamba murejista A
tinofanira kutaura
ldw [0]
Kune mamwe maficha ezvirongwa zve seccomp, semuenzaniso, mamiriro acho anogona kuwanikwa chete ne 32-bit alignment uye haugone kurodha hafu yezwi kana byte - paunenge uchiedza kurodha sefa. ldh [0]
system call seccomp
achadzoka EINVAL
. Basa rinotarisa mafirita akatakurwa seccomp_check_filter()
mod
(chikamu chasara) uye haichawanikwi seccomp BPF zvirongwa, kubva pakuwedzera kwayo
Chaizvoizvo, isu tinotoziva zvese kunyora uye kuverenga seccomp zvirongwa. Kazhinji iyo logic yehurongwa inorongwa senge chena kana dema runyorwa rwekufona system, semuenzaniso chirongwa
ld [0]
jeq #304, bad
jeq #176, bad
jeq #239, bad
jeq #279, bad
good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
bad: ret #0
inotarisa blacklist yechina system call ine nhamba 304, 176, 239, 279. Ndedzipi idzi nharembozha? Hatigoni kutaura chokwadi, sezvo tisingazivi kuti purogiramu yacho yakanyorerwa mavakirwo api. Naizvozvo, vanyori ve seccomp arch
chimiro struct seccomp_data
) Nekuvakwa kwakatariswa, kutanga kwemuenzaniso kwaizoita senge:
ld [4]
jne #0xc000003e, bad_arch ; SCMP_ARCH_X86_64
uye ipapo nhamba dzedu dzekufona dzehurongwa dzaizowana humwe hunhu.
Isu tinonyora nekutakura mafirita ekushandisa seccomp libseccomp
Kunyora mafirita mukodhi kodhi kana muBPF gungano rinokutendera iwe kuti uve nekutonga kwakazara pamusoro pemhedzisiro, asi panguva imwe chete, dzimwe nguva zvinofanirwa kuve neinotakurika uye / kana inoverengeka kodhi. Raibhurari ichatibatsira neizvi
Ngatitorei, semuenzaniso, tinyore chirongwa chinomhanyisa bhinari faira yesarudzo yemushandisi, takamboisa runyoro runyoro rwekufona system kubva
#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]);
}
Kutanga tinotsanangura mutsara sys_numbers
ye40+ system yekufona manhamba kuvhara. Zvadaro, tanga mashoko akapoteredza ctx
uye taurira raibhurari izvo zvatinoda kubvumidza (SCMP_ACT_ALLOW
) ese anofona system nekukasira (zviri nyore kuvaka blacklists). Zvadaro, imwe neimwe, isu tinowedzera ese masystem mafoni kubva kune blacklist. Mukupindura kufona system kubva pane iyo rondedzero, tinokumbira SCMP_ACT_TRAP
, munyaya iyi seccomp inotumira chiratidzo kune iyo nzira SIGSYS
ine tsananguro yekuti ndeipi nharembozha yakatyora mitemo. Pakupedzisira, tinoisa purogiramu mu kernel tichishandisa seccomp_load
, iyo inounganidza chirongwa ichi uye ichibatanidza kune iyo maitiro uchishandisa system call seccomp(2)
.
Kuti ibudirire kuunganidzwa, chirongwa chinofanira kunge chakabatana neraibhurari libseccomp
, somuenzaniso:
cc -std=c17 -Wall -Wextra -c -o seccomp_lib.o seccomp_lib.c
cc -o seccomp_lib seccomp_lib.o -lseccomp
Muenzaniso wekutanga kunobudirira:
$ ./seccomp_lib echo ok
ok
Muenzaniso weiyo blocked system call:
$ sudo ./seccomp_lib mount -t bpf bpf /tmp
Bad system call
Isu tinoshandisa strace
zveruzivo:
$ 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
tingaziva sei kuti chirongwa chakamiswa nekuda kwekushandiswa kwekufona system isiri pamutemo mount(2)
.
Saka, takanyora sefa tichishandisa raibhurari libseccomp
, kuisa kodhi isiri-yadiki mumitsara mina. Mumuenzaniso uri pamusoro apa, kana pane nhamba huru yemafoni ehurongwa, nguva yekuuraya inogona kuderedzwa zvinooneka, sezvo cheki inongova rondedzero yekuenzanisa. Nekugadzirisa, libseccomp nguva pfupi yadarika yaive nayo SCMP_FLTATR_CTL_OPTIMIZE
. Kuseta hunhu uhu ku2 kunoshandura sefa kuita chirongwa chebhinari yekutsvaga.
Kana iwe uchida kuona kuti mafirita ekutsvaga anoshanda sei, tarisa
$ 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
Iwe haugone kunyora chero chinhu nekukurumidza nekukurumidza, sezvo zvirongwa zveBPF zvisingakwanisi kuita kusvetuka kwekusvetuka (hatigone kuita, semuenzaniso, jmp A
kana jmp [label+X]
) uye saka shanduko dzese dzakamira.
seccomp uye strace
Munhu wose anoziva kushandiswa strace
chishandiso chakakosha pakudzidza maitiro emaitiro paLinux. Zvisinei, vakawanda vakanzwawo nezvazvo strace
kushandiswa kushandiswa ptrace(2)
, uye mune iyi nzira isu hatigone kutsanangura kuti ndeipi seti yekufona system yatinoda kumisa maitiro, i.e., semuenzaniso, mirairo.
$ 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
zvinogadziriswa mukati menguva imwe chete, kunyangwe muchiitiko chechipiri tinoda kutsvaga imwe chete system call.
Sarudzo itsva --seccomp-bpf
, akawedzera ku strace
vhezheni 5.3, inobvumidza iwe kukurumidzira maitiro kakawanda uye nguva yekutanga pasi pekutsvaga kweimwe system yekufona yatove kufananidzwa nenguva yenguva yekutanga yekutanga:
$ 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
(Pano, hongu, pane hunyengeri hushoma pakuti hatisi kuronda hurongwa hwekudanwa kwemurairo uyu. Kana taironda, semuenzaniso, newfsstat
, ipapo strace
yaibva yatyoka kunge isina --seccomp-bpf
.)
Sarudzo iyi inoshanda sei? Pasina iye strace
inobatanidza kune iyo nzira uye inotanga kushandisa PTRACE_SYSCALL
. Kana chirongwa chinogadziriswa chinoburitsa (chero) system yekufona, kutonga kunoendeswa kune strace
, iyo inotarisa kupokana kweiyo system call uye inoimhanyisa uchishandisa PTRACE_SYSCALL
. Mushure menguva yakati, maitiro anopedzisa iyo system yekufona uye kana ichibuda, kutonga kunotamiswa zvakare strace
, iyo inotarisa kukosha kwekudzoka uye inotanga maitiro uchishandisa PTRACE_SYSCALL
, zvichingoenda zvakadaro.
Ne seccomp, zvisinei, maitiro aya anogona kuvandudzwa chaizvo sezvatinoda. Zvinoreva, kana tichida kutarisa chete kufona system X
, ipapo tinogona kunyora BPF sefa kuti X
inodzosera kukosha SECCOMP_RET_TRACE
, uye nekufona kwatisina basa nesu - SECCOMP_RET_ALLOW
:
ld [0]
jneq #X, ignore
trace: ret #0x7ff00000
ignore: ret #0x7fff0000
Mune ino kesi strace
pakutanga anotanga maitiro se PTRACE_CONT
, sefa yedu inogadziriswa kune yega yega system yekufona, kana iyo system yekufona isiri X
, ipapo maitiro anoramba achimhanya, asi kana izvi X
, ipapo seccomp ichatamisa control strace
iyo inotarisa kune nharo uye kutanga maitiro se PTRACE_SYSCALL
(sezvo seccomp isina kugona kumhanyisa chirongwa pakubuda kubva kunharembozha). Kana iyo system call yadzoka, strace
ichatangazve maitiro uchishandisa PTRACE_CONT
uye ichamirira mameseji matsva kubva ku seccomp.
Paunenge uchishandisa sarudzo --seccomp-bpf
pane zvirambidzo zviviri. Chekutanga, hazvizogone kujoinha maitiro agara aripo (sarudzo -p
zvirongwa strace
), sezvo izvi zvisingatsigirwe ne seccomp. Chechipiri, hapana zvinogoneka kwete tarisa maitiro emwana, sezvo seccomp mafirita anogarwa nhaka nemaitiro ese emwana pasina kugona kudzima izvi.
Tsanangudzo shoma yekuti sei chaizvo strace
inoshanda ne seccomp
inogona kuwanikwa kubva
xt_bpf
Ngatidzokerei kunyika yemanetwork.
Background: kare kare, muna 2007, musimboti waiva xt_u32
ye netfilter. Yakanyorwa nekuenzanisa neinotova yekare traffic classifier cls_u32
uye yakakubvumidza kuti unyore zvisina tsarukano bhinari mitemo yeiptables uchishandisa anotevera mashandiro ari nyore: takura 32 bits kubva pasuru uye ita seti yemasvomhu mabasa pavari. Semuyenzaniso,
sudo iptables -A INPUT -m u32 --u32 "6&0xFF=1" -j LOG --log-prefix "seen-by-xt_u32"
Inotakura iyo 32 bits yeIP musoro, kutanga padding 6, uye inoisa mask kwavari. 0xFF
(tora low byte). Munda uyu protocol
IP musoro uye tinoienzanisa ne1 (ICMP). Iwe unogona kusanganisa macheki akawanda mumutemo mumwe, uye iwe unogona zvakare kuuraya opareta @
- fambisa X bytes kurudyi. Somuenzaniso, mutemo
iptables -m u32 --u32 "6&0xFF=0x6 && 0>>22&0x3C@4=0x29"
inotarisa kana TCP Sequence Number haina kuenzana 0x29
. Ini handisi kuzoenda kune mamwe mashoko, sezvo zvatova pachena kuti kunyora mitemo yakadaro nemaoko hakusi nyore. Muchinyorwa xt_u32
. Onawo zvinongedzo pakupera kwechinyorwa chino.
Kubva 2013 module pachinzvimbo chemodule xt_u32
unogona kushandisa BPF yakavakirwa module xt_bpf
. Chero ani zvake akaverenga izvi kure anofanira kunge atove akajeka pamusoro pemusimboti wekushanda kwayo: mhanya BPF bytecode semitemo iptables. Iwe unogona kugadzira mutemo mutsva, semuenzaniso, seizvi:
iptables -A INPUT -m bpf --bytecode <Π±Π°ΠΉΡΠΊΠΎΠ΄> -j LOG
pano <Π±Π°ΠΉΡΠΊΠΎΠ΄>
- iyi ndiyo kodhi mune assembler inobuda fomati bpf_asm
by default, semuenzaniso,
$ 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
Mumuenzaniso uyu tiri kusefa ese eUDP mapaketi. Mamiriro echirongwa cheBPF mune module xt_bpf
, hongu, inonongedza ku data yepakiti, munyaya ye iptables, kusvika pakutanga kwe IPv4 musoro. Dzorera kukosha kubva kuchirongwa cheBPF false
zvinoreva kuti packet haina kufanana.
Zviri pachena kuti module xt_bpf
inotsigira mafirita akaoma kunzwisisa kupfuura muenzaniso uri pamusoro. Ngatitarisei mienzaniso chaiyo kubva Cloudfare. Kusvikira munguva pfupi yapfuura vakashandisa module xt_bpf
kudzivirira kurwiswa kweDDoS. Muchinyorwa bpfgen
unogona kugadzira chirongwa cheBPF chinofanana nemubvunzo weDNS wezita 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
Muchirongwa tinotanga kutakura murejista X
kutanga kwemutsara kero x04habrx03comx00
mukati meUDP datagraph uye wobva watarisa chikumbiro: 0x04686162 <-> "x04hab"
uye zvakadaro.
Kwapera chinguva, Cloudfare yakaburitsa p0f -> BPF compiler kodhi. Muchinyorwa
$ ./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,
...
Parizvino haachashandisi Cloudfare xt_bpf
, sezvo vakatamira kuXDP - imwe yesarudzo dzekushandisa shanduro itsva yeBPF, ona.
cls_bpf
Muenzaniso wekupedzisira wekushandisa classic BPF mu kernel ndiye classifier cls_bpf
yeiyo traffic control subsystem muLinux, yakawedzerwa kuLinux pakupera kwa2013 uye nekufungidzira kutsiva yekare. cls_u32
.
Zvisinei, isu hatisi kuzotsanangura ikozvino basa cls_bpf
, kubva pakuona kwezivo pamusoro peBPF yekare izvi hazvizotipi chero chinhu - isu tatove tichiziva nezvese kushanda. Pamusoro pezvo, muzvinyorwa zvinotevera zvichitaura nezve Yakawedzerwa BPF, tichasangana nemugadziri uyu kanopfuura kamwe.
Chimwe chikonzero chekusataura nezvekushandisa classic BPF c cls_bpf
Dambudziko nderekuti, kana ichienzaniswa neYakawedzerwa BPF, chiyero chekushandiswa mune iyi kesi yakadzikiswa zvakanyanya: mapurogiramu echinyakare haagone kushandura zvirimo mumapakeji uye haakwanise kuchengetedza nyika pakati pekufona.
Saka yave nguva yekuonekana kune yekare BPF uye kutarisa kune ramangwana.
Farewell kune classic BPF
Takatarisa kuti tekinoroji yeBPF, yakagadzirwa sei mukutanga kwemakumi mapfumbamwe, yakabudirira kurarama kwekota yezana ramakore uye kusvika kumagumo kwakawana zvikumbiro zvitsva. Nekudaro, zvakafanana neshanduko kubva kumichina yemakina kuenda kuRISC, iyo yakashanda sekusimudzira kwekuvandudzwa kweBPF yekare, muma32s pakanga paine shanduko kubva ku64-bit kuenda kuXNUMX-bit michina uye yekirasi BPF yakatanga kusashanda. Uye zvakare, kugona kweiyo classic BPF kushoma kwazvo, uye nekuwedzera kune echinyakare architecture - isu hatigone kuchengetedza nyika pakati pekufona kune BPF zvirongwa, hapana mukana wekuita zvakanangana nemushandisi, hapana mukana wekudyidzana. ne kernel, kunze kwekuverenga nhamba shoma yeminda yezvimiro sk_buff
uye nekutangisa mabasa akareruka emubatsiri, haugone kushandura zviri mukati memapakiti uye wozvitungamira.
Muchokwadi, parizvino zvese zvasara zveiyo classic BPF muLinux ndiyo API interface, uye mukati me kernel ese ekirasi mapurogiramu, angave socket mafirita kana seccomp mafirita, anoshandurirwa otomatiki kuita chimiro chitsva, Yakawedzerwa BPF. (Tichataura nezve kuti izvi zvinoitika sei munyaya inotevera.)
Shanduko yekuvaka nyowani yakatanga muna 2013, apo Alexey Starovoitov akaronga chirongwa chekuvandudza BPF. Muna 2014 zvigamba zvinoenderana
Zvimwe zvinyorwa munhevedzano ino zvichavhara mavakirwo uye mashandisirwo etekinoroji nyowani, yakatanga kuzivikanwa seyemukati BPF, ndokuzowedzerwa BPF, uye ikozvino yangove BPF.
nezvakanyorwa
- Steven McCanne naVan Jacobson, "The BSD Packet Filter: A New Architecture for User-level Packet Capture",
https://www.tcpdump.org/papers/bpf-usenix93.pdf
- Steven McCanne, "libpcap: An Architecture uye Optimization Methodology yePacket Capture",
https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
tcpdump
,libpcap
:https://www.tcpdump.org/ IPtable U32 Match Tutorial .- BPF - iyo yakakanganwa bytecode:
https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
- Kusuma BPF Tool:
https://blog.cloudflare.com/introducing-the-bpf-tools/
bpf_cls
:http://man7.org/linux/man-pages/man8/tc-bpf.8.html
- Mhedziso pfupi:
https://lwn.net/Articles/656307/
https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
habr: midziyo uye chengetedzo: seccomp habr: Kuparadzanisa madhimoni ane systemd kana "haude Docker pane izvi!" - Paul Chaignon, "strace --seccomp-bpf: kutarisa pasi pehodhi",
https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
netsniff-ng
:http://netsniff-ng.org/
Source: www.habr.com