تخطَّ إلى المحتوى

تحليل تقني معمّق

تصليب JBoss / WildFly ضد DDoS: حدود مستمع Undertow وخيوط الإدخال والإخراج

آخر تحديث: أغسطس 2026 · حدود مستمع Undertow وخيوط IO والطبقة الأمامية · زمن القراءة ~15 دقيقة

قلعة داخلية ببوابتها المحدودة قائمة خلف سور خارجي؛ حتى حيث يُخترق السور الخارجي، تظل القلعة تُقنّن ما تسمح بدخوله وتُبقي نواة صغيرة هادئة.

في JBoss EAP وWildFly يقع سطح DDoS في Undertow لا في موصّل Tomcat. الخصائص الحاملة هي max-connections ومُهَل الطلب والفصل بين خيوط الإدخال/الإخراج والعمل، وتُضبط جميعها عبر واجهة الإدارة CLI. Undertow غير حاجب، فالاتصال البطيء يكلّف مخزناً مؤقتاً لا خيط عمل. لكن، كما في Tomcat، يُوضع خادم التطبيقات خلف طبقة أمامية مُصلَّبة لا في الإنترنت المفتوح.

يُصلّب هذا الدليل خادمَي JBoss EAP وWildFly نفسيهما ضد الجزء المُستنزِف للاتصالات والخيوط من هجوم DDoS. وأول فرق مهم: في EAP أو WildFly حديث، خادم الويب هو Undertow لا موصّل JBossWeb القديم، وكل شيء يُضبط في نظام Undertow الفرعي عبر واجهة الإدارة CLI. فإن كنت لا تزال على JBoss AS 5/6 بـ JBossWeb فإن دليل Tomcat أقرب إلى إعدادك، والفكرة الأكبر أن خادماً انتهى دعمه هو بذاته ثغرة.

كما في Tomcat، فإن JBoss خادم تطبيقات ويُوضع خلف طبقة أمامية مُصلَّبة. وحدود Undertow أدناه هي الخط الثاني، يُطبَّق خلف تلك الطبقة. وتأتي كل خاصية مع أمر jboss-cli.sh والعدّاد الذي يُظهر عملها.

أشكال الهجوم وخصائص Undertow التي تجيب عنها
الجهازشكل الهجومخاصية Undertowمسار CLI
ترويسة بطيئة / جسم بطيءno-request-timeout, request-parse-timeout/subsystem=undertow/server=*/http-listener=*
طوفان الاتصالاتmax-connections; tcp-backloghttp-listener + socket-binding
استنزاف الخيوط / الإدخال والإخراجio-threads, task-max-threads (worker)/subsystem=io/worker=default
إساءة استخدام الطلبات الكبيرةmax-header-size, max-parameters, max-post-size/subsystem=undertow/server=*/http-listener=*
التعرّض المباشر للإنترنتاربط المستمع داخلياً؛ الطبقة الأمامية تُنهي الاتصالواجهة socket-binding

مثل Tomcat، فإن JBoss خادم تطبيقات: التصميم القياسي يضع أمامه طبقة مُصلَّبة، وحدود Undertow هذه هي الخط الثاني خلفها. ولا ينفع أيٌّ منها حين يملأ الهجوم القناة.

0. أولاً القياسات المرجعية: اقرأ مقاييس المستمع ومجموعة العمل

يوفّر Undertow ونظام الإدخال/الإخراج الفرعي مقاييس وقت التشغيل عبر CLI. فعّل الإحصاءات واقرأها خلال أسبوع عادي:

# تفعيل إحصاءات Undertow
/subsystem=undertow:write-attribute(name=statistics-enabled,value=true)

# الاتصالات النشطة والمعالجة على مستمع HTTP
/subsystem=undertow/server=default-server/http-listener=default:read-resource(include-runtime=true)

# مجموعة العمل: الخيوط المشغولة مقابل core/max
/subsystem=io/worker=default:read-resource(include-runtime=true)

عدد الاتصالات النشطة للمستمع وعدد الخيوط المشغولة في مجموعة العمل هما القياسان المرجعيان اللذان تُضبط كل قيمة أدناه قياساً عليهما.

