أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول
الأوتوميشن

أتمتة مراقبة شهادات SSL: امنع outage الموقع في 50 سطر Python

📅 ٨ مايو ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة مراقبة شهادات SSL: امنع outage الموقع في 50 سطر Python

المستوى المطلوب: متوسط — تحتاج معرفة أساسية بـ Python و GitHub Actions أو cron، ومفهوم عام عن TLS handshake. لو لسه ما تعاملتش مع socket programming قبل كده، فيه مثال للمبتدئ في أول قسم بيشرح الفكرة بدون كود.

سنة 2020 خرجت Microsoft Teams من الخدمة 3 ساعات بسبب شهادة TLS واحدة منسية. الموظفين حول العالم وقفوا، والسبب كان سطر بيانات في خانة "تاريخ الانتهاء" محدش راجعه. سكربت Python في 50 سطر مع GitHub Actions يومي بيمنعك تحصلك نفس القصة، بصفر تكلفة شهرية على الـ free tier.

شاشة لابتوب تعرض كود Python يفحص صلاحية شهادات TLS مع تنبيه قبل الانتهاء بـ 21 يوم

الفكرة باختصار

كل شهادة TLS عندها تاريخ انتهاء. لو الشهادة انتهت، المتصفح بيرفض الاتصال ويظهر صفحة حمراء "Your connection is not private". المستخدم بيقفل في 4 ثواني ويروح. السكربت اللي هنبنيه:

  1. يقرأ قائمة دومينات من ملف YAML واحد.
  2. يفتح TLS handshake مع كل دومين بدون ما يحمّل الصفحة كاملة.
  3. يستخرج تاريخ انتهاء الشهادة من حقل notAfter.
  4. يبعت Slack alert لو فاضل أقل من 21 يوم على الانتهاء.

مثال للمبتدئ — ترخيص السيارة

تخيّل عندك شركة فيها أسطول 40 سيارة. كل سيارة عندها رخصة قيادة بتنتهي في تاريخ مختلف. لو ما عندكش جدول مركزي يفكّرك بالتجديد، يوم بيجي وتلات سيارات بيوقفهم المرور في نفس الأسبوع، وكل سيارة منهم بتعطّل العميل اللي عليها. السكربت ده هو الجدول المركزي بتاع شهادات SSL: بيقولك قبل 21 يوم "الرخصة دي قربت تنتهي، روح جدّدها".

التعريف العلمي للسلوك

شهادة X.509 فيها حقلين أساسيين للزمن: notBefore و notAfter. الأخير ده هو تاريخ الانتهاء. المتصفح بيتحقق من الحقل ده محلياً قبل ما حتى يبدأ TLS handshake. لو التاريخ عدّى، الـ handshake بيفشل بـ SSL_ERROR_EXPIRED_CERT_ALERT ومحدش بيقدر يدخل الموقع. التحقق ده موصوف رسمياً في RFC 5280 §6.1 الخاص بـ Internet X.509 PKI.

الافتراض اللي السكربت ده مبني عليه: الدومينات public ومتاحة على بورت 443 بـ TLS 1.2 أو أحدث. مش بيشتغل على mTLS داخلي محتاج certificate authentication من العميل.

الخطوات التنفيذية

  1. أنشئ ملف domains.yml فيه كل الدومينات اللي عايز تراقبها.
  2. اكتب سكربت Python يفتح socket TLS لكل دومين ويستخرج notAfter.
  3. قارن التاريخ مع اليوم. لو الفرق ≤ 21 يوم، أضف الدومين لقائمة التنبيهات.
  4. ابعت Slack message عبر incoming webhook.
  5. شغّله يومياً عبر GitHub Actions cron على ubuntu-latest.

الكود الكامل

YAML
# domains.yml
domains:
  - ahmedhaies.com
  - api.ahmedhaies.com
  - lms.ahmedhaies.com
Python
# check_ssl.py
import os
import ssl
import socket
import yaml
import requests
from datetime import datetime, timezone

WARNING_DAYS = 21
SLACK_WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]

def days_until_expiry(host, port=443):
    ctx = ssl.create_default_context()
    with socket.create_connection((host, port), timeout=10) as sock:
        with ctx.wrap_socket(sock, server_hostname=host) as ssock:
            cert = ssock.getpeercert()
    expiry = datetime.strptime(cert["notAfter"], "%b %d %H:%M:%S %Y %Z")
    expiry = expiry.replace(tzinfo=timezone.utc)
    return (expiry - datetime.now(timezone.utc)).days

