عندك سيرفر لينكس في مرام هوست ودومين، وتريد أن يفتح موقعك على https:// بقفل أخضر؟ في هذا الدليل الشامل ننصّب Nginx، ونربط الدومين بالسيرفر، ثم نحصل على شهادة SSL مجانية من Let’s Encrypt تتجدد وحدها. نفّذنا الخطوات كلها على سيرفر حقيقي وحصلنا على شهادة فعلية، وهذه المخرجات كما ظهرت.

⚡ الإجابة المختصرة

وجّه سجل A للدومين إلى عنوان سيرفرك، ثم: sudo apt install -y nginx، وأنشئ ملف الموقع في /etc/nginx/sites-available/ مع server_name دومينك، وفعّله وsudo nginx -t && sudo systemctl reload nginx، وأخيرًا sudo apt install -y certbot python3-certbot-nginx && sudo certbot --nginx -d دومينك --redirect.

قبل أن تبدأ

  • المنفذان 80 و443 مفتوحان في جدار لوحة مرام وفي ufw — وهما مفتوحان افتراضيًا في قوالب مرام. إن غيّرت شيئًا راجع دليل جدار الحماية.
  • لا يستعمل برنامج آخر المنفذين (مثل Apache أو حاوية Docker). افحص بـsudo ss -tlnp | grep -E ":80 |:443 ". في سيرفرنا كانت حاوية Caddy تستعملهما فأوقفناها أولًا.
  • دومين تملكه (من مرام أو أي مسجّل). في الأمثلة نستعمل 203-0-113-10.sslip.io — ضع دومينك مكانه.

الخطوة 1: اربط الدومين بالسيرفر (سجل A)

من لوحة الدومين (في مرام: النطاقات ← إدارة DNS، أو لوحة Cloudflare إن كنت تستعملها) أضف سجلين:

النوعالاسمالقيمة
A@ (الدومين نفسه)عنوان IP سيرفرك
Awwwعنوان IP سيرفرك

ثم تأكد أن الدومين يشير إلى سيرفرك (قد يستغرق الانتشار من دقائق إلى ساعات) — من أي جهاز:

nslookup 203-0-113-10.sslip.io 1.1.1.1
# Name:    203-0-113-10.sslip.io
# Address: 203.0.113.10          ← يجب أن يظهر عنوان سيرفرك

إن كنت تستعمل Cloudflare: اجعل السحابة رمادية (DNS only) أثناء إصدار الشهادة، ثم فعّلها بعد ذلك مع وضع SSL Full (strict).

الخطوة 2: ثبّت Nginx

تثبيت Nginx والتأكد أنه يعمل ويستمع على المنفذ 80
مخرجات حقيقية

الخطوة 3: ملفات موقعك وملف الإعداد

ضع ملفات موقعك في مجلد مثل /var/www/shop (بـscp أو WinSCP)، ثم أنشئ ملف إعداد للموقع وفعّله وافحصه:

sudo mkdir -p /var/www/shop
sudo chown -R www-data:www-data /var/www/shop
sudo nano /etc/nginx/sites-available/shop       # الصق الإعداد أدناه
ملف server block في Nginx وفحصه بأمر nginx -t
مخرجات حقيقية

واحذف الموقع الافتراضي حتى لا تظهر صفحة «Welcome to nginx» بدل موقعك: sudo rm /etc/nginx/sites-enabled/default && sudo systemctl reload nginx. واجهنا هذا فعلًا: قبل حذفه ظهرت الصفحة الافتراضية في أحد الاختبارات.

الخطوة 4: شهادة SSL مجانية بأمر واحد

أداة certbot تطلب الشهادة من Let’s Encrypt، وتعدّل ملف Nginx بنفسها، وتضيف التحويل من HTTP إلى HTTPS (--redirect):

إصدار شهادة SSL مجانية بأمر certbot --nginx ونجاح تفعيل HTTPS
مخرجات حقيقية: شهادة صادرة فعلًا

لعدة دومينات أضف كل واحد بـ-d: sudo certbot --nginx -d example.com -d www.example.com --redirect. وفي أول تشغيل يسألك عن بريد للتنبيهات والموافقة على الشروط.

الخطوة 5: تأكد من HTTPS والتجديد التلقائي

الشهادة صالحة 90 يومًا، وcertbot يضيف مؤقتًا يجددها قبل انتهائها. تأكد من ذلك مرة واحدة، ثم افتح الموقع من جهازك:

مؤقت certbot وتجربة التجديد وفحص HTTPS من الخارج
مخرجات حقيقية
صفحة الموقع التجريبي تعمل على HTTPS بعد إصدار الشهادة
لقطة حقيقية للصفحة

مشاكل شائعة

المشكلةالحل
certbot: Timeout during connect أو unauthorizedالدومين لا يشير إلى السيرفر بعد، أو المنفذ 80 مغلق في جدار اللوحة أو ufw، أو Cloudflare مفعّل (برتقالي).
nginx: [emerg] bind() to 0.0.0.0:80 failedبرنامج آخر يستعمل المنفذ (Apache أو Docker). اعرفه بـsudo ss -tlnp | grep :80 وأوقفه.
تظهر «Welcome to nginx»احذف sites-enabled/default وتأكد من server_name.
403 Forbiddenلا يوجد index.html أو صلاحيات المجلد: sudo chown -R www-data:www-data /var/www/shop.
Too many certificates already issuedحدود Let’s Encrypt الأسبوعية: لا تكرر الطلب كثيرًا أثناء التجارب، واستعمل --dry-run.

إضافة: Nginx أمام تطبيق (n8n أو Node أو Uptime Kuma)

إن كان تطبيقك يعمل على منفذ داخلي (مثل 3001)، اجعل Nginx يمرر الطلبات إليه بدل فتح المنفذ للعالم، ثم أصدر الشهادة كما في الخطوة 4:

server {
    listen 80;
    server_name status.example.com;
    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;        # لدعم WebSocket
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}