SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor

تثبيت Certbot لـ nginx على Ubuntu 24.04

نفّذ sudo apt install certbot python3-certbot-nginx ثم شغّل certbot --nginx مرة واحدة. تعرّف أيضاً على فرق apt وsnap ومهلة تجديد المنفذ 80.

تثبيت Certbot: عبر apt أو snap

على نظام Ubuntu 24.04، يمنحك sudo apt install certbot python3-certbot-nginx نسخة عاملة من Certbot تُصدر شهادات Let's Encrypt حقيقية وموثوقة علنياً. تشير وثائق Certbot الرسمية إلى استخدام snap بدلاً من ذلك؛ الفرق بسيط، حيث تتابع حزمة snap إصدارات المطورين (upstream)، بينما تتابع حزمة المستودع (archive) ما تم شحنه مع إصدار LTS وتتلقى إصلاحات أمنية.

اختر إحداهما. وجود نسختين من Certbot يعني وجود مؤقتي تجديد يستهدفان نفس شجرة /etc/letsencrypt، والنسخة التي تنساها هي التي ستفاجئك.

مسار apt:

sudo apt update
sudo apt install certbot python3-certbot-nginx

هذا يثبت /usr/bin/certbot، وإضافة nginx، وزوج certbot.service + certbot.timer، ومدخل /etc/cron.d/certbot الذي لا يقوم بأي إجراء تحت نظام systemd.

مسار snap:

sudo apt remove certbot python3-certbot-nginx
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

تأتي حزمة snap مع مؤقت خاص بها، وهو snap.certbot.renew.timer. قم بإزالة حزمة apt قبل تثبيت snap.

يعمل كلا التثبيتَين بنفس الطريقة بعد ذلك، باستثناء التوقيت الدقيق الذي يقرران فيه التجديد (تمت تغطيته في قسم التجديد أدناه). تستخدم Certbot 2.x مفاتيح ECDSA (P-256) كإعداد افتراضي، مرر --key-type rsa فقط للعملاء الذين لا يدعمون ECDSA. توجد جميع بيانات الحالة تحت /etc/letsencrypt: يحتوي archive/ على ملفات المفاتيح والشهادات الفعلية، ويحتوي live/ على روابط رمزية (symlinks) للملفات الحالية، ويحتوي renewal/ على ملف إعداد واحد لكل شهادة، ويحتوي accounts/ على مفتاح حساب ACME الخاص بك.

آلية عمل HTTP-01 وسبب ضرورة المنفذ 80

تحدي HTTP-01 هو عملية استدعاء عكسي (callback). أنت تطلب من Let's Encrypt شهادة تغطي example.com؛ فيقوم النظام بحل اسم النطاق في نظام DNS العام، ويفتح اتصالاً على المنفذ 80 في العنوان الذي يجده، ثم يطلب http://example.com/.well-known/acme-challenge/<token>. يجيب خادمك بمحتوى الرمز (token) الدقيق الذي كتبه Certbot للتو على القرص. هذه هي الآلية بالكامل. ينتج عن ذلك ثلاث نتائج، وهي تفسر معظم حالات فشل إصدار الشهادات.

  • يجب أن يكون المنفذ 80 متاحاً من الإنترنت العام، وليس فقط من حاسوبك المحمول. أي قاعدة ufw، أو مجموعة أمان (security group) لدى مزود السحابة، أو جدار ناري في لوحة تحكم الـ VPS يفتح المنفذ 443 فقط، سيؤدي إلى فشل الإصدار وكل عملية تجديد مستقبلية.
  • يجب أن يشير DNS بالفعل إلى هذا الخادم. يقوم خادم التحقق بإجراء عملية البحث الخاصة به من الخارج؛ لذا فإن إدخالات /etc/hosts في جهازك وذاكرة التخزين المؤقت للمتصفح لا تعني له شيئاً.
  • إذا نشرت سجل AAAA، فسيتم تجربة IPv6 أولاً. لا تعيد Let's Encrypt المحاولة عبر IPv4 إلا عندما تنتهي مهلة اتصال IPv6. الاتصال المرفوض عبر IPv6 لا يُعاد، كما أن سجل AAAA القديم الذي يشير إلى مضيف يقبل الاتصال ويقدم محتوى مختلفاً سيؤدي إلى فشل ذريع.

