لماذا تدير Let's Encrypt بنفسك على خادم VPS
Let's Encrypt هي سلطة إصدار شهادات مجانية تُصدر شهادات TLS مُتحقَّقًا منها عبر تحدٍّ مؤتمت (HTTP-01 أو DNS-01). فعلى استضافة مشتركة، أنت خاضع لتهيئة TLS الخاصة بالمزوّد: إصدارات بروتوكول مفروضة، ولا OCSP stapling، وتجديد مبهم. أما على خادم VPS، فأنت تملك certbot (أو acme.sh) والوكيل العكسي وإنهاء TLS. أنت من يقرّر البروتوكولات (TLS 1.2/1.3 فقط)، ومجموعات التشفير، وHSTS، وربط شهادة OCSP (stapling). ويمكنك أيضًا إصدار شهادة **wildcard** (*.example.com) عبر تحدّي DNS-01، وتغطية عدة نطاقات في شهادة واحدة (SAN)، وربط التجديد بتنبيهاتك الخاصة. باختصار: تحكّم كامل في أمن النقل، وهو شرط لتقييم A+ على SSL Labs ولأقصى درجة ثقة من جانب المتصفّح.
ما الذي تكسبه باستضافة سلسلة TLS ذاتيًا
- شهادات مجانية 100%، صالحة 90 يومًا وتُجدَّد تلقائيًا دون تدخّل.
- شهادة wildcard
*.example.comممكنة عبر تحدّي DNS-01: شهادة واحدة لجميع نطاقاتك الفرعية. - تحكّم كامل في التهيئة: TLS 1.3، ومجموعات تشفير حديثة، وHSTS، وOCSP stapling.
- شهادات SAN متعددة النطاقات (
example.comوwww.example.comوapi.example.com) على عنوان IP واحد. - تجديد قابل للبرمجة والمراقبة: خطّافات إعادة التحميل، وتنبيهات Slack/بريد إلكتروني قبل انتهاء الصلاحية.
- لا اعتماد على لوحة طرف ثالث: الوصفة نفسها تعمل على جميع خوادمك VPS وبيئاتك.
متطلبات مسبقة واقعية
يستهلك إنهاء TLS موارد قليلة جدًا: فخادم VPS بـ **1 vCPU / 512 ميغابايت إلى 1 غيغابايت من RAM** يكفي وأكثر لتقديم HTTPS لموقع واحد أو عدة مواقع. من ناحية البرمجيات: Docker وdocker compose (أو Nginx/Caddy أصلي)، و**اسم نطاق يشير إلى عنوان IP العام للخادم** (سجلّ A/AAAA منتشِر)، و**المنفذان 80 و443 مفتوحان** في جدار الحماية — فالمنفذ 80 ضروري لتحدّي HTTP-01. ولشهادة wildcard، جهّز وصولًا عبر واجهة برمجة (API) إلى مزوّد DNS الخاص بك (رمز token) لأتمتة تحدّي DNS-01. تحقّق من الانتشار قبل البدء: يجب أن يُرجع dig +short example.com عنوان IP الخاص بالخادم.
نشر HTTPS مؤتمت في بضع خطوات
توجيه النطاق وفتح المنافذ
أنشئ سجلّ A باسم example.com (وسجلّ AAAA إن كان IPv6) يشير إلى عنوان IP الخاص بالخادم، ثم اسمح بحركة الويب: ufw allow 80,443/tcp. أكّد التحويل (resolution) عبر dig +short example.com قبل المضي أبعد — فالتحدّي يفشل دائمًا إذا لم يكن DNS يشير بعد.
اختيار الوكيل العكسي الذي يتولّى TLS
الأبسط: Caddy، الذي يحصل على Let's Encrypt ويجدّده تلقائيًا. ويكفي ملف Caddyfile مبسّط — example.com { reverse_proxy app:3000 } — لتقديم HTTPS بمجرّد docker compose up -d. وللتحكّم الدقيق، اختر بدلًا من ذلك Nginx + certbot، أو Traefik مع محلّل ACME المدمج فيه.
إصدار أول شهادة (HTTP-01)
مع Nginx + Certbot في حاوية: docker run --rm -v ./certs:/etc/letsencrypt -v ./webroot:/var/www certbot/certbot certonly --webroot -w /var/www -d example.com -d www.example.com. يضع Certbot ملف تحدٍّ في webroot الذي يقدّمه Nginx، ويتحقّق منه Let's Encrypt، ثم يُودع fullchain.pem + privkey.pem.
إصدار شهادة wildcard عبر DNS-01 (اختياري)
بالنسبة إلى *.example.com، لا يصلح تحدّي HTTP-01: استخدم DNS-01. مع acme.sh ورمز API: acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'. يُنشئ السكربت سجلّ TXT باسم _acme-challenge، وينتظر الانتشار، ثم ينظّف تلقائيًا.
تحصين تهيئة TLS
في Nginx، افرض ssl_protocols TLSv1.2 TLSv1.3;، وفعّل ssl_stapling on;، وأضِف add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;. وجّه كل المنفذ 80 إلى 443. أعِد التحميل دون انقطاع: nginx -s reload.
أتمتة التجديد
جدوِل تجديدًا مرتين يوميًا مع إعادة تحميل الوكيل: 0 0,12 * * * docker run --rm -v ./certs:/etc/letsencrypt certbot/certbot renew --quiet --deploy-hook "nginx -s reload". ويقوم Caddy وTraefik بذلك أصليًا؛ تحقّق من انتهاء الصلاحية عبر echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates.
قبل الانتقال إلى الإنتاج، اختبر مقابل بيئة **staging** الخاصة بـ Let's Encrypt (--staging مع Certbot، و--server letsencrypt_test مع acme.sh): فحدّ الإنتاج هو 5 إصدارات لكل نطاق أسبوعيًا، وقد يجعلك سكربت سيّئ الضبط تبلغه بسرعة. وأضِف أيضًا **مراقبة انتهاء الصلاحية**: مسبار (probe) ينفّذ openssl x509 -checkend 604800 (7 أيام) ويُطلق تنبيهًا إذا فشل التجديد التلقائي بصمت — فمهمة cron معطّلة هي السبب الأول لانتهاء صلاحية HTTPS في جوف الليل.