Skip to content

شهادات SSL

يدعم FORGE استراتيجيات متعددة لشهادات SSL/TLS حسب طريقة نشرك ومتطلباتك. كل طريقة نشر -- Docker Compose أو Kubernetes أو SSH -- تتضمن إعدادات SSL مدمجة لضمان تقديم تطبيقك عبر HTTPS في الإنتاج.

نظرة سريعة على خيارات SSL

الطريقةالتكلفةالتجديد التلقائيالأفضل لـ
Let's Encryptمجانينعم (شهادات 90 يوماً)معظم عمليات النشر
Cloudflare Proxyمجانينعم (Cloudflare يُدير)حماية DDoS و CDN
شهادة مخصصةمتفاوتيدويالمؤسسات، شهادات EV، wildcards

توصية

لمعظم التطبيقات، Let's Encrypt هو الخيار الأفضل. إنه مجاني ومؤتمت بالكامل وموثوق من جميع المتصفحات. استخدم Cloudflare Proxy إذا كنت تحتاج أيضاً حماية DDoS وقدرات CDN.

Let's Encrypt

Let's Encrypt يوفر شهادات TLS مجانية ومؤتمتة موثوقة من جميع المتصفحات الرئيسية. الشهادات صالحة لـ 90 يوماً وتُجدد تلقائياً قبل انتهاء الصلاحية.

المتطلبات

قبل الحصول على شهادة Let's Encrypt، تأكد من:

  1. سجل DNS A لنطاقك يُشير إلى عنوان IP خادمك
  2. المنفذ 80 متاح من الإنترنت (للتحقق بتحدي HTTP-01)
  3. لديك عنوان بريد إلكتروني صالح لإشعارات انتهاء الصلاحية

مع Kubernetes (cert-manager)

cert-manager هو متحكم إدارة شهادات أصلي لـ Kubernetes يُؤتمت الإصدار والتجديد.

الخطوة 1: تثبيت cert-manager

bash
# Install cert-manager in the cluster
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.0/cert-manager.yaml

# Verify installation
kubectl wait --for=condition=ready pod \
  -l app.kubernetes.io/instance=cert-manager \
  -n cert-manager --timeout=120s

الخطوة 2: توليد manifests مع Let's Encrypt

bash
forge deploy:k8s --ssl=letsencrypt --email=admin@myapp.com

الخطوة 3: تطبيق ClusterIssuer

ملف cluster-issuer.yaml المُولّد يُعدّ Let's Encrypt:

yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: admin@myapp.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx
bash
kubectl apply -f k8s/cert-manager/cluster-issuer.yaml

الخطوة 4: تطبيق Ingress مع TLS

Ingress المُولّد يُشير إلى ClusterIssuer عبر annotation:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
    - hosts:
        - myapp.com
        - admin.myapp.com
        - api.myapp.com
      secretName: myapp-tls
  rules:
    # ... قواعد التوجيه
bash
kubectl apply -f k8s/ingress.yaml

الخطوة 5: التحقق من إصدار الشهادة

bash
# Check certificate status
kubectl get certificate -n myapp

# View certificate details
kubectl describe certificate myapp-tls -n myapp

# Check certificate request
kubectl get certificaterequest -n myapp
kubectl get order -n myapp

استخدم staging أولاً

للاختبار، استخدم خادم staging لـ Let's Encrypt لتجنب الوصول لحدود المعدل:

yaml
# In cluster-issuer.yaml, change:
server: https://acme-staging-v02.api.letsencrypt.org/directory

انتقل لخادم الإنتاج بمجرد التأكد من أن كل شيء يعمل.

مع Docker Compose (Caddy)

Caddy يتعامل مع Let's Encrypt تلقائياً بدون أي إعدادات. عندما يرى Caddy اسم نطاق حقيقي في إعداداته، يحصل على شهادات TLS ويُجددها بدون أي إعداد يدوي.

الخطوة 1: توليد ملف Compose للإنتاج

bash
forge deploy:compose --env=production --ssl=letsencrypt

الخطوة 2: إعداد Caddy

ملف Caddyfile المُولّد:

{
    email admin@myapp.com
}

myapp.com {
    reverse_proxy web:3000
    encode gzip
}

admin.myapp.com {
    reverse_proxy admin:3001
    encode gzip
}

api.myapp.com {
    reverse_proxy api:8080
    encode gzip
}

الخطوة 3: بدء الـ stack

bash
docker compose -f docker-compose.prod.yaml up -d

Caddy سيقوم تلقائياً بـ:

  1. الحصول على شهادات من Let's Encrypt
  2. إعداد HTTPS على المنفذ 443
  3. إعادة توجيه HTTP إلى HTTPS
  4. تجديد الشهادات قبل انتهاء صلاحيتها
  5. تفعيل OCSP stapling

تخزين شهادات Caddy

Caddy يُخزّن الشهادات في Docker volume باسم caddy_data. هذا الـ volume يستمر عبر إعادة تشغيل الحاويات، لذا لا تُطلب الشهادات من جديد بدون داعٍ.

مع SSH (certbot)

