HTTPS و TLS
HTTPS و TLS
بروتوكول HTTPS (HTTP الآمن) و TLS (أمان طبقة النقل) هما أساس أمان الويب. فهم كيفية عمل التشفير أثناء النقل يحمي بيانات المستخدم من الاعتراض والتلاعب.
أساسيات SSL/TLS
بروتوكول SSL (طبقة المقابس الآمنة) وخليفته TLS ينشئان اتصالات مشفرة بين العملاء والخوادم:
SSL 1.0 - لم يتم إصداره أبدًا (عيوب أمنية)
SSL 2.0 - 1995 (مهمل - غير آمن)
SSL 3.0 - 1996 (مهمل - هجوم POODLE)
TLS 1.0 - 1999 (مهمل اعتبارًا من 2020)
TLS 1.1 - 2006 (مهمل اعتبارًا من 2020)
TLS 1.2 - 2008 (لا يزال آمنًا)
TLS 1.3 - 2018 (المعيار الموصى به حاليًا)
// تكوين Apache - فرض TLS 1.2+
# /etc/httpd/conf.d/ssl.conf
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on
// تكوين Nginx
# /etc/nginx/nginx.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
عملية مصافحة TLS
مصافحة TLS تؤسس اتصالًا آمنًا قبل نقل أي بيانات:
1. Client Hello (تحية العميل)
- إصدارات TLS المدعومة
- مجموعات الشفرات المدعومة
- رقم عشوائي
2. Server Hello (تحية الخادم)
- إصدار TLS المحدد
- مجموعة الشفرات المحددة
- شهادة الخادم
- رقم عشوائي
3. Client Key Exchange (تبادل مفتاح العميل)
- التحقق من شهادة الخادم
- توليد السر الرئيسي المسبق
- التشفير باستخدام المفتاح العام للخادم
4. Change Cipher Spec (تغيير مواصفات الشفرة)
- كلا الجانبين يتحول إلى الاتصال المشفر
- تبادل رسائل "Finished" (انتهى)
// مصافحة TLS 1.3 (رحلة واحدة - أسرع!)
1. Client Hello (تحية العميل)
- الإصدارات والشفرات المدعومة
- مشاركة المفتاح (محسوبة مسبقًا)
2. Server Hello (تحية الخادم)
- المعلمات المحددة
- مشاركة المفتاح
- الشهادة
- رسالة Finished (انتهى)
[يبدأ الاتصال المشفر فورًا]
أنواع الشهادات
شهادات SSL/TLS تتحقق من هوية الخادم وتمكن التشفير. أنواع مختلفة تخدم احتياجات مختلفة:
- تتحقق من ملكية النطاق فقط
- تصدر في غضون دقائق
- خيارات مجانية متاحة (Let's Encrypt)
- مناسبة للمدونات والمحافظ والمواقع الصغيرة
مثال: Let's Encrypt، ZeroSSL
// 2. شهادات التحقق من المؤسسة (OV)
- تتحقق من النطاق + هوية المؤسسة
- تتطلب التحقق من الأعمال
- تصدر في غضون 1-3 أيام
- تعرض اسم المؤسسة في تفاصيل الشهادة
- مناسبة لمواقع الأعمال
مثال: DigiCert OV، Sectigo OV
// 3. شهادات التحقق الموسع (EV)
- أعلى مستوى تحقق
- التحقق الشامل من المؤسسة
- تصدر في غضون 1-2 أسبوع
- تعرض اسم المؤسسة في شريط عنوان المتصفح (المتصفحات القديمة)
- مناسبة للتجارة الإلكترونية والبنوك والمواقع عالية الأمان
مثال: DigiCert EV، Entrust EV
// 4. الشهادات البدلية (Wildcard)
- تؤمن النطاق + نطاقات فرعية غير محدودة
- *.example.com يغطي blog.example.com، shop.example.com، إلخ.
- فعالة من حيث التكلفة للنطاقات الفرعية المتعددة
مثال: *.esb1995.com
// 5. شهادات متعددة النطاقات (SAN)
- تؤمن نطاقات مختلفة متعددة
- أسماء بديلة للموضوع (SAN)
- example.com، example.net، example.org
مثال: شهادة الاتصالات الموحدة
Let's Encrypt - شهادات SSL مجانية
يوفر Let's Encrypt شهادات DV مجانية وآلية. مثالي لمعظم المواقع:
sudo yum install certbot python3-certbot-apache # RHEL/CentOS
sudo apt install certbot python3-certbot-nginx # Ubuntu/Debian
# الحصول على الشهادة وتثبيتها (Apache)
sudo certbot --apache -d example.com -d www.example.com
# الحصول على الشهادة وتثبيتها (Nginx)
sudo certbot --nginx -d example.com -d www.example.com
# شهادة يدوية (مستقلة)
sudo certbot certonly --standalone -d example.com
# التجديد التلقائي (يعمل مرتين يوميًا)
sudo certbot renew
# اختبار عملية التجديد
sudo certbot renew --dry-run
# إضافة إلى crontab للتجديد التلقائي
0 0,12 * * * certbot renew --quiet --deploy-hook "systemctl reload apache2"
--dry-run قبل الاعتماد على الأتمتة.HSTS (أمان النقل الصارم HTTP)
بروتوكول HSTS يجبر المتصفحات على استخدام HTTPS دائمًا، مما يمنع هجمات الرجوع إلى الإصدار الأقدم:
# .htaccess أو VirtualHost
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
// تكوين Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
// تنفيذ PHP
<?php
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
?>
// شرح المعلمات:
max-age=31536000 // سنة واحدة بالثواني
includeSubDomains // تطبيق على جميع النطاقات الفرعية
preload // مؤهل لقوائم التحميل المسبق للمتصفح
max-age: المدة التي تتذكر فيها المتصفحات فرض HTTPS (موصى به: سنة واحدة)
includeSubDomains: يطبق HSTS على جميع النطاقات الفرعية (تأكد من أن جميع النطاقات الفرعية تدعم HTTPS)
preload: أرسل إلى hstspreload.org ليتم تضمينه في قوائم التحميل المسبق للمتصفح (لا رجعة فيه!)
التحميل المسبق لـ HSTS
قائمة التحميل المسبق لـ HSTS مشفرة في المتصفحات، مما يحمي مستخدمي الزيارة الأولى:
1. تقديم شهادة HTTPS صالحة
2. إعادة توجيه HTTP إلى HTTPS (نفس المضيف)
3. تقديم رأس HSTS على النطاق الأساسي:
- max-age >= 31536000 (سنة واحدة)
- توجيه includeSubDomains
- توجيه preload
4. تقديم رأس HSTS على جميع النطاقات الفرعية
// إرسال إلى قائمة التحميل المسبق
// زيارة: https://hstspreload.org/
// أدخل النطاق وتحقق من المتطلبات
// إعادة توجيه Apache + HSTS
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# ... تكوين SSL ...
</VirtualHost>
تثبيت الشهادة
تثبيت الشهادة يمنع هجمات الرجل في المنتصف عن طريق تشفير الشهادات أو المفاتيح العامة المتوقعة:
// لا تستخدم: مهمل بسبب المخاطر
Public-Key-Pins: pin-sha256="base64=="; max-age=5184000
// البديل الحديث: شفافية الشهادة
Expect-CT: max-age=86400, enforce, report-uri="https://example.com/ct-report"
// تثبيت تطبيق الهاتف المحمول (iOS - Swift)
let serverTrustPolicy = ServerTrustPolicy.pinPublicKeys(
publicKeys: ServerTrustPolicy.publicKeys(),
validateCertificateChain: true,
validateHost: true
)
// تثبيت تطبيق الهاتف المحمول (Android - Kotlin)
val certificatePinner = CertificatePinner.Builder()
.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
مشاكل المحتوى المختلط
يحدث المحتوى المختلط عندما تحمل صفحات HTTPS موارد HTTP، مما يكسر الأمان:
<!-- صفحة HTTPS تحمل موارد HTTP -->
<img src="http://example.com/image.jpg">
<script src="http://cdn.example.com/script.js"></script>
<link href="http://example.com/style.css" rel="stylesheet">
<!-- آمن: عناوين URL النسبية للبروتوكول (نهج قديم) -->
<img src="//example.com/image.jpg">
<script src="//cdn.example.com/script.js"></script>
<!-- الأفضل: عناوين HTTPS صريحة -->
<img src="https://example.com/image.jpg">
<script src="https://cdn.example.com/script.js"></script>
<!-- سياسة أمان المحتوى - حظر المحتوى المختلط -->
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
<?php
// رأس من جانب الخادم
header('Content-Security-Policy: upgrade-insecure-requests');
?>
upgrade-insecure-requests لترقية طلبات HTTP إلى HTTPS تلقائيًا. هذا يمنع أخطاء المحتوى المختلط دون تعديل كل عنوان URL للموارد.أفضل ممارسات تكوين TLS
التكوين الصحيح لـ TLS يزيد من الأمان والتوافق:
<VirtualHost *:443>
ServerName example.com
# تمكين SSL/TLS
SSLEngine on
# مسارات الشهادة
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# بروتوكولات TLS (تعطيل الإصدارات القديمة)
SSLProtocol -all +TLSv1.2 +TLSv1.3
# مجموعات الشفرات (تشفير قوي فقط)
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
# تدبيس OCSP (يحسن الأداء)
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
# رأس HSTS
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
// اختبار تكوين TLS
// استخدم SSL Labs: https://www.ssllabs.com/ssltest/
// اختبار سطر الأوامر:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
// فحص تفاصيل الشهادة
openssl x509 -in certificate.crt -text -noout
// التحقق من سلسلة الشهادة
openssl verify -CAfile chain.pem certificate.crt
ثغرات TLS الشائعة
فهم ثغرات TLS الشائعة يساعد في منع الهجمات:
// هجوم على SSL 3.0
// الإصلاح: تعطيل SSL 3.0 تمامًا
SSLProtocol -all +TLSv1.2 +TLSv1.3
// 2. BEAST (Browser Exploit Against SSL/TLS)
// هجوم على شفرات CBC في TLS 1.0
// الإصلاح: استخدم TLS 1.2+ أو عطل شفرات CBC في TLS 1.0
// 3. CRIME (Compression Ratio Info-leak Made Easy)
// هجوم على ضغط TLS
// الإصلاح: تعطيل ضغط TLS
SSLCompression off
// 4. Heartbleed
// قراءة زائدة للمخزن المؤقت في OpenSSL
// الإصلاح: تحديث OpenSSL إلى 1.0.1g أو أحدث
yum update openssl
// 5. FREAK (Factoring RSA Export Keys)
// هجوم الرجوع إلى شفرات التصدير الضعيفة
// الإصلاح: تعطيل شفرات التصدير
SSLCipherSuite !EXPORT
// 6. Logjam
// الرجوع إلى تبادل مفتاح Diffie-Hellman الضعيف
// الإصلاح: استخدم معلمات DH قوية (2048+ بت)
openssl dhparam -out dhparams.pem 2048
SSLOpenSSLConfCmd DHParameters "/path/to/dhparams.pem"
// 7. DROWN (Decrypting RSA with Obsolete and Weakened eNcryption)
// هجوم على الخوادم الداعمة لـ SSLv2
// الإصلاح: تعطيل SSLv2 في كل مكان
SSLProtocol -all +TLSv1.2 +TLSv1.3
1. قم بتثبيت Certbot والحصول على شهادة Let's Encrypt لنطاقك
2. قم بتكوين Apache/Nginx لاستخدام TLS 1.2 و TLS 1.3 فقط
3. قم بإعداد مجموعات شفرات قوية (استخدم مولد تكوين Mozilla SSL)
4. قم بتمكين تدبيس OCSP للأداء
5. أضف رأس HSTS مع max-age لمدة سنة واحدة و includeSubDomains
6. قم بتكوين إعادة التوجيه التلقائي من HTTP إلى HTTPS
7. قم بإعداد التجديد التلقائي للشهادة باستخدام cron
8. اختبر التكوين في SSL Labs (هدف تصنيف A+)
9. قم بتطبيق Content-Security-Policy مع upgrade-insecure-requests
10. راقب تواريخ انتهاء صلاحية الشهادات