إعادة التوجيه (Redirects) مسموح بها: يتبع التحقق إعادة توجيه HTTP إلى HTTPS ولا يهتم بكون الشهادة في الطرف الآخر مفقودة أو منتهية الصلاحية أو موقعة ذاتياً. ما لن يفعله النظام هو البدء من أي منفذ غير المنفذ 80. لا يمتلك Certbot تطبيقاً لـ TLS-ALPN-01، لذا فإن خيار "استخدم المنفذ 443 فقط" ليس مخرجاً متاحاً.

اختيار أداة المصادقة: --nginx و--webroot و--standalone

--nginx هو الخيار الافتراضي المناسب عندما يكون nginx قيد التشغيل ويخدم النطاق بالفعل. يحلل Certbot إعداداتك، ويضيف مؤقتاً موقع التحقق، ثم يعيد تحميل nginx ويتحقق من النطاق، وبعد ذلك يكتب توجيهات TLS داخل كتلة الخادم لديك. لا يحدث توقف للخدمة.

sudo certbot --nginx -d example.com -d www.example.com

مناسب للبرمجة النصية على خادم جديد:

sudo certbot --nginx \
  -d example.com -d www.example.com \
  --agree-tos -m ops@example.com --no-eff-email \
  --redirect --non-interactive

--webroot مناسب عندما تريد إبقاء Certbot بعيداً تماماً عن إعدادات nginx، سواء كنت تنشئها من قالب، أو تحتفظ بها في git، أو تنشرها باستخدام Ansible. يكتب Certbot ملف التحقق فقط داخل مجلد تقدمه للخدمة مسبقاً.

sudo certbot certonly --webroot -w /var/www/example.com \
  -d example.com -d www.example.com \
  --deploy-hook "systemctl reload nginx"

--standalone مناسب عندما لا توجد خدمة تستمع على المنفذ 80، مثل خادم بريد، أو واجهة API لا تستخدم إلا 443، أو نص يعمل عند الإقلاع الأول قبل وجود nginx. يربط Certbot المنفذ 80 بنفسه لبضع ثوانٍ. إذا كان nginx قيد التشغيل، تفشل العملية. أوقفه أثناء التنفيذ:

sudo certbot certonly --standalone -d mail.example.com \
  --pre-hook "systemctl stop nginx" \
  --post-hook "systemctl start nginx"

تُسجَّل هذه الخطافات في إعدادات تجديد الشهادة، لذلك يحدث الإيقاف والتشغيل نفسهما تلقائياً عند التجديد.

كتلة خادم تعمل قبل وبعد وجود الشهادة

مشكلة البيضة والدجاجة: يرفض Nginx البدء إذا كان ssl_certificate يشير إلى ملف غير موجود، ولا يستطيع Certbot التحقق من النطاق بينما Nginx متوقف. اجعل الموقع يعمل على المنفذ 80 أولاً.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.html;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

نفّذ sudo nginx -t && sudo systemctl reload nginx، وتأكد من أن curl -I http://example.com/ يستجيب من خارج الخادم، ثم أصدر الشهادة. بعد ذلك:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

البادئة الأطول لـ ACME تتفوق بالفعل على location /، لذا فإن return 301 لا يرى طلب التحدي (challenge request) أبداً. المعدّل ^~ يثبت أهميته في مواضع أخرى: بمجرد مطابقة هذه البادئة، يتخطى Nginx مواقع regex تماماً، لذا فإن أي قاعدة تُضاف لاحقاً مثل location ~ /\. { deny all; } لا يمكنها حظر التحدي. الحفاظ على هذا الموقع في المنفذ 80 يضمن استمرار عمل التجديدات بعد تحويل باقي الموقع إلى HTTPS فقط.

كلا الكتلتين أعلاه تخدمان ملفات من القرص؛ إذا كان Nginx يعمل كواجهة أمامية لتطبيق، فإن location / تصبح كتلة proxy_pass، ويغطي كتلة خادم الـ reverse proxy، سطراً بسطر الترويسات (headers) التي يحتاجها ذلك التطبيق، بينما يظل موقع ACME وتوجيهات TLS كما هي تماماً.

