Peb tab tom sau kev tiv thaiv DDoS tawm tsam ntawm XDP. Nuclear ib feem
eXpress Data Path (XDP) thev naus laus zis tso cai rau kev ua lag luam random ua rau ntawm Linux interfaces ua ntej cov pob ntawv nkag mus rau hauv cov ntsiav tshuaj network. Daim ntawv thov XDP - tiv thaiv DDoS tawm tsam (CloudFlare), cov ntxaij lim dej nyuaj, kev sau txheeb cais (Netflix). XDP cov kev pab cuam raug tua los ntawm eBPF lub tshuab virtual, yog li lawv muaj kev txwv rau ob qho tib si lawv cov cai thiab cov khoom siv muaj nyob ntawm seb hom lim.
Tsab ntawv no yog npaj los ua kom tiav qhov tsis txaus ntawm ntau cov ntaub ntawv ntawm XDP. Ua ntej, lawv muab cov cai npaj ua ntej uas tam sim ntawd hla cov yam ntxwv ntawm XDP: nws tau npaj rau kev txheeb xyuas lossis yooj yim dhau los ua teeb meem. Thaum koj sim sau koj cov cai los ntawm kos, koj tsis muaj lub tswv yim yuav ua li cas nrog qhov tsis raug. Qhov thib ob, txoj hauv kev los sim XDP hauv zos yam tsis muaj VM thiab kho vajtse tsis raug them, txawm tias lawv muaj lawv tus kheej qhov teeb meem. Cov ntawv nyeem yog npaj rau cov programmers paub txog kev sib tham thiab Linux uas txaus siab rau XDP thiab eBPF.
Hauv seem no, peb yuav nkag siab meej tias XDP lim tau sib sau ua ke li cas thiab kuaj nws li cas, tom qab ntawd peb yuav sau cov qauv yooj yim ntawm cov txheej txheem SYN cov ncuav qab zib uas paub zoo ntawm cov txheej txheem ntim khoom. Peb yuav tsis tsim "dawb daim ntawv teev npe" tseem
cov neeg tau txais kev pom zoo, khaws cov txee thiab tswj xyuas cov lim dej - cov ntaub ntawv txaus.
Peb yuav sau hauv C - nws tsis yog fashionable, tab sis nws yog tswv yim. Tag nrho cov cai muaj nyob rau ntawm GitHub ntawm qhov txuas ntawm qhov kawg thiab muab faib ua kev cog lus raws li cov theem tau piav qhia hauv tsab xov xwm.
Kev tsis lees paub. Nyob rau hauv cov ntaub ntawv no, kuv yuav tsim ib tug mini-kev daws teeb meem los tiv thaiv DDoS tawm tsam, vim hais tias qhov no yog ib tug tiag tiag txoj hauj lwm rau XDP thiab kuv cheeb tsam ntawm kev txawj ntse. Txawm li cas los xij, lub hom phiaj tseem ceeb yog kom nkag siab txog thev naus laus zis; qhov no tsis yog phau ntawv qhia los tsim kev tiv thaiv npaj txhij. Cov lus qhia code tsis zoo thiab tshem tawm qee qhov nuances.
Yog li, lim code yog loaded rau hauv lub ntsiav. Cov pob khoom tuaj raug xa mus rau lub lim. Yog li ntawd, lub lim yuav tsum txiav txim siab: hla lub pob ntawv rau hauv cov ntsiav (XDP_PASS), poob pob ntawv (XDP_DROP) lossis xa rov qab (XDP_TX). Cov lim tuaj yeem hloov lub pob, qhov no yog qhov tseeb tshwj xeeb rau XDP_TX. Koj tseem tuaj yeem rho tawm qhov program (XDP_ABORTED) thiab pib dua lub pob, tab sis qhov no yog qhov sib piv assert(0) - rau kev debugging.
Lub eBPF (extended Berkley Packet Filter) lub tshuab virtual yog txhob txwm ua kom yooj yim kom cov ntsiav tuaj yeem tshawb xyuas tias cov cai tsis voj thiab tsis ua rau lwm tus neeg lub cim xeeb. Kev txwv ntau thiab kev kuaj xyuas:
Tsuas yog hu rau cov haujlwm tshwj xeeb kernel (eBPF pab) tau tso cai.
Tsim thiab txhim kho lub lim zoo li no:
Source code (eg kernel.c) muab tso ua ke rau hauv cov khoom (kernel.o) rau eBPF virtual tshuab architecture. Raws li lub Kaum Hlis 2019, muab tso ua ke rau eBPF tau txais kev txhawb nqa los ntawm Clang thiab tau cog lus hauv GCC 10.1.
Yog hais tias cov khoom code no muaj hu mus rau cov qauv kernel (piv txwv li, cov ntxhuav thiab cov txee), lawv cov ID yog hloov los ntawm xoom, uas txhais tau hais tias cov cai no tsis tuaj yeem ua tiav. Ua ntej thauj khoom rau hauv cov ntsiav, koj yuav tsum hloov cov lej no nrog cov IDs ntawm cov khoom tshwj xeeb tsim los ntawm cov xov tooj hu (txuas cov cai). Koj tuaj yeem ua qhov no nrog cov khoom siv hluav taws xob sab nraud, lossis koj tuaj yeem sau qhov program uas yuav txuas thiab thauj cov lim tshwj xeeb.
Lub kernel txheeb xyuas qhov kev pab cuam loaded. Qhov tsis muaj lub voj voog thiab tsis ua kom dhau ntawm pob ntawv thiab pawg ciam teb raug kuaj xyuas. Yog tias tus neeg kuaj xyuas tsis tuaj yeem ua pov thawj tias cov cai yog qhov tseeb, qhov kev zov me nyuam raug tsis lees paub - koj yuav tsum muaj peev xwm txaus siab rau nws.
Tom qab ua tiav kev pov thawj, lub kernel compiles eBPF architecture khoom code rau hauv tshuab code rau lub system architecture (tsuas yog-hauv-lub sijhawm).
Qhov kev pab cuam txuas mus rau lub interface thiab pib ua cov pob ntawv.
Txij li thaum XDP khiav hauv lub kernel, debugging yog nqa tawm siv cov ntaub ntawv taug qab thiab, qhov tseeb, pob ntawv uas qhov kev pab cuam lim lossis tsim. Txawm li cas los xij, eBPF ua kom ntseeg tau tias cov lej rub tawm muaj kev nyab xeeb rau lub kaw lus, yog li koj tuaj yeem sim nrog XDP ncaj qha ntawm koj lub zos Linux.
Npaj ib puag ncig
Sib dhos
Clang tsis tuaj yeem tsim cov cai ncaj qha rau eBPF architecture, yog li cov txheej txheem muaj ob kauj ruam:
Compile C code rau LLVM bytecode (clang -emit-llvm).
# другая команда
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 txuas ib daim ntawv teev npe nrog pab pawg headers thiab ob peb phau ntawv nrog cov kernel headers. Cim __KERNEL__ txhais tau hais tias UAPI (userspace API) headers yog txhais rau kernel code, txij li thaum lub lim raug tua nyob rau hauv lub kernel.
Kev tiv thaiv pawg tuaj yeem raug kaw (-fno-stack-protector), vim tias eBPF code verifier tseem kuaj xyuas cov kev ua txhaum cai ntawm pawg. Nws tsim nyog tig rau kev ua kom zoo tam sim ntawd, vim tias qhov loj ntawm eBPF bytecode raug txwv.
Cia peb pib nrog lub lim uas hla tag nrho cov pob ntawv thiab tsis muaj dab tsi:
pab neeg make sau xdp_filter.o. Tam sim no sim qhov twg?
Test sawv
Lub chaw muag khoom yuav tsum muaj ob lub interfaces: ntawm qhov uas yuav muaj lub lim dej thiab los ntawm cov pob ntawv twg yuav raug xa mus. Cov no yuav tsum yog tag nrho cov khoom siv Linux nrog lawv tus kheej IPs txhawm rau txheeb xyuas seb cov ntawv thov ua haujlwm li cas nrog peb cov lim dej.
Devices ntawm veth (virtual Ethernet) hom yog haum rau peb: cov no yog ib khub ntawm virtual network interfaces "txuas" ncaj qha rau ib leeg. Koj tuaj yeem tsim lawv zoo li no (hauv ntu no tag nrho cov lus txib ip yog ua los ntawm root):
ip link add xdp-remote type veth peer name xdp-local
nws yog xdp-remote и xdp-local - cov npe khoom siv. Ntawm xdp-local (192.0.2.1/24) lub lim yuav txuas nrog, nrog xdp-remote (192.0.2.2/24) cov tsheb thauj mus los yuav raug xa mus. Txawm li cas los xij, muaj ib qho teeb meem: cov interfaces nyob rau tib lub tshuab, thiab Linux yuav tsis xa tsheb mus rau ib qho ntawm lawv mus rau lwm qhov. Koj tuaj yeem daws qhov no nrog cov cai tsis yooj yim iptables, tab sis lawv yuav tau hloov cov pob khoom, uas tsis yooj yim rau kev debugging. Nws yog qhov zoo dua los siv network namespaces (tom qab no netns).
Lub network namespace muaj cov txheej txheem kev sib txuas, cov rooj sib tham, thiab NetFilter cov cai uas raug cais tawm ntawm cov khoom zoo sib xws hauv lwm cov netns. Txhua tus txheej txheem khiav hauv lub npe chaw thiab tsuas yog nkag mus rau cov khoom ntawm cov netns ntawd. Los ntawm lub neej ntawd, lub kaw lus muaj ib lub network namespace rau txhua yam khoom, yog li koj tuaj yeem ua haujlwm hauv Linux thiab tsis paub txog netns.
Cia peb tsim lub npe tshiab xdp-test thiab txav mus rau ntawd xdp-remote.
ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test
Ces tus txheej txheem khiav hauv xdp-test, yuav tsis "pom" xdp-local (nws yuav nyob twj ywm hauv netns los ntawm lub neej ntawd) thiab thaum xa ib pob ntawv rau 192.0.2.1 nws yuav dhau los ntawm xdp-remotevim nws yog tib lub interface ntawm 192.0.2.0/24 nkag mus rau cov txheej txheem no. Qhov no kuj ua hauj lwm nyob rau hauv qhov opposite direction.
Thaum tsiv ntawm netns, lub interface poob thiab poob nws qhov chaw nyob. Txhawm rau teeb tsa lub interface hauv netns, koj yuav tsum khiav ip ... hauv no command namespace 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
Raws li koj tuaj yeem pom, qhov no tsis txawv ntawm qhov chaw xdp-local nyob rau hauv lub default namespace:
ip address add 192.0.2.1/24 dev xdp-local
ip link set xdp-local up
Yog koj khiav tcpdump -tnevi xdp-local, koj tuaj yeem pom tias pob ntawv xa los ntawm xdp-test, yog xa mus rau qhov interface no:
ip netns exec xdp-test ping 192.0.2.1
Nws yog qhov yooj yim los tso lub plhaub rau hauv xdp-test. Lub chaw cia khoom muaj ib tsab ntawv uas automates ua haujlwm nrog lub chaw muag khoom; piv txwv li, koj tuaj yeem teeb tsa qhov muag nrog cov lus txib sudo ./stand up thiab rho tawm nws sudo ./stand down.
Tracing
Lub lim yog txuam nrog cov cuab yeej zoo li no:
ip -force link set dev xdp-local xdp object xdp_filter.o verbose
Ntsiab -force xav tau los txuas ib qhov kev pab cuam tshiab yog tias lwm tus twb tau txuas lawm. "Tsis muaj xov xwm yog xov xwm zoo" tsis yog hais txog cov lus txib no, qhov xaus yog voluminous nyob rau hauv txhua rooj plaub. qhia verbose xaiv tau, tab sis nrog nws ib tsab ntawv ceeb toom tshwm nyob rau hauv kev ua hauj lwm ntawm tus code verifier nrog ib tug sib sau npe teev:
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
Unlink qhov kev pab cuam los ntawm lub interface:
ip link set dev xdp-local xdp off
Hauv tsab ntawv no yog cov lus txib sudo ./stand attach и sudo ./stand detach.
Vim li no, debug tso zis heev bloats lub resulting code.
Xa XDP Packets
Cia peb hloov lub lim: cia nws xa rov qab tag nrho cov pob khoom tuaj. Qhov no yog qhov tsis raug los ntawm qhov kev xav hauv lub network, vim nws yuav tsim nyog hloov chaw nyob hauv cov ntsiab lus, tab sis tam sim no txoj haujlwm tseem ceeb.
Yog tias tsuas yog ARPs tau pom xwb, koj yuav tsum tshem tawm cov lim dej (qhov no ua sudo ./stand detach), cia mus ping, ces teeb cov lim thiab sim dua. Qhov teeb meem yog qhov lim XDP_TX siv rau ob qho tib si ARP thiab yog tias pawg
cov npe xdp-test tswj kom "tsis nco qab" MAC chaw nyob 192.0.2.1, nws yuav tsis tuaj yeem daws qhov IP no.
Nqe lus ntawm qhov teeb meem
Cia peb mus rau txoj haujlwm tau hais tseg: sau SYN ncuav qab zib mechanism ntawm XDP.
SYN dej nyab tseem yog qhov nrov DDoS nres, cov ntsiab lus ntawm cov hauv qab no. Thaum muaj kev sib txuas (TCP tuav tes), tus neeg rau zaub mov tau txais SYN, faib cov peev txheej rau kev sib txuas yav tom ntej, teb nrog SYNACK pob ntawv thiab tos ACK. Tus neeg tawm tsam tsuas yog xa ntau txhiab SYN pob ntawv ib ob los ntawm qhov chaw nyob spoofed los ntawm txhua tus tswv tsev hauv ntau txhiab-muaj zog botnet. Cov neeg rau zaub mov raug yuam kom faib cov peev txheej tam sim ntawd thaum tuaj txog ntawm pob ntawv, tab sis tso tawm tom qab lub sijhawm loj; vim li ntawd, nco lossis txwv tsis pub dhau, kev sib txuas tshiab tsis tau txais, thiab cov kev pabcuam tsis muaj.
Yog tias koj tsis faib cov peev txheej raws li SYN pob ntawv, tab sis tsuas yog teb nrog pob ntawv SYNACK, yuav ua li cas tus neeg rau zaub mov nkag siab tias ACK pob ntawv uas tuaj txog tom qab yog hais txog SYN pob ntawv uas tsis tau txais kev cawmdim? Tom qab tag nrho, tus neeg tawm tsam tuaj yeem tsim cov ACKs cuav. Lub ntsiab lus ntawm SYN ncuav qab zib yog encode nws seqnum kev twb kev txuas tsis raws li ib tug hash ntawm chaw nyob, ports thiab hloov ntsev. Yog tias ACK tswj tuaj txog ua ntej cov ntsev hloov pauv, koj tuaj yeem suav cov hash dua thiab muab piv nrog acknum. Forge acknum tus neeg tawm tsam tsis tuaj yeem, txij li cov ntsev suav nrog qhov zais cia, thiab yuav tsis muaj sijhawm los txheeb xyuas nws vim qhov txwv channel.
Lub SYN ncuav qab zib tau ntev tau siv nyob rau hauv Linux ntsiav thiab tuaj yeem qhib tau txawm tias SYNs tuaj txog sai heev thiab ntau.
Kev kawm txuj ci ntawm TCP tuav tes
TCP muab cov ntaub ntawv xa mus raws li cov kwj ntawm bytes, piv txwv li, HTTP thov raug xa mus rau TCP. Cov kwj deg yog xa mus rau hauv daim hauv pob ntawv. Tag nrho cov pob ntawv TCP muaj cov cim cim thiab 32-ntsis kab zauv:
Kev sib xyaw ntawm cov chij txiav txim siab lub luag haujlwm ntawm ib pob tshwj xeeb. Tus chij SYN qhia tias qhov no yog tus xa khoom thawj pob khoom ntawm kev sib txuas. Tus chij ACK txhais tau hais tias tus neeg xa khoom tau txais tag nrho cov ntaub ntawv txuas mus txog byte acknum. Ib pob ntawv tuaj yeem muaj ntau tus chij thiab raug hu los ntawm lawv qhov sib xyaw ua ke, piv txwv li, pob ntawv SYNACK.
Sequence naj npawb (seqnum) qhia txog qhov offset nyob rau hauv cov ntaub ntawv kwj rau thawj byte uas kis tau nyob rau hauv lub pob ntawv no. Piv txwv li, yog tias hauv thawj pob ntawv nrog X bytes ntawm cov ntaub ntawv tus lej no yog N, hauv pob ntawv tom ntej nrog cov ntaub ntawv tshiab nws yuav yog N + X. Thaum pib ntawm kev sib txuas, txhua sab xaiv tus lej no randomly.
Kev lees paub tus lej (acknum) - tib yam offset raws li seqnum, tab sis nws tsis txiav txim siab tus lej ntawm byte raug xa mus, tab sis tus naj npawb ntawm thawj byte los ntawm tus neeg tau txais, uas tus xa tsis pom.
Thaum pib ntawm kev sib txuas, ob tog yuav tsum pom zoo seqnum и acknum. Tus neeg siv khoom xa SYN pob ntawv nrog nws seqnum = X. Cov neeg rau zaub mov teb nrog SYNACK pob ntawv, qhov twg nws sau nws seqnum = Y thiab nthuav tawm acknum = X + 1. Tus neeg siv khoom teb rau SYNACK nrog ACK pob ntawv, qhov twg seqnum = X + 1, acknum = Y + 1. Tom qab no, qhov tseeb cov ntaub ntawv hloov chaw pib.
Yog tias tus phooj ywg tsis lees paub qhov tau txais ntawm pob ntawv, TCP rov xa nws tom qab lub sijhawm.
Vim li cas SYN ncuav qab zib tsis siv tas li?
Ua ntej, yog tias SYNACK lossis ACK ploj lawm, koj yuav tsum tau tos kom nws xa rov qab - kev teeb tsa kev sib txuas yuav qeeb. Thib ob, hauv pob SYN - thiab tsuas yog hauv nws! - Ntau qhov kev xaiv raug xa mus uas cuam tshuam rau kev ua haujlwm ntxiv ntawm kev sib txuas. Yog tias tsis nco qab cov pob ntawv SYN tuaj, tus neeg rau zaub mov yog li tsis quav ntsej cov kev xaiv no; tus neeg siv yuav tsis xa lawv mus rau hauv cov pob ntawv tom ntej. TCP tuaj yeem ua haujlwm nyob rau hauv rooj plaub no, tab sis tsawg kawg ntawm thawj theem qhov zoo ntawm kev sib txuas yuav txo qis.
Los ntawm kev pom pob khoom, ib qho kev pab cuam XDP yuav tsum ua cov hauv qab no:
teb rau SYN nrog SYNACK nrog lub ncuav qab zib;
teb rau ACK nrog RST (disconnect);
pov tseg cov pob ntawv ntxiv.
Pseudocode ntawm lub algorithm nrog rau pob parsing:
Если это не Ethernet,
пропустить пакет.
Если это не IPv4,
пропустить пакет.
Если адрес в таблице проверенных, (*)
уменьшить счетчик оставшихся проверок,
пропустить пакет.
Если это не TCP,
сбросить пакет. (**)
Если это SYN,
ответить SYN-ACK с cookie.
Если это ACK,
если в acknum лежит не cookie,
сбросить пакет.
Занести в таблицу адрес с N оставшихся проверок. (*)
Ответить RST. (**)
В остальных случаях сбросить пакет.
Ib (*) cov ntsiab lus uas koj xav tau los tswj lub xeev ntawm lub kaw lus raug cim - thawj theem koj tuaj yeem ua yam tsis muaj lawv los ntawm kev siv TCP tuav tes nrog lub cim ntawm SYN ncuav qab zib ua seqnum.
Ntawm qhov chaw (**), thaum peb tsis muaj lub rooj, peb yuav hla lub pob ntawv.
Tag nrho cov haujlwm uas tau hais tseg hauv C rau kev nyeem tau yuav tsum tau sau rau ntawm qhov chaw hu, vim tias eBPF tus neeg txheeb xyuas hauv lub ntsiav txwv tsis pub rov qab los, qhov tseeb, lub voj voog thiab kev ua haujlwm hu.
uas ua kom pom tseeb tias qhov teeb meem yog ether. Nws yeej yuav zoo li no.
Teb rau SYN
Lub hom phiaj ntawm theem no yog tsim kom muaj ib pob ntawv SYNACK kom raug nrog rau qhov ruaj khov seqnum, uas yuav raug hloov yav tom ntej los ntawm SYN ncuav qab zib. Txhua qhov kev hloov pauv tshwm sim hauv process_tcp_syn() thiab thaj chaw ib puag ncig.
Pob ntawv pov thawj
Oddly txaus, ntawm no yog cov kab lus zoo tshaj plaws, lossis theej, cov lus hais rau nws:
IPv4 thiab TCP checksums xav tau qhov sib ntxiv ntawm tag nrho 16-ntsis cov lus nyob rau hauv headers, thiab qhov luaj li cas ntawm headers yog sau rau hauv lawv, uas yog, tsis paub thaum compile lub sij hawm. Qhov no yog ib qho teeb meem vim hais tias tus neeg txheeb xyuas yuav tsis hla lub voj voog ib txwm mus rau qhov sib txawv ntawm ciam teb. Tab sis qhov loj ntawm headers yog txwv: mus txog 64 bytes txhua. Koj tuaj yeem ua ib lub voj nrog ib tus naj npawb ntawm iterations, uas tuaj yeem xaus ntxov.
Kuv nco ntsoov tias muaj RFC 1624 hais txog yuav ua li cas rov xam ib nrab ntawm cov checksum yog tias tsuas yog cov lus ruaj khov ntawm cov pob khoom raug hloov. Txawm li cas los xij, txoj kev tsis yog universal, thiab kev siv yuav nyuaj dua los tswj.
Checksum xam muaj nuj nqi:
#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;
}
Txawm tias size txheeb xyuas los ntawm kev hu xov tooj, qhov kev tawm thib ob yog qhov tsim nyog kom tus neeg txheeb xyuas tuaj yeem ua pov thawj qhov ua tiav ntawm lub voj.
muaj nuj nqi carry() ua ib qho checksum los ntawm 32-ntsis suav ntawm 16-ntsis cov lus, raws li RFC 791.
TCP tes tuav pov thawj
Lub lim kom raug tsim kom muaj kev sib txuas nrog netcat, ploj lawm qhov kawg ACK, uas Linux tau teb nrog RST pob ntawv, txij li pawg network tsis tau txais SYN - nws tau hloov mus rau SYNACK thiab xa rov qab - thiab los ntawm OS qhov kev xav, pob ntawv tuaj txog uas tsis cuam tshuam rau qhib. kev sib txuas.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
Qhia rau TODOs tshiab ntsig txog kev sib txuas lus sab nraud:
XDP program tsis tuaj yeem khaws cia cookie_seed (qhov zais cia ntawm cov ntsev) nyob rau hauv lub ntiaj teb no sib txawv, koj yuav tsum tau cia nyob rau hauv lub ntsiav, tus nqi ntawm uas yuav tsum tau hloov kho raws sij hawm los ntawm ib tug txhim khu kev qha generator.
Yog tias SYN ncuav qab zib sib tw hauv pob ntawv ACK, koj tsis tas yuav luam cov lus, tab sis nco ntsoov tus IP ntawm tus neeg siv khoom tau lees paub txhawm rau txhawm rau txuas ntxiv cov pob ntawv los ntawm nws.