كل يوم تسجل خوادمي آلاف عمليات الفحص الآلي بحثًا عن ثغرات. شكل الطلبات وحده قد يبدو مقلقًا:
/wp-admin/wp.php/111.php/code.php/.git/config/i.php/admin/api/.env/kal.php
ما فاجأني لم يكن العدد، بل مدى ضآلة تأثيره على الخادم. أثناء مراقبتي لهذا الترافيك لم أرَ تغيرًا ملحوظًا في حمل CPU.
هذه الملاحظة صحيحة، لكن تفسيري الأول لها كان حاسمًا أكثر مما ينبغي. التقديم الثابت ليس درعًا سحريًا، ورد 404 ليس مجانيًا. الميزة الفعلية في معماريتي أدق من ذلك: كثير من عمليات الفحص الانتهازية تكون رخيصة لأن المسار العام لا يحتوي تقريبًا على منطق تطبيق server-side يمكن الوصول إليه.
هذه محاولات استكشاف وليست دليلًا على اختراق
من السهل رؤية مسارات مثل /wp-admin/wp.php أو /111.php وتسميتها كلها “exploits”. هذا غير دقيق تقنيًا. أغلب ما أراه هو probing آلي: بوتات تجرب أسماء ملفات وendpoints شائعة ثم تراقب الاستجابة.
بعض المسارات يستهدف WordPress أو PHP بوضوح. مسارات أخرى مثل /.git/config و/api/.env تبحث عن إعدادات أو أسرار نُشرت بالخطأ. أما /admin فهو مسار عام جدًا وقد يكون شرعيًا في بعض المواقع. الطلب المشبوه يخبرني بما يبحث عنه الماسح، لكنه لا يثبت وجود الثغرة.
في حالتي، العامل الحاسم هو المعمارية: الموقع العام عبارة عن HTML ثابت مُسبق الرندر يولده Next.js ويخدمه Nginx مباشرة.
لماذا تكون هذه الطلبات منخفضة الكلفة على مكدسي
في الصفحات التي أتحدث عنها لا يوجد PHP runtime ولا قاعدة بيانات خلف كل request. Nginx يقدّم ملفات موجودة مسبقًا. إذا طلب الماسح /111.php ولم يكن الملف موجودًا، فلا يبدأ تطبيق PHP، ولا ينفذ كود WordPress، ولا يحدث استعلام قاعدة بيانات. تنتهي العملية ببساطة كـ miss ثم 404.
هذا يغير نموذج الكلفة. في تطبيق ديناميكي قد يمر الطلب عبر routing وframework والتحقق من الهوية والرندر وقاعدة البيانات أو خدمات أخرى. المسار الثابت عندي يحتوي على أجزاء متحركة أقل بكثير. ما زال على Nginx قبول الاتصال ومعالجة HTTP والبحث عن المورد وكتابة السجل وإرسال الرد، لكن العمل التطبيقي نفسه محدود.
أستخدم أيضًا caching قويًا للموقع، وهو مفيد في التقديم الطبيعي للمحتوى الثابت. لكنني لا أنسب كل 404 عشوائي إلى الكاش؛ URI جديد وغير موجود قد يمر بالمعالجة المعتادة في Nginx وبحث في filesystem قبل إرجاع 404.
التصحيح المهم: الموقع الثابت ليس «آمنًا بحكم التعريف»
هذه أكثر نقطة أغيّر صياغتها اليوم. المعمارية الثابتة تزيل كثيرًا من مكونات server-side من مسار الطلب العام، لكنها لا تلغي الحاجة إلى الأمن.
- الملف المكشوف يظل مكشوفًا. إذا وُضع
.gitأو.envأو backup أو أي secret بالخطأ داخل الدليل العام، فقد يخدمه Nginx بكفاءة مثل أي HTML ما لم تمنع الإعدادات ذلك. - Nginx وTLS ونظام التشغيل والشبكة ما زالت جزءًا من attack surface. تحتاج إلى تحديث وإعداد سليم.
- كود العميل قد يحتوي على ثغرات. HTML الثابت لا يجعل JavaScript أو منطق التحقق في المتصفح أو third-party scripts آمنة تلقائيًا.
- استنزاف الموارد ما زال ممكنًا. الاتصالات وbandwidth وTLS handshakes والworkers وI/O للسجلات ومساحة القرص كلها محدودة. كمية كافية من الترافيك يمكن أن تؤثر حتى على موقع ثابت.
إذًا الاستنتاج الأدق ليس «هذه الطلبات لا تهم»، بل: كثير من الـ probes الخاصة بتطبيقات معينة لا تجد شيئًا قابلًا للتنفيذ في هذه المعمارية.
«آلاف الفحوصات يوميًا» قد تبدو أخطر من العبء الفعلي
السجلات تجعل ضجيج الإنترنت الخلفي يبدو شديدًا لأن كل محاولة فاشلة تظهر كسطر مستقل. لكن العدد اليومي وحده لا يحدد الأثر التشغيلي. بضعة آلاف من الطلبات موزعة على 24 ساعة تختلف تمامًا عن العدد نفسه في burst قصير.
CPU أيضًا مجرد مؤشر واحد. في حالتي بقي ثابتًا، وهذا دليل مفيد على أن هذه الطلبات لم تكن تولد ضغطًا حاسوبيًا ملحوظًا وقت المراقبة. لكنه لا يثبت أن الكلفة كانت صفرًا في بقية الموارد. للتقييم الجيد أنظر أيضًا إلى request rate وbandwidth والاتصالات النشطة وحالة Nginx workers وزمن الاستجابة وحجم السجلات واستخدام القرص.
ما تعلمته من مراقبة هذا الضجيج
أهم درس بالنسبة لي هو أن المعمارية نفسها تستطيع جعل فئات كاملة من الهجمات الآلية غير ذات صلة من دون قاعدة خاصة لكل signature. يمكن لبوت أن يبحث طوال اليوم عن WordPress وPHP backdoors؛ إذا لم يحتوِ المسار العام على WordPress أو PHP فلن تجد تلك probes الكثير لتستغله.
لكنني لم أعد أساوي بين «غير ذي صلة بمكدسي» و«ترافيك بلا ضرر». قائمتي الذهنية الآن أبسط:
- اعرف ما هي runtimes والخدمات التي يمكن الوصول إليها فعليًا من المسار العام.
- أبقِ الأسرار وrepository metadata والنسخ الاحتياطية وbuild artifacts خارج web root أو امنعها صراحة.
- تعامل مع probes المتكررة التي تنتهي 404 كضجيج إنترنت عادي ما لم توجد أدلة أخرى على استهداف أو أثر.
- لا تحكم على كلفة الترافيك المسيء من CPU وحده.
- حدّث Nginx ونظام التشغيل ومكتبات TLS والاعتماديات حتى لو كان التطبيق نفسه ثابتًا.
ما الذي لا تثبته هذه التجربة
لم أجرِ benchmark مضبوطًا ولم أختبر هجوم DDoS. كل ما فعلته هو مراقبة production logs وحمل الخادم بينما تصل آلاف طلبات الماسحات يوميًا. هذا يكفي لاستنتاج عملي عن إعدادي، لكنه لا يثبت قاعدة عامة تقول إن «المواقع الثابتة تفوز دائمًا».
ما أستطيع تأكيده بشكل أدق هو الآتي: في static export الخاص بي من Next.js والمخدوم عبر Nginx، تحولت معظم حركة الماسحات التي رأيتها إلى file misses و404 منخفضة الكلفة بدل الوصول إلى PHP runtime أو تطبيق يعتمد على قاعدة بيانات. أثناء المراقبة ظل حمل CPU دون تغير.
هذه هي ميزة resilience التي تهمني فعلًا. قلة الأجزاء المتحركة لا تجعل النظام محصنًا، لكنها تترك لضجيج الإنترنت العشوائي أماكن أقل ليتحول فيها إلى عمل تطبيقي حقيقي.