تعتمد صيغة HTTP/2 على إصدار Nginx لديك. يأتي Ubuntu 24.04 مع Nginx 1.24، الذي يتطلب كتابتها ضمن السطر listen 443 ssl http2;، ويفشل في البدء إذا استخدمت التوجيه المنفصل http2 on;. بينما يأتي Debian 13 مع Nginx 1.26، الذي يتطلب http2 on; ويصدر تحذيراً فقط بأن الصيغة المضمنة أصبحت قديمة (deprecated). تحقق من nginx -v أولاً.

وجّه Nginx إلى live/، ولا توجّهه أبداً إلى archive/. يتم تحديث الروابط الرمزية live/ عند كل عملية تجديد؛ أما المسار الثابت داخل archive/ فسيجعلك عالقاً بشهادة ستنتهي صلاحيتها دون أن يتم تحديثها.

تعني Wildcards استخدام DNS-01، ويعني DNS-01 استخدام plugin

لا يمكن التحقق من شهادة wildcard (*.example.com) عبر HTTP-01، لأنه لا يوجد اسم مضيف واحد لجلب ملف منه. المسار الوحيد هو DNS-01: تثبت أنك تتحكم في النطاق من خلال نشر سجل _acme-challenge.example.com TXT. يحتاج Certbot إلى بيانات اعتماد API لدى موفر DNS لتنفيذ ذلك تلقائياً، وهذا هو سبب وجود provider plugins. يشرح الدليل الكامل لشهادة wildcard آلية سجل TXT ومشكلة التجديد في الوضع اليدوي؛ وتأتي بعده نسخة Cloudflare المختصرة.

sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

في مسار apt، يكون الأمر sudo apt install python3-certbot-dns-cloudflare بدلاً من ذلك. ضع بيانات الاعتماد في ملف لا يقرأه إلا root:

# /root/.secrets/cloudflare.ini
# then: sudo chmod 600 /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_scoped_token_here

قيّد الرمز المميز بحقوق تعديل DNS في تلك المنطقة وحدها. هذا مفتاح لخدمة DNS لديك؛ فتعامل معه على هذا الأساس.

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

ضع wildcard بين علامتي اقتباس حتى لا يوسّعه shell وفق نمط glob. يحل DNS-01 أيضاً مشكلة لا يستطيع HTTP-01 حلها: إصدار شهادات لمضيفين بلا منفذ عام 80، أو لخدمة داخلية، أو لجهاز لا يمكن الوصول إليه إلا عبر WireGuard VPN مستضاف ذاتياً على VPS، أو للوحة إدارة على واجهة خاصة.

التجديد: فترة الـ 90 يوماً، والمؤقت، وخطاف النشر (deploy hook)

شهادات Let's Encrypt صالحة لمدة 90 يوماً. تقوم حزمة apt (إصدار Certbot 2.9.0) بالتجديد عندما يتبقى أقل من 30 يوماً. تتابع حزمة snap إصدار Certbot الحالي، والذي يطلب منذ الإصدار 4.1 من Let's Encrypt وقتاً مقترحاً للتجديد عبر بروتوكول ACME Renewal Info (ARI)، وقد يقوم بالتجديد في وقت أبكر؛ بالنسبة لشهادة Let's Encrypt، يعني هذا عادةً ثلثي فترة صلاحيتها. في كلتا الحالتين، تحصل على نافذة زمنية مدتها 30 يوماً تقريباً، حيث يكون فشل التجديد مشكلة قابلة للإصلاح بدلاً من أن يكون انقطاعاً في الخدمة. توقع أن تتكرر عمليات التجديد بشكل أكبر بدءاً من العام المقبل: سينتقل الملف التعريفي الافتراضي لـ Let's Encrypt إلى شهادات مدتها 64 يوماً في 10 فبراير 2027، وإلى شهادات مدتها 45 يوماً في 16 فبراير 2028. لم تعد Let's Encrypt ترسل رسائل بريد إلكتروني للتحذير من انتهاء الصلاحية، ولن ينبهك أحد، لذا فإن المراقبة تقع على عاتقك الآن.

تحقق من المؤقت الذي جاء مع تثبيتك:

systemctl list-timers 'certbot*' 'snap.certbot*'
sudo certbot certificates

يقوم certbot renew بفحص كل إعداد في /etc/letsencrypt/renewal/، ويتخطى أي شهادة لم يحن موعد تجديدها بعد، ويجدد البقية باستخدام الخيارات المحفوظة في ذلك الإعداد. هذه هي الأعلام (flags) الخاصة بالتشغيل الأول ما لم تقم بتغييرها لاحقاً باستخدام certbot reconfigure. لهذا السبب يعد التشغيل الأول مهماً: فهو الذي يتم تسجيله.

