تخطَّ إلى المحتوى
netrewind
صندوق أسود للشبكة

المشكلة

حين تتعطّل شبكة، يكون الوصف الصادق عادةً على هذا النحو

انقطع الاتصال الساعة 10:43، ولا نعرف لماذا.

الأدلة موزّعة على سجلّات السويتشات وجدران الحماية وDHCP وDNS، لكلٍّ منها ساعته وصيغته — ومعظمها يكون تدوير السجلّات قد محاه قبل أن ينظر فيه أحد.

فيخمّن المهندس، ويبدّل كابلًا، ويعيد تشغيل خدمة، ثم يعود العطل بعد يومين.

والعطل المتقطّع أسوأ

ينقطع تسعين ثانية كل يومين، في غير وقت معلوم.

لا سبيل عمليًّا إلى أن تكون مراقبًا لحظة وقوعه، والتقاط الحزم يملأ القرص في ساعة.

فيبقى بلا حلّ شهورًا.

ضَع كل تغيّر حالة على خط زمني واحد بدقّة النانوثانية، فتتجمّع القصّة من تلقاء نفسها:

10:41:58  a second DHCP server appeared on 192.168.20.99
10:42:17    nine hosts took a different default gateway
10:42:19      34% packet loss outbound
10:42:23        41 TCP connections to Server X dropped
10:47:12  ended - port Gi0/14 was shut manually

لمن هذا

لكل من سُئل «ماذا جرى؟» ولم يجد ما يشير إليه

أين موقعه

ما الذي تعطيه الأدوات القائمة، وما الذي لا تعطيه

لكلٍّ من هذه موضعه، ولا شيء منها يُجيب السؤال الذي يُطرح بعد انتهاء العطل: ما الذي تغيّر قبل أن ينكسر؟

الأداةما تعطيهما لا تعطيه
NetFlow / ntopngإحصاءات حركة المروربلا سياق سببي، وبلا حالة الطبقتين الثانية والثالثة
Zeek / Arkimeسجلّات غنية من منفذ SPANتخزين ثقيل، وعمًى عن تغيّرات الحالة والإعدادات
Cilium / Pixie / Retinaرصد eBPF ممتازمبنية للحاويات وKubernetes؛ لا تعرف شيئًا عن VLANs ولا ARP ولا السويتشات
SIEMتجميع السجلّاتبنية تحتية كبيرة، ويبقى الربط السببي مهمّتك أنت

الفجوة التي يملؤها NetRewind: تسجيل مستمرّ وخفيف لتغيّرات حالة الشبكة، مع سرد سببيّ يُبنى منها بعد وقوع العطل.

ما الذي أُنجز

الطبقات من الأولى إلى الرابعة: مسجَّلة، ومترابطة، ومُثبَتة من طرف إلى طرف

حالة الواجهات وجداول الجيران والمسارات والعناوين تأتي من netlink. ونتائج الاتصالات من برنامجَي eBPF على tracepoints مستقرّة. وتغيّرات الترشيح من استطلاع مجموعة قواعد nftables. وبيانات DHCP وDNS وICMP الوصفية من مقبس حزم مُرشَّح، وقياس الوصول من نبضات ICMP منسوبةً إلى خط أساس. وتقرأ النتيجةَ تسعَ عشرةَ قاعدةَ ترابط.

يشغّل المختبر أربعة عشر سيناريو: ثلاثة عشر عطلًا محقونًا، ومعها فترة من حركة مرور ناجحة عادية — لأن مسجّلًا لم يرَ إلا الأعطال لم يُثبت شيئًا عن خطّ أساسه. ثم تُبوَّب التشغيلة مرتين: أولًا أن كل عطل محقون يمكن إيجاده في السجل، وثانيًا — وهي مسألة منفصلة — أن الترابط بلغ الاستنتاج الصحيح، لا أن الدليل كان متاحًا أمامه فحسب. وتغطّي طوبولوجيا GNS3 من راوترات وسويتشات Cisco ما لا تستطيعه الـnamespaces: شبكات VLAN حقيقية، وOSPF حقيقي، وعنوان بوابة ينتقل بين راوترين ماديّين.

sudo make lab
ok gateway-hijack concluded
ok contested-address concluded
ok default-route-moved concluded
ok default-route-lost concluded
ok service-unreachable concluded
ok change-broke-a-path concluded
 
PASS: every injected fault was reconstructed, and correlation named the cause

البوابة الثانية هي المهمّة. أن يكون الدليل في المخزن، وأن يُستخلص منه الاستنتاج الصحيح، إنجازان مختلفان، والأول وحده هو السهل.

خارطة الطريق

