كابوس “الموقع غير آمن”: كيف أتمتت مراقبة شهادات SSL ونمت قرير العين

بتذكرها زي كأنها مبارح… كنت قاعد في مكتبي، فنجان القهوة جنبي، وبحضر للعرض التقديمي لأحد أهم العملاء. المشروع كان عبارة عن منصة تحليل بيانات بتعتمد على واجهات برمجية (APIs) استضفناها على نطاق فرعي. كل شيء كان جاهز، الكود نظيف، والواجهات سريعة. قبل الاجتماع بخمس دقايق، قلت خليني أتأكد من كل شي للمرة الأخيرة.

فتحت المتصفح، كتبت عنوان الـ API… وإذ بالشاشة الحمرا المزعجة تطلع بوجهي: “اتصالك ليس خاصاً” (Your connection is not private). قلبي وقع بين رجليّ. يا ويلي! شو اللي صار؟ هل السيرفر وقع؟ هل في حدا عمل اختراق؟ عرقت وبديت أراجع كل شي بسرعة جنونية، والمدير ببعتلي رسائل “جاهز يا أبو عمر؟”.

بعد دقائق من البحث المحموم، اكتشفت المصيبة. كانت أبسط وأغبى مما توقعت: شهادة الـ SSL انتهت صلاحيتها… مبارح! شعرت بالإحراج الشديد، واضطررت أطلب تأجيل الاجتماع نص ساعة عشان أجدد الشهادة بشكل يدوي ومستعجل. يومها، أخذت عهد على نفسي: هذا الكابوس لن يتكرر. ومن رحم هذه المعاناة، ولدت فكرة نظام الأتمتة اللي راح أشارككم تفاصيله اليوم.

لماذا انتهاء شهادة SSL هو أكثر من مجرد “إشعار مزعج”؟

قد يظن البعض أن مشكلة انتهاء صلاحية شهادة SSL هي مجرد رسالة تحذيرية يمكن للمستخدم تجاوزها. لكن الحقيقة أن أثرها أعمق بكثير، خصوصاً في عالم اليوم الرقمي:

  • فقدان ثقة المستخدم: عندما يرى الزائر رسالة “غير آمن”، أول انطباع يأخذه هو أن موقعك غير احترافي وربما خطير. 90% من المستخدمين سيغادرون فوراً.
  • توقف الخدمات والـ APIs: إذا كانت لديك واجهات برمجية (APIs) تعتمد عليها تطبيقات الموبايل أو خدمات أخرى، فإن انتهاء الشهادة يعني توقف هذه الخدمات بالكامل. وهذا ما حدث معي بالضبط.
  • عقوبات محركات البحث (SEO): جوجل والمتصفحات الأخرى تعطي أولوية للمواقع الآمنة (HTTPS). انتهاء شهادتك يمكن أن يؤثر سلباً على ترتيبك في نتائج البحث.
  • فشل عمليات الدفع: إذا كنت تملك متجراً إلكترونياً، فإن بوابات الدفع ستتوقف عن العمل فوراً، مما يعني خسارة مباشرة في المبيعات.

المشكلة تتفاقم كلما زاد عدد النطاقات والمشاريع التي تديرها. أنا مثلاً أملك نطاقات شخصية مثل moveed.net ونطاقات لمشاريع مثل qedama.com بالإضافة إلى عشرات النطاقات الفرعية للعملاء. الاعتماد على الذاكرة أو منبه التقويم لتجديد كل هذا “كوم” من الشهادات هو وصفة أكيدة للكارثة.

بناء نظام الإنذار المبكر: الأتمتة هي الحل

بدلاً من الاعتماد على “إن شاء الله ما أنسى”، قررت بناء نظام آلي بسيط يقوم بفحص صلاحية كل شهاداتي بشكل يومي ويرسل لي تنبيهاً على تيليجرام قبل فترة كافية من انتهاء الصلاحية. الأداة التي اخترتها لهذا الغرض هي n8n (يمكنك استخدام Zapier, Make, أو أي أداة مشابهة)، لأنها تمنحني مرونة كبيرة وتسمح لي بكتابة كود مخصص.

