Let’s Encrypt گواهی‌ها را برای نود روز صادر می‌کند و خودکار تمدیدشان می‌کند، و به همین سبب مردم یک هفته پس از تنظیم دیگر به آن‌ها نمی‌اندیشند. دشواری آن است که تمدید خودکار بی‌صدا خراب می‌شود: کسی خطاها را نمی‌بیند، و سه ماه بعد سایت بازدیدکنندگان را با هشدار مرورگر پیشواز می‌رود. از ۲۰۲۵ به بعد Let’s Encrypt دیگر نامه اعلان انقضا نمی‌فرستد، پس آخرین یادآور بیرونی هم از میان رفته است.

در ادامه دلایل ازکارافتادن تمدید می‌آید، به ترتیب کاهش بسامد.

۱. گواهی تمدید شد و سرویس هرگز آن را دوباره نخواند

رایج‌ترین. certbot renew کارش را کرد، فایل تازه روی دیسک است، و nginx یا Apache کهنه را در حافظه نگه داشته‌اند — و تا بارگذاری دوباره پیکربندی همان را به بازدیدکنندگان می‌دهند. به‌ظاهر همه‌چیز خوب است؛ در واقع سایت گواهی منقضی دارد.

درمان قلابی است که پس از تمدید کامیاب اجرا می‌شود:

sudo certbot renew --deploy-hook "systemctl reload nginx"

این یک‌بار در فایل تمدید نوشته می‌شود (/etc/letsencrypt/renewal/example.com.conf، بخش [renewalparams]، سطر renew_hook) و از آن پس خودش کار می‌کند.

۲. وب‌سرور عوض شد و چالش نه

چالش HTTP-01 می‌خواهد که فایلی از /.well-known/acme-challenge/ روی HTTP ساده داده شود. و معمولاً چنین خراب می‌شود:

  • به پیکربندی تغییرمسیر بی‌قیدوشرط از HTTP به HTTPS افزوده شد — چالش تغییرمسیر را دنبال می‌کند و شکست می‌خورد؛
  • قاعده location ~ /\. با deny all پیدا شد و هر پوشه‌ای با نقطه را بست، از جمله .well-known؛
  • ریشه سایت جابه‌جا شد در حالی که تنظیمات certbot همان --webroot-path کهنه را نگه داشت؛
  • مسدودسازی بر پایه کشور یا احراز هویت پایه فعال شد و همراه همه، سرور اعتبارسنجی را هم گرفت.

ترتیب درست در پیکربندی: نخست location ویژه برای /.well-known/acme-challenge/، و تنها پس از آن تغییرمسیر عمومی.

۳. زمان‌سنج خاموش است

تمدید از زمان‌سنج systemd یا از وظیفه cron اجرا می‌شود، و هر دو ممکن است هنگام عیب‌یابی به‌خطا خاموش شوند یا هنگام جابه‌جایی سرور گم شوند.

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

فرمان دوم یک چرخه کامل تمدید را در حالت آزمایشی و بدون مصرف سهمیه شما اجرا می‌کند. و این تنها بررسی‌ای است که به پرسش «آیا این یک ماه دیگر تمدید خواهد شد» از پیش پاسخ می‌دهد نه پس از رخداد.

۴. دامنه‌ای دیگر به اینجا اشاره نمی‌کند

گواهی پنج دامنه را پوشش می‌دهد، یکی از آن‌ها به میزبانی دیگر رفته، و DNS عوض شده. اعتبارسنجی برای آن دامنه دیگر نمی‌گذرد، و certbot تمام گواهی را تمدید نمی‌کند — از جمله چهار دامنه‌ای که کار می‌کنند. دامنه‌های زائد باید از گواهی برداشته شوند نه اینکه همراه پیام نادیده گرفته شوند.

۵. به سقف نرخ رسیدید

Let’s Encrypt شمار گواهی‌ها را برای هر دامنه در هفته محدود می‌کند. و این معمولاً پیامد حلقه «نشد، دوباره امتحان کنم» هنگام عیب‌یابی است. برای آزمایش‌ها سروری آزمایشی هست (--dry-run یا --test-cert)، و باید پیش از تمام‌شدن سقف به کارش برد نه پس از آن.

آنچه را داده می‌شود بررسی کنید نه آنچه را ذخیره شده

هر بررسی‌ای که بر فایل‌های روی دیسک تکیه دارد یک عیب دارد: فایل ممکن است تازه باشد در حالی که بازدیدکننده گواهی کهنه را می‌گیرد. از سمت کارخواه بنگرید:

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

گزینه -servername الزامی است: بدون آن روی سروری با چند سایت گواهی نخستین میزبان مجازی را می‌گیرید نه آنکه در نظر داشتید. در خروجی، notAfter تاریخ واقعی انقضاست.

و حالا که آنجایید، زنجیره را هم بررسی کنید:

echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null | grep -c 'BEGIN CERTIFICATE'

اگر تنها یک گواهی باشد، گواهی میانی داده نمی‌شود. مرورگرها معمولاً این چیدمان را می‌بخشند — خودشان زنجیره را می‌سازند — اما curl و برنامه‌های موبایل و کارخواه‌های Java اعتبارسنجی را نمی‌گذرانند. و این همان حالت کلاسیک «پیش من درست باز می‌شود و پیش مشتری کار نمی‌کند» است.

چند روز پیش‌تر هشدار

سی روز نخستین هشدار معقول است: همین اندازه هم می‌ماند وقتی certbot تلاش‌های تمدید را آغاز می‌کند، پس اگر تا آن هنگام چیزی رخ نداده باشد سازوکار خراب است. چهارده روز هشدار دوم است و همین امروز کنش می‌خواهد. هفت روز وضعیت اضطراری است.

و مهم آن است که همه گواهی‌ها را یک‌جا پایش کنید، از جمله آن‌ها که از Let’s Encrypt نیامده‌اند: آن‌هایی که برای یک سال خریده شده‌اند مطمئن‌تر از همه فراموش می‌شوند، چون در یک سال همه هم خودشان را از یاد می‌برند و هم اینکه اعلان‌ها به صندوق پستی چه کسی می‌رود. یک صفحه با دامنه‌ها و تاریخ‌ها و روزهای مانده این پرونده را یکسره می‌بندد — چنان‌که در نمایش پایین.