تجديد الملف على القرص لا يغير شيئاً بحد ذاته، حيث يستمر nginx في تقديم الشهادة القديمة من الذاكرة حتى يخبره شيء ما بإعادة التحميل. قم بضبط خطاف نشر (deploy hook) مرة واحدة:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
set -e
nginx -t && systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

يتم تشغيل أي ملف قابل للتنفيذ في renewal-hooks/deploy/ بعد كل عملية تجديد ناجحة. يقوم العلم --deploy-hook بنفس المهمة لشهادة واحدة، حيث يخزن renew_hook = ... في إعداد التجديد الخاص بها. يقوم certbot --nginx بإعادة التحميل نيابة عنك؛ بينما لا تقوم إعدادات --webroot و --standalone بذلك. الخطاف المفقود هو السبب الدقيق وراء تقديم الموقع لشهادة منتهية الصلاحية بينما يبلغ certbot certificates بكل سرور عن وجود شهادة جديدة. أي شيء آخر يقرأ الشهادة عند بدء التشغيل يحتاج إلى نفس الخطاف، فالتطبيق المعتمد على الحاويات (containerised) مثل تثبيت Nextcloud على خادم افتراضي مع Docker وTLS ونسخ احتياطية يحتاج أيضاً إلى خطوة إعادة التشغيل أو إعادة التحميل الخاصة به ليتم ضبطها هنا.

اختبار التجديد الفعلي

sudo certbot renew --dry-run

يُشغّل هذا الأمر عملية التحقق الكاملة مقابل بيئة الاختبار (staging) الخاصة بـ Let's Encrypt: نفس مسار الكود، ونفس إعدادات جدار الحماية، ونفس إعدادات DNS، ولا يتم احتساب أي شيء ضمن حدود معدل الإنتاج (حيث تمتلك بيئة الاختبار حدوداً خاصة بها وأكثر مرونة بكثير)، كما لا يتم حفظ أي شهادات على القرص. إذا نجح الاختبار اليوم، فسيتم التجديد التلقائي بعد 60 يوماً بنجاح أيضاً، بافتراض عدم تغير أي شيء في الخادم.

لا يثبت التشغيل التجريبي (dry run) أن الـ hook الخاص بإعادة التحميل يعمل، إذ يختلف هذا السلوك حسب إصدار Certbot. اختبر هذا الجزء يدوياً: نفّذ سكربت الـ hook مباشرة، وتأكد من نجاح systemctl reload nginx، ثم تحقق من sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.

الأخطاء التي ستواجهها فعلياً

Could not bind to IPv4 or IPv6.، --standalone بينما يشغل Nginx المنفذ 80 بالفعل. استخدم --nginx أو --webroot، أو أوقف Nginx أثناء التشغيل. تأكد من العملية التي تشغل المنفذ باستخدام sudo ss -lntp | grep ':80'.

Timeout during connect (likely firewall problem)، لم يتمكن Let's Encrypt من الوصول إلى المنفذ 80. تحقق من الخارج إلى الداخل: sudo ufw status (افتحه باستخدام sudo ufw allow 'Nginx Full')، ثم جدار حماية مزود الـVPS، ثم DNS. اختبر من مكان خارج خادمك: curl -sSv http://example.com/.well-known/acme-challenge/test. سجل AAAA قديم يؤدي إلى ظهور هذه الرسالة نفسها.

unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404، المنفذ 80 متاح، لكن الرمز (token) لا يُقدَّم. وصل الطلب إلى كتلة خادم (server block) مختلفة (تحقق من أي واحدة تملك default_server)، أو أن المجلد الممرر إلى -w ليس هو الذي يخدمه Nginx. ضع ملفاً في /var/www/example.com/.well-known/acme-challenge/test واجلبه من الخارج؛ إذا ظهر خطأ 404، فالمشكلة لم تكن في الشهادة أبداً.

DNS problem: NXDOMAIN looking up A for example.com، الاسم لا يُحل (resolve) بشكل عام. سجلات جديدة لم تنتشر بعد، أو سجل في منطقة (zone) لا يخدمها مسجل النطاقات الخاص بك.