هذا هو الـ “Workflow” أو مسار العمل الذي قمت ببنائه خطوة بخطوة:

الخطوة الأولى: الجدولة اليومية (Schedule Node)

هذه هي نقطة البداية. قمت بإضافة عقدة (Node) من نوع “Schedule” وجعلتها تعمل مرة واحدة كل يوم في ساعة محددة (مثلاً، 8 صباحاً). هذه العقدة هي بمثابة المنبه الذي يوقظ النظام ليقوم بمهمته اليومية، وأنا بشرب قهوتي.

نصيحة أبو عمر: اجعل الفحص يومياً. لا تقلل من أهمية هذا الأمر. قد تحدث مشكلة في التجديد التلقائي (مثل Let’s Encrypt) دون أن تدري، والفحص اليومي هو شبكة الأمان الخاصة بك.

الخطوة الثانية: فحص الشهادة وحساب الأيام (Code Node)

هنا يكمن قلب النظام. بدلاً من استخدام عقدة HTTP Request مباشرة، والتي قد تكون معقدة لجلب تاريخ انتهاء الشهادة، استخدمت عقدة “Code” التي تسمح لي بكتابة كود JavaScript. هذا يعطيني قوة ومرونة أكبر.

في هذه العقدة، قمت بكتابة سكربت بسيط يقوم بالآتي:

  1. يستقبل قائمة بالنطاقات التي أريد فحصها.
  2. يلف على كل نطاق في القائمة.
  3. يستخدم مكتبة مدمجة في Node.js لعمل اتصال آمن (TLS) والحصول على تفاصيل الشهادة.
  4. يستخرج تاريخ انتهاء الصلاحية (valid_to).
  5. يحسب عدد الأيام المتبقية حتى تاريخ الانتهاء.
  6. يُرجع قائمة بالنطاقات التي قاربت شهاداتها على الانتهاء.

هذا مثال مبسط للكود الذي يمكنك وضعه في عقدة الـ “Code”:


// قائمة النطاقات المراد فحصها
const domains = ["moveed.net", "qedama.com", "api.moveed.net"];
const results = [];
const tls = require('tls');
const thirtyDaysInMilliseconds = 14 * 24 * 60 * 60 * 1000;

