الشيفرة المصدرية: github.com/Alex0176/odoo-web-rbl — بترخيص AGPL-3، متاح للاستخدام بحرية.
كل من يشغّل خادم Odoo على الإنترنت يستقبل زيارات. ليس بين حين وآخر، بل باستمرار. على مدى سبعة عشر يومًا، سجّلنا وحلّلنا 731,297 طلبًا على مواقعنا الخمسة. لم يكن 110,511 منها صادرًا عن زوّار، بل عن عمليات بحث آلية عن ثغرات أمنية وبيانات دخول وملفات إعدادات.
يستعرض هذا المقال Web RBL، وهي وحدة مفتوحة المصدر لإصدار Odoo 19 Community، ترصد هذه الحركة وتقيّمها وتسجّلها وتحظرها، وتنشر قائمة الحظر بصيغة قائمة RBL، أي بالصيغة التي تستطيع جدران الحماية والخوادم الوكيلة العكسية قراءتها مباشرة. جميع الأرقام مستمدة من التشغيل الفعلي.
ما الذي تقدّمه الوحدة — نظرة عامة على الوظائف
| الوظيفة | ما تفعله | الوضع عند التسليم |
|---|---|---|
| التعرّف على الأنماط | ترصد محاولات الاستكشاف من خلال المسار والامتداد: .env و.git وملفات الإعدادات ومفاتيح الخدمات السحابية وتعليمات البناء في CI/CD وWordPress وPHP واجتياز المسارات وأدوات إدارة قواعد البيانات وGraphQL وتنفيذ الأوامر عبر /api/fs/exec والواجهات المشابهة | حظر |
| ثلاثة مستويات لكل نمط | حظر أو عدّ أو إبلاغ — يمكن تغيير الإجراء لكل نمط، دون برمجة | لكل نمط |
| العتبات | عدد مرات رصد النمط نفسه قبل الحظر؛ عشر محاولات لتسجيل الدخول | 10 لتسجيل الدخول |
| الحماية من محاولات تسجيل الدخول | محاولات تسجيل الدخول الفاشلة عبر النموذج وكذلك XML-RPC/JSON-RPC، وفحوص الجلسات الفاشلة، ومحاولات الوصول إلى مدير قواعد البيانات — تُسجّل في قاعدة البيانات، لا في الذاكرة | مفعّل |
| اكتشاف الروبوتات عند تسجيل الدخول | من يتجاهل رسالة الانتظار بعد عشر محاولات فاشلة ويواصل المحاولة يُحظر فورًا | حظر |
| الكشف السلوكي | عناوين تتسبب خلال خمس دقائق في عشرين صفحة خطأ، ولا تكاد تصل إلى صفحة موجودة — أي إنها تخمّن المسارات بدلًا من تصفح المحتوى | إبلاغ |
| تقييم من 0 إلى 100 | ما مدى اليقين بأن وراء العنوان مهاجمًا؟ يُحسب التقييم من خطورة النمط، وعدد الأنماط المختلفة، والأيام التي شهدت نشاطًا مريبًا، والنطاقات المتأثرة، وعدد مرات الرصد — مع توضيح الأسباب بلغة واضحة | مفعّل |
| منع تسجيل الدخول بناءً على التقييم | يُمنع تسجيل الدخول عند بلوغ تقييم قابل للضبط، مع بقاء الموقع متاحًا للقراءة | من 40 فما فوق |
| الاشتباه في سرقة بيانات الدخول | يُبلَّغ عن تسجيل الدخول الناجح من عنوان مريب، ويمكن إسناده كمهمة عند الرغبة — مرة واحدة لكل عنوان في اليوم | مفعّل |
| قوائم التهديدات | عُقد خروج Tor وSpamhaus DROP وFireHOL Level 1 وblocklist.de معدّة مسبقًا؛ يمكن إضافة أي قائمة RBL أخرى بإدخال عنوانها، مع مزامنة يومية ومستوى مستقل لكل قائمة | إبلاغ |
| منع الوصول إلى تسجيل الدخول | المستوى الرابع للقوائم والبلدان: الموقع متاح للقراءة، مع إغلاق نموذج تسجيل الدخول والواجهات — الاستجابة المناسبة لـ Tor | اختياري |
| بلد المصدر | تحديد البلد لكل واقعة رصد ولكل عنوان عبر GeoLite2؛ وتتولى الوحدة تحديث قاعدة البيانات تلقائيًا باستخدام مفتاح ترخيص مجاني | عرض |
| قواعد البلدان | حظر أو منع الوصول إلى تسجيل الدخول أو إبلاغ أو سماح صريح — لكل بلد، دون إعدادات افتراضية عن قصد | لا توجد |
| أخطاء الإعداد | يُكتشف QNAP وSynology وExchange-Autodiscover وActiveSync وWebDAV/CalDAV/CardDAV، ولا تُحظر عناوينها أبدًا، بل تُدرج في قائمة متابعة مع وصف المشكلة والنطاق المتأثر | إبلاغ |
| تذكرة لكل عنوان | يمكن تحويل المشكلة المرصودة إلى تذكرة عند الرغبة — تذكرة واحدة فقط لكل عنوان، وتُعاد فتح التذكرة المغلقة بدلًا من إنشاء نسخة أخرى | معطّل |
| الصفحات الإلزامية وأدوات جمع البيانات | يبقى المسار المعتمد لصفحة البيانات القانونية متاحًا دائمًا؛ وتُكتشف المحاولات الآلية لتجريب صيغ بديلة غير معتمدة ويمكن حظرها عند الرغبة | إبلاغ |
| قائمة السماح | عناوين وشبكات لا تُحظر أبدًا؛ تُضاف إليها يوميًا عناوين من جدار الحماية (الأطراف المقابلة لاتصالات VPN) ومن نطاقات العناوين المنشورة لـ Googlebot وBingbot | مفعّل |
| ربط النشاط بالعميل | يُربط النشاط المرصود من شبكة عميل بذلك العميل — استنادًا إلى قائمة السماح، دون تخمين يدوي | مفعّل |
| النطاق والمعرّف لكل واقعة رصد | أي موقع جرى الوصول إليه، وبأي User-Agent — وكلاهما غير موجود في سجل الوصول | مفعّل |
| التحليل | رسم بياني وجدول محوري لجميع الوقائع المرصودة: حسب النمط واليوم والنطاق والبلد والعنوان | مفعّل |
| الطُّعم | تتلقى طلبات الاستطلاع ردودًا مختلقة تتضمن قيمة تتبّع؛ ومن يطلب هذه القيمة لاحقًا يكون قد قرأ تلك الردود | معطّل |
| إتاحة قائمة RBL | قائمة الحظر بصيغة قائمة عناوين مجردة أو JSON، عبر عنوان خاص محمي برمز وصول — لاستخدامها مع HAProxy وOPNsense وأي جدار حماية يقرأ القوائم من عناوين URL | مفعّل |
كل ما يأتي افتراضيًا بوضع إبلاغ أو معطّل أو اختياري مضبوط على ذلك عن قصد: من يفعّل الحظر ينبغي أن يفعل ذلك لأنه راقب بضعة أيام وعرف من سيشمله الحظر، لا لأن الإعداد الافتراضي فرضه.
التحليل: مرات الرصد لكل نمط على مدى سبعة أيام. يمثّل أعلى عمود عمليات البحث عن ملفات .env.
قوائم RBL: طريقة موحّدة لإتاحة قوائم الحظر
RBL اختصار لـ Real-time Blackhole List. نشأ المصطلح في عالم البريد الإلكتروني، حيث تنشر Spamhaus وجهات أخرى قوائم بعناوين المرسلين الخبيثين منذ التسعينيات. والمبدأ في غاية البساطة، وهذا تحديدًا سبب انتشاره: عنوان واحد في كل سطر، يمكن جلب القائمة عبر HTTP وإعادة تحميلها بانتظام. لا صيغة تحتاج إلى تحليل خاص أولًا، ولا واجهة تتطلب أداة للتعامل معها.
يستطيع كل جدار حماية ووكيل عكسي تقريبًا قراءة قائمة كهذه وبناء قواعد منها. تختلف تسمياتها بين الشركات المصنّعة، لكن الآلية واحدة في كل مكان:
- OPNsense وpfSense — URL Table Alias: تحميل قائمة عناوين عبر HTTP، واستخدامها كاسم مستعار في قواعد جدار الحماية، وتحديثها كل ساعة أو كل يوم
- HAProxy — ملفات ACL وMaps: استخدام
src -f sperrliste.txtفي قاعدةhttp-request deny، مع إمكانية إعادة التحميل عبر واجهة API وقت التشغيل دون إعادة تشغيل - nginx — وحدة geo مع ملف عناوين مضمّن، أو تعليمات
denyمن ملفincludeمولّد - Fortinet FortiGate — External Block List أو Threat Feed: عنوان URL يجلب منه جدار الحماية قائمة بعناوين IP ويستخدمها في السياسات
- Palo Alto Networks — External Dynamic List (EDL): المبدأ نفسه، في صورة نوع مستقل من الكائنات ضمن سياسات الأمان
- Check Point — موجزات معلومات التهديدات المخصصة وقوائم حظر عناوين IP عبر عنوان URL
- Cisco Secure Firewall (Firepower) — Security Intelligence Feeds مع مصادر قوائم مخصّصة
- Sophos Firewall — Third-Party Threat Feeds: قوائم عناوين من عنوان URL تُستخدم مصدرًا لقواعد الحظر
- Juniper SRX — Dynamic Address Entries من موجزات البيانات
- MikroTik RouterOS — Address Lists، تُملأ من عنوان URL باستخدام برنامج نصي والأمر
fetch - CrowdSec — قوائم مخصّصة كمصدر لمكوّنات Bouncer على كل نظام مدعوم
يتيح Web RBL قائمة الحظر بهذه الصيغة تحديدًا. فيُسقط جدار الحماية الحزم قبل وصولها إلى خادم الويب — ومعها أي محاولة أخرى من العنوان نفسه، سواء استهدفت خادم البريد أو بوابة VPN مثلًا.
في الاتجاهين، ولكن في الموضع المناسب
تعمل الآلية في الاتجاه المعاكس أيضًا: يمكن إضافة أي قائمة RBL إلى Web RBL — عنوان URL ومستوى، وانتهى الأمر. عُقد خروج Tor وSpamhaus DROP وFireHOL وblocklist.de معدّة مسبقًا، ويمكن إضافة غيرها بثلاث نقرات. تحلّل الوحدة كل قائمة إلى نطاقات عناوين وتفحص كل طلب بمقارنتها، في بضعة ميكروثوانٍ.
ومع ذلك، من الأنسب استخدام قوائم الجهات الأخرى على جدار الحماية الذي يسبق الخادم. وذلك لثلاثة أسباب. يرى جدار الحماية جميع الخدمات، لا HTTP وحده — فالعنوان المدرج في قائمة Spamhaus ينبغي منعه أيضًا من الوصول إلى خادم البريد وVPN. وهو يُسقط الحزم قبل إنشاء أي اتصال أصلًا، فلا يحمّل خادم التطبيقات أي عبء. كما أنه الموضع الذي تُدار فيه هذه القوائم أصلًا؛ ووجود نسخة ثانية في التطبيق يعني موضعًا ثانيًا قد تصبح بياناته قديمة.
فما فائدة القوائم داخل الوحدة إذن؟ فائدتها فيما يعجز عنه جدار الحماية، فهو لا يعرف نموذج تسجيل الدخول. يستطيع Web RBL منع عنوان مدرج في قائمة Tor من الوصول إلى تسجيل الدخول، مع إبقاء الموقع متاحًا له — فمن يريد القراءة دون كشف هويته ينبغي أن يُسمح له بذلك، أما من يريد تجريب كلمات المرور دون كشف هويته فلا. ويمكنه أيضًا الإبلاغ عن تسجيل دخول ناجح من عنوان مدرج بوصفه حالة اشتباه. وتتطلب الوظيفتان وجود القائمة حيث تجري عملية تسجيل الدخول.
تقييم بدلًا من الحدس
العنوان الذي طلب /wp-login.php مرة واحدة يختلف عن عنوان ظهر خلال يومين بخمسة أنماط مختلفة عبر ثلاثة نطاقات. يحوّل Web RBL ذلك إلى تقييم من 0 إلى 100 — استنادًا إلى ما رصده بنفسه، دون خدمة خارجية ودون إرسال استعلامات إلى الخارج.
سجل واحد: 99 واقعة رصد، وتقييم 84، والأسباب بلغة واضحة — النمط الأشد خطورة، وخمسة أنماط خطيرة مختلفة، ويومان شهدا نشاطًا مريبًا، وأكثر من عشرين واقعة رصد.
يحدّد التقييم أمرين. عند بلوغ قيمة قابلة للضبط، يُمنع تسجيل الدخول — يظل الموقع متاحًا للقراءة، لكن من سبق له البحث عن بيانات الدخول لا يُمنح فرصة لتجريب ما عثر عليه. ويُبلَّغ أيضًا عن تسجيل الدخول الناجح من عنوان له تقييم: فهنا لم يعد الشخص يخمّن، بل كان يعرف البيانات. إما أن المستخدم المخوّل كان يتصل من مكان آخر، أو أن بيانات الدخول وقعت في يد غيره — لا تحسم الوحدة ذلك، بل تعرض الحالة على من يستطيع الاستفسار عنها. ولا يجري المساس بكلمة المرور نفسها في أي موضع خلال ذلك.
قائمة الحظر، مع تصفية التقييمات من 40 فما فوق: عدد مرات الرصد، والأيام التي شهدت نشاطًا مريبًا، والنطاقات المتأثرة، وآخر مسار لكل عنوان.
ما الذي يحميه Web RBL — تفاصيل الحماية
1. تظل بيانات الدخول بعيدة عن الاكتشاف
أكبر فئة من الهجمات المرصودة لا تبحث عن ثغرات في Odoo، بل عن أسرار تُركت مكشوفة. خلال سبعة عشر يومًا:
- 57,721 طلبًا لملفات
.env— وهي تحتوي على كلمات مرور قواعد البيانات ومفاتيح API وأسرار الجلسات - 5,535 طلبًا لملفات الإعداد
- 4,388 طلبًا لبيانات الدخول إلى الخدمات السحابية:
credentials.json،service-account.json،firebase-adminsdk.json،rclone.conf،.git-credentials - 2,811 طلبًا لمجلدات
.git— من يعثر على أحدها ينزّل الشيفرة المصدرية كاملة مع سجل تعديلاتها - 1,907 طلبات لملفات تعليمات البناء مثل
.github/workflows/deploy.ymlأو.gitlab-ci.yml، التي تتضمن سجلات الحزم وأسماء المفاتيح
العامل الحاسم هنا ليس عدد الطلبات، بل عدد العناوين المختلفة: جاءت طلبات /credentials.json من 98 عنوانًا، وطلبات /.git-credentials من 92 عنوانًا. هذه ليست أداة فحص واحدة، بل مجموعة أساليب شائعة تُستخدم بالتزامن حول العالم.
2. إحباط محاولات تسجيل الدخول — بصورة دائمة
يتضمن Odoo آلية خاصة لإبطاء تجريب كلمات المرور. ولها ثلاثة قيود موثّقة في شيفرة Odoo المصدرية نفسها: يوجد العدّاد في ذاكرة العملية العاملة ويُصفّر عند كل إعادة تشغيل، وهي تؤخّر فقط ولا تحظر، ولا تحتسب إلا المحاولات التي تصل إلى مرحلة التحقق من كلمة المرور.
يتدخل Web RBL في المواضع نفسها، لكنه يكتب البيانات في قاعدة البيانات. وبذلك:
- تبقى قيمة العدّاد محفوظة بعد كل إعادة تشغيل وتسري على جميع العمليات العاملة
- تُرصد الطريقتان: نموذج تسجيل الدخول
/web/loginوالواجهتان/xmlrpc/2/commonو/jsonrpc - تُرصد أيضًا المحاولات التي لا تصل مطلقًا إلى التحقق من كلمة المرور — مثل محاولات تسجيل الدخول دون معرّف جلسة صالح
- تُحتسب محاولة الوصول الفاشلة إلى مدير قواعد البيانات أيضًا؛ فهي أخطر محاولات تسجيل الدخول على الإطلاق
ضُبطت عتبة تسجيل الدخول على عشر محاولات استنادًا إلى قياس فعلي: من بين تسع محاولات تسجيل دخول فاشلة خلال سبعة عشر يومًا، كانت غالبيتها من عملاء كانوا يُعدّون الوصول بأنفسهم على جهاز إضافي وأدخلوا نطاقًا خاطئًا — وفي إحدى الحالات كان نطاق العميل نفسه، لكن بشرطة بدلًا من نقطة. لذلك كان الحظر من أول محاولة فاشلة سيطال العملاء أثناء الإعداد بدلًا من المهاجمين.
أما من يواصل المحاولة رغم أن الخادم أجابه بالفعل برسالة «يُرجى الانتظار قليلًا»، فيُحظر فورًا. يقرأ الإنسان هذه الرسالة وينتظر؛ أما من يتجاهلها فهو برنامج. يلتقط نمط مستقل بعتبة صفر هذه الحالة تحديدًا، ولا يمكن أن يطال أحد الزملاء: فلا يصل إلى هذه المرحلة إلا من أخفق عشر مرات ثم واصل المحاولة.
3. لم يعد الهجوم يحمّل الخادم أي عبء
قبل استخدام الوحدة، كان طلب استطلاع لمسار مثل /@fs/../../.env مكلفًا: يبحث Odoo عن صفحة الخطأ ويولّدها، ثم يتعثر أثناء تكوين العنوان بسبب مقاطع النقاط، فيفشل أيضًا في معالجة صفحة الخطأ الخاصة بصفحة الخطأ. سجلّا تتبّع للمكدس لكل طلب استطلاع. رُصد 28,401 خطأ من هذا النوع خلال سبعة عشر يومًا، إلى جانب 9,467 خطأ ناتجًا عنها.
يتدخل Web RBL في ir.http._match، أي قبل توجيه الطلب. ويصدر الرد دون قالب، ودون وصول إلى قاعدة البيانات يتجاوز فحص الحظر، ودون إضافة سطر إلى السجل. يجري فحص قائمة السماح وقوائم التهديدات وقواعد البلدان من الذاكرة المؤقتة باستخدام نطاقات عناوين مرتبة — في بضعة ميكروثوانٍ، حتى مع أكثر من ثلاثين ألف نطاق.
4. جدار الحماية يصدّ المهاجم قبل وصوله
تُنشر قائمة الحظر بصيغة قائمة RBL يقرأها HAProxy وOPNsense مباشرة. وبذلك لا يصل المهاجم إلى خادم الويب أصلًا — ولا إلى أي خدمة أخرى على المضيف نفسه. وهكذا، ما إن يُكتشف طلب خبيث حتى تمتد الحماية إلى الجهاز بأكمله.
ثلاثة مستويات: حظر وعدّ وإبلاغ
ليس كل طلب لمسار غير موجود هجومًا. لذلك يميّز Web RBL بين ثلاثة مستويات، ويمكن تغيير المستوى لكل نمط دون تعديل الشيفرة.
| المستوى | الطلب الذي فعّل الإجراء | ما يترتب على العنوان |
|---|---|---|
| حظر | يُرفض | يُحظر لمدة 24 ساعة، ويصبح الحظر دائمًا بعد ثلاثة أيام تشهد نشاطًا مريبًا |
| عدّ | يُسمح بمروره | يُسجّل فقط، دون حظر |
| إبلاغ | يُسمح بمروره | يُسجّل مع وصف المشكلة، ولا يُحظر أبدًا |
يتوفر مستوى رابع لقوائم التهديدات والبلدان: منع الوصول إلى تسجيل الدخول. يبقى الموقع متاحًا للقراءة، مع إغلاق نموذج تسجيل الدخول والواجهات. وهذا حل وسط لكل ما يثير الشك دون أن يكون خبيثًا بالضرورة — مثل Tor أو نطاق عناوين لمركز بيانات أو بلد لا يوجد فيه عملاء.
الهجمات التي يجري اكتشافها
اختُبرت جميع الأنماط على حركة مرور فعلية. ويُعرض بجانبها عدد العناوين المختلفة عن قصد — فهو يبيّن ما إذا كان النمط يلتقط أداة فحص واحدة أم أسلوبًا واسع الانتشار.
| فئة الهجوم | الطلبات | العناوين |
|---|---|---|
محاولات الاستيلاء على ملفات .env | 57.721 | 223 |
| طلبات استطلاع PHP | 12.237 | 256 |
| اجتياز المسارات للوصول إلى هدف ذي قيمة | 10.046 | 64 |
| ملفات الإعداد | 5.535 | 114 |
| مفاتيح الوصول إلى الخدمات السحابية | 4.388 | 152 |
| طلبات استطلاع WordPress | 3.366 | 385 |
محاولات الاستيلاء على مجلدات .git | 2.811 | 255 |
| استطلاع Odoo (مدير قواعد البيانات، والاستعلام عن الإصدار) | 2.500 | 213 |
سلاسل أدوات الذكاء الاصطناعي وتنفيذ الأوامر (/mcp، /api/fs/exec) | 2.450 | 74 |
| تعليمات البناء (CI/CD) | 1.907 | 88 |
| نقاط نهاية GraphQL | 1.878 | 71 |
الفئة الأحدث لافتة للنظر. طُلب /api/fs/exec 369 مرة من 54 عنوانًا مختلفًا — وهذا ليس طلبًا للقراءة، بل محاولة لتنفيذ أوامر. لم تكن مثل هذه الأهداف موجودة قبل عامين؛ فهي تأتي من واجهات أدوات الذكاء الاصطناعي الجديدة وطوابير المهام. ومن يقصر دفاعاته على WordPress وPHP لن يرصد شيئًا منها. لذلك تُمنح هذه الفئة وزنًا كبيرًا في التقييم.
قوائم التهديدات وبلد المصدر
أربع قوائم، و32,851 نطاق عناوين، وجميعها مضبوطة على «الإبلاغ فقط». وإضافة أي قائمة أخرى لا تتطلب سوى عنوان ومستوى.
قائمة الجهة الخارجية هي حكم يصدره طرف آخر، لأسباب لا نعرفها، بشأن حركة مرور لم نرها قط. قد يكون الحكم خاطئًا أو قديمًا أو موجّهًا لغرض آخر: تجمع blocklist.de أساسًا عناوين جرّبت بيانات تسجيل الدخول إلى SSH في أماكن أخرى، وهذا لا يخبرنا بالكثير عن سلوكها تجاه خادم ويب. لذلك يفصل Web RBL قوائم الجهات الخارجية عن قائمة الحظر الخاصة به، ولذلك يكون الإعداد الافتراضي هو إبلاغ. وتبقى الأولوية دائمًا لقائمة السماح الخاصة بنا: فالعميل الذي نعرفه أرجح من تقدير طرف ثالث.
يظهر بلد المصدر مع كل واقعة رصد وكل عنوان. وهو ضروري لتقدير الحالة — فمحاولة تسجيل دخول من بلدنا عند العاشرة صباحًا تختلف عن محاولة من بلد لا يوجد فيه عميل واحد. لكنه لا يصلح كثيرًا للحظر الشامل، وهذا ما تؤكده أرقامنا: جاء معظم المهاجمين في قائمتنا من نطاقات سحابية في بلجيكا وفنلندا وهولندا. ولو حظرنا كل ما يأتي من خارج البلدان الناطقة بالألمانية لما شملهم الحظر — لكنه كان سيشمل موظفينا في العطلات وعملاءنا في رحلات العمل.
تأتي قواعد البلدان فارغة، وتوضح شاشة العرض السبب.
الإبلاغ عن أخطاء الإعداد بدلًا من الحظر
الحالة الأكثر تكرارًا في حركة المرور الفعلية ليست هجومًا ولا زائرًا، بل برنامج معطوب يحسب خادم الويب شيئًا آخر:
- 1,367 طلبًا لواجهة الويب الخاصة بجهاز QNAP NAS — من برنامج مزامنة لم تعد وجهته صحيحة. وجاءت 962 محاولة من اتصال واحد فقط.
- 65 استعلامًا من Autodiscover — برنامج Outlook يظن أن نطاق الموقع هو خادم Exchange الخاص به
لا تُحظر هذه العناوين أبدًا. فالحظر لا يصلح الخلل، بل يخفيه — ويضر بصاحب الجهاز الذي يعاني أصلًا من إعداد خاطئ. وبدلًا من ذلك، يُنشأ سجل يتضمن وصف المشكلة والنطاقات المتأثرة، ويمكن تحويله تلقائيًا إلى تذكرة عند الرغبة: تذكرة واحدة بالضبط لكل عنوان، وإذا أُغلقت ثم ظهر نشاط مريب من العنوان مجددًا، تُعاد فتح التذكرة نفسها بدلًا من إنشاء ثانية.
يجري اكتشاف QNAP وSynology وExchange-Autodiscover وActiveSync، وكذلك برامج WebDAV وCalDAV وCardDAV. وتحدّد الأنماط أسماء ملفات ومجلدات دقيقة، ولا تعتمد مطلقًا على الامتدادات وحدها: ففي المجلد نفسه /cgi-bin/ توجد طلبات المزامنة غير الضارة إلى جانب أهداف الاستطلاع التقليدية مثل printenv.pl.
قائمة السماح: عناوين لا تُحظر أبدًا
ثمن الخطأ ليس واحدًا لجميع العناوين. فمع ماسح من مركز بيانات لا يكلّف الإنذار الخاطئ شيئًا. أما مع الطرف المقابل لنفق موقع، فإنه يكلّف الموقع كله.
لذلك توجد قائمة ثانية لها الأولوية على الأولى: عناوين وشبكات لا تُحظر أبدًا. لكنها لا توقف الرصد — فالعناوين المدرجة فيها تظل خاضعة للفحص والتسجيل، ويُعفى أصحابها من الإجراء الناتج فقط. وهذا ما يميّزها عن الاستثناء في جدار الحماية: ذاك يحجب الرؤية، وهذه تتيح مزيدًا من التريّث.
تُملأ القائمة يوميًا من مصدرين: من جدار الحماية نفسه، بجميع الأطراف المقابلة لاتصالات VPN، حتى لا يعتمد نفق أُنشئ حديثًا على تذكّر أحدهم تحديث قائمة الحظر — ومن نطاقات العناوين التي تنشرها Google وMicrosoft لبرامج الزحف التابعة لهما. فهذه هي الطريقة الوحيدة لتمييز Googlebot الحقيقي من أداة فحص تنتحل اسمه. يجب ألّا تُحظر محركات البحث أبدًا؛ فمن يمنع وصولها يُخرج موقعه من الفهرسة بلا رجعة.
وهنا تسري قاعدة أهم من المزامنة: الاستجابة الفارغة لا تحذف شيئًا أبدًا. إذا لم يستجب المصدر، أو كانت استجابته فارغة أو غير مفهومة، تبقى القائمة كما هي. فقائمة السماح التي تُفرغ نفسها عند حدوث عطل قد تُسقط جميع الأنفاق في أسوأ لحظة ممكنة.
إذا كان إدخال في قائمة السماح مرتبطًا بعميل، يُنسب إليه كل نشاط مرصود من شبكته. وهكذا يتوافر فورًا طرف يمكن التواصل معه بشأن أي خطأ في الإعداد، من دون الحاجة إلى البحث عن أصحاب العناوين.
البيانات الإلزامية وأدوات جمع البيانات الآلية
صفحة البيانات القانونية ليست صفحة عادية. يجب أن تبقى متاحة للأشخاص، لأن حجبها يُنشئ بالضبط المخالفة التي تبحث عنها أداة الجمع. وفي الوقت نفسه، فهي الصفحة التي تتضمن الاسم والعنوان — ولذلك تستهدفها أدوات الجمع الآلي للبيانات.
في موجة الإنذارات القانونية في النمسا بسبب تضمين خطوط Google، أظهرت السجلات أن الرسائل لم تنشأ من زيارات فردية، بل من حملة آلية شاملة: مضيفون مختلفون لا صلة بينهم، بفارق أجزاء من الثانية.
يعالج Web RBL ذلك عبر خفض التصنيف بدلًا من الاستثناء. فالمسار الأساسي /impressum لا يطابق أي نمط، ويظل متاحًا دائمًا. أما الصيغ الأخرى مثل /impressum.php — التي لا يمكن أن توجد على موقع Odoo — فيُبلَّغ عنها، ومن لا يريد قبول الجمع الآلي للبيانات يمكنه تغيير أحد المعلمات. ويُستثنى sitemap وrobots من ذلك، ولا يمكن حظرهما أصلًا: فهما لا يتضمنان بيانات شخصية، وجلبهما من مهام كل برنامج زحف لمحركات البحث.
النطاق ومعرّف الجهة الطالبة: ما يغيب عن سجل الوصول
لا يسجّل سجل الوصول في werkzeug اسم المضيف المطلوب ولا معرّف الجهة الطالبة. ويتلقى Odoo كليهما بالطبع — فمن دون اسم المضيف لا يمكنه اختيار الموقع الصحيح عند استضافة مواقع متعددة. لكن لا يمكن الرجوع إلى هاتين المعلومتين لاحقًا.
يسجّل Web RBL المعلومتين لكل نشاط مرصود. وهذا يجيب عن سؤالين يتعذر الإجابة عنهما لولا ذلك: أيّ موقع يستهدفه الإعداد الخاطئ — وبالتالي، لأي عميل ينتمي النطاق — وهل يزور العنوان موقعًا واحدًا أم جميع المواقع. فاستهداف عنوان واحد لنطاقات متعددة لا تربطها صلة علامة على حملة مسح شاملة، ويرفع درجة التقييم.
أظهر تحليل أجريناه على أحد مواقعنا مدى أهمية هذا المعرّف: أكثر من سبعين بالمئة من إجمالي حركة الزيارات جاء من جهة طالبة واحدة، موزعًا على أكثر من مئة عنوان. ولولا المعرّف لبدا الأمر وكأنه أداة جمع بيانات موزعة. لكنه كان GPTBot، برنامج الزحف التابع لـ OpenAI — وكان يطلب robots.txt مرارًا ويتصرف بصورة سليمة تمامًا.
الجوانب الأمنية بالتفصيل
1. التعرّف على الوكيل — أخطر نقطة على الإطلاق
إذا كان Odoo يعمل خلف وكيل عكسي وكانت قيمة proxy_mode مضبوطة بشكل خاطئ، فسترى الوحدة العنوان نفسه في كل طلب: عنوان الوكيل. وعندئذ سيؤدي الحظر إلى منع جميع الزوار من الوصول في الوقت نفسه.
لذلك يتحقق Web RBL قبل كل حظر من موثوقية تحديد العنوان. فهو يشترط تفعيل proxy_mode مع وجود ترويسة إعادة توجيه، ويمتنع عن العمل إذا وصل طلب مُعاد توجيهه من دون proxy_mode، وكذلك عند وجود أكثر من وكيل وسيط واحد. وعند الشك، لا يُطبَّق الحظر.
2. الشبكات الخاصة بنا لا تُحظر أبدًا
تُستثنى نطاقات العناوين الخاصة وعناوين الاسترجاع والعناوين المحلية للرابط وCGNAT استثناءً ثابتًا. ولا يمكن أن تُدرج في القائمة تحت أي ظرف، حتى يدويًا. وينطبق الأمر نفسه على القوائم الخارجية: تُستبعد النطاقات الخاصة والمحجوزة والشبكات الضخمة بصورة غير معقولة عند استيرادها.
3. يجب ألّا يتسبب خطأ في الوحدة في تعطيل الموقع
تجري عملية الفحص بأكملها داخل آلية حماية تلتقط جميع الأخطاء. ويُسجَّل أي خلل يحدث فيها، فيما يواصل الطلب مساره من دون تغيير. وحدة حماية تُعطّل الموقع بسبب خطأ فيها أسوأ من عدم وجودها. كما تُنفَّذ جميع الاستعلامات أثناء معالجة الطلب من دون الاعتماد على لغة متصفح الزائر أو الترتيب بحسب الحقول المترجمة — فلا يجوز أن تتسبب لغة غير مثبّتة يستخدمها الزائر في فشل الفحص.
4. المراقبة قبل الحظر
بعد التثبيت، يكون حظر العناوين المدرجة عند إرسال طلبات عادية معطّلًا. تُرفض محاولات الاستطلاع وتُسجَّل، وتُمرَّر بقية الطلبات. وهكذا يمكن مراقبة العناوين التي تُدرج فعليًا في القائمة لبضعة أيام قبل منع أي شخص من الوصول. وينطبق الأمر نفسه على كشف السلوك وقوائم التهديدات وقواعد البلدان: الإبلاغ أولًا، والحظر بعد المراجعة.
5. أنماط دقيقة بدلًا من قواعد فضفاضة
تكلفة تصنيف زائر بالخطأ أعلى من تكلفة تفويت محاولة استطلاع. لذلك لكل نمط مستوى خاص به يمكن تغييره على حدة. ونادرًا ما يكفي امتداد الملف وحده: ففي حالة .php توجد 14,012 محاولة استطلاع حقيقية مقابل حفنة من الروابط القديمة، بينما تنعكس النسبة مع .asp. يجب أن تستند هذه القرارات إلى القياس، لا إلى التخمين.
6. السماح اليدوي يظل ساريًا
من سمح لعنوان بالوصول فعل ذلك لسبب. ورصد نشاط جديد من هذا العنوان لا يلغي ذلك القرار ضمنيًا.
7. القائمة محمية، لكنها ليست سرية
تتطلب نقطة النهاية رمز وصول، وترد بالرمز 404 عند غياب رمز صالح، وليس 403 — وبذلك لا تؤكد أصلًا وجود العنوان. وتُجرى المقارنة بزمن ثابت. أما القائمة نفسها فلا تحتوي على معلومات سرية: فهي تتألف من عناوين بادرت بالاتصال بنا.
8. لا أسرار في السجلات
عند فشل تسجيل الدخول، يُسجَّل اسم المستخدم الذي جرت المحاولة به، ولا تُسجَّل كلمة المرور أبدًا. وفي مدير قواعد البيانات، لا تُقرأ أيٌّ من القيم المُرسلة: فكلمة المرور الرئيسية تأتي في مقدمتها، وأي إدخال في قائمة الحظر ينتقل إلى كل نسخة احتياطية لقاعدة البيانات. ولا يُحفظ مفتاح ترخيص GeoLite2 إلا في معلمة النظام، ولا يظهر في أي سطر من السجلات.
9. الطُّعم لا يكشف معلومات قابلة للاستغلال
يمكن اختياريًا أن يرد Web RBL على محاولات الاستطلاع بمحتوى مختلق يتضمن قيمة طُعم فريدة. ومن يطلب هذه القيمة لاحقًا يكون قد قرأ الاستجابة المزيفة وتصرف بناءً عليها — وهنا يُستبعد الإنذار الكاذب. لا تتضمن الطعوم أي معلومات قابلة للاستغلال، ولا مسارات حقيقية، ولا بيانات دخول صالحة. تأتي هذه الميزة معطّلة افتراضيًا، لأنها تغيّر السلوك بصورة ظاهرة للجهات الخارجية.
ما لا تستطيع الوحدة فعله
لا تحل الوحدة محل جدار حماية أو جدار حماية لتطبيقات الويب. فهي تكشف أنماط الاستطلاع المعروفة في المسارات، ومحاولات تسجيل الدخول الفاشلة، والسلوك المريب — لكنها لا تكشف الهجمات على النماذج ولا محاولات الحقن في المعلمات.
كما أنها لا ترى إلا ما يعود عبر HTTP. أما ما يفعله المهاجم ببيانات دخول مسروقة إلى قواعد البيانات أو صناديق البريد فيظل خارج نطاق رؤيتها — ولهذا تحديدًا تكون قيم الطُّعم مسارات، لا بيانات دخول.
ولا تُغني عن توخي العناية: فالوحدة التي ترفض محاولات استطلاع .env لا تجعل ملف .env المكشوف عن طريق الخطأ آمنًا.
التوفّر
يتوفر Web RBL للجميع بموجب ترخيص AGPL-3، ونستخدمه فعليًا في بيئة الإنتاج على خمسة مواقع:
github.com/Alex0176/odoo-web-rbl
تتطلب الوحدة Odoo 19 Community، ولا تعتمد إلا على base وweb. والتكامل مع نظام التذاكر اختياري ولا يتطلب نظامًا بعينه؛ وعند عدم وجوده، لا يحدث شيء ببساطة. أما تحديد بلد المنشأ فيتطلب قاعدة بيانات GeoLite2 المجانية من MaxMind؛ وإذا لم تتوفر، يبقى الحقل فارغًا وتعمل بقية الوظائف كالمعتاد.
للمزيد: كيف يندمج Web RBL في بنية أمنية متكاملة -- إلى جانب جدار الحماية والمصادقة الثنائية والصلاحيات، مع دليل خطوة بخطوة: الجمع الصحيح بين مكونات البنية الأمنية في Odoo 19.
يسعدنا تلقي الأسئلة والملاحظات وتقارير الأخطاء — ويفضَّل أن تكون على هيئة Issue في GitHub.