too many certificates (5) already issued ...، حد معدل (rate limit)، وهو الخطأ الذي يواجهه الناس عند التصحيح في حلقة مفرغة. تسمي الرسالة الحد وتنتهي بوقت retry after. يضع Let's Encrypt حداً للشهادات المكررة، أي نفس مجموعة الأسماء تماماً، بخمس شهادات في الأسبوع، ولا يوفر تجاوزاً لهذا الحد، لذا الوقت فقط هو ما يزيل الحظر. بشكل منفصل، يسمح بـ 50 شهادة جديدة لكل نطاق مسجل في الأسبوع؛ يمكن رفع هذا الحد بطلب تجاوز، والطلب لنفس مجموعة الأسماء الموجودة في شهادة حالية يُحتسب كتجديد ومعفى من هذا الحد، كما أن التجديدات المنسقة عبر ARI معفاة من كل الحدود. قم بالتصحيح مقابل بيئة الاختبار (staging) باستخدام --dry-run.

nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory، Nginx مهيأ لشهادة لم تُصدر أبداً، أو شهادة حُذفت باستخدام certbot delete. علّق كتلة خادم TLS، ابدأ Nginx، أصدر الشهادة، ثم استعد الكتلة.

open() "/etc/letsencrypt/options-ssl-nginx.conf" failed، هذا الملف يأتي مع حزمة إضافة Nginx. على خادم certonly بدون python3-certbot-nginx، أضف الإضافة أو استبدل سطر include بإعدادات ssl_protocols و ssl_ciphers الخاصة بك.

إدارة النطاق الواسع

يمكن لشهادة واحدة أن تحمل ما يصل إلى 100 اسم، وقد يبدو استخدام certbot --nginx -d a.example.com -d b.example.com ... واحداً أمراً مغرياً، لكنه يظل خطراً؛ فإذا فشل سجل DNS واحد في التحقق، سيتعطل كل اسم آخر مرتبط بتلك الشهادة. الشهادات المنفصلة لكل موقع تفشل بشكل مستقل، وهو ما تحتاجه عند استضافة أكثر من موقعين على خادم واحد. عند تجاوز عدد قليل من المواقع، يصبح استخدام بوابة أمامية تدعم بروتوكول ACME خياراً ضرورياً: حيث يقوم Traefik reverse proxy الذي يشغّل تطبيقات متعددة عبر Docker Compose بطلب الشهادات وتجديدها تلقائياً، ويخرج Certbot من المشهد تماماً. اختيار الوكيل المناسب لهذه البوابة يعتمد على تفضيلاتك، وتعتمد عملية المفاضلة بين Nginx وCaddy وTraefik بشكل أساسي على حجم المهام التي تريد من الوكيل القيام بها نيابة عنك فيما يخص الشهادات وإعدادات كل تطبيق.

احتفظ بنسخة احتياطية من /etc/letsencrypt بالكامل، مع استخدام sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt للحفاظ على الروابط الرمزية (symlinks) سليمة. يحتوي هذا المسار على accounts/، وهو مفتاح حساب ACME الخاص بك، والذي لا يمكنك إعادة إنشائه بنفس القيمة. عند الانتقال إلى خادم VPS جديد، تقتصر العملية على: مزامنة المسار باستخدام -a، وتثبيت Certbot، وتوجيه سجلات DNS إلى الخادم الجديد، ثم تشغيل certbot renew --dry-run قبل تحويل حركة المرور.

عند إعادة بناء الخادم أو الانتقال إلى إصدار LTS جديد، لن ينتقل مؤقت التجديد معك تلقائياً. بعد أي عملية ترحيل، أو استعادة لقطة (snapshot)، أو ترقية للنظام، قم بتشغيل systemctl list-timers 'certbot*' متبوعاً بـ --dry-run. تجاهل هذه الخطوة يؤدي إلى توقف الموقع عن العمل بعد 89 يوماً، في الساعة الثالثة صباحاً، بسبب شهادة كان الجميع يفترض أنها تجدد نفسها.

تفترض مسارات HTTP-01 المذكورة أعلاه وجود خادم تتحكم به، يمتلك عنوان IP عاماً والمنفذ 80 مفتوحاً للعالم، أي خادم VPS؛ بينما لا يحتاج DNS-01 إلى أي من ذلك. آليات العمل المذكورة أعلاه متطابقة في كلتا الحالتين.