لعمليات النشر التقليدية على الخادم بدون حاويات، استخدم certbot للحصول على شهادات Let's Encrypt وإدارتها.

الخطوة 1: توليد سكربت إعداد SSL

bash
forge deploy:ssl --method=certbot --domain=myapp.com --email=admin@myapp.com

الخطوة 2: تشغيل السكربت المُولّد على خادمك

bash
ssh deploy@myapp.com 'bash -s' < deploy/ssl/setup-certbot.sh

السكربت يُنفّذ:

bash
#!/bin/bash
set -euo pipefail

# Install certbot
sudo apt update
sudo apt install -y certbot python3-certbot-nginx

# Obtain certificates for all domains
sudo certbot certonly --nginx \
  -d myapp.com \
  -d admin.myapp.com \
  -d api.myapp.com \
  --email admin@myapp.com \
  --agree-tos \
  --non-interactive

# Certificates are stored in:
#   /etc/letsencrypt/live/myapp.com/fullchain.pem
#   /etc/letsencrypt/live/myapp.com/privkey.pem

الخطوة 3: إعداد التجديد التلقائي

certbot يُعدّ systemd timer للتجديد التلقائي. تحقق أنه نشط:

bash
# Check renewal timer
sudo systemctl status certbot.timer

# Test renewal (dry run)
sudo certbot renew --dry-run

الخطوة 4: إعداد Nginx لاستخدام الشهادات

nginx
server {
    listen 443 ssl http2;
    server_name myapp.com;

    ssl_certificate     /etc/letsencrypt/live/myapp.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myapp.com/privkey.pem;

    # Recommended SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000" always;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name myapp.com admin.myapp.com api.myapp.com;
    return 301 https://$host$request_uri;
}

Cloudflare Proxy

Cloudflare يوفر SSL/TLS مجاني عند توجيه حركة المرور عبر شبكتهم. هذا يضيف أيضاً حماية DDoS و CDN وقدرات Web Application Firewall (WAF).

الإعداد

الخطوة 1: أضف نطاقك إلى Cloudflare

  1. أنشئ حساب Cloudflare مجاني على cloudflare.com
  2. أضف نطاقك واتبع تعليمات إعداد DNS
  3. حدّث nameservers نطاقك للإشارة إلى Cloudflare

الخطوة 2: إعداد وضع SSL

في Cloudflare Dashboard > SSL/TLS:

الوضعالوصفالتوصية
Offبدون تشفيرلا تستخدم أبداً
Flexibleيُشفّر من المتصفح إلى Cloudflare فقطغير موصى به
Fullتشفير من طرف لطرف، يقبل self-signed على الخادممقبول
Full (Strict)تشفير من طرف لطرف، يتطلب شهادة صالحة على الخادمموصى به

استخدم وضع Full (Strict)

