الأمن السيبراني الأدلة التقنية

CrowdSec: اكتشاف هجمات التخمين وحظرها جماعياً

نبني مختبراً من حاويتين، نشن تخميناً حقيقياً على SSH، ونرى CrowdSec يكتشفه ويصدر قرار حظر ينفذه الجدار الناري.

CrowdSec: اكتشاف هجمات التخمين وحظرها جماعياً

إذا فتحت سجل الدخول على أي سيرفر مكشوف للإنترنت، فسوف تجد مئات محاولات الدخول الفاشلة كل يوم من عناوين لا تعرفها، تجرب أسماء مستخدمين وكلمات مرور شائعة واحداً تلو الآخر. وأداة fail2ban التقليدية تحظر العنوان الذي يكرر المحاولة على سيرفرك، لكنها تنتظر حتى يهاجمك هو، فكل سيرفر يبدأ من الصفر ويتعلم المهاجمين بنفسه. وفكرة CrowdSec مختلفة: يكتشف السلوك المريب محلياً كما يفعل fail2ban، لكنه يفصل الاكتشاف عن التنفيذ، ويستطيع أن يشارك ويستفيد من قائمة حظر جماعية بنيت من ملايين السيرفرات. وفي هذا المقال نبني مختبراً حقيقياً من Containers: واحدة تهاجم وواحدة تدافع، ونرى CrowdSec يكتشف التخمين ويصدر قرار حظر فعلياً، ثم ينفذه حاجز Bouncer فيحجب المهاجم.

وهذا المقال هو الرابع في مرحلة الأمن السيبراني، ويأتي بعد تقوية السيرفر Hardening، فالتقوية تقلل سطح الهجوم، وCrowdSec يضيف طبقة الدفاع النشط التي ترد على من يحاول. وقد شرحنا الفرق بين fail2ban وCrowdSec بإيجاز في حماية تطبيقات الويب على مستوى HTTP، وهنا نذهب أعمق بمختبر كامل. وسوف نتناول ما يلي:

  • كيف يعمل CrowdSec: الوكيل Agent والحاجز Bouncer والسيناريو Scenario والقرار Decision.
  • بناء مختبر من Containers: مهاجم وهدف على شبكة Docker معزولة.
  • تخمين Brute Force حقيقي على SSH بأداة hydra، في بيئة نملكها فقط.
  • مشاهدة CrowdSec يكتشف الهجوم ويصدر قرار حظر، بمخرجات cscli الحقيقية.
  • تثبيت حاجز الجدار الناري Firewall Bouncer، والتأكد أن المهاجم صار محجوباً فعلاً.
  • مشكلة واجهتنا في المختبر: لماذا لم تظهر أي قرارات في البداية، وكيف حللناها.

كيف يعمل CrowdSec؟ الاكتشاف منفصل عن التنفيذ

يقسم CrowdSec العمل إلى جزأين مستقلين، وهذا أهم ما يميزه:

  • الوكيل Agent: يقرأ السجلات Logs ويحللها بقواعد تسمى السيناريوهات Scenarios، فإذا طابق سلوكاً مريباً اتخذ قراراً Decision، مثل حظر عنوان معين أربع ساعات. والوكيل لا يحجب أحداً بنفسه، بل يسجل القرار فقط في واجهة محلية LAPI.
  • الحاجز Bouncer: برنامج منفصل يقرأ القرارات من الوكيل وينفذها، فحاجز الجدار الناري يضيف قاعدة iptables تمنع العنوان، وحاجز خادم الويب يرد عليه بصفحة حظر. ويمكن أن يكون لديك عدة حواجز لنفس الوكيل.

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

حاويتان على شبكة Docker: Container المهاجم scc-cs-attacker تشغل hydra ضد SSH على Container الهدف scc-cs-target، وعلى الهدف تكتب خدمة SSH الدخول الفاشل في auth.log، فيقرؤه وكيل CrowdSec ويحلله بسيناريو ssh-bf فيصدر قرار حظر، ثم يطبقه الحاجز Bouncer بقاعدة iptables فيحجب الاتصال التالي
مختبر CrowdSec: المهاجم على اليمين، والهدف بالوكيل والحاجز على اليسار
💡
يعمل الوكيل بفكرة الدلو المثقوب Leaky Bucket: كل حدث مريب يسكب نقطة في دلو، والدلو يسرب نقطة مع الوقت، فإذا امتلأ قبل أن يسرب أصدر قراراً. وهذا يميز بين موظف أخطأ كلمة المرور مرتين، ومهاجم يجرب عشرات المرات في ثوان.

