إنهاء TLS وإعداد HTTPS
إنهاء TLS وإعداد HTTPS
تشغيل بروتوكول HTTP النصي في بيئة الإنتاج ليس مجرد خيار في الإعداد — بل هو مسؤولية أمنية خطيرة. TLS هو الطبقة التشفيرية التي تُوثّق خادمك للعملاء وتشفّر كل بايت يُرسَل عبر الشبكة. في بنية DevOps الحديثة، يعمل Nginx دائمًا تقريبًا نقطةَ إنهاء TLS: يفكّ تشفير حركة مرور HTTPS الواردة، ثم يُحيل طلبات HTTP غير المشفّرة إلى الخلفيات التطبيقية العاملة على localhost أو شبكة داخلية لا تحتاج إلى تشفير إضافي.
لن يقتصر هذا الدرس على "أضف سطر ssl_certificate وانتهى." ستتعلم كيف تحصل على الشهادات، وتكتب كتلة TLS احترافية في Nginx، وتُطبّق إعادة التوجيه، وتُعدّ HSTS، وتضبط مجموعات التشفير، وتتجنب أعطال الإنتاج الشائعة التي تُضعف الأمان بصمت أو تتسبب في أخطاء اتصال العميل في الساعة الثالثة صباحًا.
كيف يعمل إنهاء TLS
الحصول على الشهادات باستخدام Certbot (Let's Encrypt)
تُصدر Let's Encrypt شهادات DV (التحقق من النطاق) مجانية صالحة لمدة 90 يومًا وتثق بها جميع المتصفحات الرئيسية. يُؤتمت certbot عملية الإصدار والتجديد. للبدء على خادم جديد:
*.example.com) عبر تحدي DNS-01 بدلًا من HTTP-01. يتطلب ذلك إضافة مزود DNS (مثل certbot-dns-cloudflare) لكنه يُلغي الحاجة إلى خادم HTTP متاح للعموم أثناء التجديد، وهو أمر بالغ الأهمية للخدمات الداخلية. احفظ شهادات Wildcard مركزيًا ووزّعها على جميع عقد Nginx عبر مدير أسرار أو أداة شهادات مخصصة مثل step-ca.
كتلة TLS احترافية في Nginx
لا تقبل الإعداد الأدنى الذي "يعمل فقط". لكل إعداد أدناه سبب واضح ومحدد.
ssl_session_tickets off؟ تُشفّر تذاكر الجلسة حالتها باستخدام مفتاح جانب الخادم. إذا اختُرق هذا المفتاح يومًا، يستطيع المهاجم فكّ تشفير كل حركة المرور السابقة (لا سرية تامة للأمام). تعطيل التذاكر يجبر Nginx على استخدام ذاكرة التخزين المؤقت للجلسة الداخلية، التي تدور بشكل طبيعي. معظم إعدادات الإنتاج في Google وCloudflare وMozilla تُعطّل التذاكر لهذا السبب.
HTTP Strict Transport Security (HSTS)
HSTS هو رأس استجابة HTTP يأمر المتصفحات بعدم الاتصال بنطاقك عبر HTTP غير المشفّر مطلقًا — حتى للطلب الأول بعد انتهاء max-age. بمجرد أن يرى المتصفح رأس HSTS، سيُعيد توجيه http:// داخليًا إلى https:// قبل إرسال أي بيانات على السلك، مما يُلغي نافذة هجمات SSL-stripping.
max-age=31536000— سنة واحدة؛ يتذكر المتصفح هذا لمدة 365 يومًا بعد آخر استجابة.includeSubDomains— يُمدّد السياسة لكل نطاق فرعي. أضفه فقط بعد التأكد من أن كل نطاق فرعي يملك شهادة سارية.preload— يُدرج نطاقك في قوائم HSTS المحملة مسبقًا في المتصفحات (Chrome وFirefox وSafari). قدّم الطلب علىhstspreload.org. هذا إجراء شبه دائم — قد يستغرق الإزالة أشهرًا.
preload وقدّمت طلبًا للقائمة ثم احتجت لاحقًا للعودة إلى HTTP (مثلًا لنطاق تجريبي)، سترفض المتصفحات الاتصال لمدة تصل إلى عام. لا تُفعّل preload إلا على النطاقات التي أنت متأكد تمامًا من أنها ستخدم HTTPS إلى الأبد.
التحقق من إعداد TLS
بعد تطبيق الإعداد، اختبر قبل افتراض الصحة. فحصان أساسيان:
أنماط الفشل الشائعة
- تحذيرات المحتوى المختلط — يُحمَّل HTML عبر HTTPS لكنه يتضمن عناوين موارد
http://. يحجبها المتصفح أو يُنبّه عنها. الحل: تأكد من أن جميع عناوين الأصول تستخدمhttps://أو//المستقلة عن البروتوكول. أعدّ إطار تطبيقك لتوليد عناوين HTTPS خلف proxy (APP_URL=https://...، أوURL::forceScheme('https')في Laravel). - سلسلة الشهادة غير مكتملة — يجب أن تُرسل الخوادم السلسلة الكاملة (الورقة + الوسيطات). استخدم
fullchain.pemلاcert.pem. عملاء الجوال بالذات يفشلون بصمت عند غياب الشهادة الوسيطة. - انتهاء صلاحية الشهادة — تنتهي شهادات Let's Encrypt بعد 90 يومًا. يُجدّد مؤقت systemd لـ Certbot في اليوم 60، لكن إذا توقف المؤقت (إعادة تشغيل النظام مع فشل الخدمات)، لديك 60 يومًا لاكتشاف المشكلة. راقب الانتهاء:
certbot certificatesأو مراقب خارجي مثل فحص SSL في UptimeRobot. - خطأ في
server_name— يخدم Nginx أول كتلةserverمطابقة إذا لم يتطابقserver_name، مما قد يُقدّم شهادة خاطئة. ضع دائمًا خادمًا افتراضيًا صريحًا أو تحقق من ترتيب الكتل.
openssl s_client -connect $HOST:443 < /dev/null 2>&1 | openssl x509 -noout -dates وتُنبّه إذا كان notAfter خلال 30 يومًا. يكتشف هذا فشل التجديد قبل أن يفعل المستخدمون.