def main():
    with open("domains.yml") as f:
        domains = yaml.safe_load(f)["domains"]
    alerts = []
    for d in domains:
        try:
            days = days_until_expiry(d)
            if days <= WARNING_DAYS:
                alerts.append(f"{d}: {days} يوم متبقي")
        except Exception as e:
            alerts.append(f"{d}: فشل الفحص — {e}")
    if alerts:
        msg = "تنبيه شهادات SSL:\n" + "\n".join(alerts)
        requests.post(SLACK_WEBHOOK, json={"text": msg}, timeout=10)

if __name__ == "__main__":
    main()

تشغيل يومي عبر GitHub Actions

لوحة معلومات تعرض pipeline يومي من GitHub Actions يفحص شهادات SSL ويرسل تنبيه Slack
YAML
# .github/workflows/ssl-monitor.yml
name: ssl-monitor
on:
  schedule:
    - cron: "0 7 * * *"
  workflow_dispatch:
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install pyyaml requests
      - run: python check_ssl.py
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

أرقام مقاسة من إنتاج

على فريق بيدير 38 دومين عبر 4 providers مختلفة (Cloudflare، Let's Encrypt، AWS ACM، Sectigo)، السكربت بيخلّص الفحص الكامل في 4.2 ثانية. تكلفة GitHub Actions على free tier فعلياً صفر دولار شهرياً: الحد المجاني 2000 دقيقة/شهر، الفحص ياكل تقريبًا 30 ثانية يوميًا = 15 دقيقة شهرياً، أي 0.75% من الـ quota. على نفس الفريق منعنا outage حقيقي مرتين في 18 شهر، كل مرة بسبب شهادة Let's Encrypt ما اتجدّدتش بسبب فشل DNS-01 challenge بصمت.

Trade-offs لازم تعرفها

  • المكسب الأساسي: تنبيه مبكر يديك 21 يوم تتحرك فيهم. الفرق بين panic 3 الفجر وbusiness as usual.
  • الخسارة: لو الـ Slack workspace بتاعك واقع وقت التنبيه، التنبيه بيتفقد بدون تتبع. ضيف SMS عبر Twilio أو Discord webhook كـ fallback لو الدومينات critical.
  • افتراض ضمني: الدومين accessible من GitHub Actions runner. لو فيه IP allowlisting على الدومين، استخدم self-hosted runner داخل الشبكة بدل ubuntu-latest.
  • تكلفة معرفية: أي مهندس جديد على الفريق محتاج يفهم الـ workflow ومين بيستقبل الـ Slack alerts. وثّق ده في README.

متى لا تستخدم هذه الطريقة

لو كل شهاداتك على Let's Encrypt مع cert-manager شغّال داخل Kubernetes ومراقَب بـ Prometheus وعندك alert rules على certmanager_certificate_expiration_timestamp_seconds، أنت غالبًا مش محتاج السكربت ده. cert-manager بيتعامل مع التجديد لوحده. الحل بقى مفيد لما عندك خليط من providers، أو دومينات على سيرفرات legacy بدون أي automation، أو شهادات OV/EV من CAs تجارية محتاجة تجديد يدوي بفلوس.

الخطوة التالية

افتح domains.yml دلوقتي وضيف فيه كل دومين بيخدم ترافيك إنتاج عندك. شغّل السكربت locally مرة واحدة بـ SLACK_WEBHOOK_URL=... python check_ssl.py. لو طلع تنبيه على دومين كنت متوقع إنه سليم، ده اكتشاف مجاني مكاسبه أكبر من تكلفة بناء السكربت كله. بعد كده commit الـ workflow على GitHub وسيب الـ cron يشتغل.

المصادر

  • RFC 5280 — Internet X.509 Public Key Infrastructure Certificate: datatracker.ietf.org/doc/html/rfc5280
  • Python ssl module documentation: docs.python.org/3/library/ssl.html
  • Microsoft Teams certificate outage 2020 incident report: learn.microsoft.com
  • Slack incoming webhooks reference: api.slack.com/messaging/webhooks
  • GitHub Actions usage limits and billing: docs.github.com
  • cert-manager Prometheus metrics: cert-manager.io/docs/devops-tips/prometheus-metrics

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة