ProHoster > بلوق > إدارة > نكتب الحماية ضد هجمات DDoS على XDP. الجزء النووي
نكتب الحماية ضد هجمات DDoS على XDP. الجزء النووي
تسمح تقنية مسار بيانات eXpress (XDP) بمعالجة عشوائية لحركة المرور على واجهات Linux قبل دخول الحزم إلى مكدس شبكة kernel. تطبيق XDP - الحماية من هجمات DDoS (CloudFlare) ، المرشحات المعقدة ، جمع الإحصائيات (Netflix). يتم تنفيذ برامج XDP بواسطة الجهاز الظاهري لـ eBPF ، وبالتالي فإن لها قيودًا على كل من التعليمات البرمجية ووظائف kernel المتاحة ، اعتمادًا على نوع المرشح.
تهدف المقالة إلى تعويض أوجه القصور في العديد من المواد على XDP. أولاً ، يقدمون رمزًا جاهزًا يتخطى فورًا ميزات XDP: مُعد للتحقق أو بسيط جدًا بحيث لا يتسبب في حدوث مشكلات. عندما تحاول كتابة التعليمات البرمجية الخاصة بك من البداية لاحقًا ، لا يوجد فهم لما يجب فعله مع الأخطاء النموذجية. ثانيًا ، لا يغطي طرق اختبار XDP محليًا بدون جهاز افتراضي وأجهزة ، على الرغم من حقيقة أن لديهم عيوبهم الخاصة. النص مخصص للمبرمجين المطلعين على الشبكات ونظام Linux المهتمين بـ XDP و eBPF.
في هذا الجزء ، سوف نفهم بالتفصيل كيف يتم تجميع مرشح XDP وكيفية اختباره ، ثم سنكتب نسخة بسيطة من آلية ملفات تعريف الارتباط SYN المعروفة على مستوى معالجة الحزمة. حتى نشكل "قائمة بيضاء"
العملاء الذين تم التحقق منهم ، والاحتفاظ بالعدادات وإدارة عامل التصفية - سجلات كافية.
سنكتب بلغة C - هذا ليس عصريًا ولكنه عملي. كل الكود متاح على GitHub على الرابط في النهاية وينقسم إلى التزامات وفقًا للخطوات الموضحة في المقالة.
تنصل. في سياق المقال ، سيتم تطوير حل صغير لصد هجمات DDoS ، لأن هذه مهمة واقعية لـ XDP ومنطقتنا. ومع ذلك ، فإن الهدف الرئيسي هو فهم التكنولوجيا ، وهذا ليس دليلًا لإنشاء حماية جاهزة. لم يتم تحسين الكود التعليمي ويغفل بعض الفروق الدقيقة.
نظرة عامة موجزة عن XDP
سأذكر فقط النقاط الرئيسية حتى لا يتم تكرار الوثائق والمواد الموجودة.
لذلك ، يتم تحميل كود المرشح في النواة. يتم تمرير المرشح الحزم الواردة. نتيجة لذلك ، يجب أن يتخذ المرشح قرارًا: لتمرير الحزمة إلى النواة (XDP_PASS) ، إسقاط الحزمة (XDP_DROP) أو أرسلها مرة أخرى (XDP_TX). يمكن للمرشح تغيير الحزمة ، وهذا ينطبق بشكل خاص على XDP_TX. يمكنك أيضًا تعطل البرنامج (XDP_ABORTED) وإسقاط الحزمة ، ولكن هذا مماثل assert(0) - للتصحيح.
تم تصميم الجهاز الظاهري لـ eBPF (مرشح Berkley Packet Filter) البسيط عن عمد بحيث يمكن للنواة التحقق من أن الكود لا يتكرر ولا يتلف ذاكرة الآخرين. القيود والشيكات التراكمية:
الحلقات (القفز للخلف) محظورة.
هناك مكدس للبيانات ، ولكن لا توجد وظائف (يجب أن تكون جميع وظائف C مضمنة).
يحظر الوصول إلى الذاكرة خارج المكدس والمخزن المؤقت للحزمة.
حجم الكود محدود ، لكن من الناحية العملية ، هذا ليس مهمًا للغاية.
يُسمح فقط بوظائف kernel الخاصة (مساعدات eBPF).
يبدو تطوير مرشح وتثبيته كما يلي:
كود المصدر (على سبيل المثال. kernel.c) يجمع للاعتراض (kernel.o) لبنية الآلة الافتراضية eBPF. اعتبارًا من أكتوبر 2019 ، يتم دعم التجميع إلى eBPF بواسطة Clang ووعد به في دول مجلس التعاون الخليجي 10.1.
إذا كانت هناك استدعاءات في كود الكائن هذا لهياكل kernel (على سبيل المثال ، للجداول والعدادات) ، فبدلاً من معرفاتهم توجد أصفار ، أي لا يمكن تنفيذ هذا الكود. قبل التحميل في النواة ، يجب استبدال هذه الأصفار بمعرفات كائنات محددة تم إنشاؤها من خلال استدعاءات kernel (اربط الكود). يمكنك القيام بذلك باستخدام أدوات مساعدة خارجية ، أو يمكنك كتابة برنامج يقوم بربط وتحميل عامل تصفية معين.
تتحقق النواة من البرنامج الجاري تحميله. يتحقق من عدم وجود دورات وعدم خروج من الحزمة وحدود المكدس. إذا لم يتمكن المدقق من إثبات صحة الرمز ، فسيتم رفض البرنامج - يجب أن يكون المرء قادرًا على إرضائه.
بعد التحقق الناجح ، تقوم النواة بتجميع رمز كائن بنية eBPF في رمز آلة بنية النظام (في الوقت المناسب).
يتم إرفاق البرنامج بالواجهة ويبدأ في معالجة الحزم.
نظرًا لأن XDP يعمل في النواة ، يتم إجراء التصحيح بواسطة سجلات التتبع ، وفي الواقع ، بواسطة الحزم التي يقوم البرنامج بتصفية أو إنشاءها. ومع ذلك ، فإن eBPF يحافظ على الكود الذي تم تنزيله آمنًا للنظام ، بحيث يمكنك تجربة XDP مباشرة على نظام Linux المحلي.
اعداد البيئة
جمعية
لا يمكن لـ Clang إصدار رمز كائن مباشرة لهندسة eBPF ، لذلك تتكون العملية من خطوتين:
ترجمة كود C إلى LLVM bytecode (clang -emit-llvm).
تحويل بايت كود إلى كود كائن eBPF (llc -march=bpf -filetype=obj).
عند كتابة مرشح ، سيكون زوجان من الملفات ذات الوظائف الإضافية ووحدات الماكرو في متناول اليد من اختبارات النواة. من المهم أن تتطابق مع إصدار kernel (KVER). قم بتنزيلها على helpers/:
KDIR يحتوي على المسار إلى رؤوس kernel ، ARCH - بنية النظام. قد تختلف المسارات والأدوات قليلاً بين التوزيعات.
مثال على الاختلاف لـ 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 قم بتضمين دليل برؤوس مساعدة وأدلة متعددة برؤوس kernel. رمز __KERNEL__ يعني أن رؤوس UAPI (userspace API) محددة لرمز kernel ، حيث يتم تنفيذ عامل التصفية في kernel.
يمكن تعطيل حماية المكدس (-fno-stack-protector) لأن مدقق رمز eBPF يتحقق من عدم الخروج من حدود المكدس على أي حال. يجب عليك تمكين التحسينات على الفور ، لأن حجم رمز eBPF bytecode محدود.
فريق make يجمع xdp_filter.o. أين يمكنك اختباره الآن؟
اختبار موقف
يجب أن يشتمل الحامل على واجهتين: حيث سيكون هناك مرشح ومنه سيتم إرسال الحزم. يجب أن تكون هذه أجهزة Linux كاملة مع عناوين IP الخاصة بها للتحقق من كيفية عمل التطبيقات العادية مع عامل التصفية الخاص بنا.
أجهزة مثل veth (إيثرنت افتراضية) مناسبة لنا: فهي عبارة عن زوج من واجهات الشبكة الافتراضية "المتصلة" مباشرة ببعضها البعض. يمكنك إنشاؤها على هذا النحو (في هذا القسم ، جميع الأوامر ip منجز من root):
ip link add xdp-remote type veth peer name xdp-local
ومن xdp-remote и xdp-local - أسماء الأجهزة. على xdp-local (192.0.2.1/24) سيتم إرفاق مرشح مع xdp-remote (192.0.2.2/24) سيتم إرسال حركة المرور الواردة. ومع ذلك ، هناك مشكلة: الواجهات موجودة على نفس الجهاز ، ولن يرسل Linux حركة المرور إلى أحدهما عبر الآخر. يمكنك حلها بقواعد صعبة iptables، ولكن سيتعين عليهم تغيير الحزم ، وهو أمر غير مريح عند تصحيح الأخطاء. من الأفضل استخدام مساحات أسماء الشبكات (مساحات أسماء الشبكات ، شبكات أخرى).
تحتوي مساحة اسم الشبكة على مجموعة من الواجهات وجداول التوجيه وقواعد NetFilter المعزولة عن الكائنات المماثلة في الشبكات الأخرى. يتم تشغيل كل عملية في بعض مساحات الأسماء ، ولا تتوفر لها سوى كائنات هذه الشبكات. بشكل افتراضي ، يحتوي النظام على مساحة اسم شبكة واحدة لجميع الكائنات ، لذا يمكنك العمل على Linux وعدم معرفة الشبكات.
لنقم بإنشاء مساحة اسم جديدة xdp-test وانتقل إلى هناك xdp-remote.
ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test
ثم يتم تشغيل العملية xdp-test، لن ترى" xdp-local (ستبقى في netns افتراضيًا) وعند إرسال حزمة إلى 192.0.2.1 سوف تمر عبرها xdp-remote، لأن هذه هي الواجهة الوحيدة المتاحة لهذه العملية عند 192.0.2.0/24. هذا أيضا يعمل في الاتجاه المعاكس.
عند التنقل بين الشبكات ، تنخفض الواجهة وتفقد العنوان. لإعداد واجهة في الشبكات ، تحتاج إلى تشغيل ip ... في مساحة اسم الأمر هذه 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
كما ترى ، هذا لا يختلف عن الإعداد xdp-local في مساحة الاسم الافتراضية:
ip address add 192.0.2.1/24 dev xdp-local
ip link set xdp-local up
إذا ركض tcpdump -tnevi xdp-local، يمكنك أن ترى أن الحزم المرسلة من xdp-test، يتم تسليمها إلى هذه الواجهة:
ip netns exec xdp-test ping 192.0.2.1
من الملائم تشغيل قذيفة فيها xdp-test. يحتوي المستودع على برنامج نصي يعمل على أتمتة العمل مع الحامل ، على سبيل المثال ، يمكنك إعداد الحامل باستخدام الأمر sudo ./stand up وإزالته sudo ./stand down.
اقتفاء أثر
المرشح متصل بالجهاز مثل هذا:
ip -force link set dev xdp-local xdp object xdp_filter.o verbose
مفتاح -force مطلوب لربط برنامج جديد إذا كان برنامج آخر مرتبطًا بالفعل. "لا توجد أخبار جيدة" لا يتعلق بهذا الأمر ، الناتج ضخم على أي حال. يشير verbose اختياري ، ولكن يظهر معه تقرير حول عمل مدقق الشفرة مع قائمة المجمّع:
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
افصل البرنامج عن الواجهة:
ip link set dev xdp-local xdp off
في النص ، هذه هي الأوامر sudo ./stand attach и sudo ./stand detach.
من خلال ربط المرشح ، يمكنك التأكد من ذلك ping يستمر في العمل ، ولكن هل يعمل البرنامج؟ دعونا نضيف الشعارات. وظيفة bpf_trace_printk() مشابه ل printf()، ولكنه يدعم فقط ما يصل إلى ثلاث وسيطات بخلاف النمط وقائمة محدودة من المحددات. دقيق bpf_printk() يبسط المكالمة.
لهذا السبب ، يؤدي إخراج التصحيح إلى تضخيم الكود الناتج بشكل كبير.
إرسال حزم XDP
دعنا نغير عامل التصفية: دعه يرسل كل الحزم الواردة مرة أخرى. هذا غير صحيح من وجهة نظر الشبكة ، حيث سيكون من الضروري تغيير العناوين في الرؤوس ، لكن العمل الآن من حيث المبدأ مهم.
نطلق tcpdump في xdp-remote. يجب أن يُظهر طلب ارتداد ICMP الصادر والوارد المتطابق ويتوقف عن إظهار رد ICMP Echo Reply. لكنها لا تظهر. اتضح للعمل XDP_TX في برنامج xdp-localيجبلإقران الواجهة xdp-remote تم تخصيص برنامج أيضًا ، حتى لو كان فارغًا ، وتم رفعه.
كيف عرفت؟
تتبع مسار الحزمة في النواة تسمح آلية أحداث perf ، بالمناسبة ، باستخدام نفس الجهاز الظاهري ، أي أن eBPF يُستخدم للتفكيك باستخدام eBPF.
يجب أن تصنع الخير من الشر ، لأنه لا يوجد شيء آخر تصنعه.
إذا تم عرض ARP فقط بدلاً من ذلك ، فأنت بحاجة إلى إزالة المرشحات (وهذا يجعل sudo ./stand detach)، يترك ping، ثم قم بتثبيت عوامل التصفية وحاول مرة أخرى. المشكلة هي أن المرشح XDP_TX يؤثر أيضًا على ARP ، وإذا كان المكدس
مساحات الأسماء xdp-test تمكن من "نسيان" عنوان MAC 192.0.2.1 ، فلن يتمكن من حل عنوان IP هذا.
صياغة المشكلة
دعنا ننتقل إلى المهمة المذكورة: كتابة آلية ملف تعريف ارتباط SYN على XDP.
حتى الآن ، لا يزال فيضان SYN هجوم DDoS شائعًا ، وجوهره كما يلي. عند إنشاء اتصال (مصافحة TCP) ، يتلقى الخادم SYN ، ويخصص الموارد للاتصال المستقبلي ، ويستجيب بحزمة SYNACK ، وينتظر ACK. يرسل المهاجم ببساطة حزم SYN من عناوين وهمية بمقدار الآلاف في الثانية من كل مضيف في شبكة متعددة الآلاف. يُجبر الخادم على تخصيص الموارد فور وصول الحزمة ، ولكنه يطلقها بعد مهلة طويلة ، ونتيجة لذلك ، يتم استنفاد الذاكرة أو الحدود ، ولا يتم قبول الاتصالات الجديدة ، والخدمة غير متاحة.
إذا لم تقم بتخصيص موارد على حزمة SYN ، ولكنك تستجيب فقط بحزمة SYNACK ، فكيف يمكن للخادم أن يفهم أن حزمة ACK التي جاءت لاحقًا تنتمي إلى حزمة SYN التي لم يتم حفظها؟ بعد كل شيء ، يمكن للمهاجم أيضًا إنشاء إشعارات مزيفة. جوهر ملف تعريف الارتباط SYN هو الترميز بتنسيق seqnum معلمات الاتصال كتجزئة للعناوين والموانئ والملح المتغير. إذا تمكنت ACK من الوصول قبل تغيير الملح ، فيمكنك حساب التجزئة مرة أخرى والمقارنة مع acknum. مزيف acknum لا يستطيع المهاجم ، لأن الملح يشمل السر ، ولن يكون لديه وقت لفرزها بسبب القناة المحدودة.
تم تنفيذ ملفات تعريف الارتباط SYN في Linux kernel لفترة طويلة ويمكن حتى تمكينها تلقائيًا إذا وصلت SYNs بسرعة كبيرة وبشكل مجمّع.
برنامج تعليمي عن مصافحة TCP
يوفر TCP نقل البيانات كتدفق من البايتات ، على سبيل المثال ، يتم إرسال طلبات HTTP عبر TCP. ينتقل الدفق قطعة قطعة في حزم. تحتوي جميع حزم TCP على أعلام منطقية وأرقام تسلسل 32 بت:
تحدد مجموعة الأعلام دور حزمة معينة. تعني علامة SYN أن هذه هي الحزمة الأولى للمرسل على الاتصال. تعني علامة ACK أن المرسل قد تلقى كافة بيانات الاتصال حتى بايت. acknum. قد تحتوي الحزمة على العديد من الأعلام ويتم تسميتها بعد توليفها ، على سبيل المثال ، حزمة SYNACK.
يحدد رقم التسلسل (seqnum) الإزاحة في دفق البيانات للبايت الأول الذي يتم إرساله في هذه الحزمة. على سبيل المثال ، إذا كان هذا الرقم في الحزمة الأولى التي تحتوي على X بايت من البيانات هو N ، فسيكون في الحزمة التالية مع البيانات الجديدة N + X. في بداية الاتصال ، يختار كل طرف هذا الرقم بشكل عشوائي.
رقم الإقرار (acknum) - نفس الإزاحة مثل seqnum ، لكنها لا تحدد رقم البايت المرسل ، ولكن رقم البايت الأول من المستلم ، والذي لم يراه المرسل.
في بداية الاتصال ، يجب أن يتفق الطرفان seqnum и acknum. يرسل العميل حزمة SYN مع ملف seqnum = X. يستجيب الخادم بحزمة SYNACK ، حيث يكتب حزمة خاصة به seqnum = Y ويفضح acknum = X + 1. يستجيب العميل لـ SYNACK بحزمة ACK ، حيث seqnum = X + 1, acknum = Y + 1. بعد ذلك ، يبدأ نقل البيانات الفعلي.
إذا لم يقر المحاور باستلام الحزمة ، يقوم TCP بإعادة إرسالها قبل انتهاء المهلة.
لماذا لا تستخدم ملفات تعريف الارتباط SYN دائمًا؟
أولاً ، في حالة فقد SYNACK أو ACK ، فسيتعين عليك انتظار إعادة الإرسال - يتباطأ إنشاء الاتصال. ثانيًا ، في حزمة SYN - وفيها فقط! - يتم إرسال عدد من الخيارات التي تؤثر على التشغيل الإضافي للاتصال. لا يتذكر الخادم حزم SYN الواردة ، وبالتالي يتجاهل هذه الخيارات ، في الحزم التالية لن يرسلها العميل بعد الآن. يمكن أن يعمل TCP في هذه الحالة ، ولكن على الأقل في المرحلة الأولية ، ستنخفض جودة الاتصال.
فيما يتعلق بالحزم ، يجب أن يقوم برنامج XDP بما يلي:
الرد على SYN مع SYNACK مع ملف تعريف الارتباط ؛
الرد على ACK مع RST (قطع الاتصال) ؛
إسقاط الحزم الأخرى.
الكود الزائف للخوارزمية مع تحليل الحزمة:
Если это не Ethernet,
пропустить пакет.
Если это не IPv4,
пропустить пакет.
Если адрес в таблице проверенных, (*)
уменьшить счетчик оставшихся проверок,
пропустить пакет.
Если это не TCP,
сбросить пакет. (**)
Если это SYN,
ответить SYN-ACK с cookie.
Если это ACK,
если в acknum лежит не cookie,
сбросить пакет.
Занести в таблицу адрес с N оставшихся проверок. (*)
Ответить RST. (**)
В остальных случаях сбросить пакет.
واحد (*) يتم تمييز النقاط التي تحتاج فيها إلى إدارة حالة النظام - في المرحلة الأولى ، يمكنك الاستغناء عنها ببساطة عن طريق تنفيذ مصافحة TCP مع إنشاء ملف تعريف ارتباط SYN باعتباره seqnum.
بالموقع (**)، بينما ليس لدينا طاولة ، سنتخطى الحزمة.
تنفيذ مصافحة TCP
تحليل الحزمة والتحقق من الكود
نحتاج إلى هياكل رؤوس الشبكة: إيثرنت (uapi/linux/if_ether.h) ، IPv4 (uapi/linux/ip.h) و TCP (uapi/linux/tcp.h). آخر ملف لم أتمكن من الاتصال به بسبب أخطاء متعلقة بـ atomic64_t، كان علي نسخ التعريفات الضرورية في الكود.
يجب أن تكون جميع الوظائف المميزة في لغة C لسهولة القراءة مضمنة في موقع الاستدعاء ، نظرًا لأن مدقق eBPF في النواة يمنع القفزات العكسية ، أي في الواقع الحلقات واستدعاءات الوظائف.
البرنامج عبارة عن مجموعة من الوظائف. يتلقى كل حزمة حزمة يتم فيها تمييز رأس المستوى المقابل ، على سبيل المثال ، process_ether() في انتظار شغلها ether. بناءً على نتائج التحليل الميداني ، يمكن للوظيفة نقل الحزمة إلى مستوى أعلى. نتيجة الوظيفة هي إجراء XDP. بينما تسمح معالجات SYN و ACK لجميع الحزم بالمرور.
السلسلة الرئيسية invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0): توجد مسارات تنفيذ عندما يكون البايت الثالث عشر من بداية المخزن المؤقت خارج الحزمة. من الصعب تحديد السطر الذي نتحدث عنه من القائمة ، ولكن هناك رقم تعليمي (12) ومُفكك يُظهر سطور شفرة المصدر:
الهدف في هذه المرحلة هو إنشاء حزمة SYNACK صحيحة مع ثابت seqnum، والذي سيتم استبداله بملف تعريف الارتباط SYN في المستقبل. كل التغييرات تحدث في process_tcp_syn() والمناطق المحيطة بها.
فحص العبوة
من الغريب أن هذا هو أبرز سطر ، أو بالأحرى تعليق عليه:
عند كتابة الإصدار الأول من الكود ، تم استخدام نواة 5.1 ، حيث كان هناك فرق بين المدقق data_end и (const void*)ctx->data_end. في وقت كتابة هذا التقرير ، لم يكن لدى النواة 5.3.1 هذه المشكلة. ربما كان المترجم يصل إلى متغير محلي بشكل مختلف عن الحقل. أخلاقي - عند إجراء تداخل كبير ، يمكن أن يساعد تبسيط الكود.
المزيد من الفحوصات الروتينية لأطوال مجد المدقق ؛ ا MAX_CSUM_BYTES أدناه.
تتطلب المجاميع الاختبارية لـ IPv4 و TCP إضافة كل الكلمات ذات 16 بت في الرؤوس ، ويكون حجم الرؤوس مكتوبًا فيها ، أي في وقت التجميع غير معروف. هذه مشكلة لأن المدقق لن يتخطى الحلقة العادية حتى متغير الحدود. لكن حجم الرؤوس محدود: حتى 64 بايت لكل منها. يمكنك إنشاء حلقة بعدد ثابت من التكرارات ، والتي يمكن أن تنتهي مبكرًا.
ألاحظ أن هناك RFC 1624 حول كيفية إعادة حساب المجموع الاختباري جزئيًا إذا تم تغيير الكلمات الثابتة للحزم فقط. ومع ذلك ، فإن الطريقة ليست عالمية ، وسيكون من الصعب الحفاظ على التنفيذ.
وظيفة حساب المجموع الاختباري:
#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;
}
بالرغم من size بعد التحقق من رمز الاستدعاء ، يعد شرط الخروج الثاني ضروريًا حتى يتمكن المدقق من إثبات نهاية الحلقة.
بالنسبة للكلمات ذات 32 بت ، يتم تطبيق نسخة أبسط:
INTERNAL u32
sum16_32(u32 v) {
return (v >> 16) + (v & 0xffff);
}
في الواقع إعادة حساب المجاميع الاختبارية وإعادة الحزمة:
وظيفة carry() يجعل مجموع اختباري من مجموع 32 بت لكلمات 16 بت ، وفقًا لـ RFC 791.
فحص اتصال TCP
يقوم المرشح بإنشاء اتصال مع netcat، تخطي ACK النهائي ، الذي استجاب له Linux بحزمة RST ، نظرًا لأن مكدس الشبكة لم يتلق SYN - تم تحويله إلى SYNACK وأعيد إرساله - ومن وجهة نظر نظام التشغيل ، وصلت حزمة لم تكن كذلك المتعلقة بالاتصالات المفتوحة.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
من المهم التحقق من التطبيقات الكاملة ومراقبتها tcpdump في xdp-remote لأنه ، على سبيل المثال ، hping3 لا يستجيب لمجموعات اختبارية غير صحيحة.
ملف تعريف الارتباط SYN
من وجهة نظر XDP ، فإن الشيك نفسه تافه. تعد خوارزمية الحساب بدائية وربما تكون عرضة لمهاجم متطور. نواة Linux ، على سبيل المثال ، تستخدم التشفير SipHash ، ولكن من الواضح أن تنفيذها لـ XDP خارج نطاق هذه المقالة.
ظهرت في TODOs الجديدة المتعلقة بالتفاعل الخارجي:
لا يمكن تخزين برنامج XDP cookie_seed (الجزء السري من الملح) في متغير عام ، فأنت بحاجة إلى متجر kernel سيتم تحديث قيمته بشكل دوري من مُنشئ موثوق.
إذا تطابق ملف تعريف الارتباط SYN في حزمة ACK ، فلن تحتاج إلى طباعة رسالة ، ولكن تذكر عنوان IP الخاص بالعميل الذي تم التحقق منه لتخطي الحزم منه.
في بعض الأحيان ، يتم تقديم eBPF بشكل عام و XDP بشكل خاص كأداة مسؤول متقدمة أكثر من كونها منصة تطوير. في الواقع ، تعد XDP أداة للتدخل في معالجة حزم النواة ، وليست بديلاً لمكدس النواة ، مثل DPDK وخيارات تجاوز kernel الأخرى. من ناحية أخرى ، يتيح لك XDP تنفيذ منطق معقد إلى حد ما ، والذي ، علاوة على ذلك ، من السهل تحديثه دون توقف في معالجة حركة المرور. المدقق لا يخلق مشاكل كبيرة ، وأنا شخصيا لن أرفض مثل هذه لأجزاء من رمز مساحة المستخدمين.
في الجزء الثاني ، إذا كان الموضوع مثيرًا للاهتمام ، فسنكمل جدول العملاء الذين تم التحقق منهم ونقطع الاتصالات ، وننفذ العدادات ونكتب أداة userpace لإدارة عامل التصفية.