1. الطبقة الأمامية أولاً

تأكّد أن Undertow ليس مكشوفاً مباشرةً على واجهة عامة:

# يجب أن يكون http socket-binding على واجهة داخلية لا عامة
/socket-binding-group=standard-sockets/socket-binding=http:read-resource(include-runtime=true)
ss -ltnp | grep 8080

إن كان عاماً فاربطه داخلياً ودع طبقة أمامية مُصلَّبة تُنهي اتصال الإنترنت. ويتناول تلك الطبقة دليلا nginx وApache. فالطبقة الأمامية تحمل TLS وتحديد المعدّل وطرد الاتصالات البطيئة أفضل مما ينبغي لخادم تطبيقات أن يحمله.

2. حدود اتصال المستمع ومُهَله الزمنية

يحمل http-listener سقف الاتصالات والمُهلتين اللتين تجيبان عن هجمات الطلب البطيء. اضبطهما عبر CLI:

# حدّ الاتصالات المتزامنة على المستمع
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-connections,value=8192)

# Slowloris: الوقت المتاح لتحليل ترويسات الطلب
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=request-parse-timeout,value=30000)

# اتصال خامل لم يُرسل طلباً
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=no-request-timeout,value=30000)

# طبّق عبر reload لا إعادة تشغيل
reload

كلتا المُهلتين غير مضبوطتين افتراضياً، لذا يجب ضبطهما صراحةً على أي مستمع مكشوف. request-parse-timeout يمسك من يُقطّر الترويسات؛ وno-request-timeout يمسك من يفتح اتصالاً ولا يُرسل شيئاً.

3. الفصل بين خيوط الإدخال/الإخراج وخيوط العمل

يفصل Undertow خيوط الإدخال/الإخراج غير الحاجبة عن مجموعة العمل الحاجبة. حدّد حجم كلٍّ منهما بشكل مستقل ولا تخلط بينهما:

# خيوط الإدخال/الإخراج تُدير حلقة الأحداث؛ حدّدها بعدد الأنوية (قاعدة شائعة: الأنوية أو الأنوية*2)
/subsystem=io/worker=default:write-attribute(name=io-threads,value=8)

# مجموعة العمل تعالج العمل الحاجب (servlet)؛ حدّدها بحسب ما تحتمله الكومة/التطبيق
/subsystem=io/worker=default:write-attribute(name=task-max-threads,value=128)

reload

تضخيم io-threads لا يفيد أمام عنق زجاجة في العمل الحاجب، وتضخيم task-max-threads فوق ما تحتمله الكومة يُبدّل استنزافاً باستنزاف للذاكرة. والاتصال البطيء تخدمه خيوط الإدخال/الإخراج بوصفه مخزناً مؤقتاً، ولهذا يقاوم Undertow هجوم Slowloris بحكم تصميمه. والمُهَل أعلاه تحوّل تلك المناعة شبه الكاملة إلى طرد فعلي.

4. حدود حجم الطلب

أغلق سطح الطلبات الكبيرة على المستمع:

/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-header-size,value=8192)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-parameters,value=1000)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-headers,value=100)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-cookies,value=50)
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=max-post-size,value=10485760)
reload

max-parameters وmax-headers مهمّتان لأكثر من الذاكرة: العدد غير المحدود وسيلة رخيصة لحرق المعالج في التحليل، وتاريخياً لإطلاق هجوم على تصادم الـ hash. والقيم الافتراضية سخيّة؛ وتضييقها على مستمع مكشوف لا يكلّف شيئاً مشروعاً.

5. طابور TCP backlog

قيمة backlog في socket-binding هي طابور الاتصالات على مستوى نظام التشغيل المنتظرة للقبول، وهي نظير acceptCount في Tomcat:

/socket-binding-group=standard-sockets/socket-binding=http:write-attribute(name=backlog,value=200)
reload

أبقِ الـ backlog قصيراً لا كبيراً. الطابور الكبير يؤخّر فقط الرفض الذي يحمي مجموعة العمل.

