يُفعَّل ModSecurity مع مجموعة قواعد OWASP CRS في عشر دقائق ويُعطَّل بعد ثلاثة أيام — بعد أن تتوقف المقالات عن الحفظ في لوحة الإدارة، ويتعطّل رفع الملفات، ويعجز عميل عن إتمام طلبه لأن عنوانه احتوى فاصلة عليا. وينساق المرء إلى نتيجة «جدار حماية التطبيقات يعيق العمل»، وهي خاطئة: فكل هذه الحجوب تقريبًا تُعالَج بثلاثة أو أربعة استثناءات دقيقة، وكل الحيلة في إيجادها على نحو صحيح.

لا تفعّل الحجب فورًا

الأسبوع الأول مراقبة فقط. في /etc/modsecurity/modsecurity.conf:

SecRuleEngine DetectionOnly

في هذا الوضع يسجّل جدار حماية التطبيقات كل ما كان سيحجبه ولا يحجب شيئًا. وأسبوع من الحركة الحقيقية — بما فيها عملك أنت في لوحة الإدارة، ورفع الصور، وإتمام طلب — يعطي قائمة بإنذارات كاذبة حقيقية لا افتراضية. والانتقال إلى On لا معنى له إلا بعد معالجة تلك القائمة.

كيف يعمل CRS: ليست قاعدة واحدة بل مجموع

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

والنتيجة العملية: يجب عمل الاستثناء للقاعدة التي منحت النقاط، لا للقاعدة 949110. فإن عطّلت القاعدة الجامعة عطّلت المجموعة بأكملها، ولم يبقَ من جدار الحماية سوى سطر في ملف إعداد.

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

جد القاعدة المذنبة

كل ما تحتاجه موجود في سجل التدقيق (/var/log/modsec_audit.log) وفي سجل أخطاء خادم الويب. ابحث بحسب وقت الحجب:

sudo grep -o 'id "[0-9]*"' /var/log/modsec_audit.log | sort | uniq -c | sort -rn | head

هذه قائمة بتكرار القواعد التي انطلقت. ثم انظر لمعرّف بعينه ما الذي أطلقه بالضبط:

sudo grep -A5 'id "942100"' /var/log/modsec_audit.log | head -40

تحتاج ثلاثة أشياء: معرّف القاعدة، واسم المعامل (ARGS:content، ARGS:comment)، ومسار الطلب. ومنها يُبنى الاستثناء.

المشتبه بهم المعتادون

تتكرر القائمة من موقع إلى آخر:

  • 942100 — حقن SQL. تنطلق على الحقول النصية ذات المحتوى الطويل: متن مقالة، وصف منتج، تعليق. فعلامات الاقتباس والأقواس وكلمات مثل select تبدو مريبة للكاشف داخل نثر عادي؛
  • 941100 وعائلة 941xxx — XSS. تأتي مع محرر مرئي: فوسوم HTML في حقل هي جوهر طريقة عمله؛
  • 920420 — Content-Type غير مسموح. يعطّل واجهات API ورفع الملفات: فالمجموعة الافتراضية من الأنواع المسموحة ضيّقة، وفي الإصدارات الأقدم لم يكن application/json ضمنها؛
  • 913100 — ماسح بحسب User-Agent. يلتقط أدوات مشروعة مع الماسحات: مراقبة التوافر، و curl في سكربتاتك أنت؛
  • 200002، 200004 — أخطاء تحليل متن الطلب. وهي تعني عادة لا هجومًا بل تجاوز حد حجم المتن، أي رفع ملف كبير.

ثلاث طرق لعمل استثناء

بترتيب تصاعدي للفظاظة. وكلها تذهب إلى ملفك أنت (مثلًا /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES.conf) لا إلى ملفات CRS نفسها: فمجموعة القواعد تُحدَّث وستختفي تعديلاتك معها.

أزل معاملًا واحدًا من تحت قاعدة واحدة. الخيار الأدق، وهو ما ينبغي السعي إليه:

SecRuleUpdateTargetById 942100 "!ARGS:content"

عطّل قاعدة على مسار واحد فقط. وهذا مناسب تمامًا حين تكون صفحة بعينها هي مصدر الضجيج — محرر، أو استيراد، أو نموذج تقييم:

SecRule REQUEST_URI "@beginsWith /admin/post" \
    "id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=942100"

عطّل القاعدة بالكامل. ملاذ أخير، وعلامة شبه دائمة على أن السبب لم يُعثر عليه أصلًا:

SecRuleRemoveById 942100

الفرق بين الأول والثالث جوهري. ففي الحالة الأولى يتوقف حقل واحد — متن المقالة — عن الفحص ضد حقن SQL بقاعدة واحدة؛ وفي الثانية والثالثة يتوقف الموقع كله عن الفحص. أما فارق الجهد فنحو خمس دقائق.

بعد التعديلات افحص الإعداد وأعد التحميل برفق:

sudo apachectl configtest && sudo systemctl reload apache2
sudo nginx -t && sudo systemctl reload nginx

ترتيب يوفّر أسبوعًا

  1. أسبوع في وضع DetectionOnly مع عمل طبيعي على الموقع ولوحة الإدارة والرفع.
  2. قائمة بتكرار القواعد من سجل التدقيق. اعمل من الأعلى إلى الأسفل — فالثلاث أو الأربع الأولى تشكّل تسعين بالمئة من الضجيج.
  3. لكل واحدة: حدّد أي معامل وعلى أي صفحة. واعمل الاستثناء بحسب المعامل لا بحسب القاعدة.
  4. والآن فقط SecRuleEngine On.
  5. مرة في الشهر ألقِ نظرة على الحجوب: فقد تغيّر الموقع، أي ظهرت إنذارات كاذبة جديدة.

وعند هذه النقطة الأخيرة ينهار الأمر عادة: فسجل التدقيق غيغابايتات من النص ولن يقرأه أحد يدويًا. ومعنى لوحة مجمّعة هو أن تكون قائمة القواعد التي انطلقت والطلبات المحجوبة ومجموعة القواعد النشطة أمام عينيك بدل استخراجها بـ grep. وشكل ذلك تعرضه صفحة العرض التوضيحي أدناه.