بناء المختبر: شبكة Docker وContainers

نبدأ بشبكة Docker معزولة وContainers اثنتين من Debian 13، واحدة للهدف نمنحها صلاحية NET_ADMIN لأن الحاجز سوف يعدل قواعد الجدار الناري، وواحدة للمهاجم:

docker network create scc-cs-net
docker run -d --name scc-cs-target --network scc-cs-net \
  --cap-add NET_ADMIN --cap-add NET_RAW debian:trixie-20261005-slim sleep infinity
docker run -d --name scc-cs-attacker --network scc-cs-net \
  debian:trixie-20261005-slim sleep infinity
🛑
كل ما في هذا المقال يجري داخل شبكة Docker معزولة على جهاز نملكه، والمهاجم Container نملكه نهاجم به هدفاً نملكه. لا تستخدم hydra أو أي أداة تخمين على أي نظام أو عنوان لا تملكه أو لا تملك إذناً مكتوباً باختباره، فالتخمين دون إذن مخالفة نظامية.

تجهيز الهدف: خدمة SSH ووكيل CrowdSec

على Container الهدف نثبت خدمة SSH مع rsyslog لتكتب الدخول الفاشل في /var/log/auth.log، ونثبت CrowdSec من مستودعه الرسمي، وننشئ مستخدماً للاختبار:

apt-get install -y openssh-server rsyslog iptables ipset
curl -s https://install.crowdsec.net | sh
apt-get install -y crowdsec
useradd -m -s /bin/bash testuser
echo "testuser:Correct-Horse-123" | chpasswd

ثم نثبت مجموعة sshd التي تحتوي على المحلل Parser وسيناريوهات التخمين، ونخبر CrowdSec بمكان السجل عبر ملف جمع Acquisition:

cscli collections install crowdsecurity/sshd
cat > /etc/crowdsec/acquis.d/sshd.yaml <

وبما أن الـ Container لا يشغل systemd، نشغل الخدمات الثلاث يدوياً: rsyslog وsshd ووكيل CrowdSec:

ssh-keygen -A
/usr/sbin/rsyslogd
/usr/sbin/sshd
crowdsec

أول محاولة: لماذا لم يظهر أي قرار؟

قبل أن ننجح، نقف عند خطأ وقعنا فيه فعلاً في المختبر لأنه درس مفيد. بعد تشغيل تخمين كامل على SSH، فتحنا قائمة القرارات فوجدناها فارغة:

cscli decisions list
No active decisions

والسبب ظهر في مقياس الجمع Acquisition Metrics، فكل الأسطر كانت «غير مقروءة» Unparsed:

| Source                 | Lines read | Lines parsed | Lines unparsed |
| file:/var/log/auth.log | 77         | -            | 77             |

ومعنى «غير مقروءة» أن الوكيل قرأ الأسطر لكنه لم يفهمها، فلم تصل أصلاً إلى سيناريو SSH. وبعد البحث تبين سببان:

  • تنسيق التاريخ: كان rsyslog يكتب التاريخ بصيغة ISO حديثة، بينما يتوقع محلل syslog في CrowdSec الصيغة التقليدية Oct 25 20:42:14، فأجبرنا rsyslog على الصيغة التقليدية بإضافة سطر إعداد واحد.
  • محلل أساسي ناقص: مجموعة sshd تحتاج المحلل الأساسي crowdsecurity/syslog-logs الذي يقسم سطر syslog إلى أجزاء، ولم يكن مثبتاً، فكل سطر يصل خاماً ولا يعرف الوكيل أين اسم البرنامج ولا الرسالة.

فأضفنا السطر لتنسيق التاريخ وثبتنا المحلل الأساسي، ثم أعدنا تشغيل الوكيل:

echo '$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat' > /etc/rsyslog.d/00-traditional.conf
cscli parsers install crowdsecurity/syslog-logs crowdsecurity/dateparse-enrich
⚠️
إذا رأيت أسطرك كلها Unparsed في مقياس الجمع، فالمشكلة ليست في السيناريو بل قبله، في المحلل. تحقق من أن المحلل الأساسي لنوع السجل مثبت، ومن أن تنسيق التاريخ في سجلك هو ما يتوقعه المحلل. ولاحظ أيضاً أن OpenSSH 10 يسجل باسم العملية sshd-session لا sshd، وهذا يتعامل معه محلل CrowdSec الحديث، لكن محللاً قديماً قد يفوته.

تنفيذ التخمين من Container المهاجم