6. عنوان العميل خلف الطبقة الأمامية

مع وجود طبقة أمامية، يجب تفعيل proxy-address-forwarding وإلا سجّلت كل سطر سجلّ وكل قاعدة عنوان الطبقةَ الأمامية لا العميل:

# تفعيل معالجة forwarded-for على المستمع
/subsystem=undertow/server=default-server/http-listener=default:write-attribute(name=proxy-address-forwarding,value=true)
reload

بدونه يُنسب كل طلب إلى الطبقة الأمامية — وهو خلل proxy-IP المتكرّر عبر السلسلة كلها.

العدّادات التي تُربط بالمراقبة

# 1. الاتصالات النشطة على المستمع (read-resource include-runtime) مقابل max-connections
# 2. خيوط العمل المشغولة مقابل task-max-threads (/subsystem=io/worker=default)
# 3. عدّادات request-parse-timeout وno-request-timeout (إحصاءات وقت تشغيل المستمع)
# 4. عدّادات الأخطاء/المعالجة من إحصاءات المستمع
/subsystem=undertow/server=default-server/http-listener=default:read-resource(include-runtime=true,recursive=true)

بلوغ الاتصالات النشطة قيمة max-connections مع انشغال مجموعة العمل علامة أن معدّل الطلبات تجاوز ما يقدر Undertow على استيعابه، وهي النقطة التي يجب فيها أن تأخذ الطبقة الأمامية أو طبقة أعلى الفائض.

الحدّ الصادق لتصليب JBoss

كل ما هنا يدافع عن طبقة التطبيقات، خلف طبقة أمامية ينبغي أن تلتقط معظمه أولاً. وحالتان تقعان خارج ذلك.

الأولى إشباع القناة: الحجم الذي يملأ الأنبوب لا يصل لا إلى الطبقة الأمامية ولا إلى Undertow.

أين تتوقف الطبقة داخل المنشأة عن أن تنفع وصلة الوصول لديك: 10 غيغابت/ث الخط مُشبع أصلاً — الطبقة العليا فقط الجهاز داخل المنشأة يخفّف 2 غيغابت/ث 8 غيغابت/ث 25 غيغابت/ث 120 غيغابت/ث 1 تيرابت/ث+ حجم الهجوم (مقياس لوغاريتمي)
تحت سقف القناة لحدود Undertow نصيب؛ وفوقه لا معنى لأي خاصية.

والثانية طبقة نظام التشغيل تحت الخوادم، ويتناولها دليلا Linux وWindows. ويفترض تصليب JBoss أن الطبقة الأمامية وطبقة نظام التشغيل كلتيهما في مكانهما. وفوق القناة يكون الجواب في الطبقة الشبكية.

ترتيب التطبيق

  1. تأكّد أن المستمع مربوط داخلياً؛ ضع أمامه طبقة مُصلَّبة.
  2. فعّل إحصاءات Undertow؛ سجّل القياسات المرجعية.
  3. اضبط max-connections ومُهلتَي الطلب عبر CLI.
  4. حدّد io-threads بعدد الأنوية وtask-max-threads بحسب الكومة.
  5. فعّل proxy-address-forwarding كي ترى السجلات والقواعد العميل الحقيقي.
  6. اضبط حدود حجم الطلب وطابوراً قصيراً.
  7. اربط مقاييس وقت التشغيل بالمراقبة.

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

أسئلة متكررة

