الأمان والأداء

HTTPS و TLS

18 دقيقة الدرس 7 من 35

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;
تحذير: لا تستخدم أبدًا SSL 3.0 أو TLS 1.0 أو TLS 1.1 في الإنتاج. هذه البروتوكولات لها ثغرات معروفة وهي مهملة من قبل المتصفحات الرئيسية ومعايير الأمان.

عملية مصافحة TLS

مصافحة TLS تؤسس اتصالًا آمنًا قبل نقل أي بيانات:

// مصافحة TLS 1.2 (4 رحلات ذهابًا وإيابًا)
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 (انتهى)
[يبدأ الاتصال المشفر فورًا]
ملاحظة: بروتوكول TLS 1.3 يقلل زمن انتقال المصافحة بنسبة 50٪ مقارنة بـ TLS 1.2، مما يحسن الأداء مع الحفاظ على الأمان. كما يزيل مجموعات الشفرات الضعيفة والميزات المهملة.

أنواع الشهادات

شهادات SSL/TLS تتحقق من هوية الخادم وتمكن التشفير. أنواع مختلفة تخدم احتياجات مختلفة:

// 1. شهادات التحقق من النطاق (DV)
- تتحقق من ملكية النطاق فقط
- تصدر في غضون دقائق
- خيارات مجانية متاحة (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 مجانية وآلية. مثالي لمعظم المواقع:

# تثبيت Certbot (عميل ACME)
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"
أفضل ممارسة: تنتهي صلاحية شهادات Let's Encrypt بعد 90 يومًا. قم دائمًا بإعداد التجديد التلقائي باستخدام cron أو مؤقتات systemd. اختبر التجديد باستخدام --dry-run قبل الاعتماد على الأتمتة.

HSTS (أمان النقل الصارم HTTP)

بروتوكول HSTS يجبر المتصفحات على استخدام HTTPS دائمًا، مما يمنع هجمات الرجوع إلى الإصدار الأقدم:

// تكوين Apache
# .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 // مؤهل لقوائم التحميل المسبق للمتصفح
ملاحظة: معلمات HSTS:
max-age: المدة التي تتذكر فيها المتصفحات فرض HTTPS (موصى به: سنة واحدة)
includeSubDomains: يطبق HSTS على جميع النطاقات الفرعية (تأكد من أن جميع النطاقات الفرعية تدعم HTTPS)
preload: أرسل إلى hstspreload.org ليتم تضمينه في قوائم التحميل المسبق للمتصفح (لا رجعة فيه!)

التحميل المسبق لـ HSTS

قائمة التحميل المسبق لـ 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>
تحذير: التحميل المسبق لـ HSTS دائم فعليًا. الإزالة من قوائم التحميل المسبق تستغرق شهورًا. قم بتمكينه فقط إذا كنت متأكدًا من أن جميع النطاقات الفرعية ستدعم HTTPS دائمًا.

تثبيت الشهادة

تثبيت الشهادة يمنع هجمات الرجل في المنتصف عن طريق تشفير الشهادات أو المفاتيح العامة المتوقعة:

// تثبيت المفتاح العام HTTP (HPKP) - مهمل
// لا تستخدم: مهمل بسبب المخاطر
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()
ملاحظة: تم إهمال HPKP في عام 2017 بسبب مخاطر إتلاف المواقع بشكل دائم إذا تم تكوينها بشكل خاطئ. استخدم شفافية الشهادة (Expect-CT) لتطبيقات الويب أو قم بتطبيق التثبيت في تطبيقات الهاتف المحمول فقط.

مشاكل المحتوى المختلط

يحدث المحتوى المختلط عندما تحمل صفحات 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');
?>
أفضل ممارسة: استخدم توجيه CSP upgrade-insecure-requests لترقية طلبات HTTP إلى HTTPS تلقائيًا. هذا يمنع أخطاء المحتوى المختلط دون تعديل كل عنوان URL للموارد.

أفضل ممارسات تكوين TLS

التكوين الصحيح لـ TLS يزيد من الأمان والتوافق:

// تكوين Apache Virtual Host
<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 الشائعة يساعد في منع الهجمات:

// 1. POODLE (Padding Oracle On Downgraded Legacy Encryption)
// هجوم على 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
تمرين: قم بإعداد بيئة HTTPS كاملة:
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. راقب تواريخ انتهاء صلاحية الشهادات