على Container المهاجم نثبت أداة hydra، ونجهز قائمة كلمات مرور شائعة، ثم نشغل التخمين على خدمة SSH في الهدف:

hydra -l testuser -P /root/passwords.txt -t 4 -W 1 ssh://192.168.112.2

وبعد ثوان نعود إلى Container الهدف ونسأل CrowdSec: هل اكتشف شيئاً؟ أولاً نرى مقياس الجمع وقد صار يقرأ الأسطر فعلاً:

| Source                 | Lines read | Lines parsed | Lines unparsed | Lines poured to bucket |
| file:/var/log/auth.log | 38         | 21           | 17             | 66                     |

ثم نسأل عن التنبيهات Alerts التي أنشأها:

cscli alerts list
| ID | value            | reason                    | decisions | created_at           |
| 2  | Ip:192.168.112.3 | crowdsecurity/ssh-slow-bf | ban:1     | 2026-10-25T20:44:09Z |
| 1  | Ip:192.168.112.3 | crowdsecurity/ssh-bf      | ban:1     | 2026-10-25T20:44:09Z |

وأخيراً قائمة القرارات Decisions الفعلية:

cscli decisions list
| ID | Source   | Scope:Value      | Reason                    | Action | Events | expiration |
| 2  | crowdsec | Ip:192.168.112.3 | crowdsecurity/ssh-slow-bf | ban    | 11     | 3h59m50s   |

في المخرج أعلاه لاحظ التالي:

  • اكتشف الوكيل عنوان المهاجم 192.168.112.3 وأصدر قرار حظر Ban عليه لمدة أربع ساعات تقريباً، بناءً على أحد عشر حدثاً Events.
  • طابق سيناريوهان مختلفان: ssh-bf للتخمين السريع، وssh-slow-bf للتخمين البطيء، ولكل منهما تنبيه، بينما القرار الفعلي واحد لأن العنوان نفسه.
  • السبب Reason يذكر السيناريو الذي أصدر القرار، فتعرف لماذا حظر هذا العنوان، لا مجرد أنه حظر.

تنفيذ الحظر: حاجز الجدار الناري Firewall Bouncer

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

apt-get install -y crowdsec-firewall-bouncer-iptables

يسجل التثبيت الحاجز تلقائياً عند الوكيل ويكتب مفتاح API في إعداده. وبما أننا في Container بلا systemd، نشغل الحاجز يدوياً:

crowdsec-firewall-bouncer -c /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml

وبعد ثوان نتأكد أن الحاجز متصل بالوكيل، وأنه أنشأ قاعدة الحظر:

cscli bouncers list
iptables -L CROWDSEC_CHAIN -n
ipset list crowdsec-blacklists-0
DROP  all  --  0.0.0.0/0  0.0.0.0/0  match-set crowdsec-blacklists-0 src /* CrowdSec */
Name: crowdsec-blacklists-0
Number of entries: 1
Members:
192.168.112.3 timeout 13674

أي أن عنوان المهاجم دخل قائمة الحظر crowdsec-blacklists-0، وقاعدة iptables تسقط DROP كل حزمة منه. والآن نعود إلى Container المهاجم ونجرب الاتصال بـ SSH:

ssh -o ConnectTimeout=6 [email protected]
ssh: connect to host 192.168.112.2 port 22: Connection timed out

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

رفع الحظر Unban

قد يحظر CrowdSec عنواناً بالخطأ، مثل موظف أخطأ كلمة المرور مراراً، فترفع الحظر يدوياً بأمر واحد:

cscli decisions delete --ip 192.168.112.3
2 decision(s) deleted

وخلال ثوان يحدث الحاجز قائمته فيزيل العنوان من قائمة الحظر، ويعود المهاجم يصل إلى الخدمة، وقد تأكدنا من ذلك بإعادة محاولة الاتصال، فتغير الرد من «انتهت المهلة» إلى «رفض الصلاحية Permission denied»، أي أن الاتصال وصل إلى الخدمة ورفضته المصادقة لا الجدار الناري. ولا تحتاج أن تعيد تشغيل أي شيء، فالوكيل والحاجز يتزامنان وحدهما.

القائمة الجماعية والقائمة المحلية