for (const domain of domains) {
  const options = {
    host: domain,
    port: 443,
    servername: domain,
    rejectUnauthorized: false // ضروري لتجنب الأخطاء
  };

  const promise = new Promise((resolve, reject) => {
    try {
      const socket = tls.connect(options, () => {
        const cert = socket.getPeerCertificate();
        if (Object.keys(cert).length === 0) {
          console.log(`Could not get certificate for ${domain}`);
          resolve(null);
          socket.destroy();
          return;
        }

        const expiryDate = new Date(cert.valid_to);
        const now = new Date();
        const daysRemaining = Math.floor((expiryDate - now) / (1000 * 60 * 60 * 24));

        console.log(`Domain: ${domain}, Expires in: ${daysRemaining} days.`);

        // الشرط هنا: إذا كانت الأيام المتبقية أقل من 14
        if (daysRemaining  {
        console.error(`Error connecting to ${domain}:`, err.message);
        socket.destroy();
        resolve(null); // أكمل العمل حتى لو فشل نطاق واحد
      });

      socket.setTimeout(5000, () => {
        console.log(`Timeout for ${domain}`);
        socket.destroy();
        resolve(null);
      });

    } catch (e) {
      console.error(`Exception for ${domain}:`, e.message);
      resolve(null);
    }
  });
  // انتظر انتهاء الفحص الحالي قبل الانتقال للتالي
  await promise;
}

// إرجاع النتائج للعقدة التالية في n8n
return results;

الخطوة الثالثة: الشرط (If Node)

هذه العقدة بسيطة جداً. وظيفتها هي فحص ما إذا كانت عقدة الكود السابقة قد أرجعت أي نتائج أم لا. إذا كانت قائمة النتائج تحتوي على عناصر (أي أن هناك شهادات على وشك الانتهاء)، فإنها تسمح للـ “Workflow” بالاستمرار إلى الخطوة التالية. إذا كانت القائمة فارغة، يتوقف مسار العمل هنا، وهذا يعني أن كل شيء على ما يرام.

الخطوة الرابعة: إرسال التنبيه (Telegram Node)

إذا وصل مسار العمل إلى هنا، فهذا يعني أن هناك أخباراً سيئة (أو بالأحرى، تنبيهاً جيداً!). أقوم بربط عقدة “If” بعقدة “Telegram”.

في عقدة تيليجرام، أقوم بصياغة رسالة ديناميكية باستخدام البيانات القادمة من عقدة الكود. الرسالة تبدو كالتالي:

🚨 تنبيه عاجل يا أبو عمر! 🚨

الشهادة الخاصة بالنطاق {{$json.domain}} على وشك الانتهاء.

الأيام المتبقية: {{$json.daysRemaining}} يوم
تاريخ الانتهاء: {{$json.expiryDate}}

الرجاء اتخاذ الإجراء اللازم للتجديد فوراً.

بهذه الطريقة، لكل نطاق تنتهي صلاحيته قريباً، تصلني رسالة منفصلة وواضحة على هاتفي مباشرة.

نصائح من قلب المعركة

بعد استخدام هذا النظام لفترة، تعلمت بعض الدروس الإضافية التي أود مشاركتها معكم:

  • لا تكتفِ بالـ SSL: يمكنك تعديل الكود بسهولة ليفحص أيضاً تاريخ انتهاء صلاحية النطاق نفسه (Domain Expiry). معظم شركات تسجيل النطاقات توفر API لهذا الغرض. لا شيء أسوأ من أن تفقد نطاقك بالكامل!
  • التجديد التلقائي ليس كافياً: حتى لو كنت تستخدم Let’s Encrypt مع التجديد التلقائي، يمكن أن تفشل عملية التجديد لأسباب عديدة (مشكلة في إعدادات DNS، تغيير في الخادم، …إلخ). اعتبر نظام المراقبة هذا بمثابة “شبكة أمان” تكتشف الفشل قبل أن يصبح كارثة.
  • تعدد قنوات التنبيه: لا تعتمد على قناة واحدة فقط. أضفت أيضاً إرسال بريد إلكتروني كقناة تنبيه ثانوية في حال وجود مشكلة في تيليجرام. التكرار هنا صديقك.
  • اجعل التنبيه مبكراً: 14 يوماً هي فترة جيدة، لكن للمشاريع الحساسة جداً، قد ترغب في جعلها 30 يوماً. هذا يعطيك وقتاً كافياً لحل أي مشاكل بيروقراطية أو تقنية قد تواجهك أثناء التجديد.

الخلاصة: ارتاح يا مبرمج! 😴

بناء هذا النظام لم يستغرق مني أكثر من ساعة، لكنه وفّر عليّ ساعات لا تحصى من القلق والعمل الطارئ. الأتمتة ليست رفاهية، بل هي ضرورة أساسية لكل مطور أو مدير نظام يريد أن ينام قرير العين ليلاً.

بدلاً من أن تكون رجل إطفاء يركض لإخماد الحرائق، كن مهندساً يبني أنظمة تمنع اندلاعها من الأساس. استثمر القليل من وقتك اليوم في بناء هذا النظام البسيط، وركز طاقتك وإبداعك في بناء الأشياء العظيمة التي تحبها، بدلاً من القلق بشأن شهادة SSL منسية. صدقني، راحة البال لا تقدر بثمن. 💪

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

أتمتة العمليات

قهوتك الصباحية مع ملخص الإنجازات: كيف تبني داشبورد يومي يصلك على الموبايل باستخدام n8n والذكاء الاصطناعي

كف عن تشتيت نفسك كل صباح بين Jira وGitHub والإيميلات. تعلم معي، أبو عمر، كيف تبني ورك فلو أتمتة يرسل لك ملخصاً ذكياً ومنسقاً بإنجازات...

12 فبراير، 2026 قراءة المزيد
البودكاست