استخدم دائماً وضع Full (Strict). هذا يتطلب شهادة صالحة على خادم الأصل (استخدم Cloudflare Origin Certificate أو Let's Encrypt). وضع Flexible يترك حركة المرور بين Cloudflare وخادمك بدون تشفير.

الخطوة 3: تثبيت Cloudflare Origin Certificate

Origin Certificates هي شهادات مجانية تُصدرها Cloudflare لتشفير حركة المرور بين Cloudflare وخادمك:

  1. اذهب إلى Cloudflare Dashboard > SSL/TLS > Origin Server
  2. اضغط "Create Certificate"
  3. اختر أسماء المضيفين (مثل *.myapp.com، myapp.com)
  4. اختر فترة الصلاحية (حتى 15 سنة)
  5. حمّل الشهادة والمفتاح الخاص

ثبّت على خادمك:

bash
# Save certificate files
sudo mkdir -p /etc/ssl/cloudflare
sudo nano /etc/ssl/cloudflare/myapp.com.pem      # Paste certificate
sudo nano /etc/ssl/cloudflare/myapp.com-key.pem   # Paste private key

# Set permissions
sudo chmod 600 /etc/ssl/cloudflare/myapp.com-key.pem

أعدّ Nginx لاستخدام Origin Certificate:

nginx
server {
    listen 443 ssl http2;
    server_name myapp.com;

    ssl_certificate     /etc/ssl/cloudflare/myapp.com.pem;
    ssl_certificate_key /etc/ssl/cloudflare/myapp.com-key.pem;

    location / {
        proxy_pass http://localhost:3000;
    }
}

الخطوة 4: تفعيل ميزات الأمان الإضافية

في Cloudflare Dashboard، فعّل:

  • Always Use HTTPS -- يُعيد توجيه كل حركة HTTP إلى HTTPS
  • Automatic HTTPS Rewrites -- يُصلح مشاكل المحتوى المختلط
  • Minimum TLS Version -- عيّن إلى TLS 1.2
  • HSTS -- فعّل HTTP Strict Transport Security

الشهادات المخصصة

لمتطلبات المؤسسات مثل شهادات Extended Validation (EV) أو شهادات wildcard من CAs محددة أو شهادات organization-validated.

الإعداد

الخطوة 1: الحصول على شهادة من CA الخاص بك

أنشئ Certificate Signing Request (CSR):

bash
# Generate private key and CSR
openssl req -new -newkey rsa:2048 -nodes \
  -keyout myapp.com.key \
  -out myapp.com.csr \
  -subj "/C=US/ST=State/L=City/O=MyOrg/CN=myapp.com"

أرسل CSR إلى Certificate Authority (DigiCert أو Sectigo أو غيرها) وحمّل الشهادة الصادرة.

الخطوة 2: التثبيت على خادمك

bash
# Create certificate directory
sudo mkdir -p /etc/ssl/custom

# Copy certificate files
sudo cp myapp.com.crt /etc/ssl/custom/
sudo cp myapp.com.key /etc/ssl/custom/
sudo cp ca-bundle.crt /etc/ssl/custom/

# Create full chain
cat /etc/ssl/custom/myapp.com.crt /etc/ssl/custom/ca-bundle.crt \
  > /etc/ssl/custom/myapp.com-fullchain.crt

# Set permissions
sudo chmod 600 /etc/ssl/custom/myapp.com.key

الخطوة 3: إعداد خادم الويب

nginx
server {
    listen 443 ssl http2;
    server_name myapp.com;

    ssl_certificate     /etc/ssl/custom/myapp.com-fullchain.crt;
    ssl_certificate_key /etc/ssl/custom/myapp.com.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
}
yaml
# Create TLS secret from certificate files
kubectl create secret tls myapp-tls \
  --cert=myapp.com-fullchain.crt \
  --key=myapp.com.key \
  -n myapp
caddy
myapp.com {
    tls /etc/ssl/custom/myapp.com-fullchain.crt /etc/ssl/custom/myapp.com.key
    reverse_proxy web:3000
}

تجديد الشهادة

الشهادات المخصصة لا تُجدد تلقائياً. عيّن تذكيراً في التقويم للتجديد قبل انتهاء الصلاحية. معظم الشهادات صالحة لسنة واحدة.

مقارنة خيارات SSL

الميزةLet's EncryptCloudflare Proxyشهادة مخصصة
التكلفةمجانيمجاني (مع CF)$10 - $500+/سنة
التجديد التلقائينعم (دورة 90 يوماً)نعم (CF يُدير)لا (يدوي)
جهد الإعدادمنخفضمتوسطعالي
حماية DDoSلانعم (مُضمّنة)لا
CDNلانعم (مُضمّنة)لا
أنواع الشهاداتDV فقطDV (proxy)، OV/EV (origin)DV، OV، EV
دعم Wildcardنعم (DNS-01)نعمنعم
ثقة المتصفحاتجميع المتصفحاتجميع المتصفحاتجميع المتصفحات
Kubernetescert-managerوضع ProxySecret يدوي
Docker ComposeCaddy (تلقائي)وضع ProxyVolume يدوي
SSH / Bare Metalcertbotوضع Proxyتثبيت يدوي

أوامر FORGE SSL

يوفر FORGE أوامر CLI لكل طريقة نشر:

bash
# Kubernetes مع Let's Encrypt
forge deploy:k8s --ssl=letsencrypt --email=admin@myapp.com

# Docker Compose مع Caddy (Let's Encrypt تلقائي)
forge deploy:compose --ssl=letsencrypt --email=admin@myapp.com

# خادم SSH مع certbot
forge deploy:ssl --method=certbot --domain=myapp.com --email=admin@myapp.com

# توليد سكربتات إعداد SSL بدون تنفيذ
forge deploy:ssl --method=certbot --domain=myapp.com --output=./deploy/ssl/

التحقق من إعدادات SSL

بعد النشر، تحقق من إعداد SSL:

bash
# Check certificate details
openssl s_client -connect myapp.com:443 -servername myapp.com 2>/dev/null | \
  openssl x509 -noout -subject -dates -issuer

# Test with curl
curl -vI https://myapp.com 2>&1 | grep -E "SSL|issuer|expire"

# Check all subdomains
for domain in myapp.com admin.myapp.com api.myapp.com; do
  echo "--- $domain ---"
  curl -sI "https://$domain" | head -1
done

أدوات عبر الإنترنت للاختبار الشامل:

استكشاف الأخطاء

الشهادة لا تُصدر

bash
# cert-manager: Check certificate request status
kubectl describe certificaterequest -n myapp
kubectl describe order -n myapp
kubectl describe challenge -n myapp

# Common reasons:
# - DNS not pointing to server
# - Port 80 blocked by firewall
# - Rate limit exceeded (use staging server)

الشهادة انتهت صلاحيتها

bash
# certbot: Force renewal
sudo certbot renew --force-renewal

# cert-manager: Delete and recreate
kubectl delete certificate myapp-tls -n myapp
kubectl apply -f k8s/cert-manager/certificate.yaml

تحذيرات المحتوى المختلط

تأكد أن جميع الموارد تُحمّل عبر HTTPS. تحقق من عناوين URL المُثبّتة بـ http:// في إعدادات تطبيقك والقوالب.

الخطوات التالية

Released under the MIT License.