لماذا تختار نفق Cloudflare بدلاً من فتح منفذ
الإعداد التقليدي — فتح المنفذين 80 و443 في جدار الحماية، وتوجيه سجل DNS نحو عنوان IP الخادم، وتثبيت وكيل عكسي — يعمل جيداً حين تتحكم في الشبكة. غير أن ثلاثة سيناريوهات تُعطّله: مزوّد الإنترنت أو شبكة المؤسسة التي تحجب الاتصالات الواردة على المنفذ 443، وعنوان IP ديناميكي يُبطل سجلات DNS كل 24 ساعة، وخادم VPS خلف NAT صارم لا يسمح بأي إعادة توجيه للمنافذ.
يتجاوز Cloudflare Tunnel الحالات الثلاث بآلية واحدة: يُنشئ الوكيل cloudflared اتصالاً خارجياً دائماً بنقاط تواجد Cloudflare. لا يقبل خادمك أي اتصال وارد؛ يستقبل Cloudflare طلبات HTTPS ويعيد إرسالها عبر هذا النفق المشفّر. ولا يصل أي حركة مرور واردة إلى خادمك مباشرةً.
ما يُقدّمه Cloudflare Tunnel عملياً
- صفر منافذ مفتوحة — يمكن لجدار حماية VPS حجب جميع حركة المرور الواردة (بما فيها 80 و443) دون التأثير على إمكانية الوصول إلى التطبيق.
- HTTPS تلقائي — يدير Cloudflare شهادة TLS من جانب العميل: لا حاجة لإعداد Let's Encrypt، ولا تجديد يدوي للشهادات.
- شفافية NAT والـIP الديناميكي — يخترق الاتصال الخارجي من
cloudflaredأي NAT؛ ويمكن لعنوان IP الخادم التغير دون إعادة تهيئة DNS. - شبكة المؤسسة أو مزوّد الإنترنت المقيّد — إذا كان المنفذ 443 الوارد محجوباً، يستمر النفق في العمل لاعتماده على اتصالات خارجية HTTP/2 أو QUIC.
- تكامل Zero Trust اختياري — تتزاوج الأنفاق مع Cloudflare Access لتقييد الوصول بالمستخدمين المصادق عليهم، دون الحاجة إلى VPN.
- حماية Cloudflare مضمّنة — تمر حركة المرور عبر شبكة Cloudflare: تشغيل التخفيف من DDoS وWAF وحدود المعدل دون إعداد إضافي.
- الخطة المجانية متاحة — نفق بسيط بدون موازنة الأحمال قابل للاستخدام دون اشتراك مدفوع في Cloudflare.
المتطلبات الأساسية
لمتابعة هذا الدليل تحتاج إلى:
خادم VPS بصلاحيات root. يستلزم تثبيت cloudflared كخدمة systemd — الطريقة الوحيدة لضمان إعادة التشغيل التلقائي — امتلاك صلاحيات root. لا تتيح الاستضافة المشتركة أو الأنظمة التي تفتقر إلى صلاحيات root هذا الإعداد.
موارد دنيا. يستهلك cloudflared أقل من 50 ميغابايت من الذاكرة العشوائية مع استهلاك هزيل للمعالج. احسب 1 vCPU و512 ميغابايت RAM كحدّ أدنى صارم للوكيل وحده؛ القيد الفعلي يأتي من التطبيق الذي تعرضه.
نطاق مُدار بواسطة Cloudflare. يجب أن يكون النطاق مسجلاً أو محوّلاً إلى Cloudflare (أو تفويض NS إلى Cloudflare). بدون منطقة Cloudflare نشطة، لا يستطيع النفق المُسمَّى إنشاء سجلات DNS تلقائياً.
Docker Engine (في حال استخدام متغيّر Docker Compose من هذا الدليل). متاح على Ubuntu 22.04/24.04 وDebian 12 والتوزيعات المتوافقة مع RHEL.
حساب Cloudflare مجاني. لا يُشترط أي اشتراك مدفوع لنفق واحد بدون موازنة أحمال.
تثبيت cloudflared وإعداده على الخادم VPS
تثبيت cloudflared عبر مستودع Cloudflare
تنشر Cloudflare حزم cloudflared بصيغ .deb و.rpm وملف ثنائي ثابت. للتثبيت عبر APT على Debian/Ubuntu:
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install cloudflaredتحقق من صحة التثبيت:
cloudflared --versionيجب أن تُعيد الأمر سطراً مشابهاً لـcloudflared version 2025.x.x (built ...). يعتمد الإصدار الدقيق على وقت التثبيت؛ ارجع إلى مستودع cloudflare/cloudflared الرسمي للاطلاع على الرقم الحالي.
مصادقة cloudflared مع Cloudflare
على خادم VPS (أو محلياً إن توفّر وصول رسومي)، نفّذ:
cloudflared tunnel loginيظهر رابط في الطرفية. افتحه في متصفح، واختر منطقة Cloudflare المراد تفويضها، ثم أكّد. يُنشأ شهادة ~/.cloudflared/cert.pem على الجهاز.
إنشاء نفق مُسمَّى
أنشئ نفقاً باسم وصفي:
cloudflared tunnel create my-tunnelتُولّد Cloudflare معرّف UUID وملف اعتماد ~/.cloudflared/<UUID>.json. احتفظ بالـUUID، ستحتاجه في الخطوات التالية.
كتابة ملف الإعداد config.yml
أنشئ /etc/cloudflared/config.yml:
sudo mkdir -p /etc/cloudflaredمحتوى الملف (عدّل <UUID> وyour-domain.com ومنفذ تطبيقك):
tunnel: <UUID>
credentials-file: /home/<user>/.cloudflared/<UUID>.json
ingress:
- hostname: app.your-domain.com
service: http://localhost:3000
- service: http_status:404القاعدة الأخيرة — service: http_status:404 بدون hostname — إلزامية: تعمل كقاعدة احتياطية شاملة. بدونها، يرفض cloudflared الانطلاق ويُعيد الخطأ "You must specify an ingress rule that matches all incoming requests".
إنشاء سجل DNS وتشغيل النفق
سجّل النطاق الفرعي تلقائياً في منطقة Cloudflare:
cloudflared tunnel route dns my-tunnel app.your-domain.comثم اختبر النفق في وضع العمل الأمامي للتحقق من الإعداد:
cloudflared tunnel run my-tunnelافتح https://app.your-domain.com في متصفح. إذا أجاب التطبيق، أوقف العملية (Ctrl+C) وانتقل للخطوة التالية.
تثبيت cloudflared كخدمة systemd
لإعادة تشغيل النفق تلقائياً عند إعادة التشغيل، ثبّته كوكيل نظام:
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflaredملف وحدة systemd الذي يُنشئه Cloudflare موجود في /etc/systemd/system/cloudflared.service. يبدو مشابهاً لـ:
[Unit]
Description=cloudflared
After=network.target
[Service]
TimeoutStartSec=0
Type=notify
ExecStart=/usr/bin/cloudflared --no-autoupdate tunnel run
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.targetمع هذه الخدمة النشطة، يعمل النفق منذ لحظة تشغيل خادم VPS دون تدخل يدوي.
دمج cloudflared في مكدس Docker Compose موجود
إذا كان تطبيقك يعمل بالفعل في مكدس Docker Compose، أضف خدمة cloudflared في الملف نفسه. نهج التوكن (بدون ملف اعتماد) هو الأبسط للحاوية:
services:
app:
image: my-image
networks:
- internal
cloudflared:
image: cloudflare/cloudflared:latest
command: tunnel --no-autoupdate run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
networks:
- internal
restart: unless-stopped
networks:
internal:عرّف TUNNEL_TOKEN في ملف .env على المستوى نفسه. يُسترجع التوكن من لوحة تحكم Cloudflare ← Zero Trust ← Networks ← Tunnels ← النفق الخاص بك ← Configure ← موصّلات Docker. تشارك خدمة cloudflared وتطبيقك شبكة internal؛ أشر إلى التطبيق باسم خدمة Docker (http://app:3000 بدلاً من http://localhost:3000).
الإعداد بعد التثبيت
بمجرد تشغيل النفق، تُحسّن بعض الإعدادات الإضافية متانة التكوين.
استرجاع عنوان IP الحقيقي للعميل. افتراضياً، يستقبل تطبيقك الطلبات من 127.0.0.1 أو من IP الداخلي للنفق. للحصول على IP الزائر الحقيقي، اقرأ ترويسة CF-Connecting-IP التي تضخها Cloudflare تلقائياً. هيّئ تطبيقك أو الوكيل العكسي المحلي للوثوق بهذه الترويسة.
تشفير شامل. يُشفّر النفق الاتصال بين cloudflared وCloudflare. أما الاتصال بين cloudflared وتطبيقك المحلي فهو HTTP بشكل افتراضي (loopback أو شبكة Docker الداخلية). إذا كشف تطبيقك HTTPS محلياً، أضف originServerName: app.your-domain.com في قاعدة الـingress المقابلة لكي يتحقق cloudflared من الشهادة.
عدة خدمات، نفق واحد. يمكن لنفق واحد كشف عدة خدمات على نطاقات فرعية متميزة: ما عليك سوى إضافة مداخل إضافية في كتلة ingress في config.yml، قبل قاعدة الاحتياطي الشاملة.
التصليب: أغلق المنافذ الواردة 80 و443
الميزة الرئيسية لهذه البنية هي القدرة على إغلاق جميع المنافذ الواردة على خادم VPS. بمجرد التحقق من صحة النفق، طبّق قواعد UFW التالية:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw enableيبقى تطبيقك قابلاً للوصول عبر نفق Cloudflare (الذي يعتمد على اتصالات خارجية)، ويبقى منفذ SSH مفتوحاً للإدارة. ولن يصل أي اتصال مباشر على 80 أو 443 إلى الخادم بعد الآن.
Cloudflare Tunnel مقابل Nginx / Traefik: نهجان متكاملان
اعتراض شائع: «لديّ بالفعل Nginx وTraefik تضطلعان بهذا الدور، فلماذا أضيف طبقة Cloudflare؟» الجواب أن النهجين لا يحلّان المشكلة ذاتها.
يدير الوكيل العكسي المحلي (Nginx أو Traefik أو Caddy) التوجيه بين الخدمات على الشبكة ذاتها وتجديد شهادات SSL — لكنه يفترض وصول حركة المرور الواردة إلى الخادم. إذا كان المنفذ 443 محجوباً في الشبكة الأعلى، فالوكيل العكسي لا يجدي.
يحل Cloudflare Tunnel تحديداً ما لا يستطيعه الوكيل العكسي المحلي: تصل حركة المرور إلى Cloudflare بصرف النظر عن اتصال الشبكة للخادم. النهجان متكاملان: يمكنك بسهولة وضع Traefik خلف النفق لإدارة التوجيه الداخلي، بينما تتولى Cloudflare إدارة TLS العام.
Cloudflare Tunnel مقابل الوكيل العكسي المحلي
| المعيار | Cloudflare Tunnel | وكيل عكسي محلي (Nginx/Traefik) |
|---|---|---|
| منفذ وارد مطلوب | لا — اتصال خارجي فقط | نعم — يجب إمكانية الوصول إلى 80/443 |
| TLS العام | تديره Cloudflare، تلقائي | Let's Encrypt عبر ACME (certbot، Traefik…) |
| IP ديناميكي / NAT صارم | شفاف — لا حاجة لتحديث DNS | إشكالية — تتطلب DynDNS أو IP ثابت |
| موازنة الأحمال | خطة مدفوعة (Cloudflare Load Balancing) | متاحة بشكل أصلي (Traefik، Nginx upstream) |
| زمن الاستجابة | أعلى قليلاً (توجيه عبر POP كلاود فلير) | أدنى ما يمكن — مرور مباشر إلى الخادم |
| اعتماد خارجي | نعم — يجب إمكانية الوصول إلى Cloudflare | لا — يعمل بدون طرف ثالث |
استكشاف الأخطاء: رسائل الخطأ الشائعة
You must specify an ingress rule that matches all incoming requests
قاعدة الاحتياطي الشاملة غائبة أو في موضع خاطئ في config.yml. يجب أن تكون آخر مدخل في كتلة ingress، بدون hostname، مع service: http_status:404.
Unable to locate config file in default locations
يبحث cloudflared عن إعداداته في ~/.cloudflared/config.yml أو /etc/cloudflared/config.yml. حدّد المسار صراحةً باستخدام cloudflared tunnel --config /etc/cloudflared/config.yml run my-tunnel.
ERR connection to origin timed out في السجلات
التطبيق المستهدف غير قابل للوصول من cloudflared. تحقق من تشغيل الخدمة المحلية (curl http://localhost:3000) وتطابق المنفذ في config.yml. في سياق Docker Compose، استخدم اسم الخدمة (http://app:3000) بدلاً من localhost.
توكن منتهي الصلاحية: tunnel credentials file not found أو token is expired
للتوكنات المُولَّدة عبر واجهة Cloudflare مدة صلاحية محدودة إذا لم يُسجَّل الموصّل قط. أعد إنشاء التوكن من Zero Trust ← Networks ← Tunnels ← Configure ← Connectors، ثم حدّث المتغير TUNNEL_TOKEN في ملف .env.
قيود الخطة المجانية: موازنة الأحمال والـSSH عبر النفق
لا تدعم الخطة المجانية موازنة الأحمال بين أصول متعددة. يستلزم الوصول إلى SSH عبر النفق (cloudflared access ssh) في الخطة المجانية إعداداً محدداً لـCloudflare Access وليس مفعّلاً بشكل افتراضي. يقتصر عدد الموصّلات لكل نفق على بضع نسخ في الخطة المجانية.
Cloudflare Tunnel كبنية مرجعية على VPS
يوضح Cloudflare Tunnel ما يتيحه الوصول بصلاحيات root على VPS: تثبيت cloudflared كوكيل نظام، وتعديل قواعد جدار الحماية، وإدارة خدمات systemd. على الاستضافة المشتركة بدون وصول root، لا تُنجَز أيٌّ من هذه الخطوات — لا يمكن تثبيت الوكيل، وجدار الحماية خارج سيطرتك، ولا يمكن إعداد الخدمة للانطلاق عند بدء التشغيل.
تناسب هذه البنية بصفة خاصة الحالات التي تكون فيها اتصالية الشبكة مقيّدة أو غير مضمونة: بيئات التطوير، والمكاتب ذات جدران الحماية المؤسسية الصارمة، وخوادم الحافة، أو مجرد رفض كشف IP عام. وتتكامل بشكل طبيعي مع الوكلاء العكسيين المحليين كـTraefik أوNginx Proxy Manager للتوجيه الداخلي، ومع تصليب النظام لإغلاق أسطح الهجوم المباشرة.