M0
الظرف، والمخزن، وحالة الواجهات، وسطر الأوامر
مُنجَز
M1
الجيران والمسارات والعناوين؛ الهوية الزمنية؛ الاستعلامات السردية؛ مختبر حقن الأعطال
مُنجَز
M2
رصد الاتصالات بـeBPF، والتجميع الدوري، وsystem.drop
مُنجَز
M2b
تغيّرات قواعد nftables؛ والـresets والانقطاعات من tracepoint ثانٍ
مُنجَز
M3
محرّك Isnad بالمطابقة السببية العكسية، ومكتبة من تسع عشرة قاعدة
مُنجَز
M4
مختبر GNS3: نواة OSPF، وVLANs حقيقية، وtrunk، والمسجّل على منفذ وصول
مُنجَز
M5
واجهة الويب، وتصدير Prometheus وOpenTelemetry، وحزم amd64 وarm64، وصورة قابلة للإقلاع
مُنجَز
M5e
التحديث الذاتي من إصدارات موقّعة
مُنجَز

الباقي هو conntrack، ليرى المسجّل عند البوابة الاتصالات التي يمرّرها لا اتصالاته وحدها، ثم LLDP وSNMP لطوبولوجيا جهة السويتش. وكلاهما مذكور في سجل التغييرات بدل أن يُوحى بوجوده.

حدوده

ما لا يفعله، مقولًا بدل أن يُغطّى عليه

مسجّلٌ يُسقط ما فاته في صمت ليس دليلًا على شيء: سيُظهر السِّجلّ شبكةً هادئة، والهدوء هو ما يستنتجه المشغّل حين لا يكون ثمّة خطب. وهذا المبدأ مفروضٌ في الشيفرة، وهو مفروضٌ على هذه الصفحة أيضًا.

يرى ما يصله
موضع المسجّل هو ما يقرّر قيمة السِّجلّ. فعند البوّابة يرى كل ما يعبر الحدّ؛ وعلى منفذ مرآة لا يرى قرارات التوجيه ولا الترشيح التي تتّخذها البوّابة نفسها؛ وكمضيفٍ على القطاع لا يرى محادثاتٍ ليس طرفًا فيها. ودليل التشغيل يذكر ثمن كل موضع.
مآلات الاتصالات محليّة للمضيف، والسويتشات غير مرئية
الـtracepoint يرى مقابس هذا المضيف، فالمسجّل عند البوّابة يرى اتصالاته هو لا التي يمرّرها — وذلك يحتاج conntrack وهو غير مبنيّ. كما أن LLDP وSNMP لا يُجمَعان، فما يعرفه السويتش عن منافذه يبقى خارج السِّجلّ.
تعشية عناوين MAC تكسر التتبّع الطويل
تولّد الهواتف عنوانًا عتاديًّا عشوائيًّا لكل شبكة، فلا يستطيع جدول الهويّات أن يتتبّع جهازًا محمولًا عبر أسابيع. ويضيّق مُعرّف عميل DHCP والبصمة السلوكية الفجوةَ ولا يسدّانها.
مُجمِّع الترشيح يستطلع كل خمس ثوانٍ
قاعدةٌ تُضاف وتُتراجَع داخل الفترة الواحدة لا تترك أثرًا. وتحليل مخرَج nft monitor بديلًا عن ذلك كان سينكسر كلما غيّرت nft طريقة طباعتها — ومسجّلٌ يكفّ عن التسجيل دون أن يقول ذلك هو العطب الذي وُجد هذا المشروع لمنعه. فالاستطلاع أهون الشرّين.
لم يُشغَّل على شبكة إنتاجية
كل ما عُرض هنا جرى في network namespaces على لينكس، أو على طوبولوجيا GNS3 من موجّهات وسويتشات سيسكو. وجامعات Windows اختُبرت أيضًا على جهاز فعلي — منفذٌ حقيقي ذبذبناه، وحادثة حقيقية شُخِّصت — لكن لم يُشغَّل أيٌّ منهما بعد على شبكة إنتاجية حيّة. والشبكات الحقيقية فيها خصوصيات مصنّعين، وحجم، وأنماط أعطال لا يُنتجها مختبر. فاعتبِر هذا منهجًا مُثبَتًا، لا سِجلَّ تشغيلٍ ميداني.

وثمّة قاعدة مشحونة لا وجود لها إلا لتقول هذا صراحةً أثناء الحادثة: recorder-was-blind تُطلق على system.gap أو system.drop بثقة 100%، ونصيحتها أنه لا يمكن استنتاج شيء عن تلك المدّة من هذا المسجّل.

الترخيص والخصوصية

برمجية حرّة، وستبقى كذلك

رخصة AGPL-3.0. شغّله على ما شئت من الأجهزة، وما شئت من الوقت، تجاريًّا أو غير تجاري، بلا شيء يُشترى ولا أحد يُستأذَن.

اقرأ الرخصة