احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

أهلاً بكم! اسمي ديمتري سامسونوف، أعمل كمسؤول نظام رائد في Odnoklassniki. لدينا أكثر من 7 آلاف خادم فعلي، و11 ألف حاوية في السحابة الخاصة بنا، و200 تطبيق، والتي تشكل في تكوينات مختلفة 700 مجموعة مختلفة. الغالبية العظمى من الخوادم تعمل بنظام CentOS 7.
في 14 أغسطس 2018، تم نشر معلومات حول ثغرة FragmentSmack
(CVE-2018-5391) وSegmentSmack (CVE-2018-5390). هذه هي نقاط الضعف مع ناقل هجوم الشبكة ودرجة عالية إلى حد ما (7.5)، مما يهدد برفض الخدمة (DoS) بسبب استنفاد الموارد (CPU). لم يتم اقتراح إصلاح kernel لـ FragmentSmack في ذلك الوقت، علاوة على ذلك، فقد ظهر في وقت لاحق بكثير من نشر المعلومات حول الثغرة الأمنية. للتخلص من SegmentSmack، تم اقتراح تحديث النواة. تم إصدار حزمة التحديث نفسها في نفس اليوم، ولم يتبق سوى تثبيتها.
لا، نحن لسنا ضد تحديث النواة إطلاقاً! ومع ذلك، هناك فروق دقيقة...

كيف نقوم بتحديث النواة عند الإنتاج

بشكل عام، لا شيء معقد:

  1. تنزيل الحزم؛
  2. تثبيتها على عدد من الخوادم (بما في ذلك الخوادم التي تستضيف السحابة الخاصة بنا)؛
  3. تأكد من عدم كسر أي شيء؛
  4. تأكد من تطبيق كافة إعدادات kernel القياسية دون أخطاء؛
  5. انتظر بضعة أيام.
  6. التحقق من أداء الخادم.
  7. تبديل نشر الخوادم الجديدة إلى النواة الجديدة؛
  8. تحديث جميع الخوادم حسب مركز البيانات (مركز بيانات واحد في كل مرة لتقليل التأثير على المستخدمين في حالة حدوث مشكلات)؛
  9. إعادة تشغيل كافة الخوادم.

كرر لجميع فروع الحبوب لدينا. في هذه اللحظة هو:

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

ومع ذلك، لا يزال هناك الكثير من العمل، وقد يستغرق الأمر عدة أسابيع، وإذا كانت هناك أي مشاكل في الإصدار الجديد، فقد يصل الأمر إلى عدة أشهر. يفهم المهاجمون ذلك جيدًا، لذا فهم بحاجة إلى خطة بديلة.

FragmentSmack/SegmentSmack. الحل البديل

لحسن الحظ، بالنسبة لبعض نقاط الضعف، توجد خطة B، ويطلق عليها اسم الحل البديل. في أغلب الأحيان، يكون هذا تغييرًا في إعدادات kernel/التطبيق الذي يمكنه تقليل التأثير المحتمل أو القضاء تمامًا على استغلال الثغرات الأمنية.

في حالة FragmentSmack/SegmentSmack أقترح هذا الحل البديل:

«يمكنك تغيير القيم الافتراضية 4 ميجابايت و3 ميجابايت في net.ipv4.ipfrag_high_thresh وnet.ipv4.ipfrag_low_thresh (ونظائرها لـ ipv6 net.ipv6.ipfrag_high_thresh وnet.ipv6.ipfrag_low_thresh) إلى 256 كيلو بايت و192 كيلو بايت على التوالي أو أدنى. تظهر الاختبارات انخفاضات صغيرة إلى كبيرة في استخدام وحدة المعالجة المركزية أثناء الهجوم اعتمادًا على الأجهزة والإعدادات والظروف. ومع ذلك، قد يكون هناك بعض التأثير على الأداء بسبب ipfrag_high_thresh=262144 بايت، نظرًا لأنه يمكن احتواء شظيتين فقط بحجم 64 كيلو بايت في قائمة انتظار إعادة التجميع في المرة الواحدة. على سبيل المثال، هناك خطر تعطل التطبيقات التي تعمل مع حزم UDP الكبيرة".

