برنامج يتصل بخطاف XDP الخاص بنواة Linux من خلال (e)BPF لمعالجة الحزم السريعة ويقوم بإعادة توجيه الطبقة الأساسية 3/4. يقوم هذا البرنامج بتعيين منفذ المصدر بشكل مشابه لـ IPTables وNFTables للتعامل مع الاتصالات. يتم تحديد أولويات الاتصالات الحالية بناءً على حزم الاتصال لكل نانو ثانية. وهذا يعني أنه عند استنفاد المنفذ، سيتم استبدال الاتصالات التي تحتوي على أقل عدد من الحزم في النانو ثانية. أعتقد أن هذا هو الأفضل نظرًا لأن الاتصالات ذات الحزم الأعلى لكل نانو ثانية ستكون أكثر حساسية.
بالإضافة إلى ذلك، إذا كان تكوين شبكة المضيف أو بطاقة واجهة الشبكة (NIC) لا يدعم خطاف XDP DRV (المعروف أيضًا باسم AKA الأصلي؛ ويحدث قبل إنشاء SKB)، فسيحاول البرنامج الارتباط بخطاف XDP SKB (المعروف أيضًا باسم عام؛ ويحدث بعد SKB). حيث تتم معالجة IPTables وNFTables عبر وحدة netfilter
kernel). يمكنك استخدام التجاوزات من خلال سطر الأوامر لفرض أوضاع SKB أو إلغاء التحميل.
مع ذلك، قد تكون أسباب عدم دعم تكوين شبكة المضيف لخطاف DRV الخاص بـ XDP هي التالية.
آمل أن يساعد هذا المشروع مهندسي/مبرمجي الشبكات الحاليين المهتمين باستخدام XDP أو أي شخص مهتم بالدخول في هذه المجالات! تعد أجهزة التوجيه / إعادة توجيه الحزم عالية الأداء وتخفيف / منع (D) DoS من الأجزاء المهمة للأمن السيبراني وفهم مفهوم الشبكات وتدفق الحزم على مستوى منخفض إلى متوسط سيساعد بالتأكيد أولئك الذين يتابعون مهنة في هذا المجال؟
تحذير - لا يزال هناك العديد من الأشياء التي يجب القيام بها لهذا المشروع، وهو يدعم IPv4 فقط حتى الآن. ستتم إضافة دعم IPv6 قبل الإصدار الرسمي. اعتبارًا من الآن، قد يشتمل البرنامج على أخطاء، ولا تتوفر ميزات إعادة التوجيه بعد.
الحد الأقصى الافتراضي لمنافذ المصدر التي يمكن استخدامها لكل عنوان ربط هو 21 ويتم تعيينه هنا (يمكنك تعديلها إذا كنت ترغب في ذلك). نستخدم نطاق المنافذ 500 - 520 بشكل افتراضي، ولكن يمكن تكوينه.
في البداية، كنت أحاول استخدام معظم المنافذ المتاحة (1 - 65534). ومع ذلك، نظرًا لقيود التحقق من BPF، اضطررت إلى رفع بعض الثوابت داخل نواة Linux وإعادة ترجمة النواة. لقد قمت بعمل تصحيحات لهذه وتم توثيق كل شيء هنا. أنا قادر على تشغيل البرنامج بحد أقصى 65534 منفذًا لكل عنوان ربط دون أي مشاكل مع النواة المخصصة التي أنشأتها باستخدام التصحيحات التي قمت بإنشائها. ومع ذلك، ضع في اعتبارك أنه كلما زاد عدد منافذ المصدر المتاحة، زادت معالجة برنامج XDP عند التحقق من المنافذ المتاحة.
إذا كنت تخطط لاستخدام هذا للإنتاج، فأنا أقترح بشدة تجميع النواة الخاصة بك مع الثوابت الموضحة أعلاه. الحد الأقصى لعدد 21 منفذ مصدر لكل عنوان ربط ليس كثيرًا، ولكن لسوء الحظ، فإن قيود التحقق الافتراضية من BPF لا تسمح لنا بالمضي قدمًا في الوقت الحالي.
الكود الرئيسي الذي يسبب هذه القيود موجود هنا ويحدث عندما نحاول العثور على أفضل منفذ مصدر لاستخدامه في اتصال جديد. لا توجد حقًا طريقة أخرى للتحقق من أفضل منفذ مصدر متاح مع مقدار المرونة التي نتمتع بها حسب فهمي حيث يجب علينا التكرار عبر جميع منافذ المصدر والتحقق من الحزم لكل قيمة نانو ثانية (خرائط BPF تبحث عن طريق المفتاح).
ستحتاج إلى make
و clang
و libelf
و llvm
نظرًا لأننا نستخدم هذه الحزم لبناء المشروع. بالإضافة إلى ذلك، ستحتاج أيضًا إلى libconfig
( libconfig-dev
هي الحزمة الموجودة على أنظمة Ubuntu/Debian) لتحليل ملف التكوين.
بالنسبة لنظام التشغيل Ubuntu/Debian، يجب أن يعمل ما يلي.
apt install build-essential make clang libelf-dev llvm libconfig-dev
أفترض أن أسماء الحزم متشابهة في توزيعات Linux الأخرى.
من أجل استخدام xdpfwd-add
و xdpfwd-del
، يجب عليك تحميل نظام الملفات BPF حيث يقوم برنامج XDP بتثبيت خرائط BPF على /sys/fs/bpf/xdpfwd
. هناك احتمال كبير أن يكون هذا قد تم بالفعل عبر iproute2
أو شيء مشابه، ولكن إذا لم يكن الأمر كذلك، فيمكنك استخدام الأمر التالي.
mount -t bpf bpf /sys/fs/bpf/
يتضمن الاستخدام الأساسي لسطر الأوامر ما يلي.
-o --offload => Attempt to load XDP program with HW/offload mode. If fails, will try DRV and SKB mode in that order.
-s --skb => Force program to load in SKB/generic mode.
-t --time => The amount of time in seconds to run the program for. Unset or 0 = infinite.
-c --config => Location to XDP Forward config (default is /etc/xdpfwd/xdpfwd.conf).
-l --list => List all forwarding rules.
-h --help => Print out command line usage.
يتيح إلغاء تحميل برنامج XDP/BPF الخاص بك إلى بطاقة NIC الخاصة بنظامك أسرع معالجة للحزم يمكنك تحقيقها بفضل معالجة/إعادة توجيه NIC للحزم مع أجهزتها. ومع ذلك، لا يوجد العديد من الشركات المصنعة لبطاقات NIC التي تدعم هذه الميزة وأنت مقيد بذاكرة/معالجة بطاقة NIC (على سبيل المثال، ستكون أحجام خرائط BPF الخاصة بك محدودة للغاية). بالإضافة إلى ذلك، عادةً ما تكون هناك قيود أكثر صرامة للتحقق من BPF لبرامج BPF التي تم إلغاء تحميلها، ولكن يمكنك محاولة التواصل مع الشركة المصنعة لبطاقة NIC لمعرفة ما إذا كانت ستمنحك إصدارًا خاصًا من برنامج تشغيل NIC الخاص بها لرفع هذه القيود (وهذا ما فعلته مع إحدى الشركات المصنعة لقد استخدمت).
اعتبارًا من هذا الوقت، لست على علم بأي من الشركات المصنعة لبطاقة NIC التي ستكون قادرة على إلغاء تحميل هذه الأداة بالكامل إلى NIC نظرًا لتعقيد BPF ومتطلبات الحلقة. لأكون صادقًا، في عصر الشبكات الحالي، أعتقد أنه من الأفضل ترك البرامج التي تم إلغاء تحميلها لعمليات البحث عن خرائط BPF والحد الأدنى من فحص الحزم. على سبيل المثال، بحث بسيط عن خريطة جدول توجيه الطبقة الثانية من BPF، ثم إرسال الحزم مرة أخرى إلى خارج بطاقة واجهة الشبكة (NIC). ومع ذلك، لا يزال XDP جديدًا جدًا وأتصور أننا سنرى تخفيف هذه القيود أو رفعها في السنوات القادمة. ولهذا السبب أضفت دعمًا لوضع إلغاء التحميل في هذا البرنامج.
يقبل الملف xdpfwd-add
القابل للتنفيذ والذي تمت إضافته إلى $PATH
عبر /usr/bin
عند التثبيت الوسائط التالية.
-b --baddr => The address to bind/look for.
-B --bport => The port to bind/look for.
-d --daddr => The destination address.
-D --dport => The destination port.
-p --protocol => The protocol (either "tcp", "udp", "icmp", or unset for all).
-a --save => Save rule to config file.
سيؤدي هذا إلى إضافة قاعدة إعادة توجيه أثناء تشغيل برنامج XDP.
يقبل الملف xdpfwd-del
القابل للتنفيذ والذي تمت إضافته إلى $PATH
عبر /usr/bin
عند التثبيت الوسائط التالية.
-b --baddr => The address to bind/look for.
-B --bport => The port to bind/look for.
-p --protocol => The protocol (either "tcp", "udp", "icmp", or unset for all).
-a --save => Remove rule from config file.
سيؤدي هذا إلى حذف قاعدة إعادة التوجيه أثناء تشغيل برنامج XDP.
يوجد ملف التكوين الافتراضي في /etc/xdpfwd/xdpfwd.conf
ويستخدم بناء جملة libconfig
. فيما يلي مثال للتكوين باستخدام جميع ميزاته الحالية.
interface = "ens18"; // The interface the XDP program attaches to.
// Forwarding rules array.
forwarding = (
{
bind = "10.50.0.3", // The bind address which incoming packets must match.
bindport = 80, // The bind port which incoming packets must match.
protocol = "tcp", // The protocol (as of right now "udp", "tcp", and "icmp" are supported). Right now, you must specify a protocol. However, in the future I will be implementing functionality so you don't have to and it'll do full layer-3 forwarding.
dest = "10.50.0.4", // The address we're forwarding to.
destport = 8080 // The port we're forwarding to (if not set, will use the bind port).
},
...
);
على افتراض أنك قمت بتنزيل كافة الحزم المطلوبة، يجب أن يتم بناء هذا المشروع بشكل مستقيم. يمكنك استخدام أوامر Shell و Bash التالية!
# Clone respository and its sub-modules such as LibBPF.
git clone --recursive https://github.com/gamemann/XDP-Forwarding
# Change directory.
cd XDP-Forwarding
# Make project using all cores.
make -j $( nproc )
# Install binaries to PATH as root so you may use 'xdpfwd', 'xdpfwd-add', 'xdpfwd-del'.
sudo make install