Tailscale Serve أم Funnel: أيهما تختار؟
تعرّف إلى الفرق العملي: Serve يتيح HTTPS داخل tailnet، بينما Funnel يفتح المنفذ للعامة. اكتشف رسالة الخطأ وسياسة الوصول التي تمنع Funnel.
tailscale serve مقابل funnel: من يمكنه الوصول إلى عنوان URL
الفرق بين tailscale serve وtailscale funnel هو الجمهور المستهدف، ولا شيء آخر. يضع serve واجهة HTTPS (بروتوكول نقل النص التشعبي الآمن) أمام منفذ محلي، وينشره داخل tailnet لديك فقط. أما funnel فينشر المنفذ المحلي نفسه على الإنترنت العام بالكامل، عبر خوادم الترحيل التي تديرها Tailscale. يستخدم الأمران العلامات والأهداف نفسها. تفصل كلمة واحدة بين لوحة تحكم خاصة وأخرى يمكن للعالم الوصول إليها.
يمنحك كلاهما شهادة تثق بها المتصفحات مسبقاً، على اسم ينتهي بـ ts.net، ولا يحتاج أي منهما إلى فتح منفذ وارد في جدار VPS الناري. يحتفظ daemon الخاص بـ tailscaled باتصال صادر إلى tailnet، لذلك تصل حركة الشبكة عبر هذا الاتصال بدلاً من ذلك. إضافة خادم إلى tailnet مهمة مستقلة، ويغطي ذلك تشغيل VPS كعقدة خروج لـTailscale أو الإعلان عن موجّه شبكة فرعية لشبكة خاصة. أما نشر خدمة موجودة أصلاً داخل tailnet، فهو موضوع هذا القسم.
ما تحتاج إليه قبل أن يعمل أي من الأمرين
- الإصدار 1.38.3 أو أحدث من Tailscale على VPS، مع تسجيل الدخول إلى tailnet. تحقّق من ذلك باستخدام
tailscale versionوtailscale status. - تفعيل MagicDNS. MagicDNS هو نظام DNS المضمّن في Tailscale، وهو الذي يمنح الجهاز اسماً مثل
blog-vps.your-tailnet.ts.netبدلاً من استخدام عنوان100.xفقط. - تفعيل شهادات HTTPS لـtailnet من صفحة DNS في وحدة تحكم الإدارة. من دون ذلك، لا توجد شهادة تضعها أمام المنفذ.
- بالنسبة إلى
funnelفقط، يجب وجود سمة العقدةfunnelفي ملف سياسة tailnet. تتوقف معظم المحاولات الأولى عند هذه النقطة، ويجري شرحها أدناه.
تبدأ كل الأوامر هنا بـ sudo، لأن CLI يتصل بـtailscaled عبر socket لا يستطيع الكتابة إليه إلا root. امنح مستخدماً واحداً صلاحية تجاوز ذلك:
sudo tailscale set --operator=$USERالنشر على tailnet باستخدام tailscale serve
وجّه serve إلى منفذ محلي، وسيتولى بقية العمل.
sudo tailscale serve 3000Available within your tailnet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.يُعدّ 3000 المختصر صيغةً لـhttp://127.0.0.1:3000. يستمع Tailscale على المنفذ 443 لعنوان tailnet الخاص بالجهاز، وينهي TLS (أمان طبقة النقل) باستخدام الشهادة ts.net، ثم يمرّر HTTP عاديًا إلى منفذك المحلي. لا يحتاج تطبيقك إلى معرفة وجود شهادة، وهذا هو السبب الرئيسي لاستخدام هذه الطريقة أمام لوحة إدارة كنت ستتركها بخلاف ذلك تعمل عبر HTTP عادي.
اقرأ الآن السطر الأخير: Press Ctrl+C to exit. يعمل الأمر في الواجهة الأمامية، ويظل الربط داخل هذه العملية. إذا أغلقت الطرفية، يتوقف عنوان URL عن العمل، لأن شيئًا لم يُكتب على القرص. أضف --bg، وسيُحفظ الربط في إعدادات serve الخاصة بالعقدة، ويبقى بعد إغلاق الطرفية وإعادة التشغيل.
sudo tailscale serve --bg 3000يقبل Serve أكثر من رقم منفذ. يربط --set-path خدمةً بمسار فرعي، بحيث يمكن لعدة تطبيقات مشاركة اسم مضيف واحد:
sudo tailscale serve --bg --set-path=/grafana 3000
sudo tailscale serve --bg --set-path=/metrics 9090يمكن أن يكون الهدف أيضًا مجلدًا يحتوي على ملفات ثابتة، أو خدمة خلفية تستخدم TLS أصلًا مع شهادة لا تريد التحقق منها:
sudo tailscale serve --bg /srv/reports
sudo tailscale serve --bg https+insecure://localhost:8443ولا يقتصر الأمر على HTTP. يمرّر --tcp=<port> تدفق TCP خامًا (بروتوكول التحكم في الإرسال)، بينما ينهي --tls-terminated-tcp=<port> TLS على عقدتك ويمرّر النص الواضح، ما يضع شهادة موثوقة أمام خدمة لا تستخدم HTTP على الإطلاق:
sudo tailscale serve --bg --tls-terminated-tcp=443 tcp://127.0.0.1:9899لماذا يقول Funnel إن سمة العقدة غير مضبوطة؟
يكون Funnel معطّلاً افتراضياً على مستوى tailnet بالكامل. يعرض التشغيل الأول الرسالة التالية ثم يتوقف:
Funnel not available; "funnel" node attribute not set. See https://tailscale.com/kb/1223/tailscale-funnel/.كان الأمر صحيحاً. لم تمنح سياسة tailnet هذه العقدة الإذن بالنشر، لذلك يرفض العميل الطلب قبل أن يتصل بأي relay. حرّر ملف سياسة tailnet في وحدة تحكم الإدارة، ضمن Access Controls، وأضف السمة التالية:
"nodeAttrs": [
{
"target": ["autogroup:member"],
"attr": ["funnel"],
},
],تمنح autogroup:member هذه الصلاحية لكل عضو في tailnet. إذا كان يجب السماح لجهاز واحد فقط بالنشر، فأضف tag إلى ذلك الجهاز واستهدف الـtag بدلاً من ذلك، على سبيل المثال tag:public. احفظ السياسة، ثم شغّل أمر Funnel مرة أخرى.
إذا كان حسابك مسؤول tailnet، توفّر الإصدارات الحديثة من العملاء اختصاراً لذلك: يطبع CLI عنوان URL للموافقة ضمن login.tailscale.com، ويؤدي فتحه إلى تفعيل شهادات HTTPS وإضافة السمة نيابةً عنك. إذا لم تكن مسؤولاً، فلن يفيدك عنوان URL هذا. يجب أن يجري التعديل شخص لديه صلاحية الوصول إلى السياسة.
النشر على الإنترنت باستخدام tailscale funnel
بعد ضبط السمة، يصبح الأمر هو نفسه الذي تعرفه، مع فعل مختلف.
sudo tailscale funnel --bg 3000Available on the internet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.اقرأ السطر الأول في كل مرة. Available within your tailnet وAvailable on the internet هما الفرق المرئي الوحيد بين الخدمة الخاصة والعامة، وتختلف الأوامر التي تنشئهما بكلمة واحدة.
اعتباراً من August 2026، يستمع funnel على المنفذ 443 أو 8443 أو 10000، ولا يستمع على أي منفذ آخر. الإعداد الافتراضي هو 443، أما --https=8443 أو --https=10000 فهما البديلان. يُرفض أي منفذ آخر، لأن مرحلات funnel تقبل الاتصالات على هذه المنافذ فقط. لذلك يكون عنوان funnel دائماً اسم المضيف وحده، أو اسم المضيف متبوعاً بـ:8443.
كيف أرى ما هو منشور حالياً؟
التخمين هو ما يجعل لوحة المعلومات متاحة للعامة شهراً كاملاً. اسأل العقدة مباشرة.
tailscale serve status
tailscale funnel status
tailscale serve status --jsonيقرأ أمرا الحالة كلاهما الإعداد نفسه، لذلك يعرض أيٌّ منهما الصورة كاملة. استخدم صيغة --json داخل script أو في فحص مجدول، لأن المخرجات العادية مهيأة للقراءة البشرية. عندما لا يكون هناك أي إعداد، يظهر سطر واحد:
No serve configإذا رأيت ذلك بعد إعداد تعرف أنه نجح، فهذا يعني أن الربط أُنشئ في الواجهة الأمامية ثم انتهت العملية. أعد إنشاءه باستخدام --bg.
لإزالة ربط واحد، كرر الأمر الذي أنشأه وأضف off في نهايته. لمسح جميع عمليات serve وfunnel على العقدة، استخدم reset.
sudo tailscale funnel --https=443 3000 off
sudo tailscale serve resetشغّل tailscale serve status مرة أخرى بعد أي من العمليتين، واقرأ ما تبقى بدلاً من افتراض أن الأمر نفّذ ما قصدته.
ما الذي تحصل عليه، وما الذي تتنازل عنه
الفوائد حقيقية، وهي سبب اختيار بعض المستخدمين لهذا الحل بدلاً من Reverse Proxy.
- شهادة تثق بها المتصفحات، مع تجديدها تلقائياً. لا تحتاج إلى تثبيت عميل ACME (بيئة إدارة الشهادات تلقائياً)، ولا إلى تذكّر مهمة التجديد.
- لا يوجد منفذ وارد في جدار VPS الناري. يتصل
tailscaledإلى الخارج، لذلك يمكن أن يبقى جدار ufw افتراضي يرفض كل الاتصالات على VPS بالصرامة نفسها. - لا تحتاج إلى شراء سجل DNS أو توجيهه أو انتظار تحديثه.
- لا تحتاج إلى إعادة توجيه المنافذ، وهذا هو الحل الكامل لجهاز يقع خلف NAT (ترجمة عناوين الشبكة) بدلاً من VPS يملك عنوان IP عاماً.
التكاليف حقيقية بالقدر نفسه، ويتحمل Funnel جميعها.
- الاسم ليس ملكك. يرى الزوار العموميون
host.your-tailnet.ts.net. لا يدعم Funnel النطاقات المخصصة، لذلك لا يمكنك وضعapp.example.comأمامه. - المسار ليس ملكك. تصل حركة الشبكة أولاً إلى مرحّل Tailscale، ثم يمرر المرحّل التدفق إلى عقدتك عبر tailnet. توضح Tailscale أن حركة Funnel تخضع لحدود نطاق ترددي غير منشورة ولا يمكن ضبطها، لذلك قِس معدل النقل لديك قبل الاعتماد على قيمة معينة.
- عناصر التحكم غير متاحة. يمنحك Reverse Proxy الذي تديره بنفسك سجلات الوصول، وحدود معدل الطلبات، وحدود حجم الطلبات، ومكاناً لإضافة المصادقة. أما Funnel فيمنحك عنوان URL. يجب أن تكون جميع الوظائف الأخرى داخل تطبيقك.
- قائمة المنافذ ثابتة، كما سبق.
تعتمد الميزتان أيضاً على بنية تحتية تديرها Tailscale، وهي إصدار الشهادة لاسم ts.net ومرحلات Funnel نفسها. إذا كنت تقيّم خادم تحكم Headscale مستضافاً ذاتياً، فلا تفترض أن أياً منهما ينتقل معك. راجع ملاحظات الإصدار لإصدار Headscale الذي تخطط لتشغيله.
ما الخيار الذي ينبغي أن أستخدمه؟
القاعدة قصيرة.
استخدم serve لأي شيء داخلي: واجهات الإدارة، ولوحات المعلومات، وواجهة مقاييس لا تريد فهرستها، ونسخة تجريبية من موقع. عضوية tailnet هي آلية التحكم في الوصول، وهي آلية جيدة. لا يستطيع الجهاز غير الموجود في tailnet حتى تحليل الاسم.
استخدم funnel لرابط تجريبي، أو مستقبِل webhook يجب أن يرسل إليه طرف ثالث طلبات POST، أو عنوان OAuth callback أثناء التطوير. إنه أسرع طريق إلى عنوان HTTPS عام، وينهيه أمر off واحد. لكن العام يعني العام: اسم المضيف ليس سراً، ووجود funnel أمام تطبيق بلا تسجيل دخول يعني أن الخدمة مفتوحة. يجب أن يصادق كل ما يوجد خلفه على طلباته بنفسه، وبالعناية نفسها التي يحتاج إليها نقطة نهاية Ollama المكشوفة.
استخدم reverse proxy حقيقياً لأي شيء ستصفه بأنه production. نطاقك، وشهادتك، وسجلاتك، وحدود معدل الطلبات الخاصة بك، ولا أحد غيرك في مسار الطلب. يوضّح مقارنة nginx وCaddy وTraefik بوصفها reverse proxy كيفية اختيار أحدها.
أوضاع الفشل، مع النصوص التي ستظهر لك
يرفض Funnel البدء. Funnel not available; "funnel" node attribute not set. مشكلة في السياسة، وليست مشكلة في الأمر. أضف السمة funnel إلى ملف سياسة tailnet، واحفظه، ثم أعد المحاولة.
كان يعمل، والآن يعرض tailscale serve status الرسالة No serve config. أُنشئ الربط في المقدمة، ثم انتهت تلك العملية. أعد تشغيل الأمر نفسه مع --bg.
يُحلّ الاسم، لكن لا يستجيب شيء. يمرر Serve الطلبات إلى الهدف الذي حددته. لذلك، إذا لم يكن هناك شيء يستمع على ذلك الهدف، فلن يجد Serve ما يمرر الطلبات إليه. تحقّق باستخدام ss -ltnp | grep 3000 على الجهاز نفسه الذي يشغّل tailscaled. السبب الشائع هو أن حاوية تنشر منفذها على عنوان جسر Docker بدلاً من 127.0.0.1، ما يعني أن المضيف لا يرى أي مستمع في المكان المتوقع. يوضح كيفية عمل شبكات Docker Compose المكان الذي يصل إليه المنفذ المنشور فعلياً.
أخطاء الشهادة عند استخدام اسم ts.net. من المرجح أن شهادات HTTPS غير مفعّلة لـtailnet. فعّلها في وحدة تحكم الإدارة، ثم شغّل خطوة الشهادة وحدها حتى لا تختلط أخطاؤها بمخرجات Serve:
sudo tailscale cert your-host.your-tailnet.ts.netيُحمّل Funnel عبر بيانات الهاتف المحمول، لكنه يتصرف بشكل مختلف عن حاسوبك المحمول. حاسوبك المحمول متصل بـtailnet، لذلك يحل MagicDNS الاسم إلى العنوان 100.x، وتصل إلى الخدمة مباشرةً من دون المرور بمرحل. هذا سلوك صحيح، ويعني أن حاسوبك المحمول لا يستطيع اختبار إمكانية الوصول العامة إطلاقاً. استخدم curl من جهاز غير متصل بـtailnet.
FAQ
ما الفرق بين tailscale serve وtailscale funnel؟
من يستطيع الوصول إلى النتيجة. ينشر tailscale serve منفذاً محلياً على عنوان URL باستخدام HTTPS، ولا يمكن الوصول إليه إلا من الأجهزة الموجودة في tailnet الخاص بك. ينشر tailscale funnel المنفذ نفسه على عنوان URL يمكن لأي شخص على الإنترنت الوصول إليه، وتُوجَّه الاتصالات عبر خوادم relay التي تديرها Tailscale. تكون العلامات والأهداف مشتركة بينهما. يخبرك السطر الأول من الناتج بأي منهما حصلت عليه: Available within your tailnet أو Available on the internet.
لماذا يقول tailscale funnel إن سمة العقدة غير مضبوطة؟
لأن funnel يكون معطلاً لـtailnet حتى يفعّله أحد. الرسالة هي Funnel not available; "funnel" node attribute not set.، وتصدر من عميلك نفسه قبل الاتصال بأي relay. أضف إدخال nodeAttrs يمنح السمة funnel إلى autogroup:member، أو إلى tag إذا كان يجب أن تنشر آلة واحدة فقط، وذلك في ملف سياسة tailnet ضمن Access Controls. ويمكن لمسؤول tailnet بدلاً من ذلك اتباع عنوان الموافقة الذي تطبعه واجهة CLI.
ما المنافذ التي يمكن أن يستخدمها Tailscale Funnel؟
المنافذ المسموح بها هي 443 و8443 و10000 فقط. المنفذ الافتراضي هو 443، ويمكنك اختيار منفذ آخر باستخدام --https=8443 أو --https=10000. هذا قيد تفرضه relay الخاصة بـfunnel، وليس خادمك، لذلك لا يزيله أي تغيير في الجدار الناري أو في إعدادات VPS. لا يخضع tailscale serve لهذا القيد، لأنه لا يغادر tailnet الخاص بك مطلقاً.
هل يبقى عنوان URL الخاص بـserve أو funnel بعد إعادة التشغيل؟
يبقى فقط إذا استخدمت --bg. من دونه يعمل الأمر في الواجهة الأمامية، ويطبع Press Ctrl+C to exit.، ويختفي الربط مع انتهاء العملية. باستخدام --bg، يُكتب الربط في إعدادات serve الخاصة بالعقدة، ويعود مع tailscaled بعد إعادة التشغيل. تحقّق باستخدام tailscale serve status، الذي يطبع No serve config عندما لا يكون أي إعداد مضبوطاً.
هل من الآمن ترك funnel قيد التشغيل؟
هو آمن من ناحية النقل: الاتصال يستخدم HTTPS، ولا يكون أي منفذ مفتوحاً في الجدار الناري لديك. لكنه ليس آمناً بالمعنى المعتاد، لأن عنوان URL عام، ولذلك يصبح التطبيق الموجود خلفه عاماً أيضاً. لا تترك funnel قيد التشغيل إلا أمام تطبيق يصادق على طلباته بنفسه، وأوقفه عند انتهاء العرض التجريبي أو اختبار webhook، باستخدام الأمر الذي أنشأه مع إضافة off في نهايته.
مصادر سلوك الأوامر أعلاه هي وثائق Tailscale Serve وFunnel ومرجع CLI على tailscale.com/docs.