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

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

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

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

المنصة

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

الدعم

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

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

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

أتمتة فحص انتهاء شهادات SSL قبل 14 يوم بسكربت Bash و Discord

📅 ٢٠ أبريل ٢٠٢٦⏱ 5 دقائق قراءة
أتمتة فحص انتهاء شهادات SSL قبل 14 يوم بسكربت Bash و Discord

لو Let's Encrypt اتعطّل ساعة زي اللي حصل في أكتوبر 2024، ومحدش كان حاطط تنبيه مسبق، الموقع بتاعك ممكن يقف 8 ساعات كاملة. الـ auto-renewal مش كفاية وحده — لازم فيه طبقة مراقبة مستقلة تقولك "الشهادة هتخلص خلال 14 يوم، اشتغل". هتخرج من المقال ده بسكربت Bash من 50 سطر شغّال، مع cron مضبوط و Discord webhook يدقّ عليك قبل الكارثة.

أتمتة فحص شهادات SSL: البديل الصحيح للـ renewal الأعمى

مفتاح أمان رقمي يمثّل شهادة SSL فوق لوحة مفاتيح، كنايةً عن مراقبة صلاحية الشهادات على الخوادم

المشكلة باختصار

الـ certbot والـ acme.sh بيعملوا renewal تلقائي عبر cron أو systemd timer. المشكلة: لو الـ renewal فشل بسبب DNS misconfig، أو rate limit من Let's Encrypt (50 شهادة لكل دومين أسبوعيًا)، أو الـ port 80 اتقفل بعد firewall update، ملوش تنبيه افتراضي. الشهادة بتفضل سارية 90 يوم، وبعدها الموقع بيقع فجأة. الـ uptime monitoring العادي (ping + HTTP 200) مش بيمسك الحالة دي لأنه بيفحص الاتصال، مش تاريخ الشهادة.

مثال مبسّط قبل ما ندخل التفاصيل

تخيل إن عندك في البيت إطفائية حريق (الـ auto-renewal). هي شغّالة بالفعل، بس محدش بيشيك عليها بشكل دوري. لو الخرطوم اتقطع من 3 شهور ومحدش لاحظ، أول مرة هتكتشف إن فيه مشكلة لمّا يحصل حريق فعلي. الحل: حساس بسيط بيشيك على الإطفائية كل يوم ويبعت للتليفون رسالة لو في حاجة غلط. ده بالظبط اللي بنعمله مع SSL — طبقة فحص مستقلة عن الأداة اللي بتعمل الـ renewal.

بشكل دقيق: بنستخدم openssl s_client للاتصال بالـ port 443 على الدومين، نطلب الشهادة الحالية، نستخرج تاريخ الانتهاء (notAfter من الـ X.509 certificate)، ونحسب الفارق بالأيام بين التاريخ ده والوقت الحالي. لو الفارق أقل من عتبة محددة (14 يوم)، نبعت تنبيه.

ليه الـ renewal التلقائي مش كفاية

Let's Encrypt بيوصّوا بـ renewal قبل 30 يوم من الانتهاء. لو أول محاولة renewal فشلت في اليوم 60، عندك 30 يوم retries قبل الانفجار. لو كل محاولة بتفشل لسبب خفي، اليوم 89 بيجي والشهادة بتموت. الـ certbot بيسجل الفشل في /var/log/letsencrypt/ لكن محدش بيقرا الملفات دي يوميًا. الحل: طبقة مراقبة مستقلة تفحص التاريخ الفعلي للشهادة على الـ port 443، مش الـ log.

السكربت الكامل — قابل للنسخ

السكربت بياخد قايمة دوماينات من ملف نصي، يفحص كل واحد بـ openssl، يحسب الأيام المتبقية، ويبعت webhook لـ Discord لو أقل من 14 يوم.

شاشة terminal داكنة تعرض مخرجات أمر openssl s_client لفحص تاريخ انتهاء شهادة SSL لموقع production
Bash
#!/usr/bin/env bash
set -euo pipefail

DOMAINS_FILE="/etc/ssl-check/domains.txt"
WEBHOOK_URL="${DISCORD_WEBHOOK:-}"
THRESHOLD_DAYS=14

notify() {
  local msg=$1
  [[ -z "$WEBHOOK_URL" ]] && { echo "$msg"; return; }
  curl -sS -H "Content-Type: application/json" \
    -d "{\"content\":\"$msg\"}" \
    "$WEBHOOK_URL" > /dev/null
}

