ProHoster > Blog > Pentadbiran > Kami menulis perlindungan terhadap serangan DDoS pada XDP. Bahagian nuklear
Kami menulis perlindungan terhadap serangan DDoS pada XDP. Bahagian nuklear
Teknologi Laluan Data eXpress (XDP) membenarkan pemprosesan trafik rawak dilakukan pada antara muka Linux sebelum paket memasuki timbunan rangkaian kernel. Aplikasi XDP - perlindungan terhadap serangan DDoS (CloudFlare), penapis kompleks, pengumpulan statistik (Netflix). Program XDP dilaksanakan oleh mesin maya eBPF, jadi ia mempunyai sekatan pada kedua-dua kod mereka dan fungsi kernel yang tersedia bergantung pada jenis penapis.
Artikel ini bertujuan untuk mengisi kekurangan banyak bahan di XDP. Pertama, mereka menyediakan kod siap pakai yang segera memintas ciri XDP: ia disediakan untuk pengesahan atau terlalu mudah untuk menimbulkan masalah. Apabila anda kemudian cuba menulis kod anda dari awal, anda tidak tahu apa yang perlu dilakukan dengan ralat biasa. Kedua, cara untuk menguji XDP secara tempatan tanpa VM dan perkakasan tidak dilindungi, walaupun pada hakikatnya mereka mempunyai perangkap mereka sendiri. Teks ini bertujuan untuk pengaturcara yang biasa dengan rangkaian dan Linux yang berminat dengan XDP dan eBPF.
Dalam bahagian ini, kami akan memahami secara terperinci bagaimana penapis XDP dipasang dan cara mengujinya, kemudian kami akan menulis versi ringkas mekanisme kuki SYN yang terkenal di peringkat pemprosesan paket. Kami tidak akan membuat "senarai putih" lagi
pelanggan yang disahkan, simpan kaunter dan uruskan penapis - log yang mencukupi.
Kami akan menulis dalam C - ia tidak bergaya, tetapi ia praktikal. Semua kod tersedia di GitHub melalui pautan di penghujung dan dibahagikan kepada komit mengikut peringkat yang diterangkan dalam artikel.
Penafian. Sepanjang artikel ini, saya akan membangunkan penyelesaian mini untuk menangkis serangan DDoS, kerana ini adalah tugas yang realistik untuk XDP dan bidang kepakaran saya. Walau bagaimanapun, matlamat utama adalah untuk memahami teknologi; ini bukan panduan untuk mencipta perlindungan sedia. Kod tutorial tidak dioptimumkan dan menghilangkan beberapa nuansa.
Gambaran Keseluruhan Ringkas XDP
Saya hanya akan menggariskan perkara-perkara penting sahaja supaya tidak menduplikasi dokumentasi dan artikel sedia ada.
Jadi, kod penapis dimuatkan ke dalam kernel. Paket masuk dihantar ke penapis. Akibatnya, penapis mesti membuat keputusan: hantar paket ke dalam kernel (XDP_PASS), drop paket (XDP_DROP) atau hantar semula (XDP_TX). Penapis boleh menukar pakej, ini terutama berlaku untuk XDP_TX. Anda juga boleh membatalkan program (XDP_ABORTED) dan tetapkan semula pakej, tetapi ini adalah analog assert(0) - untuk nyahpepijat.
Mesin maya eBPF (Extended Berkley Packet Filter) sengaja dibuat ringkas supaya kernel boleh menyemak sama ada kod tersebut tidak bergelung dan tidak merosakkan memori orang lain. Sekatan dan semakan kumulatif:
Gelung (ke belakang) adalah dilarang.
Terdapat timbunan untuk data, tetapi tiada fungsi (semua fungsi C mesti diselaraskan).
Akses memori di luar tindanan dan penimbal paket adalah dilarang.
Saiz kod adalah terhad, tetapi dalam amalan ini tidak begitu penting.
Hanya panggilan ke fungsi kernel khas (pembantu eBPF) dibenarkan.
Mereka bentuk dan memasang penapis kelihatan seperti ini:
Kod sumber (cth kernel.c) disusun menjadi objek (kernel.o) untuk seni bina mesin maya eBPF. Sehingga Oktober 2019, kompilasi kepada eBPF disokong oleh Clang dan dijanjikan dalam GCC 10.1.
Jika kod objek ini mengandungi panggilan ke struktur kernel (contohnya, jadual dan pembilang), ID mereka digantikan dengan sifar, yang bermaksud kod tersebut tidak boleh dilaksanakan. Sebelum memuatkan ke dalam kernel, anda perlu menggantikan sifar ini dengan ID objek tertentu yang dibuat melalui panggilan kernel (pautkan kod). Anda boleh melakukan ini dengan utiliti luaran, atau anda boleh menulis program yang akan memaut dan memuatkan penapis tertentu.
Kernel mengesahkan program yang dimuatkan. Ketiadaan kitaran dan kegagalan untuk melebihi sempadan paket dan tindanan diperiksa. Jika pengesah tidak dapat membuktikan bahawa kod itu betul, program itu ditolak - anda perlu dapat menggembirakannya.
Selepas pengesahan berjaya, kernel menyusun kod objek seni bina eBPF ke dalam kod mesin untuk seni bina sistem (tepat masa).
Program ini melekat pada antara muka dan mula memproses paket.
Memandangkan XDP berjalan dalam kernel, penyahpepijatan dijalankan menggunakan log surih dan, sebenarnya, paket yang ditapis atau dihasilkan oleh program. Walau bagaimanapun, eBPF memastikan bahawa kod yang dimuat turun adalah selamat untuk sistem, jadi anda boleh mencuba XDP secara langsung pada Linux tempatan anda.
Menyediakan Alam Sekitar
Perhimpunan
Clang tidak boleh terus menghasilkan kod objek untuk seni bina eBPF, jadi prosesnya terdiri daripada dua langkah:
Susun kod C kepada kod bait LLVM (clang -emit-llvm).
Tukar bytecode kepada kod objek eBPF (llc -march=bpf -filetype=obj).
Apabila menulis penapis, beberapa fail dengan fungsi tambahan dan makro akan berguna daripada ujian kernel. Adalah penting bahawa ia sepadan dengan versi kernel (KVER). Muat turunnya ke helpers/:
KDIR mengandungi laluan ke pengepala kernel, ARCH - seni bina sistem. Laluan dan alatan mungkin berbeza sedikit antara pengedaran.
Contoh perbezaan untuk 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 sambungkan direktori dengan pengepala tambahan dan beberapa direktori dengan pengepala kernel. Simbol __KERNEL__ bermakna pengepala UAPI (API ruang pengguna) ditakrifkan untuk kod kernel, kerana penapis dilaksanakan dalam kernel.
Perlindungan tindanan boleh dilumpuhkan (-fno-stack-protector), kerana pengesah kod eBPF masih menyemak pelanggaran timbunan di luar sempadan. Anda patut menghidupkan pengoptimuman dengan segera, kerana saiz kod bait eBPF adalah terhad.
Mari kita mulakan dengan penapis yang melepasi semua paket dan tidak melakukan apa-apa:
Pasukan make mengumpul xdp_filter.o. Di mana untuk mencubanya sekarang?
Tempat ujian
Pendirian mesti termasuk dua antara muka: yang akan ada penapis dan dari mana paket akan dihantar. Ini mestilah peranti Linux lengkap dengan IP mereka sendiri untuk menyemak cara aplikasi biasa berfungsi dengan penapis kami.
Peranti jenis veth (Ethernet maya) sesuai untuk kami: ini adalah sepasang antara muka rangkaian maya "disambungkan" terus antara satu sama lain. Anda boleh menciptanya seperti ini (dalam bahagian ini semua arahan ip dijalankan daripada root):
ip link add xdp-remote type veth peer name xdp-local
ia adalah xdp-remote и xdp-local — nama peranti. hidup xdp-local (192.0.2.1/24) penapis akan dilampirkan, dengan xdp-remote (192.0.2.2/24) trafik masuk akan dihantar. Walau bagaimanapun, terdapat masalah: antara muka berada pada mesin yang sama, dan Linux tidak akan menghantar trafik kepada salah satu daripada mereka melalui yang lain. Anda boleh menyelesaikannya dengan peraturan yang rumit iptables, tetapi mereka perlu menukar pakej, yang menyusahkan untuk penyahpepijatan. Adalah lebih baik untuk menggunakan ruang nama rangkaian (selepas ini netns).
Ruang nama rangkaian mengandungi satu set antara muka, jadual penghalaan dan peraturan NetFilter yang diasingkan daripada objek serupa dalam jaring lain. Setiap proses berjalan dalam ruang nama dan hanya mempunyai akses kepada objek jaring itu. Secara lalai, sistem mempunyai ruang nama rangkaian tunggal untuk semua objek, jadi anda boleh bekerja di Linux dan tidak tahu tentang jaring.
Mari buat ruang nama baharu xdp-test dan pindahkan ke sana xdp-remote.
ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test
Kemudian proses berjalan masuk xdp-test, tidak akan "melihat" xdp-local (ia akan kekal dalam netns secara lalai) dan apabila menghantar paket ke 192.0.2.1 ia akan melaluinya xdp-remotekerana ia adalah satu-satunya antara muka pada 192.0.2.0/24 yang boleh diakses untuk proses ini. Ini juga berfungsi dalam arah yang bertentangan.
Apabila bergerak antara jaring, antara muka turun dan kehilangan alamatnya. Untuk mengkonfigurasi antara muka dalam netns, anda perlu menjalankan ip ... dalam ruang nama arahan ini 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
Seperti yang anda lihat, ini tidak berbeza dengan tetapan xdp-local dalam ruang nama lalai:
ip address add 192.0.2.1/24 dev xdp-local
ip link set xdp-local up
Jika anda berlari tcpdump -tnevi xdp-local, anda boleh melihat bahawa paket dihantar dari xdp-test, dihantar ke antara muka ini:
ip netns exec xdp-test ping 192.0.2.1
Ia adalah mudah untuk melancarkan shell masuk xdp-test. Repositori mempunyai skrip yang mengautomasikan kerja dengan pendirian; sebagai contoh, anda boleh mengkonfigurasi dirian dengan arahan sudo ./stand up dan padamkannya sudo ./stand down.
Menjejak
Penapis dikaitkan dengan peranti seperti ini:
ip -force link set dev xdp-local xdp object xdp_filter.o verbose
Kunci -force diperlukan untuk memautkan program baharu jika program lain sudah dipautkan. "Tiada berita adalah berita baik" bukan mengenai arahan ini, kesimpulannya adalah besar dalam apa jua keadaan. menunjukkan verbose pilihan, tetapi dengannya laporan muncul pada kerja pengesah kod dengan penyenaraian pemasangan:
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
Nyahpaut program daripada antara muka:
ip link set dev xdp-local xdp off
Dalam skrip ini adalah arahan sudo ./stand attach и sudo ./stand detach.
Dengan melampirkan penapis, anda boleh memastikannya ping terus berjalan, tetapi adakah program ini berfungsi? Mari tambah log. Fungsi bpf_trace_printk() sama seperti printf(), tetapi hanya menyokong sehingga tiga argumen selain daripada corak dan senarai penentu yang terhad. Makro bpf_printk() memudahkan panggilan.
Atas sebab ini, keluaran nyahpepijat sangat membebankan kod yang terhasil.
Menghantar Paket XDP
Mari tukar penapis: biarkan ia menghantar semula semua paket masuk. Ini tidak betul dari sudut pandangan rangkaian, kerana ia adalah perlu untuk menukar alamat dalam pengepala, tetapi kini kerja pada dasarnya adalah penting.
Kami melancarkan tcpdump pada xdp-remote. Ia harus menunjukkan Permintaan Gema ICMP keluar dan masuk yang sama dan berhenti menunjukkan Balasan Gema ICMP. Tetapi ia tidak menunjukkan. Ternyata untuk kerja XDP_TX dalam program pada xdp-localperlukepada antara muka pasangan xdp-remote program juga telah ditetapkan, walaupun ia kosong, dan dia dibesarkan.
Bagaimana saya tahu ini?
Jejaki laluan pakej dalam kernel Mekanisme peristiwa perf membenarkan, dengan cara, menggunakan mesin maya yang sama, iaitu, eBPF digunakan untuk pembongkaran dengan eBPF.
Anda mesti membuat yang baik daripada yang jahat, kerana tidak ada apa-apa lagi untuk membuat daripadanya.
Jika hanya ARP yang ditunjukkan, anda perlu mengalih keluar penapis (ini tidak sudo ./stand detach), lepaskan ping, kemudian tetapkan penapis dan cuba lagi. Masalahnya ialah penapis XDP_TX sah kedua-duanya pada ARP dan jika timbunan
ruang nama xdp-test berjaya "melupakan" alamat MAC 192.0.2.1, ia tidak akan dapat menyelesaikan IP ini.
Pernyataan masalah
Mari kita beralih kepada tugas yang dinyatakan: tulis mekanisme kuki SYN pada XDP.
Banjir SYN kekal sebagai serangan DDoS yang popular, intipatinya adalah seperti berikut. Apabila sambungan diwujudkan (jabat tangan TCP), pelayan menerima SYN, memperuntukkan sumber untuk sambungan masa hadapan, bertindak balas dengan paket SYNACK dan menunggu ACK. Penyerang hanya menghantar beribu-ribu paket SYN sesaat daripada alamat palsu daripada setiap hos dalam botnet yang mempunyai seribu-ribu kuat. Pelayan terpaksa memperuntukkan sumber serta-merta selepas ketibaan paket, tetapi melepaskannya selepas tamat masa yang besar; akibatnya, memori atau had kehabisan, sambungan baharu tidak diterima, dan perkhidmatan tidak tersedia.
Jika anda tidak memperuntukkan sumber berdasarkan paket SYN, tetapi hanya bertindak balas dengan paket SYNACK, bagaimanakah pelayan boleh memahami bahawa paket ACK yang tiba kemudian merujuk kepada paket SYN yang tidak disimpan? Lagipun, penyerang juga boleh menjana ACK palsu. Tujuan kuki SYN adalah untuk mengekodnya seqnum parameter sambungan sebagai cincang alamat, port dan garam yang berubah-ubah. Jika ACK berjaya tiba sebelum garam ditukar, anda boleh mengira cincang sekali lagi dan membandingkannya dengannya acknum. Menjalin acknum penyerang tidak boleh, kerana garam termasuk rahsia, dan tidak akan mempunyai masa untuk menyelesaikannya kerana saluran yang terhad.
Kuki SYN telah lama dilaksanakan dalam kernel Linux malah boleh didayakan secara automatik jika SYN tiba terlalu cepat dan beramai-ramai.
Program pendidikan mengenai jabat tangan TCP
TCP menyediakan penghantaran data sebagai aliran bait, contohnya, permintaan HTTP dihantar melalui TCP. Aliran dihantar dalam kepingan dalam paket. Semua paket TCP mempunyai bendera logik dan nombor urutan 32-bit:
Gabungan bendera menentukan peranan pakej tertentu. Bendera SYN menunjukkan bahawa ini adalah paket pertama penghantar pada sambungan. Bendera ACK bermakna penghantar telah menerima semua data sambungan sehingga bait acknum. Satu paket boleh mempunyai beberapa bendera dan dipanggil dengan gabungannya, sebagai contoh, paket SYNACK.
Nombor jujukan (seqnum) menentukan offset dalam aliran data untuk bait pertama yang dihantar dalam paket ini. Sebagai contoh, jika dalam paket pertama dengan X bait data nombor ini ialah N, dalam paket seterusnya dengan data baharu ia akan menjadi N+X. Pada permulaan sambungan, setiap pihak memilih nombor ini secara rawak.
Nombor pengakuan (acknum) - offset yang sama seperti seqnum, tetapi ia tidak menentukan bilangan bait yang dihantar, tetapi nombor bait pertama daripada penerima, yang tidak dilihat oleh pengirim.
Pada permulaan perhubungan, pihak-pihak mesti bersetuju seqnum и acknum. Pelanggan menghantar paket SYN dengannya seqnum = X. Pelayan bertindak balas dengan paket SYNACK, di mana ia merekodkannya seqnum = Y dan mendedahkan acknum = X + 1. Pelanggan bertindak balas kepada SYNACK dengan paket ACK, di mana seqnum = X + 1, acknum = Y + 1. Selepas ini, pemindahan data sebenar bermula.
Jika rakan sebaya tidak mengakui penerimaan paket, TCP menghantarnya semula selepas tamat masa.
Mengapa kuki SYN tidak selalu digunakan?
Pertama, jika SYNACK atau ACK hilang, anda perlu menunggu untuk dihantar semula - persediaan sambungan akan menjadi perlahan. Kedua, dalam pakej SYN - dan hanya di dalamnya! — beberapa pilihan dihantar yang menjejaskan operasi sambungan selanjutnya. Tanpa mengingati paket SYN yang masuk, pelayan itu mengabaikan pilihan ini; pelanggan tidak akan menghantarnya dalam paket seterusnya. TCP boleh berfungsi dalam kes ini, tetapi sekurang-kurangnya pada peringkat awal kualiti sambungan akan berkurangan.
Dari perspektif pakej, program XDP mesti melakukan perkara berikut:
balas SYN dengan SYNACK dengan kuki;
balas ACK dengan RST (putuskan sambungan);
buang bungkusan yang tinggal.
Pseudokod algoritma bersama-sama dengan parsing pakej:
Если это не Ethernet,
пропустить пакет.
Если это не IPv4,
пропустить пакет.
Если адрес в таблице проверенных, (*)
уменьшить счетчик оставшихся проверок,
пропустить пакет.
Если это не TCP,
сбросить пакет. (**)
Если это SYN,
ответить SYN-ACK с cookie.
Если это ACK,
если в acknum лежит не cookie,
сбросить пакет.
Занести в таблицу адрес с N оставшихся проверок. (*)
Ответить RST. (**)
В остальных случаях сбросить пакет.
satu (*) titik di mana anda perlu mengurus keadaan sistem ditandakan - pada peringkat pertama anda boleh melakukannya tanpanya dengan hanya melaksanakan jabat tangan TCP dengan penjanaan kuki SYN sebagai seqnum.
Segera (**), sementara kami tidak mempunyai meja, kami akan melangkau paket itu.
Melaksanakan jabat tangan TCP
Menghuraikan pakej dan mengesahkan kod
Kami memerlukan struktur pengepala rangkaian: Ethernet (uapi/linux/if_ether.h), IPv4 (uapi/linux/ip.h) dan TCP (uapi/linux/tcp.h). Saya tidak dapat menyambung yang terakhir kerana ralat yang berkaitan dengan atomic64_t, saya terpaksa menyalin definisi yang diperlukan ke dalam kod.
Semua fungsi yang diserlahkan dalam C untuk kebolehbacaan mesti diselaraskan pada titik panggilan, kerana pengesah eBPF dalam kernel melarang penjejakan ke belakang, iaitu, sebenarnya, gelung dan panggilan fungsi.
Makro LOG() melumpuhkan pencetakan dalam binaan keluaran.
Program ini adalah penghantar fungsi. Setiap satu menerima paket di mana pengepala tahap yang sepadan diserlahkan, sebagai contoh, process_ether() mengharapkan ia akan diisi ether. Berdasarkan hasil analisis medan, fungsi boleh menghantar paket ke tahap yang lebih tinggi. Hasil daripada fungsi tersebut ialah tindakan XDP. Buat masa ini, pengendali SYN dan ACK melepasi semua paket.
Saya menarik perhatian anda kepada semakan bertanda A dan B. Jika anda mengulas A, program akan dibina, tetapi akan terdapat ralat pengesahan semasa memuatkan:
Rentetan kunci invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0): Terdapat laluan pelaksanaan apabila bait ketiga belas dari permulaan penimbal berada di luar paket. Sukar untuk difahami dari penyenaraian baris mana yang kita bicarakan, tetapi terdapat nombor arahan (12) dan pembongkar yang menunjukkan baris kod sumber:
yang menjelaskan bahawa masalahnya adalah ether. Ia akan sentiasa seperti ini.
Balas kepada SYN
Matlamat pada peringkat ini adalah untuk menjana paket SYNACK yang betul dengan tetap seqnum, yang akan digantikan pada masa hadapan dengan kuki SYN. Semua perubahan berlaku dalam process_tcp_syn() dan kawasan sekitarnya.
Pengesahan pakej
Anehnya, berikut adalah baris yang paling luar biasa, atau lebih tepatnya, ulasan kepadanya:
Semasa menulis versi pertama kod, kernel 5.1 telah digunakan, untuk pengesah yang terdapat perbezaan antara data_end и (const void*)ctx->data_end. Pada masa penulisan, kernel 5.3.1 tidak mempunyai masalah ini. Ada kemungkinan bahawa pengkompil mengakses pembolehubah tempatan secara berbeza daripada medan. Moral of the story: Memudahkan kod boleh membantu apabila terdapat banyak sarang.
Seterusnya ialah pemeriksaan panjang rutin untuk kemuliaan pengesah; O MAX_CSUM_BYTES di bawah.
Tukar port TCP, alamat IP dan alamat MAC. Pustaka standard tidak boleh diakses daripada program XDP, jadi memcpy() — makro yang menyembunyikan intrinsik Clang.
Jumlah semak IPv4 dan TCP memerlukan penambahan semua perkataan 16-bit dalam pengepala, dan saiz pengepala ditulis ke dalamnya, iaitu, tidak diketahui pada masa penyusunan. Ini adalah masalah kerana pengesah tidak akan melangkau gelung biasa ke pembolehubah sempadan. Tetapi saiz pengepala adalah terhad: sehingga 64 bait setiap satu. Anda boleh membuat gelung dengan bilangan lelaran tetap, yang boleh berakhir lebih awal.
Saya perhatikan bahawa ada RFC 1624 tentang cara mengira semula sebahagian daripada jumlah semak jika hanya perkataan tetap pakej itu diubah. Walau bagaimanapun, kaedah ini tidak universal, dan pelaksanaannya akan menjadi lebih sukar untuk dikekalkan.
Fungsi pengiraan 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;
}
Walaupun size disahkan oleh kod panggilan, syarat keluar kedua adalah perlu supaya pengesah boleh membuktikan penyiapan gelung.
Untuk perkataan 32-bit, versi yang lebih mudah dilaksanakan:
INTERNAL u32
sum16_32(u32 v) {
return (v >> 16) + (v & 0xffff);
}
Sebenarnya mengira semula checksum dan menghantar semula paket:
Fungsi carry() membuat checksum daripada jumlah 32-bit perkataan 16-bit, menurut RFC 791.
Pengesahan jabat tangan TCP
Penapis dengan betul mewujudkan sambungan dengan netcat, kehilangan ACK terakhir, yang Linux membalas dengan paket RST, kerana timbunan rangkaian tidak menerima SYN - ia telah ditukar kepada SYNACK dan dihantar semula - dan dari sudut pandangan OS, paket tiba yang tidak berkaitan dengan pembukaan sambungan.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
Adalah penting untuk menyemak dengan aplikasi sepenuhnya dan memerhati tcpdump pada xdp-remote kerana, sebagai contoh, hping3 tidak bertindak balas kepada jumlah semak yang salah.
kuki SYN
Dari sudut pandangan XDP, pengesahan itu sendiri adalah remeh. Algoritma pengiraan adalah primitif dan berkemungkinan terdedah kepada penyerang yang canggih. Kernel Linux, sebagai contoh, menggunakan SipHash kriptografi, tetapi pelaksanaannya untuk XDP jelas di luar skop artikel ini.
Diperkenalkan untuk TODO baharu yang berkaitan dengan komunikasi luaran:
Program XDP tidak boleh disimpan cookie_seed (bahagian rahsia garam) dalam pembolehubah global, anda memerlukan penyimpanan dalam kernel, yang nilainya akan dikemas kini secara berkala daripada penjana yang boleh dipercayai.
Jika kuki SYN sepadan dalam paket ACK, anda tidak perlu mencetak mesej, tetapi ingat IP klien yang disahkan untuk meneruskan penghantaran paket daripadanya.
Walaupun tiada senarai IP yang disahkan, tiada perlindungan daripada banjir SYN itu sendiri, tetapi berikut ialah reaksi terhadap banjir ACK yang dilancarkan oleh arahan berikut:
sudo ip netns exec xdp-test hping3 --flood -A -s 1111 -p 2222 192.0.2.1
Kadangkala eBPF secara umum dan XDP khususnya dipersembahkan lebih sebagai alat pentadbir lanjutan daripada sebagai platform pembangunan. Sesungguhnya, XDP ialah alat untuk mengganggu pemprosesan paket oleh kernel, dan bukan alternatif kepada tindanan kernel, seperti DPDK dan pilihan pintasan kernel lain. Sebaliknya, XDP membolehkan anda melaksanakan logik yang agak kompleks, yang, lebih-lebih lagi, mudah dikemas kini tanpa gangguan dalam pemprosesan lalu lintas. Pengesah tidak menimbulkan masalah besar; secara peribadi, saya tidak akan menolak ini untuk bahagian kod ruang pengguna.
Di bahagian kedua, jika topik itu menarik, kami akan melengkapkan jadual pelanggan yang disahkan dan pemutusan sambungan, melaksanakan kaunter dan menulis utiliti ruang pengguna untuk mengurus penapis.