ProHoster > blog > Utawala > Tunaandika ulinzi dhidi ya mashambulizi ya DDoS kwenye XDP. Sehemu ya nyuklia
Tunaandika ulinzi dhidi ya mashambulizi ya DDoS kwenye XDP. Sehemu ya nyuklia
Teknolojia ya eXpress Data Path (XDP) inaruhusu uchakataji holela wa trafiki kwenye violesura vya Linux kabla ya pakiti kuingia kwenye rundo la mtandao wa kernel. Utumizi wa XDP - ulinzi dhidi ya mashambulizi ya DDoS (CloudFlare), filters tata, ukusanyaji wa takwimu (Netflix). Programu za XDP hutekelezwa na mashine pepe ya eBPF, na kwa hivyo ina vizuizi kwa nambari zao zote mbili na kazi zinazopatikana za kernel, kulingana na aina ya kichungi.
Nakala hiyo imekusudiwa kufidia mapungufu ya vifaa vingi kwenye XDP. Kwanza, hutoa msimbo uliotengenezwa tayari ambao hupita mara moja vipengele vya XDP: iliyotayarishwa kwa uthibitishaji au rahisi sana kusababisha matatizo. Unapojaribu kuandika msimbo wako mwenyewe kutoka mwanzo baadaye, hakuna ufahamu wa nini cha kufanya na makosa ya kawaida. Pili, haitoi njia za kujaribu XDP ndani bila VM na vifaa, licha ya ukweli kwamba wana mitego yao wenyewe. Maandishi yanalenga watayarishaji programu wanaofahamu mitandao na Linux ambao wanapenda XDP na eBPF.
Katika sehemu hii, tutaelewa kwa undani jinsi chujio cha XDP kimekusanyika na jinsi ya kukijaribu, basi tutaandika toleo rahisi la utaratibu unaojulikana wa vidakuzi vya SYN kwenye kiwango cha usindikaji wa pakiti. Mpaka tutengeneze "orodha nyeupe"
wateja waliothibitishwa, weka vihesabio na udhibiti kichujio - kumbukumbu za kutosha.
Tutaandika katika C - hii sio mtindo, lakini ni ya vitendo. Nambari zote zinapatikana kwenye GitHub kwenye kiunga mwishoni na imegawanywa katika ahadi kulingana na hatua zilizoelezewa kwenye kifungu.
Hukumu. Katika kipindi cha kifungu, suluhisho la mini la kurudisha nyuma mashambulizi ya DDoS litatengenezwa, kwa sababu hii ni kazi ya kweli kwa XDP na eneo langu. Hata hivyo, lengo kuu ni kuelewa teknolojia, hii sio mwongozo wa kuunda ulinzi tayari. Msimbo wa mafunzo haujaboreshwa na huacha baadhi ya nuances.
Muhtasari mfupi wa XDP
Nitasema mambo muhimu tu ili si kurudia nyaraka na makala zilizopo.
Kwa hivyo, msimbo wa kichungi hupakiwa kwenye kernel. Kichujio hupitishwa pakiti zinazoingia. Kama matokeo, kichungi lazima kifanye uamuzi: kupitisha pakiti kwenye kernel (XDP_PASS), pakiti ya kuacha (XDP_DROP) au uirudishe (XDP_TX) Kichujio kinaweza kubadilisha kifurushi, hii ni kweli hasa kwa XDP_TX. Unaweza pia kuvunja programu (XDP_ABORTED) na kuacha kifurushi, lakini hii ni sawa assert(0) - kwa utatuzi.
Mashine pepe ya eBPF (Kichujio cha Pakiti kilichopanuliwa cha Berkley) inafanywa rahisi kimakusudi ili kernel iweze kuangalia kama msimbo haujizunguki na hauharibu kumbukumbu za watu wengine. Vizuizi na ukaguzi wa jumla:
Loops (kuruka nyuma) ni marufuku.
Kuna mrundikano wa data, lakini hakuna chaguo za kukokotoa (vitendaji vyote vya C lazima viwe na mstari).
Ufikiaji wa kumbukumbu nje ya rafu na bafa ya pakiti ni marufuku.
Ukubwa wa kanuni ni mdogo, lakini katika mazoezi hii sio muhimu sana.
Vitendaji maalum vya kernel (wasaidizi wa eBPF) pekee ndio wanaoruhusiwa.
Kutengeneza na kusanikisha kichungi inaonekana kama hii:
msimbo wa chanzo (km. kernel.c) hukusanya kupinga (kernel.o) kwa usanifu wa mashine pepe ya eBPF. Kuanzia Oktoba 2019, utayarishaji wa eBPF utatumika na Clang na kuahidiwa katika GCC 10.1.
Ikiwa katika msimbo huu wa kitu kuna wito kwa miundo ya kernel (kwa mfano, kwa meza na vihesabu), badala ya vitambulisho vyao kuna sufuri, yaani, kanuni hiyo haiwezi kutekelezwa. Kabla ya kupakia kwenye kernel, sufuri hizi lazima zibadilishwe na vitambulisho vya vitu maalum vilivyoundwa kupitia simu za kernel (unganisha msimbo). Unaweza kufanya hivyo na huduma za nje, au unaweza kuandika programu ambayo itaunganisha na kupakia chujio maalum.
Kernel inathibitisha programu inayopakiwa. Inachunguza kutokuwepo kwa mizunguko na kutotoka kwa kifurushi na mipaka ya stack. Ikiwa mthibitishaji hawezi kuthibitisha kwamba msimbo ni sahihi, programu inakataliwa - mtu lazima awe na uwezo wa kumpendeza.
Baada ya uthibitishaji uliofaulu, kernel inakusanya msimbo wa kitu cha usanifu wa eBPF kuwa msimbo wa mashine ya usanifu wa mfumo (kwa wakati tu).
Programu imeunganishwa kwenye kiolesura na huanza usindikaji wa pakiti.
Kwa kuwa XDP inaendesha kwenye kernel, utatuzi unategemea kumbukumbu za ufuatiliaji na, kwa kweli, kwenye pakiti ambazo programu huchuja au kuzalisha. Hata hivyo, eBPF huweka msimbo uliopakuliwa salama kwa mfumo, kwa hivyo unaweza kujaribu XDP moja kwa moja kwenye Linux ya karibu nawe.
Kuandaa Mazingira
Mkutano
Clang haiwezi kutoa nambari ya kitu moja kwa moja kwa usanifu wa eBPF, kwa hivyo mchakato una hatua mbili:
Unganisha nambari ya C kwa bytecode ya LLVM (clang -emit-llvm).
Badilisha bytecode kuwa msimbo wa kitu cha eBPF (llc -march=bpf -filetype=obj).
Wakati wa kuandika kichungi, faili kadhaa zilizo na vitendaji vya msaidizi na macros zitakuja kusaidia kutoka kwa vipimo vya kernel. Ni muhimu kwamba zilingane na toleo la kernel (KVER) Pakua kwa helpers/:
KDIR ina njia ya vichwa vya kernel, ARCH - usanifu wa mfumo. Njia na zana zinaweza kutofautiana kidogo kati ya usambazaji.
Mfano wa tofauti kwa Debian 10 (kernel 4.19.67)
# другая команда
CLANG ?= clang
LLC ?= llc-7
# другой каталог
KDIR ?= /usr/src/linux-headers-$(shell uname -r)
ARCH ?= $(subst x86_64,x86,$(shell uname -m))
# два дополнительных каталога -I
CFLAGS =
-Ihelpers
-I/usr/src/linux-headers-4.19.0-6-common/include
-I/usr/src/linux-headers-4.19.0-6-common/arch/$(ARCH)/include
# далее без изменений
CFLAGS ni pamoja na saraka iliyo na vichwa vya usaidizi na saraka kadhaa zilizo na vichwa vya kernel. Alama __KERNEL__ inamaanisha kuwa vichwa vya UAPI (userspace API) vimefafanuliwa kwa msimbo wa kernel, kwani kichujio kinatekelezwa kwenye kernel.
Ulinzi wa rafu unaweza kuzimwa (-fno-stack-protector) kwa sababu kithibitishaji cha msimbo wa eBPF hukagua kutotoka kwa mipaka ya rafu. Unapaswa kuwezesha uboreshaji mara moja, kwa sababu ukubwa wa eBPF bytecode ni mdogo.
Wacha tuanze na kichungi ambacho hupitisha pakiti zote na haifanyi chochote:
Timu make hukusanya xdp_filter.o. Unaweza kuipima wapi sasa?
benchi ya mtihani
Msimamo unapaswa kujumuisha miingiliano miwili: ambayo kutakuwa na chujio na ambayo pakiti zitatumwa. Hizi lazima ziwe vifaa kamili vya Linux vilivyo na IP zao wenyewe ili kuangalia jinsi programu za kawaida zinavyofanya kazi na kichujio chetu.
Vifaa kama vile veth (Ethernet virtual) vinafaa kwa ajili yetu: ni jozi ya violesura vya mtandao pepe "vilivyounganishwa" moja kwa moja. Unaweza kuziunda kama hii (katika sehemu hii, amri zote ip kutekelezwa kutoka root):
ip link add xdp-remote type veth peer name xdp-local
Hapa xdp-remote и xdp-local - majina ya kifaa. Washa xdp-local (192.0.2.1/24) kichujio kitaambatishwa, na xdp-remote (192.0.2.2/24) trafiki inayoingia itatumwa. Walakini, kuna shida: miingiliano iko kwenye mashine moja, na Linux haitatuma trafiki kwa mmoja wao kupitia nyingine. Unaweza kuisuluhisha kwa sheria ngumu iptables, lakini watalazimika kubadilisha vifurushi, ambayo ni ngumu wakati wa kurekebisha. Ni bora kutumia nafasi za majina za mtandao (nafasi za majina za mtandao, neti zaidi).
Nafasi ya majina ya mtandao ina seti ya violesura, jedwali za kuelekeza, na sheria za NetFilter ambazo zimetengwa kutoka kwa vitu sawa katika neti zingine. Kila mchakato unaendeshwa katika nafasi fulani ya majina, na ni vitu vya neti hizi pekee vinavyopatikana kwake. Kwa chaguo-msingi, mfumo una nafasi moja ya majina ya mtandao kwa vitu vyote, kwa hivyo unaweza kufanya kazi kwenye Linux na usijue kuhusu neti.
Hebu tuunde nafasi mpya ya majina xdp-test na kuhamia huko xdp-remote.
ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test
Kisha mchakato unaendelea xdp-test, si "kuona" xdp-local (itabaki kwenye neti kwa chaguo-msingi) na wakati wa kutuma pakiti kwa 192.0.2.1 itaipitisha. xdp-remote, kwa sababu hiyo ndiyo kiolesura pekee katika 192.0.2.0/24 kinachopatikana kwa mchakato huu. Hii pia inafanya kazi kinyume chake.
Wakati wa kusonga kati ya neti, kiolesura huenda chini na kupoteza anwani. Ili kusanidi kiolesura katika netns, unahitaji kukimbia ip ... katika nafasi hii ya majina ya amri ip netns exec:
ip netns exec xdp-test
ip address add 192.0.2.2/24 dev xdp-remote
ip netns exec xdp-test
ip link set xdp-remote up
Kama unaweza kuona, hii sio tofauti na mpangilio xdp-local katika nafasi ya majina chaguomsingi:
ip address add 192.0.2.1/24 dev xdp-local
ip link set xdp-local up
Ikiwa kukimbia tcpdump -tnevi xdp-local, unaweza kuona kwamba pakiti zimetumwa kutoka xdp-test, huwasilishwa kwa kiolesura hiki:
ip netns exec xdp-test ping 192.0.2.1
Ni rahisi kuendesha ganda ndani xdp-test. Hifadhi ina hati inayofanya kazi otomatiki na msimamo, kwa mfano, unaweza kusanidi kisima na amri. sudo ./stand up na kuiondoa sudo ./stand down.
kufuatilia
Kichujio kimeunganishwa kwenye kifaa kama hii:
ip -force link set dev xdp-local xdp object xdp_filter.o verbose
Muhimu -force inahitajika kuunganisha programu mpya ikiwa nyingine tayari imeunganishwa. "Hakuna habari ni habari njema" sio juu ya amri hii, matokeo yake ni mengi. onyesha verbose hiari, lakini nayo ripoti juu ya kazi ya kithibitishaji nambari na orodha ya mkusanyaji inaonekana:
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
Ondoa programu kutoka kwa kiolesura:
ip link set dev xdp-local xdp off
Katika hati, hizi ni amri sudo ./stand attach и sudo ./stand detach.
Kwa kufunga kichujio, unaweza kuhakikisha kuwa ping inaendelea kufanya kazi, lakini je, programu inafanya kazi? Hebu tuongeze nembo. Kazi bpf_trace_printk() sawa na printf(), lakini inaauni hadi hoja tatu pekee isipokuwa mchoro, na orodha ndogo ya vibainishi. Jumla bpf_printk() kurahisisha simu.
Kwa sababu hii, pato la utatuzi huzuia sana nambari inayotokana.
Inatuma pakiti za XDP
Wacha tubadilishe kichungi: iruhusu itume pakiti zote zinazoingia. Hii sio sahihi kutoka kwa mtazamo wa mtandao, kwani itakuwa muhimu kubadili anwani kwenye vichwa, lakini sasa kazi kwa kanuni ni muhimu.
Uzinduzi tcpdump juu ya xdp-remote. Inapaswa kuonyesha Ombi sawa la ICMP Echo linalotoka na linaloingia na kuacha kuonyesha Jibu la ICMP Echo. Lakini haionyeshi. Inageuka kufanya kazi XDP_TX katika programu ya xdp-localinahitajikaili kuoanisha kiolesura xdp-remote programu pia ilipewa, hata ikiwa ilikuwa tupu, na iliinuliwa.
Nilijuaje?
Kufuatilia njia ya kifurushi kwenye kernel utaratibu wa matukio ya perf huruhusu, kwa njia, kutumia mashine hiyo hiyo ya kawaida, yaani, eBPF inatumika kwa disassembly na eBPF.
Ni lazima ufanye wema kutokana na ubaya, kwa sababu hakuna kitu kingine cha kufanya.
Ikiwa ARP pekee ndiyo itaonyeshwa badala yake, unahitaji kuondoa vichujio (hii hufanya sudo ./stand detach), acha ping, kisha usakinishe vichujio na ujaribu tena. Tatizo ni kwamba chujio XDP_TX huathiri ARP pia, na ikiwa stack
nafasi za majina xdp-test imeweza "kusahau" anwani ya MAC 192.0.2.1, hataweza kutatua IP hii.
Taarifa ya tatizo
Wacha tuendelee kwenye kazi iliyotajwa: kuandika utaratibu wa kuki wa SYN kwenye XDP.
Hadi sasa, mafuriko ya SYN bado ni shambulio maarufu la DDoS, kiini chake ni kama ifuatavyo. Muunganisho unapoanzishwa (TCP handshake), seva hupokea SYN, hutenga rasilimali kwa muunganisho wa siku zijazo, hujibu kwa pakiti ya SYNACK, na kusubiri ACK. Mshambulizi hutuma tu pakiti za SYN kutoka kwa anwani ghushi kwa kiasi cha maelfu kwa sekunde kutoka kwa kila seva pangishi katika boti ya maelfu mengi. Seva inalazimika kutenga rasilimali mara moja baada ya kuwasili kwa pakiti, lakini huifungua baada ya muda mrefu, kwa sababu hiyo, kumbukumbu au mipaka imechoka, viunganisho vipya havikubaliki, huduma haipatikani.
Ikiwa hutagawa rasilimali kwenye pakiti ya SYN, lakini jibu tu kwa pakiti ya SYNACK, basi seva inawezaje kuelewa kwamba pakiti ya ACK iliyokuja baadaye ni ya pakiti ya SYN ambayo haikuhifadhiwa? Baada ya yote, mshambuliaji anaweza pia kutoa ACKs bandia. Kiini cha kidakuzi cha SYN ni kusimba ndani seqnum vigezo vya uunganisho kama heshi ya anwani, bandari na kubadilisha chumvi. Ikiwa ACK imeweza kufika kabla ya chumvi kubadilika, unaweza kukokotoa heshi tena na kulinganisha na acknum. bandia acknum mshambulizi hawezi, kwa kuwa chumvi inajumuisha siri, na haitakuwa na muda wa kutatua kwa sababu ya njia ndogo.
Vidakuzi vya SYN vimetekelezwa kwenye kinu cha Linux kwa muda mrefu na vinaweza kuwashwa kiotomatiki ikiwa SYN zitafika haraka sana na kwa wingi.
Mpango wa elimu juu ya TCP handshake
TCP hutoa uhamisho wa data kama mtiririko wa baiti, kwa mfano, maombi ya HTTP hupitishwa kupitia TCP. Mkondo hupitishwa kipande kwa kipande katika pakiti. Pakiti zote za TCP zina bendera za kimantiki na nambari za mlolongo wa 32-bit:
Mchanganyiko wa bendera hufafanua jukumu la kifurushi fulani. Alama ya SYN inamaanisha kuwa hii ndiyo pakiti ya kwanza ya mtumaji kwenye muunganisho. Alama ya ACK inamaanisha kuwa mtumaji amepokea data yote ya muunganisho hadi baiti. acknum. Pakiti inaweza kuwa na bendera kadhaa na inaitwa baada ya mchanganyiko wao, kwa mfano, pakiti ya SYNACK.
Nambari ya mfuatano (seqnum) inabainisha suluhu katika mtiririko wa data kwa baiti ya kwanza inayotumwa katika pakiti hii. Kwa mfano, ikiwa katika pakiti ya kwanza yenye ka X za data nambari hii ilikuwa N, katika pakiti inayofuata na data mpya itakuwa N+X. Mwanzoni mwa simu, kila upande huchagua nambari hii kwa nasibu.
Nambari ya kukiri (acknum) - kukabiliana sawa na seqnum, lakini haijui idadi ya byte iliyopitishwa, lakini idadi ya byte ya kwanza kutoka kwa mpokeaji, ambayo mtumaji hakuiona.
Mwanzoni mwa uunganisho, wahusika lazima wakubaliane seqnum и acknum. Mteja hutuma pakiti ya SYN na yake seqnum = X. Seva hujibu kwa pakiti ya SYNACK, ambapo huandika yake seqnum = Y na kufichua acknum = X + 1. Mteja anajibu SYNACK na pakiti ya ACK, ambapo seqnum = X + 1, acknum = Y + 1. Baada ya hapo, uhamisho halisi wa data huanza.
Ikiwa interlocutor haitambui kupokea pakiti, TCP huituma tena kwa muda.
Kwa nini vidakuzi vya SYN hazitumiwi kila wakati?
Kwanza, ikiwa SYNACK au ACK imepotea, itabidi ungojee kutuma tena - uanzishaji wa unganisho unapungua. Pili, kwenye pakiti ya SYN - na ndani yake tu! - idadi ya chaguzi hupitishwa zinazoathiri uendeshaji zaidi wa uunganisho. Bila kukumbuka pakiti zinazoingia za SYN, seva hupuuza chaguo hizi, katika pakiti zifuatazo mteja hatazituma tena. TCP inaweza kufanya kazi katika kesi hii, lakini angalau katika hatua ya awali, ubora wa uunganisho utapungua.
Kwa upande wa vifurushi, programu ya XDP inapaswa kufanya yafuatayo:
jibu SYN kwa SYNACK na kuki;
jibu ACK na RST (vunja unganisho);
kuacha pakiti nyingine.
Pseudocode ya algorithm pamoja na uchanganuzi wa pakiti:
Если это не Ethernet,
пропустить пакет.
Если это не IPv4,
пропустить пакет.
Если адрес в таблице проверенных, (*)
уменьшить счетчик оставшихся проверок,
пропустить пакет.
Если это не TCP,
сбросить пакет. (**)
Если это SYN,
ответить SYN-ACK с cookie.
Если это ACK,
если в acknum лежит не cookie,
сбросить пакет.
Занести в таблицу адрес с N оставшихся проверок. (*)
Ответить RST. (**)
В остальных случаях сбросить пакет.
Moja (*) pointi ambapo unahitaji kudhibiti hali ya mfumo ni alama - katika hatua ya kwanza, unaweza kufanya bila wao kwa tu kutekeleza TCP handshake na kuzalisha SYN kuki kama seqnum.
Kwenye tovuti (**), wakati hatuna meza, tutaruka pakiti.
Utekelezaji wa kupeana mkono wa TCP
Uchanganuzi wa kifurushi na uthibitishaji wa msimbo
Tunahitaji miundo ya kichwa cha mtandao: Ethernet (uapi/linux/if_ether.h), IPv4 (uapi/linux/ip.h) na TCP (uapi/linux/tcp.h) Ya mwisho sikuweza kuunganisha kwa sababu ya makosa yanayohusiana nayo atomic64_t, ilinibidi kunakili ufafanuzi unaohitajika kwenye nambari.
Vipengele vyote vya kukokotoa ambavyo vimebainishwa katika C kwa kusomeka lazima ziwekwe kwenye tovuti ya simu, kwa kuwa kithibitishaji cha eBPF kwenye kernel kinakataza kuruka nyuma, ambayo ni, kwa kweli, vitanzi na simu za utendaji.
Macro LOG() inalemaza uchapishaji katika muundo wa toleo.
Mpango huo ni bomba la kazi. Kila mmoja hupokea pakiti ambayo kichwa cha kiwango kinacholingana kinasisitizwa, kwa mfano, process_ether() kusubiri kujazwa ether. Kulingana na matokeo ya uchambuzi wa shamba, kazi inaweza kuhamisha pakiti hadi ngazi ya juu. Matokeo ya chaguo za kukokotoa ni kitendo cha XDP. Wakati vidhibiti vya SYN na ACK vinaruhusu pakiti zote kupitia.
Ninatilia maanani ukaguzi uliowekwa alama A na B. Ikiwa utatoa maoni A, programu itaundwa, lakini kutakuwa na hitilafu ya uthibitishaji wakati wa kupakia:
Kamba muhimu invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0): kuna njia za utekelezaji wakati baiti ya kumi na tatu kutoka mwanzo wa bafa iko nje ya pakiti. Ni ngumu kutofautisha kutoka kwa tangazo ni mstari gani tunazungumza, lakini kuna nambari ya maagizo (12) na kitenganisha kinachoonyesha mistari ya msimbo wa chanzo:
ambayo inaweka wazi kuwa tatizo ni ether. Ingekuwa hivyo kila wakati.
Jibu kwa SYN
Lengo katika hatua hii ni kutoa pakiti sahihi ya SYNACK na fasta seqnum, ambayo nafasi yake itachukuliwa na kidakuzi cha SYN katika siku zijazo. Mabadiliko yote hufanyika ndani process_tcp_syn() na mazingira.
Kuangalia kifurushi
Cha ajabu, hapa kuna mstari wa kushangaza zaidi, au tuseme, maoni yake:
Wakati wa kuandika toleo la kwanza la msimbo, kernel 5.1 ilitumiwa, kwa uthibitishaji ambao kulikuwa na tofauti kati ya data_end и (const void*)ctx->data_end. Wakati wa kuandika, 5.3.1 kernel haikuwa na shida hii. Labda mkusanyaji alikuwa akipata utofauti wa ndani tofauti na uwanja. Maadili - kwenye kiota kikubwa, kurahisisha kanuni inaweza kusaidia.
Ukaguzi zaidi wa kawaida wa urefu kwa utukufu wa kithibitishaji; O MAX_CSUM_BYTES chini.
Badili bandari za TCP, IP na anwani za MAC. Maktaba ya kawaida haipatikani kutoka kwa programu ya XDP, kwa hivyo memcpy() - macro ambayo huficha ndani ya Clang.
IPv4 na TCP checksums zinahitaji kuongezwa kwa maneno yote 16-bit kwenye vichwa, na ukubwa wa vichwa umeandikwa ndani yao, yaani, wakati wa kukusanya haijulikani. Hili ni tatizo kwa sababu kithibitishaji hakitaruka kitanzi cha kawaida hadi utofauti wa mpaka. Lakini ukubwa wa vichwa ni mdogo: hadi 64 bytes kila mmoja. Unaweza kutengeneza kitanzi na nambari maalum ya kurudia, ambayo inaweza kumaliza mapema.
Nakumbuka kuwa kuna RFC 1624 kuhusu jinsi ya kuhesabu tena cheki kwa sehemu ikiwa tu maneno ya kudumu ya pakiti yanabadilishwa. Walakini, njia hiyo sio ya ulimwengu wote, na utekelezaji itakuwa ngumu zaidi kudumisha.
Kazi ya kuhesabu Checksum:
#define MAX_CSUM_WORDS 32
#define MAX_CSUM_BYTES (MAX_CSUM_WORDS * 2)
INTERNAL u32
sum16(const void* data, u32 size, const void* data_end) {
u32 s = 0;
#pragma unroll
for (u32 i = 0; i < MAX_CSUM_WORDS; i++) {
if (2*i >= size) {
return s; /* normal exit */
}
if (data + 2*i + 1 + 1 > data_end) {
return 0; /* should be unreachable */
}
s += ((const u16*)data)[i];
}
return s;
}
Ingawa size kuangaliwa na msimbo wa kupiga simu, hali ya pili ya kuondoka ni muhimu ili mthibitishaji aweze kuthibitisha mwisho wa kitanzi.
Kwa maneno 32-bit, toleo rahisi zaidi linatekelezwa:
INTERNAL u32
sum16_32(u32 v) {
return (v >> 16) + (v & 0xffff);
}
Kwa kweli kuhesabu upya hundi na kutuma pakiti nyuma:
Kazi carry() hufanya hundi kutoka kwa jumla ya 32-bit ya maneno 16-bit, kulingana na RFC 791.
TCP kuangalia handshake
Kichujio huanzisha muunganisho kwa usahihi netcat, kuruka ACK ya mwisho, ambayo Linux ilijibu kwa pakiti ya RST, kwa kuwa stack ya mtandao haikupokea SYN - ilibadilishwa kuwa SYNACK na kurudishwa - na kutoka kwa mtazamo wa OS, pakiti ilifika ambayo haikuwa. kuhusiana na miunganisho wazi.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
Ni muhimu kuangalia na maombi kamili na uangalie tcpdump juu ya xdp-remote kwa sababu, kwa mfano, hping3 haijibu hesabu zisizo sahihi.
Kidakuzi cha SYN
Kwa mtazamo wa XDP, cheki yenyewe ni ndogo. Kanuni ya kukokotoa ni ya awali na pengine inaweza kuathiriwa na mshambulizi mahiri. Kiini cha Linux, kwa mfano, kinatumia SipHash ya kriptografia, lakini utekelezaji wake kwa XDP ni wazi zaidi ya upeo wa makala hii.
Imeonekana kwa TODO mpya zinazohusiana na mwingiliano wa nje:
Mpango wa XDP hauwezi kuhifadhi cookie_seed (sehemu ya siri ya chumvi) katika utofauti wa kimataifa, unahitaji duka la kernel ambalo thamani yake itasasishwa mara kwa mara kutoka kwa jenereta inayoaminika.
Ikiwa kidakuzi cha SYN katika pakiti ya ACK kinalingana, huhitaji kuchapisha ujumbe, lakini kumbuka IP ya mteja aliyeidhinishwa ili kuruka zaidi pakiti kutoka kwayo.
Maadamu hakuna orodha ya IP zilizoangaliwa, hakutakuwa na ulinzi dhidi ya mafuriko ya SYN yenyewe, lakini hapa kuna majibu ya mafuriko ya ACK yaliyozinduliwa na amri hii:
sudo ip netns exec xdp-test hping3 --flood -A -s 1111 -p 2222 192.0.2.1
Wakati mwingine eBPF kwa ujumla na XDP haswa huwasilishwa kama zana ya msimamizi wa hali ya juu kuliko jukwaa la ukuzaji. Hakika, XDP ni zana ya kuingilia uchakataji wa pakiti za kernel, na sio mbadala wa mkusanyiko wa kernel, kama DPDK na chaguzi zingine za bypass kernel. Kwa upande mwingine, XDP hukuruhusu kutekeleza mantiki ngumu, ambayo, zaidi ya hayo, ni rahisi kusasisha bila pause katika usindikaji wa trafiki. Kithibitishaji hakileti shida kubwa, kibinafsi singekataa vile kwa sehemu za nambari ya nafasi ya mtumiaji.
Katika sehemu ya pili, ikiwa mada inavutia, tutakamilisha jedwali la wateja walioidhinishwa na kuvunja miunganisho, kutekeleza vihesabio na kuandika matumizi ya nafasi ya mtumiaji ili kudhibiti kichungi.