ما فعلناه حتى الآن محلي بالكامل، ويكفي لحماية سيرفراتك. لكن أقوى ما في CrowdSec أنك تستطيع أن تشترك مجاناً في قائمة الحظر الجماعية Community Blocklist، فيحظر سيرفرك العناوين التي هاجمت سيرفرات أخرى حول العالم قبل أن تصل إليك أصلاً، وهذا ما لا يستطيعه fail2ban. والمشاركة اختيارية: ترسل تقارير الهجمات التي رأيتها، وتستقبل القائمة الجماعية، ويمكنك إيقاف الإرسال مع الإبقاء على الاستقبال. وجميع المكونات مفتوحة المصدر برخصة MIT، والوكيل والحواجز مجانية بلا حد، والخدمات المدفوعة اختيارية للمؤسسات الكبيرة فقط.

مشكلات شائعة Common Problems وحلولها

  • كل الأسطر Unparsed: المحلل الأساسي crowdsecurity/syslog-logs غير مثبت، أو تنسيق تاريخ السجل مختلف عما يتوقعه، فثبت المحلل واضبط تنسيق rsyslog التقليدي.
  • لا قرارات رغم ظهور الأسطر مقروءة: تحقق من مقياس السيناريوهات cscli metrics، فقد يكون عدد المحاولات أقل من عتبة Overflow السيناريو، فزد المحاولات أو راجع نافذة الزمن.
  • القرار موجود لكن المهاجم غير محجوب: الحاجز لا يعمل أو غير متصل، فافحص cscli bouncers list وسجل الحاجز، وتأكد أن الContainer تملك صلاحية NET_ADMIN.
  • تثبيت الحاجز يتوقف: في Container بلا systemd قد يعلق سكربت التثبيت عند محاولة تشغيل الخدمة، والحل أن تشغل الحاجز يدوياً كما فعلنا، أما على سيرفر حقيقي فـ systemctl enable --now يكفي.

الخلاصة

وصلنا لنهاية الموضوع، وأهم ما ظهر في المختبر:

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

وفي المقالات القادمة من هذه المرحلة ننتقل إلى الجانب الأحمر بإذن ومنهجية: اختبار الاختراق المصرح به، ثم Kali Linux، ثم Nmap.

دليلمصطلحات الأمن السيبراني للمبتدئين: من CVE إلى Purple Teamماذا تعني الكلمات التي تتكرر في كل عرض أمني، من رقم الثغرة وخطورتها إلى أدوات المراقبة SOC والفرق الحمراء والزرقاء.دليلتقوية السيرفر Hardening وقياسها مع Lynis ومعايير CISالتقوية حالة تقاس برقم لا شعور، فنقيس خادم Debian قبل وبعد بأداتي Lynis وCIS ونرى الفرق على السيرفر نفسه.دليلتأمين سيرفر VPS على Ubuntu من أول دخولقبل أن تثبت أي تطبيق على سيرفرك الجديد، هذه الخطوات تغلق أبرز الثغرات وأولها الدخول بمفتاح SSH بدل كلمة المرور.دليلاختبار الاختراق المصرح به: المنهجية والإذن والتقريرالأمر الذي ينفذه المختبر هو نفسه أمر المهاجم، والفرق ورقة: الإذن والنطاق وقواعد الاشتباك، ثم تقرير يصلح الفريق على أساسه.دليلاستكشاف الشبكة والمنافذ والخدمات مع Nmapنشغل Nmap على مختبر من Containers نملكها بثلاث خدمات، ونمر على الاكتشاف وفحص المنافذ وكشف الإصدار ومحرك السكربتات NSE بمخرج حقيقي.

تدريب عملي Practice

  • كرر المختبر، لكن بدل SSH استخدم خادم ويب nginx ومجموعة crowdsecurity/nginx، وشغل تخميناً على صفحة دخول، وراقب أي سيناريو يطابق.
  • على سيرفرك الحقيقي، ثبت CrowdSec في وضع القراءة فقط أسبوعاً دون حاجز، ثم افتح cscli alerts list وانظر كم عنواناً كان سيحظر، وما السيناريوهات التي طابقت.

سجل التحديثات

  • أكتوبر 2026: كتابة المقال وتنفيذ المختبر يوم 25 أكتوبر 2026 على Container اثنين من Debian 13 مع CrowdSec 1.8.1 وحاجز الجدار الناري 0.0.36 وhydra 9.5، واكتشاف قرار حظر فعلي على عنوان المهاجم وتنفيذه بـ iptables.
نشرة عرب رووت | ArabRoot

معرفة تستحق مكاناً في بريدك.

مقالات مختارة وأدوات مفيدة وأفكار لمشروعك القادم، في رسالة واحدة كل أسبوع.

يمكنك إلغاء الاشتراك متى شئت. الخصوصية

تم استلام طلبك. افتح بريدك واضغط رابط التأكيد لإتمام الاشتراك.