هل الموصّل القديم في JBoss AS هو نفسه Undertow في WildFly؟
لا، وهذا الفرق يحدّد أي الإعدادات ينطبق. كان JBoss AS القديم (5/6) يستخدم JBossWeb، وهو مشتقّ من Tomcat يحمل موصّلاً؛ واستبدله JBoss EAP 7+ وWildFly بـ Undertow، وهو خادم ويب غير حاجب مبني على XNIO. فإن كنت على EAP أو WildFly حديث فكل شيء يُضبط في نظام Undertow الفرعي عبر واجهة الإدارة CLI، لا على موصّل بأسلوب Tomcat. وإن كنت لا تزال على JBossWeb فإن دليل Tomcat أقرب إلى واقعك، والخطوة الأجدى هي الانتقال عن خادم انتهى دعمه.
بمَ يختلف نموذج خيوط Undertow عن Tomcat في سياق DDoS؟
يفصل Undertow خيوط الإدخال/الإخراج عن خيوط العمل. مجموعة صغيرة من خيوط الإدخال/الإخراج تُدير حلقة الأحداث غير الحاجبة ولا تُحجب أبداً؛ أما مجموعة العمل فتعالج الطلبات الحاجبة مثل استدعاءات الـ servlet. والاتصال البطيء تخدمه خيوط الإدخال/الإخراج بوصفه مخزناً مؤقتاً لا بشغل خيط عمل، ولهذا يقاوم Undertow هجمات الاتصال البطيء بحكم تصميمه. والضبط العملي أن تُحدّد io-threads بعدد الأنوية، وtask-max-threads بحسب ما يحتمله التطبيق والكومة، وألا تخلط بينهما: تضخيم خيوط الإدخال/الإخراج لا يفيد أمام عنق زجاجة في العمل الحاجب، والعكس صحيح.
أي مُهلة توقف هجوم الطلب البطيء في Undertow؟
تعمل اثنتان معاً. request-parse-timeout يحدّ الوقت الذي يقضيه Undertow في تحليل ترويسات الطلب، وno-request-timeout يحدّ المدة التي يبقى فيها اتصال خامل مفتوحاً دون إرسال طلب. فعميل Slowloris الذي يُقطّر الترويسات يمسكه request-parse-timeout؛ ومن يفتح اتصالاً ولا يُرسل شيئاً يمسكه no-request-timeout. وكلاهما غير مضبوط افتراضياً، لذا يجب ضبطهما صراحةً على أي مستمع مكشوف، في حدود عشرات الثواني.
أضبطها في standalone.xml أم عبر CLI؟
عبر CLI، ودعه يكتب الإعداد. تحرير standalone.xml يدوياً ممكن لكنه عرضة للخطأ ويضيع إن كان الخادم مُداراً بوحدة تحكم مجال أو بمشغّل مثل OpenShift. أوامر jboss-cli.sh في هذا الدليل متكرّرة الأثر، وتتحقق من أسماء الخصائص، وتُطبَّق على خادم قيد التشغيل عبر reload لا إعادة تشغيل. وتحرير XML يدوياً هو نظير كتابة معلمة Windows في السجلّ بينما يوجد cmdlet مدعوم.
هل يظل JBoss بحاجة إلى طبقة أمامية إذا صُلّب Undertow؟
نعم، للأسباب نفسها التي تنطبق على Tomcat. Undertow قادر ويطلّ على الإنترنت بأمان أكبر من موصّل حاجب، لكن التصميم الإنتاجي القياسي يظل يُنهي TLS ويحدّ المعدّل ويطرد الاتصالات البطيئة عند طبقة أمامية مخصّصة، ثم يمرّر الطلبات النظيفة إلى Undertow عبر شبكة خاصة. وحدود Undertow هنا هي الخط الثاني خلف تلك الطبقة. وقيمتها أن الطبقة الأمامية قد تُتجاوَز في الشبكة الداخلية أو تمرّر هجوماً لم تلتقطه، لكنها لا تحلّ محلّها.
هل توقف هذه الإعدادات هجوماً حجمياً؟
لا. إن ملأ الهجوم القناة أمام الخوادم فلا تصل الطلبات لا إلى الطبقة الأمامية ولا إلى Undertow، ولا تنطبق أي خاصية. كل ما هنا يدافع عن استنزاف الاتصالات والخيوط في طبقة التطبيقات. أما الحجم فوق سعة القناة فمسألة الطبقة الشبكية، ولا يُحلّ في نظام Undertow الفرعي.

النشر: أغسطس 2026

يُحدَّث هذا الدليل كلما طرح المصنّعون طرازات وشروط ترخيص جديدة. كيف نقارن بين المصنّعين