HTTPS التلقائي في Caddy: كيف يعمل TLS التلقائي وكيف تصلح أعطاله
يحصل Caddy على شهادات TLS ويجددها عبر ACME لكل نطاق في إعداداته. تعرّف على HTTP-01 وTLS-ALPN-01 وشهادات wildcard عبر DNS-01 وTLS عند الطلب والأعطال الشائعة.
باختصار: يفعّل Caddy بروتوكول HTTPS تلقائياً لأي عنوان موقع يكون اسم نطاق عاماً. يطلب شهادة عبر ACME (Let's Encrypt أو ZeroSSL افتراضياً)، ويثبت سيطرته على النطاق عبر تحدي HTTP-01 أو TLS-ALPN-01 على المنفذين 80 و443، ويعيد توجيه HTTP إلى HTTPS، ويجدد الشهادة قبل انتهائها، من دون أي إعداد إضافي.
أما Caddy كـ reverse proxy فهو ببساطة Caddy ينهي اتصال HTTPS هذا ويمرر الطلب إلى تطبيق على منفذ أو حاوية أو مضيف آخر باستخدام توجيه `reverse_proxy`. هذا الجمع بين TLS والتمرير في بضعة أسطر هو السبب الرئيسي لاختيار الناس له.
Reverse proxy مع SSL في ثلاثة أسطر
عندما يشير DNS إلى الخادم ويكون المنفذان 80 و443 قابلين للوصول، فإن ملف Caddyfile هذا يمثل reverse proxy كاملاً عبر HTTPS لاسمَي مضيف. يحصل Caddy على شهادات للاسمين عند بدء التشغيل، ويخدم HTTP/1.1 وHTTP/2 وHTTP/3، ويمرر `X-Forwarded-For` و`X-Forwarded-Proto` و`X-Forwarded-Host` إلى الخلفية. خيار `email` اختياري، لكنه يتيح لجهة الإصدار التواصل معك بشأن الشهادات المنتهية أو الملغاة.
التثبيت من مستودع apt الرسمي وأساسيات systemd مشروحة في دليل Caddy كـ reverse proxy؛ وللحاويات راجع Caddy كـ reverse proxy لـ Docker. طبّق التغييرات بالأمر `sudo systemctl reload caddy`.
# /etc/caddy/Caddyfile
{
email [email protected]
}
example.com, www.example.com {
reverse_proxy 127.0.0.1:8080
}كيف يعمل TLS التلقائي في Caddy من الداخل
عندما يحمّل Caddy الإعدادات، يجمع كل أسماء المضيفين من عناوين المواقع ويقرر من يجب أن يصدر كل شهادة. النطاقات العامة تذهب إلى جهات إصدار ACME العامة؛ أما `localhost` وعناوين IP والأسماء الداخلية فقط فتحصل على شهادات من جهة الإصدار المحلية الخاصة بـ Caddy (تماماً مثل كتابة `tls internal`). تُخزن الشهادات والمفاتيح وحساب ACME في مجلد بيانات Caddy: `/var/lib/caddy/.local/share/caddy` لحزمة apt، و`/data` في صورة Docker الرسمية.
يجري التجديد في الخلفية قبل الانتهاء بوقت طويل، ويدمج Caddy استجابات OCSP حيث تدعمها جهة الإصدار. إن فشل الإصدار، يعيد Caddy المحاولة بتأخير أُسّي ويستخدم بيئة staging لدى جهة الإصدار في المحاولات المتكررة لتجنب استنزاف حدود المعدل في بيئة الإنتاج. وتتنسق عدة نسخ من Caddy تتشارك التخزين نفسه بحيث تطلب نسخة واحدة فقط شهادة معينة.
| التحدي | ما تفحصه جهة الإصدار | المتطلبات | Wildcard؟ |
|---|---|---|---|
| HTTP-01 | رمز يُخدم على `http://domain/.well-known/acme-challenge/` | منفذ 80 قابل للوصول من الإنترنت | لا |
| TLS-ALPN-01 | شهادة خاصة تُقدَّم أثناء مصافحة TLS | منفذ 443 قابل للوصول من الإنترنت | لا |
| DNS-01 | سجل TXT على `_acme-challenge.domain` | رمز API لمزوّد DNS ونسخة من Caddy تتضمن وحدة ذلك المزوّد | نعم |
شهادات Wildcard عبر DNS-01
شهادات wildcard مثل `*.example.com` لا يمكن إصدارها إلا عبر تحدي DNS-01. ملف Caddy التنفيذي القياسي لا يتضمن إضافات مزوّدي DNS، لذا تبني نسخة بأداة xcaddy (أو تختار المزوّد من صفحة التنزيل الرسمية) وتعطي Caddy رمز API مقصوراً على تعديل DNS لتلك المنطقة. ويعمل DNS-01 أيضاً عندما لا يكون المنفذان 80 و443 قابلين للوصول من الإنترنت، كما في خادم داخلي فقط.
أبقِ الرمز خارج Caddyfile: ضعه في ملف بيئة تستخدمه وحدة systemd (`sudo systemctl edit caddy`، ثم `EnvironmentFile=/etc/caddy/caddy.env` تحت `[Service]`) وقيّد الملف بالأمر `chmod 600`.
# Build Caddy with a DNS provider module (example: Cloudflare)
xcaddy build --with github.com/caddy-dns/cloudflare
# Caddyfile: one wildcard certificate for all subdomains
*.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
@app host app.example.com
handle @app {
reverse_proxy 127.0.0.1:3000
}
handle {
respond "Unknown host" 404
}
}TLS عند الطلب وبيئة staging
TLS عند الطلب يجعل Caddy يحصل على شهادة أثناء أول مصافحة TLS لاسم مضيف لم يره من قبل. وهو مخصص للمنصات التي يوجّه فيها العملاء نطاقاتهم الخاصة إلى خادمك. اضبط دائماً نقطة النهاية `ask`: يستدعيها Caddy مع `?domain=name` ولا يتابع إلا عند استجابة 200. من دونها، يستطيع أي شخص توجيه أسماء عشوائية إلى عنوان IP الخاص بك ويجعلك تصطدم بحدود المعدل.
أثناء التجريب، انتقل إلى جهة الإصدار staging من Let's Encrypt عبر الخيار العام `acme_ca`. شهادات staging لا تثق بها المتصفحات، لكن حدودها أعلى بكثير، فيمكنك أن تخطئ وتصلح بحرية. احذف الخيار عند الانتهاء، واحذف اختيارياً شهادات staging من مجلد البيانات.
{
on_demand_tls {
ask http://127.0.0.1:5555/allowed
}
}
https:// {
tls {
on_demand
}
reverse_proxy 127.0.0.1:8080
}
# Global options block for testing
{
email [email protected]
# Test against Let's Encrypt staging; remove when everything works
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}أعطال TLS الشائعة في Caddy وكيفية إصلاحها
- 01.DNS غير موجّه: سجل A أو AAAA مفقود، أو لا يزال يشير إلى خادم قديم، أو مخزّن مؤقتاً. سجل AAAA قديم فخ كلاسيكي، لأن جهة الإصدار تفضّل IPv6 عند وجوده. افحص الاثنين بأداة `dig`.
- 02.المنفذ 80 أو 443 مغلق: جدار الحماية على المضيف أو جدار حماية سحابي أو موجّه يحجب الحركة الواردة، فلا يكتمل HTTP-01 ولا TLS-ALPN-01. افتح 80/tcp و443/tcp (و443/udp لـ HTTP/3).
- 03.المنفذ مستخدم بالفعل: Apache أو nginx أو حاوية أخرى مرتبطة بالمنفذ 80 أو 443، فلا يستطيع Caddy الاستماع. أوقف الخدمة الأخرى أو انقلها خلف Caddy.
- 04.بروكسي CDN في الواجهة: بروكسي من نوع «السحابة البرتقالية» ينهي TLS قبل Caddy، ما قد يعطل TLS-ALPN-01. استخدم DNS-01، أو اجعل السجل DNS فقط أثناء الإصدار.
- 05.حدود المعدل: المحاولات الفاشلة المتكررة أو مسح مجلد البيانات تجعلك تصطدم بحدود جهة الإصدار (تحدّ Let's Encrypt عمليات التحقق الفاشلة لكل اسم مضيف في الساعة والشهادات المكررة في الأسبوع). أصلح السبب الجذري، واستخدم staging، وأبقِ مجلد البيانات دائماً.
- 06.سجل CAA: سجل CAA يسمح بجهة إصدار أخرى فقط يمنع الإصدار. اسمح بـ `letsencrypt.org` و`sectigo.com` (تستخدمها ZeroSSL) أو أزل القيد.
# Does the name resolve to this server (both IPv4 and IPv6)?
dig +short A example.com
dig +short AAAA example.com
curl -4 -s https://ifconfig.me ; echo
# Are ports 80 and 443 open in the host firewall?
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
# Is something else already bound to 80/443?
sudo ss -ltnp '( sport = :80 or sport = :443 )'
# What does Caddy say?
sudo journalctl -u caddy --no-pager -n 100HTTPS إلى الخلفية أيضاً
معظم الخلفيات على المضيف نفسه تتحدث HTTP عادياً على localhost، وهذا لا بأس به. عندما تكون الخلفية على جهاز آخر أو تصرّ على TLS، استخدم خلفية `https://` وأخبر Caddy بالاسم الذي يتحقق منه وبجهة الإصدار التي يثق بها. تجنب `tls_insecure_skip_verify` خارج الاختبارات السريعة، لأنه يزيل الحماية من الاعتراض بين البروكسي والخلفية. وللحركة بين الخوادم، كثيراً ما يكون نفق WireGuard خاص أبسط من إدارة شهادات الخلفية.
على VPS من NoctisNode بصلاحيات root كاملة وعنوان IPv4 مخصص، الإعداد المعتاد هو: وجّه سجل A (ولا تضف AAAA إلا إن كان للخادم IPv6) إلى الخادم، وافتح 80 و443، ودع Caddy يتولى الباقي. إن احتجت إلى تمرير حركة غير HTTP، راجع تمرير TCP وSSH عبر Caddy.
example.com {
reverse_proxy https://10.0.0.5:8443 {
transport http {
tls_server_name backend.internal
tls_trust_pool file /etc/caddy/backend-ca.pem
}
}
}الأسئلة الشائعة
Qما هو Caddy كـ reverse proxy؟
Aهو خادم الويب Caddy يستقبل اتصالات العملاء، وينهي HTTPS عادةً، ويمرر الطلبات إلى خدمة خلفية أو أكثر بتوجيه `reverse_proxy`. ويحصل Caddy على شهادات TLS لذلك ويجددها تلقائياً.
Qهل يجدد Caddy الشهادات تلقائياً؟
Aنعم. يجدد Caddy الشهادات في الخلفية قبل انتهائها بوقت طويل ويعيد تحميلها من دون إعادة تشغيل، ما دام النطاق يشير إلى الخادم وتبقى منافذ التحدي قابلة للوصول.
Qلماذا لا يحصل Caddy على شهادة؟
Aالأسباب الأكثر شيوعاً هي سجلات DNS تشير إلى مكان آخر (بما فيها سجل AAAA قديم)، أو حجب المنفذين 80 و443، أو برنامج آخر يستخدم هذين المنفذين، أو حدود المعدل بعد إخفاقات متكررة. يعرض `journalctl -u caddy` خطأ ACME بدقة.
Qهل يستطيع Caddy إصدار شهادة wildcard؟
Aنعم، لكن فقط عبر تحدي DNS-01، الذي يتطلب نسخة من Caddy تتضمن وحدة مزوّد DNS الخاص بك ورمز API لتلك المنطقة.
Qكيف أعطّل HTTPS التلقائي في Caddy؟
Aاستخدم عنوان موقع `http://` لموقع واحد، أو اضبط الخيار العام `auto_https off`. ويمكنك أيضاً استخدام `auto_https disable_redirects` للإبقاء على الشهادات مع إيقاف إعادة التوجيه من HTTP إلى HTTPS.