تنطبق خطوات الشهادات نفسها على Apache بدلاً من nginx، وعندما لا يكون استخدام شهادة عامة خياراً متاحاً، تغطي الشهادات الموقعة ذاتياً على Ubuntu احتياجات الخدمات الداخلية.

FAQ

هل أحتاج إلى فتح المنفذ 80 إذا كان موقعي يخدم HTTPS فقط؟

نعم، من أجل تحدي HTTP-01. تبدأ Let’s Encrypt دائماً طلب التحقق الخاص بها على المنفذ 80، ولا يمتلك Certbot تطبيقاً لـ TLS-ALPN-01، لذا فإن جداراً نارياً يفتح المنفذ 443 فقط سيؤدي إلى حظر عملية الإصدار الأولى وكل عملية تجديد تلقائية تليها. إعادة التوجيه من المنفذ 80 إلى HTTPS مقبولة، حيث يتبعها التحقق. الطريقة الوحيدة لتخطي المنفذ 80 تماماً هي استخدام DNS-01، سواء عبر إضافة (plugin) لمزود الخدمة أو باستخدام --manual --preferred-challenges dns في Certbot، حيث تضيف سجل TXT بنفسك، ويتوقف التجديد عن كونه تلقائياً ما لم توفر سكربت --manual-auth-hook.

apt أم snap، أي نسخة من Certbot يجب أن أثبت لـ nginx على Ubuntu 24.04؟

استخدم apt. يوفر لك sudo apt install certbot python3-certbot-nginx نسخة Certbot 2.9.0 على Ubuntu 24.04، وهي حديثة بما يكفي لكل ما ورد في هذا الدليل، وتتلقى التحديثات الأمنية عبر unattended-upgrades، ولا تتطلب snapd. اختر snap فقط إذا كنت بحاجة إلى أحدث إصدار فور صدوره أو إذا كنت بحاجة إلى إضافة DNS يتم توزيعها حصرياً كـ snap. في كلتا الحالتين، اختر طريقة واحدة فقط: وجود تثبيتَين يعني وجود مؤقتَي تجديد يشيران إلى نفس شجرة /etc/letsencrypt، والنسخة المنسية هي التي ستتسبب في انتهاء صلاحية شهادتك.

هل يمكن لـ Certbot إصدار شهادة wildcard لـ nginx؟

فقط عبر DNS-01. شهادة wildcard مثل *.example.com لا تملك اسم مضيف واحد لجلب ملف التحدي منه، لذا فإن --nginx و--webroot و--standalone غير صالحة. ثبّت الإضافة الخاصة بمزود DNS الخاص بك، وضع رمز API مقيد الصلاحيات في ملف بيانات اعتماد لا يمكن الوصول إليه إلا بواسطة root، ثم نفذ certbot certonly --dns-cloudflare -d example.com -d '*.example.com'، مع وضع الـ wildcard بين علامتي اقتباس لمنع الـ shell من توسيع النطاق (globbing).

لماذا لا يزال nginx يخدم الشهادة القديمة بعد التجديد الناجح؟

يحتفظ nginx بالشهادة في الذاكرة ولا يلاحظ وجود الملف الجديد على القرص إلا بعد إعادة التحميل. يقوم certbot --nginx بإعادة التحميل نيابة عنك، لكن عمليات --webroot و--standalone لا تفعل ذلك، لذا قد ينجح التجديد بينما لا يزال المتصفح يرى شهادة منتهية الصلاحية. ضع سكربت قابلاً للتنفيذ في /etc/letsencrypt/renewal-hooks/deploy/ يقوم بتشغيل nginx -t && systemctl reload nginx، وسيعمل هذا السكربت بعد كل عملية تجديد ناجحة.

هل يثبت certbot renew --dry-run أن التجديد سيعمل؟

إلى حد كبير. فهو يجري التحدي الحقيقي مقابل بيئة الاختبار (staging)، باستخدام نفس الجدار الناري، ونفس DNS، ونفس مسار الكود، دون المساس بحدود المعدل (rate limits) الخاصة ببيئة الإنتاج ودون حفظ أي شهادات على القرص، لذا فإن النجاح يعني أن الجانب الشبكي سليم. ومع ذلك، فهو لا يثبت بشكل موثوق أن سكربت النشر (deploy hook) الخاص بك سيعمل. اختبر ذلك بشكل منفصل: قم بتشغيل سكربت الـ hook يدوياً وتحقق من sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.