المعلمات نفسها في وثائق النواة الموصوفة على النحو التالي:

ipfrag_high_thresh - LONG INTEGER
    Maximum memory used to reassemble IP fragments.

ipfrag_low_thresh - LONG INTEGER
    Maximum memory used to reassemble IP fragments before the kernel
    begins to remove incomplete fragment queues to free up resources.
    The kernel still accepts new fragments for defragmentation.

ليس لدينا UDPs كبيرة في خدمات الإنتاج. لا توجد حركة مرور مجزأة على شبكة LAN، بل توجد حركة مرور مجزأة على شبكة WAN، ولكنها ليست مهمة. لا توجد علامات - يمكنك طرح الحل البديل!

FragmentSmack/SegmentSmack. اول دماء

كانت المشكلة الأولى التي واجهناها هي أن الحاويات السحابية تطبق أحيانًا الإعدادات الجديدة جزئيًا فقط (ipfrag_low_thresh فقط)، وأحيانًا لا تطبقها على الإطلاق - لقد تعطلت ببساطة في البداية. لم يكن من الممكن تكرار المشكلة بشكل ثابت (تم تطبيق كافة الإعدادات يدويًا دون أي صعوبات). إن فهم سبب تعطل الحاوية في البداية ليس بالأمر السهل أيضًا: لم يتم العثور على أخطاء. كان هناك شيء واحد مؤكد: التراجع عن الإعدادات يحل مشكلة تعطل الحاوية.

لماذا لا يكفي تطبيق Sysctl على المضيف؟ تعيش الحاوية في مساحة اسم الشبكة المخصصة لها، على الأقل جزء من معلمات Sysctl الشبكة في الحاوية قد تختلف عن المضيف.

ما مدى دقة تطبيق إعدادات Sysctl في الحاوية؟ نظرًا لأن حاوياتنا لا تتمتع بأي امتيازات، فلن تتمكن من تغيير أي إعداد Sysctl عن طريق الانتقال إلى الحاوية نفسها - فأنت ببساطة لا تملك الحقوق الكافية. لتشغيل الحاويات، استخدمت السحابة الخاصة بنا في ذلك الوقت Docker (الآن Podman). تم تمرير معلمات الحاوية الجديدة إلى Docker عبر واجهة برمجة التطبيقات، بما في ذلك إعدادات Sysctl الضرورية.
أثناء البحث في الإصدارات، اتضح أن Docker API لم تُرجع جميع الأخطاء (على الأقل في الإصدار 1.10). عندما حاولنا تشغيل الحاوية عبر "تشغيل عامل الإرساء"، رأينا أخيرًا شيئًا ما على الأقل:

write /proc/sys/net/ipv4/ipfrag_high_thresh: invalid argument docker: Error response from daemon: Cannot start container <...>: [9] System error: could not synchronise with container process.

قيمة المعلمة غير صالحة. لكن لماذا؟ ولماذا لا يكون صالحا إلا في بعض الأحيان؟ اتضح أن Docker لا يضمن الترتيب الذي يتم به تطبيق معلمات Sysctl (أحدث إصدار تم اختباره هو 1.13.1)، لذلك حاول أحيانًا تعيين ipfrag_high_thresh على 256 كيلو بايت عندما كان ipfrag_low_thresh لا يزال 3M، أي أن الحد الأعلى كان أقل عن الحد الأدنى مما أدى إلى الخطأ.

في ذلك الوقت، استخدمنا بالفعل آليتنا الخاصة لإعادة تكوين الحاوية بعد البدء (تجميد الحاوية بعد ذلك). الفريزر الجماعي وتنفيذ الأوامر في مساحة اسم الحاوية عبر netns)، وأضفنا أيضًا كتابة معلمات Sysctl إلى هذا الجزء. تم حل المشكلة.