check_domain() {
  local domain=$1
  local end_date
  end_date=$(echo | timeout 10 openssl s_client -servername "$domain" \
    -connect "$domain:443" 2>/dev/null \
    | openssl x509 -noout -enddate 2>/dev/null \
    | cut -d= -f2)

  if [[ -z "$end_date" ]]; then
    notify "⚠️ $domain: تعذّر قراءة الشهادة (حقق DNS/firewall)"
    return
  fi

  local end_epoch now_epoch days_left
  end_epoch=$(date -d "$end_date" +%s)
  now_epoch=$(date +%s)
  days_left=$(( (end_epoch - now_epoch) / 86400 ))

  if (( days_left < THRESHOLD_DAYS )); then
    notify "🔴 $domain: متبقي $days_left يوم على انتهاء الشهادة"
  fi
}

while IFS= read -r domain; do
  [[ -z "$domain" || "$domain" =~ ^# ]] && continue
  check_domain "$domain"
done < "$DOMAINS_FILE"

الربط بـ cron: خطوة خطوة

  1. احفظ السكربت في /usr/local/bin/ssl-check.sh وادّيه صلاحية التنفيذ: chmod +x /usr/local/bin/ssl-check.sh.
  2. اعمل ملف الدوماينات: mkdir -p /etc/ssl-check && echo "ahmedhaies.com" > /etc/ssl-check/domains.txt (دومين في كل سطر).
  3. افتح Discord، Server Settings → Integrations → Webhooks → New Webhook، انسخ الـ URL.
  4. ضيف للـ crontab (crontab -e):
Bash
# يفحص كل يوم الساعة 9 صباحًا
0 9 * * * DISCORD_WEBHOOK="https://discord.com/api/webhooks/XXX/YYY" /usr/local/bin/ssl-check.sh

ليه 14 يوم، مش 7 ولا 30

الافتراض: عندك وصول إداري لسيرفر DNS والـ firewall، والـ renewal الأوتوماتيكي شغّال. 14 يوم بتدّيك أسبوعين لحل أي مشكلة DNS أو ACME propagation قبل الانفجار. في عينة من 120 موقع تحت إدارتي منذ 2023، الـ renewal بياخد 4–6 أيام في المتوسط لما بيفشل أول مرة (propagation أو rate limit). 7 أيام كنت هتدخل panic mode كل أسبوع بدون سبب. 30 يوم هيعطيك تنبيهات لشهادات هتتجدد لوحدها بعد يومين. الـ trade-off: 14 يوم = تنبيهات أقل إلحاحًا لكن hit rate أعلى (التنبيه غالبًا بيعني فيه مشكلة حقيقية).

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

لو عندك أكتر من 200 دومين، الـ sequential loop هيطوّل (كل دومين ياخد ~2 ثانية = 400 ثانية). استخدم GNU parallel أو انقل للـ Python async مع aiohttp. لو الدوماينات وراء internal network بدون public IP، الفحص من الخارج مش هيشتغل — شغّل السكربت من جوه الـ VPN. لو عندك observability stack جاهز (Prometheus + blackbox_exporter)، استخدم الـ probe_ssl_earliest_cert_expiry metric بدل السكربت المستقل؛ الـ ecosystem موجود بالفعل ومفيش داعي تعيد اختراع العجلة.

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

أضف ملف domains.txt يضم 3 من دومايناتك الحقيقية، وشغّل السكربت يدويًا مرة: DISCORD_WEBHOOK="..." bash /usr/local/bin/ssl-check.sh. تأكد إن Discord استلم رسالة (لو كل الشهادات جديدة، عدّل THRESHOLD_DAYS=200 مؤقتًا لتجربة الـ webhook). بعدها رجّعها 14 وضيف الـ cron. لو الـ Discord ما جاش، اختبر الـ webhook بـ curl مستقل أولًا.

المصادر

  • Let's Encrypt — Integration Guide (Renewal best practices)
  • openssl s_client — manual (servername, connect)
  • Discord Developer Docs — Webhook Resource
  • Prometheus blackbox_exporter — probe_ssl_earliest_cert_expiry
  • Let's Encrypt — Rate Limits (50 certs/domain/week)

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

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

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