FragmentSmack/SegmentSmack. الدم الأول 2

قبل أن يكون لدينا الوقت لفهم استخدام الحل البديل في السحابة، بدأت الشكاوى النادرة الأولى من المستخدمين في الوصول. في ذلك الوقت، مرت عدة أسابيع منذ بدء استخدام الحل البديل على الخوادم الأولى. وأظهر التحقيق الأولي أنه تم تلقي شكاوى ضد خدمات فردية، وليس جميع خوادم هذه الخدمات. أصبحت المشكلة غير مؤكدة للغاية مرة أخرى.

بادئ ذي بدء، حاولنا، بالطبع، التراجع عن إعدادات Sysctl، لكن هذا لم يكن له أي تأثير. لم تساعد المعالجات المختلفة مع إعدادات الخادم والتطبيق أيضًا. ساعد إعادة التشغيل. تعد إعادة تشغيل Linux أمرًا غير طبيعي كما كان طبيعيًا بالنسبة لنظام التشغيل Windows في الأيام الخوالي. ومع ذلك، فقد ساعد ذلك، وأرجعنا الأمر إلى "خلل في النواة" عند تطبيق الإعدادات الجديدة في Sysctl. كم كان الأمر تافهاً..

وبعد ثلاثة أسابيع تكررت المشكلة. كان تكوين هذه الخوادم بسيطًا للغاية: Nginx في وضع الوكيل/الموازن. ليس الكثير من حركة المرور. ملاحظة تمهيدية جديدة: عدد الأخطاء 504 على العملاء يتزايد كل يوم (مهلة العبارة). ويوضح الرسم البياني عدد 504 أخطاء يوميًا لهذه الخدمة:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

جميع الأخطاء تدور حول نفس الواجهة الخلفية - تلك الموجودة في السحابة. يبدو الرسم البياني لاستهلاك الذاكرة لأجزاء الحزمة على هذه الواجهة الخلفية كما يلي:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

يعد هذا أحد أكثر مظاهر المشكلة وضوحًا في الرسوم البيانية لنظام التشغيل. في السحابة، في نفس الوقت، تم إصلاح مشكلة أخرى في الشبكة تتعلق بإعدادات QoS (التحكم في حركة المرور). على الرسم البياني لاستهلاك الذاكرة لأجزاء الحزمة، بدا الأمر كما هو تمامًا:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

كان الافتراض بسيطًا: إذا كانت تبدو متشابهة على الرسوم البيانية، فذلك يعني أن لها نفس السبب. علاوة على ذلك، فإن أي مشاكل في هذا النوع من الذاكرة نادرة للغاية.

كان جوهر المشكلة التي تم إصلاحها هو أننا استخدمنا برنامج جدولة حزم fq مع الإعدادات الافتراضية في جودة الخدمة. بشكل افتراضي، بالنسبة لاتصال واحد، يسمح لك بإضافة 100 حزمة إلى قائمة الانتظار، وبعض الاتصالات، في حالات نقص القناة، بدأت في سد قائمة الانتظار إلى السعة. في هذه الحالة، يتم إسقاط الحزم. في إحصائيات tc (tc -s qdisc) يمكن رؤيتها على النحو التالي:

qdisc fq 2c6c: parent 1:2c6c limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023 quantum 3028 initial_quantum 15140 refill_delay 40.0ms
 Sent 454701676345 bytes 491683359 pkt (dropped 464545, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0
  1024 flows (1021 inactive, 0 throttled)
  0 gc, 0 highprio, 0 throttled, 464545 flows_plimit

"464545flows_plimit" هي الحزم التي تم إسقاطها بسبب تجاوز حد قائمة الانتظار لاتصال واحد، و"464545 التي تم إسقاطها" هي مجموع جميع الحزم التي تم إسقاطها في هذا المجدول. بعد زيادة طول قائمة الانتظار إلى ألف وإعادة تشغيل الحاويات، توقفت المشكلة عن الحدوث. يمكنك الجلوس وشرب العصير.

FragmentSmack/SegmentSmack. الدم الأخير

أولاً، بعد عدة أشهر من الإعلان عن الثغرات الأمنية في النواة، ظهر أخيرًا إصلاح لـ FragmentSmack (دعني أذكرك أنه مع الإعلان في أغسطس، تم إصدار إصلاح لـ SegmentSmack فقط)، مما أعطانا فرصة للتخلي عن الحل البديل، مما سبب لنا الكثير من المتاعب. خلال هذا الوقت، تمكنا بالفعل من نقل بعض الخوادم إلى النواة الجديدة، والآن كان علينا أن نبدأ من البداية. لماذا قمنا بتحديث النواة دون انتظار إصلاح FragmentSmack؟ الحقيقة هي أن عملية الحماية من هذه الثغرات الأمنية تزامنت (وتم دمجها) مع عملية تحديث CentOS نفسها (والتي تستغرق وقتًا أطول من تحديث النواة فقط). بالإضافة إلى ذلك، تعد SegmentSmack ثغرة أمنية أكثر خطورة، وقد ظهر إصلاح لها على الفور، لذا كان الأمر منطقيًا على أي حال. ومع ذلك، لم نتمكن ببساطة من تحديث النواة على CentOS لأن ثغرة FragmentSmack، التي ظهرت خلال CentOS 7.5، تم إصلاحها فقط في الإصدار 7.6، لذلك كان علينا إيقاف التحديث إلى 7.5 والبدء من جديد بالتحديث إلى 7.6. وهذا يحدث أيضًا.

ثانيا، عادت إلينا شكاوى المستخدمين النادرة بشأن المشكلات. نحن نعلم الآن على وجه اليقين أن جميعها مرتبطة بتحميل الملفات من العملاء إلى بعض خوادمنا. علاوة على ذلك، فقد مر عدد صغير جدًا من التحميلات من إجمالي الكتلة عبر هذه الخوادم.

كما نتذكر من القصة أعلاه، فإن التراجع عن Sysctl لم يساعد. ساعد إعادة التشغيل، ولكن مؤقتا.
لم تتم إزالة الشكوك المتعلقة بـ Sysctl، ولكن هذه المرة كان من الضروري جمع أكبر قدر ممكن من المعلومات. كان هناك أيضًا نقص كبير في القدرة على إعادة إنتاج مشكلة التحميل على العميل من أجل دراسة ما كان يحدث بدقة أكبر.

إن تحليل جميع الإحصائيات والسجلات المتاحة لم يقربنا من فهم ما كان يحدث. كان هناك نقص حاد في القدرة على إعادة إنتاج المشكلة من أجل "الشعور" باتصال معين. أخيرًا، تمكن المطورون، باستخدام إصدار خاص من التطبيق، من تحقيق إعادة إنتاج مستقرة للمشكلات على جهاز اختبار عند الاتصال عبر شبكة Wi-Fi. وكان هذا اختراقا في التحقيق. كان العميل متصلاً بـ Nginx، الذي كان وكيلاً للواجهة الخلفية، وهو تطبيق Java الخاص بنا.

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

كان حوار المشكلات على النحو التالي (تم إصلاحه على جانب وكيل Nginx):

  1. العميل: طلب الحصول على معلومات حول تنزيل ملف.
  2. خادم جافا: الاستجابة.
  3. العميل: نشر مع الملف.
  4. خادم جافا: خطأ.

في الوقت نفسه، يكتب خادم Java إلى السجل أنه تم استلام 0 بايت من البيانات من العميل، ويكتب وكيل Nginx أن الطلب استغرق أكثر من 30 ثانية (30 ثانية هي مهلة تطبيق العميل). لماذا المهلة ولماذا 0 بايت؟ من منظور HTTP، كل شيء يعمل كما ينبغي، ولكن يبدو أن POST مع الملف يختفي من الشبكة. علاوة على ذلك، فإنه يختفي بين العميل وNginx. حان الوقت لتسليح نفسك بـ Tcpdump! لكن عليك أولاً أن تفهم تكوين الشبكة. يقع وكيل Nginx خلف موازن L3 NFware. يتم استخدام الاتصال النفقي لتسليم الحزم من موازن L3 إلى الخادم، مما يضيف رؤوسه إلى الحزم:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

في هذه الحالة، تأتي الشبكة إلى هذا الخادم في شكل حركة مرور ذات علامات Vlan، والتي تضيف أيضًا حقولها الخاصة إلى الحزم:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

ويمكن أيضًا تجزئة حركة المرور هذه (نفس النسبة الصغيرة من حركة المرور المجزأة الواردة التي تحدثنا عنها عند تقييم المخاطر من الحل البديل)، مما يؤدي أيضًا إلى تغيير محتوى الرؤوس:

احذر من نقاط الضعف التي تجلب جولات العمل. الجزء 1: FragmentSmack/SegmentSmack

مرة أخرى: يتم تغليف الحزم بعلامة Vlan، مغلفة بنفق، مجزأة. لفهم كيفية حدوث ذلك بشكل أفضل، دعونا نتتبع مسار الحزمة من العميل إلى وكيل Nginx.

  1. تصل الحزمة إلى موازن L3. للتوجيه الصحيح داخل مركز البيانات، يتم تغليف الحزمة في نفق وإرسالها إلى بطاقة الشبكة.
  2. نظرًا لعدم احتواء الحزمة + رؤوس النفق في وحدة MTU، يتم تقطيع الحزمة إلى أجزاء وإرسالها إلى الشبكة.
  3. يقوم المحول بعد موازن L3، عند استلام حزمة، بإضافة علامة Vlan إليها وإرسالها.
  4. يرى المحول الموجود أمام وكيل Nginx (استنادًا إلى إعدادات المنفذ) أن الخادم يتوقع حزمة مغلفة بشبكة Vlan، لذلك يرسلها كما هي، دون إزالة علامة Vlan.
  5. يأخذ Linux أجزاء من الحزم الفردية ويدمجها في حزمة واحدة كبيرة.
  6. بعد ذلك، تصل الحزمة إلى واجهة Vlan، حيث تتم إزالة الطبقة الأولى منها - تغليف Vlan.
  7. يقوم Linux بعد ذلك بإرساله إلى واجهة Tunnel، حيث تتم إزالة طبقة أخرى منه - تغليف Tunnel.

تكمن الصعوبة في تمرير كل هذا كمعلمات إلى tcpdump.
لنبدأ من النهاية: هل توجد حزم IP نظيفة (بدون رؤوس غير ضرورية) من العملاء، مع إزالة تغليف الشبكة المحلية الظاهرية والنفق؟

tcpdump host <ip клиента>

لا، لم تكن هناك مثل هذه الحزم على الخادم. لذلك يجب أن تكون المشكلة موجودة في وقت سابق. هل هناك أي حزم تمت إزالة تغليف Vlan منها فقط؟

tcpdump ip[32:4]=0xx390x2xx

0xx390x2xx هو عنوان IP للعميل بتنسيق سداسي عشري.
32:4 — عنوان وطول الحقل الذي يُكتب فيه SCR IP في حزمة النفق.

كان لا بد من اختيار عنوان الحقل بالقوة الغاشمة، حيث يكتبون على الإنترنت حوالي 40، 44، 50، 54، ولكن لم يكن هناك عنوان IP هناك. يمكنك أيضًا الاطلاع على إحدى الحزم ذات الشكل السداسي (المعلمة -xx أو -XX في tcpdump) وحساب عنوان IP الذي تعرفه.

هل هناك أجزاء من الحزم دون إزالة تغليف Vlan وTunnel؟

tcpdump ((ip[6:2] > 0) and (not ip[6] = 64))

سيُظهر لنا هذا السحر جميع الأجزاء، بما في ذلك الجزء الأخير. ربما، يمكن تصفية نفس الشيء عن طريق IP، لكنني لم أحاول، لأنه لا يوجد الكثير من هذه الحزم، ويمكن العثور بسهولة على تلك التي أحتاجها في التدفق العام. ها هم:

14:02:58.471063 In 00:de:ff:1a:94:11 ethertype IPv4 (0x0800), length 1516: (tos 0x0, ttl 63, id 53652, offset 0, flags [+], proto IPIP (4), length 1500)
    11.11.11.11 > 22.22.22.22: truncated-ip - 20 bytes missing! (tos 0x0, ttl 50, id 57750, offset 0, flags [DF], proto TCP (6), length 1500)
    33.33.33.33.33333 > 44.44.44.44.80: Flags [.], seq 0:1448, ack 1, win 343, options [nop,nop,TS val 11660691 ecr 2998165860], length 1448
        0x0000: 0000 0001 0006 00de fb1a 9441 0000 0800 ...........A....
        0x0010: 4500 05dc d194 2000 3f09 d5fb 0a66 387d E.......?....f8}
        0x0020: 1x67 7899 4500 06xx e198 4000 3206 6xx4 [email protected].
        0x0030: b291 x9xx x345 2541 83b9 0050 9740 0x04 .......A...P.@..
        0x0040: 6444 4939 8010 0257 8c3c 0000 0101 080x dDI9...W.......
        0x0050: 00b1 ed93 b2b4 6964 xxd8 ffe1 006a 4578 ......ad.....jEx
        0x0060: 6966 0000 4x4d 002a 0500 0008 0004 0100 if..MM.*........

14:02:58.471103 In 00:de:ff:1a:94:11 ethertype IPv4 (0x0800), length 62: (tos 0x0, ttl 63, id 53652, offset 1480, flags [none], proto IPIP (4), length 40)
    11.11.11.11 > 22.22.22.22: ip-proto-4
        0x0000: 0000 0001 0006 00de fb1a 9441 0000 0800 ...........A....
        0x0010: 4500 0028 d194 00b9 3f04 faf6 2x76 385x E..(....?....f8}
        0x0020: 1x76 6545 xxxx 1x11 2d2c 0c21 8016 8e43 .faE...D-,.!...C
        0x0030: x978 e91d x9b0 d608 0000 0000 0000 7c31 .x............|Q
        0x0040: 881d c4b6 0000 0000 0000 0000 0000 ..............

هذان جزءان من حزمة واحدة (نفس المعرف 53652) مع صورة (كلمة Exif مرئية في الحزمة الأولى). نظرًا لوجود حزم على هذا المستوى، ولكن ليس في النموذج المدمج في مقالب النفايات، فمن الواضح أن المشكلة تكمن في التجميع. وأخيرا هناك دليل وثائقي على ذلك!

لم تكشف وحدة فك ترميز الحزمة عن أي مشاكل من شأنها أن تمنع الإنشاء. حاولت ذلك هنا: hpd.gasmi.net. في البداية، عندما تحاول إدخال شيء ما هناك، فإن وحدة فك التشفير لا تحب تنسيق الحزمة. اتضح أن هناك ثمانيتين إضافيتين بين Srcmac وEthertype (لا علاقة لها بمعلومات الأجزاء). وبعد إزالتها، بدأ جهاز فك التشفير في العمل. ومع ذلك، لم تظهر أي مشاكل.
مهما قال المرء، لم يتم العثور على أي شيء آخر باستثناء تلك Sysctl. كل ما تبقى هو إيجاد طريقة لتحديد الخوادم التي بها مشكلات من أجل فهم الحجم واتخاذ قرار بشأن الإجراءات الإضافية. تم العثور على العداد المطلوب بسرعة كافية:

netstat -s | grep "packet reassembles failed”

وهو موجود أيضًا في snmpd ضمن OID=1.3.6.1.2.1.4.31.1.1.16.1 (ipSystemStatsReasmFails).

"عدد حالات الفشل التي اكتشفتها خوارزمية إعادة تجميع IP (لأي سبب كان: انتهاء المهلة، أو الأخطاء، وما إلى ذلك)."

من بين مجموعة الخوادم التي تمت دراسة المشكلة عليها، زاد هذا العداد على اثنين بشكل أسرع، وعلى اثنين أبطأ، وعلى اثنين آخرين لم يزد على الإطلاق. كشفت مقارنة ديناميكيات هذا العداد مع ديناميكيات أخطاء HTTP على خادم Java عن وجود ارتباط. أي أنه يمكن مراقبة العداد.

يعد وجود مؤشر موثوق للمشكلات أمرًا مهمًا للغاية حتى تتمكن من تحديد ما إذا كان التراجع عن Sysctl يساعد بدقة، لأننا نعلم من القصة السابقة أنه لا يمكن فهم ذلك على الفور من التطبيق. سيسمح لنا هذا المؤشر بتحديد جميع مجالات المشاكل في الإنتاج قبل أن يكتشفها المستخدمون.
بعد التراجع عن Sysctl، توقفت أخطاء المراقبة، وبالتالي تم إثبات سبب المشكلة، وكذلك حقيقة أن التراجع يساعد.

لقد قمنا بإرجاع إعدادات التجزئة على الخوادم الأخرى، حيث بدأ تشغيل المراقبة الجديدة، وفي مكان ما خصصنا ذاكرة أكبر للأجزاء مما كانت عليه في السابق (كانت هذه إحصائيات UDP، والتي لم يكن فقدانها الجزئي ملحوظًا على الخلفية العامة) .

أهم الأسئلة

لماذا يتم تجزئة الحزم على موازن L3 الخاص بنا؟ معظم الحزم التي تصل من المستخدمين إلى الموازنات هي SYN وACK. أحجام هذه العبوات صغيرة. ولكن نظرًا لأن حصة هذه الحزم كبيرة جدًا، فلم نلاحظ على خلفيتها وجود حزم كبيرة بدأت في التفتت.

كان السبب هو وجود برنامج نصي للتكوين معطل com.advmss على الخوادم ذات واجهات Vlan (كان هناك عدد قليل جدًا من الخوادم ذات حركة المرور الموسومة في الإنتاج في ذلك الوقت). يتيح لنا Advmss أن ننقل إلى العميل المعلومات التي تفيد بأن الحزم في اتجاهنا يجب أن تكون أصغر حجمًا بحيث لا يلزم تجزئتها بعد إرفاق رؤوس النفق بها.

لماذا لم يساعد التراجع عن Sysctl، لكن إعادة التشغيل فعلت ذلك؟ أدى التراجع عن Sysctl إلى تغيير مقدار الذاكرة المتوفرة لدمج الحزم. في الوقت نفسه، من الواضح أن حقيقة تجاوز ذاكرة الأجزاء أدت إلى تباطؤ الاتصالات، مما أدى إلى تأخير الأجزاء لفترة طويلة في قائمة الانتظار. أي أن العملية جرت في دورات.
أدت عملية إعادة التشغيل إلى مسح الذاكرة وعاد كل شيء إلى نصابه.

هل كان من الممكن الاستغناء عن الحل البديل؟ نعم، ولكن هناك خطر كبير بترك المستخدمين بدون خدمة في حالة وقوع هجوم. وبطبيعة الحال، أدى استخدام الحل البديل إلى مشاكل مختلفة، بما في ذلك تباطؤ إحدى الخدمات للمستخدمين، ولكن مع ذلك نعتقد أن الإجراءات كانت مبررة.

شكرا جزيلا لأندريه تيموفيف (أتيموفيف) للمساعدة في إجراء التحقيق، وكذلك أليكسي كرينيف (جهازx) - للعمل الضخم المتمثل في تحديث Centos والنواة على الخوادم. وهي العملية التي في هذه الحالة كان لا بد من البدء بها من البداية عدة مرات، ولهذا السبب استمرت لعدة أشهر.

المصدر: www.habr.com

إضافة تعليق