SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-11-01

Tailscale چیست و چگونه کار می‌کند؟

در این مقاله بررسی می‌کنیم که Tailscale چگونه با استفاده از پروتکل WireGuard و معماری Mesh VPN، ارتباط مستقیم بین دستگاه‌ها را بدون نیاز به تنظیمات پیچیده فایروال برقرار می‌کند.

Tailscale چیست؟

Tailscale یک VPN است که ماشین‌های شما را مستقیماً به یکدیگر متصل می‌کند، به‌جای اینکه تمام ترافیک را از طریق یک gateway که شما مدیریت می‌کنید، عبور دهد. هر گره (node) از WireGuard استفاده می‌کند، بنابراین بسته‌ها به‌صورت رمزنگاری‌شده از یک سرور به سرور دیگر منتقل می‌شوند و هیچ‌چیز در مسیر نمی‌تواند آن‌ها را بخواند. یک سرور هماهنگ‌کننده (coordination server) میزبانی‌شده، وظیفه معرفی گره‌ها به یکدیگر را بر عهده دارد. این سرور کلیدهای عمومی را ذخیره و توزیع می‌کند و به هر گره می‌گوید که سایر گره‌ها کجا هستند. همچنین قوانین دسترسی که شما نوشته‌اید را به گره‌ها ابلاغ می‌کند.

این تفکیک، کل طراحی سیستم است. صفحه داده (data plane) به‌صورت همتا‌به‌همتا (peer to peer) و رمزنگاری‌شده بین گره‌ها عمل می‌کند. صفحه کنترل (control plane) سرویسی است که Tailscale برای شما اجرا می‌کند. هر پرسش مهمی درباره Tailscale، از جمله موارد حساس مربوط به اعتماد، از همین دو واقعیت ناشی می‌شود. اگر قبلاً یک VPN مبتنی بر WireGuard به‌صورت دستی روی یک VPS راه‌اندازی کرده‌اید، Tailscale همان تونل است با این تفاوت که توزیع کلیدها و عبور از فایروال به‌صورت خودکار برای شما انجام می‌شود.

Tailscale چگونه کار می‌کند؟

شبکه خصوصی گره‌های شما tailnet نامیده می‌شود. هنگامی که یک ماشین به این شبکه می‌پیوندد، چهار اتفاق رخ می‌دهد:

  1. دیمون tailscaled اجرا می‌شود، یک جفت کلید WireGuard تولید می‌کند و وضعیت خود را در /var/lib/tailscale/tailscaled.state نگه می‌دارد. کلید خصوصی هرگز از آن ماشین خارج نمی‌شود. عبارت‌پردازی خود Tailscale صریح است: «کلید خصوصی هرگز و تحت هیچ شرایطی گره خود را ترک نمی‌کند.»
  2. گره به سرور هماهنگ‌کننده (coordination server) وارد می‌شود و کلید عمومی خود را به همراه آدرس‌هایی که تصور می‌کند از طریق آن‌ها در دسترس است، آپلود می‌کند. Tailscale این سرور را «یک صندوق اشتراکی برای کلیدهای عمومی» توصیف می‌کند.
  3. سرور هماهنگ‌کننده یک نقشه شبکه را بازمی‌گرداند: کلید عمومی، آدرس tailnet، نام ماشین و نقاط پایانی (endpoints) کاندید برای هر گره‌ای که این گره اجازه دسترسی به آن را دارد.
  4. سپس هر جفت از گره‌ها تلاش می‌کنند یک تونل مستقیم WireGuard بین خود ایجاد کنند. هنگامی که این کار با شکست مواجه شود، بسته‌ها را از طریق یک رله (relay) ارسال می‌کنند.

هر گره یک آدرس پایدار از محدوده 100.64.0.0/10 دریافت می‌کند؛ این محدوده NAT در سطح اپراتور است که از 100.64.0.0 تا 100.127.255.255 ادامه دارد. Tailscale از این محدوده استفاده می‌کند زیرا برای زیرساخت‌های ارائه‌دهندگان رزرو شده است و به همین دلیل به‌ندرت با آدرس‌های خصوصی که سرورهای شما در حال حاضر استفاده می‌کنند، تداخل پیدا می‌کند. در لینوکس، این تونل به عنوان یک اینترفیس با نام tailscale0 ظاهر می‌شود.

پیاده‌سازی WireGuard در داخل tailscaled و در فضای کاربری (userspace) قرار دارد، نه در ماژول هسته (kernel module). به همین دلیل است که Tailscale روی مجازی‌سازی کانتینری که در آن sudo modprobe wireguard با خطای Operation not supported مواجه می‌شود، اجرا می‌گردد. این همچنین بدان معناست که سقف پهنای باند در یک ماشین مشخص، پایین‌تر از WireGuard در سطح هسته است؛ این یکی از مواردی است که در مقایسه Tailscale با WireGuard ساده به آن پرداخته شده است.

دو دستور وضعیت فعلی شما را مشخص می‌کنند.

tailscale ip -4
tailscale status

دستور tailscale status برای هر گره یک خط چاپ می‌کند و ستون آخر همان چیزی است که اهمیت دارد.

100.101.102.103  web-1      you@  linux  -
100.101.102.104  db-1       you@  linux  active; direct 198.51.100.24:41641
100.101.102.105  ci-runner  you@  linux  active; relay "fra"

خروجی direct به همراه یک آدرس و پورت به این معنی است که دو ماشین مسیری به یکدیگر پیدا کرده‌اند و ترافیک به صورت peer-to-peer است. relay "fra" به این معنی است که ترافیک از طریق یک رله Tailscale در فرانکفورت عبور می‌کند. عبارت - به این معنی است که در حال حاضر هیچ نشست فعالی با آن گره وجود ندارد که امری عادی است.

آنچه سرور هماهنگ‌کننده می‌تواند و نمی‌تواند ببیند

سرور هماهنگ‌کننده (coordination server) کلیدهای عمومی و متادیتا را نگهداری می‌کند. این سرور نام ماشین‌های شما، اینکه کدام کاربر یا تگ مالک هر گره (node) است، آدرس tailnet هر گره، آدرس‌های عمومی که گره‌های شما از طریق آن‌ها در دسترس هستند، زمان آخرین آنلاین بودن هر گره و فایل سیاستی (policy file) که نوشته‌اید را می‌داند. این اطلاعات، نقشه‌ای کامل از کل ناوگان شماست.

این سرور هیچ کلید خصوصی‌ای در اختیار ندارد، بنابراین نمی‌تواند ترافیک بین دو گره را رمزگشایی کند. رمزنگاری به‌صورت سرتاسری (end-to-end) بین همتایان WireGuard انجام می‌شود و سرور هماهنگ‌کننده یک همتا (peer) محسوب نمی‌شود.

آنچه این سرور می‌تواند انجام دهد، توزیع کلیدهاست. هر سرور هماهنگ‌کننده‌ای، چه میزبانی‌شده و چه خود-میزبان (self-run)، مورد اعتماد است تا به گره‌های شما بگوید کدام کلیدهای عمومی متعلق به tailnet هستند. این نقطه، محور اصلی مدل تهدید در ادامه است و دلیلی است که Headscale، یک سرور هماهنگ‌کننده متن‌باز که خودتان میزبانی می‌کنید وجود دارد.

نحوه برقراری ارتباط مستقیم بین دو سرور پشت فایروال‌های مختلف

NAT (ترجمه آدرس شبکه) قابلیتی است که به چندین دستگاه اجازه می‌دهد از یک آدرس عمومی مشترک استفاده کنند. سرور مجازی (VPS) شما معمولاً آدرس عمومی اختصاصی خود را دارد، اما سایر دستگاه‌هایی که می‌خواهید در tailnet قرار دهید اغلب فاقد آن هستند: مانند یک سرور خانگی، یک build runner در شبکه اداری، یا سیستمی که پشت فایروال یک سرویس‌دهنده قرار دارد و امکان تغییر تنظیمات آن را ندارید.

Tailscale با استفاده از تکنیک‌های مبتنی بر استانداردهای STUN (ابزارهای پیمایش نشست برای NAT) و ICE، مسیری را برای برقراری ارتباط پیدا می‌کند. هر گره یک بسته UDP کوچک به یک سرور STUN ارسال می‌کند و آدرس عمومی و پورتی را که روتر به آن سوکت اختصاص داده است، شناسایی می‌کند. هر دو گره این کاندیداها را به سرور هماهنگ‌کننده گزارش می‌دهند و سرور آن‌ها را به طرف مقابل منتقل می‌کند. سپس هر دو گره شروع به ارسال هم‌زمان بسته به یکدیگر می‌کنند. هر روتر ابتدا یک بسته خروجی را مشاهده می‌کند، بنابراین یک نگاشت (mapping) ایجاد کرده و پاسخ دریافتی از همان آدرس را می‌پذیرد. در این حالت، هیچ‌کدام از طرفین نیازی به تعریف قانون فایروال ورودی ندارند. به همین دلیل است که یک NAS یا یک Raspberry Pi در خانه می‌تواند بدون نیاز به port forwarding روی روتر، در دسترس باقی بماند. مطلب استفاده از Tailscale به‌جای port forwarding این تنظیمات و محدودیت‌های آن را به‌طور کامل توضیح می‌دهد.

پورت‌ها مشخص هستند. تونل‌های مستقیم WireGuard از پروتکل UDP با پورت مبدأ پیش‌فرض 41641 استفاده می‌کنند. STUN روی پورت UDP 3478 با سرورهای رله Tailscale ارتباط برقرار می‌کند. اتصال کنترلی، پروتکل HTTP ساده روی TCP 80 را ترجیح می‌دهد که در لایه انتقال رمزنگاری‌شده خودِ Tailscale بسته‌بندی شده است؛ در صورتی که پورت 80 پاسخ ندهد، اتصال به HTTPS روی TCP 443 تغییر وضعیت می‌دهد. داده‌هایی که از طریق سرورهای DERP در Tailscale رله می‌شوند از HTTPS روی TCP 443 استفاده می‌کنند، در حالی که رله‌های همتا (peer relay) که درون tailnet خود اجرا می‌کنید، داده‌ها را از طریق UDP منتقل می‌کنند. در بیشتر مواقع نیازی به باز کردن هیچ پورت ورودی ندارید، اگرچه در شبکه‌هایی با NAT پیچیده، باز کردن پورت UDP 41641 برای ترافیک ورودی، احتمال برقراری اتصال مستقیم را افزایش می‌دهد.

tailscale netcheck

دو خط از آن گزارش را بخوانید. UDP: true به این معنی است که این دستگاه می‌تواند بسته‌های UDP را به اینترنت ارسال کند و UDP: false یعنی این امکان وجود ندارد، بنابراین تمام اتصالات این گره رله (relayed) خواهند شد. MappingVariesByDestIP: true به این معنی است که روتر برای هر مقصد یک پورت عمومی متفاوت اختصاص می‌دهد؛ در نتیجه پیش‌بینی آدرس که در بالا ذکر شد کار نمی‌کند و این گره‌ها معمولاً در حالت رله باقی می‌مانند.

زمانی که Tailscale از یک DERP relay استفاده می‌کند

DERP (مخفف designated encrypted relay for packets) راهکار جایگزین (fallback) است. Tailscale رله‌هایی را در مناطق مختلف اجرا می‌کند که از طریق پورت TCP 443 در دسترس هستند؛ گره‌ای که نتواند مسیر مستقیمی پیدا کند، بسته‌های WireGuard خود را از طریق یکی از این رله‌ها ارسال می‌کند. استثنا در tailnetهایی است که شما رله‌های همتای اختصاصی (peer relays) تعیین کرده‌اید؛ این‌ها دستگاه‌های خود شما هستند که ترافیک را از طریق UDP فوروارد می‌کنند. Tailscale ابتدا آن‌ها را امتحان می‌کند و تنها زمانی که هیچ‌کدام در دسترس نباشند به سراغ DERP می‌رود، و tailscale status در آن زمان اتصال را به صورت peer-relay نمایش می‌دهد.

بسته‌ها رمزنگاری‌شده باقی می‌مانند. Tailscale این موضوع را به صراحت بیان می‌کند: «هیچ راهی برای سرور DERP جهت رمزگشایی ترافیک شما وجود ندارد. این سرور صرفاً ترافیکِ از پیش رمزنگاری‌شده را به صورت کورکورانه از یک گره به گره دیگر منتقل می‌کند.» رله فقط متن رمزنگاری‌شده (ciphertext) و اینکه کدام گره با کدام گره در حال ارتباط است را می‌بیند.

رله‌ها همچنین اولین بسته‌های اکثر اتصالات را حمل می‌کنند. یافتن مسیر مستقیم کمی زمان می‌برد، بنابراین یک نشست اغلب به صورت رله‌شده آغاز می‌شود و پس از اینکه دو گره یکدیگر را پیدا کردند، در همان لحظه به مسیر مستقیم ارتقا می‌یابد. شما می‌توانید این اتفاق را مشاهده کنید.

tailscale ping db-1

اولین پاسخ‌ها به صورت via DERP(fra) برمی‌گردند، سپس خط بعدی چیزی شبیه به via 198.51.100.24:41641 را گزارش می‌دهد. این تغییر، همان ارتقا به تونل مستقیم است. اگر این وضعیت هرگز تغییر نکرد، دستور tailscale netcheck را در هر دو سمت اجرا کنید. مسیر رله‌شده همچنان کار می‌کند. این کار باعث افزایش تأخیر (latency) می‌شود، زیرا هر بسته یک مسیر انحرافی را از طریق ماشین سوم طی می‌کند. اگر آنچه متوجه شده‌اید انتقال کند به جای قطع بودن اتصال است، چرا اتصال رله‌شده Tailscale بسیار کندتر از اتصال مستقیم است شکاف موجود را اندازه‌گیری کرده و نشان می‌دهد چگونه یک VPS را در مسیر مستقیم قرار دهید.

افزودن یک VPS به tailnet

اسکریپت نصب، توزیع‌های Ubuntu و Debian را پوشش می‌دهد.

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

sudo tailscale up یک URL چاپ می‌کند. آن را باز کنید، احراز هویت انجام دهید تا گره (node) در کنسول مدیریتی شما ظاهر شود. سپس اطمینان حاصل کنید که daemon پس از reboot دوباره بالا می‌آید، زیرا این مرحله‌ای است که کاربران اغلب فراموش می‌کنند.

sudo systemctl is-enabled tailscaled
tailscale status

is-enabled باید enabled را چاپ کند و tailscale status باید گره جدید را با آدرس 100.x آن فهرست کند. برای سروری که توسط اسکریپت ساخته شده است، URL تعاملی کاربردی ندارد. یک auth key در کنسول مدیریتی ایجاد کنید و آن را به همراه یک tag که نوع ماشین را مشخص می‌کند، ارسال کنید.

sudo tailscale up --auth-key=tskey-auth-REPLACE-ME --advertise-tags=tag:server

یک گره برچسب‌دار (tagged node) به جای شخصی که دستور را اجرا کرده، متعلق به آن tag است؛ بنابراین پس از حذف حساب کاربری آن شخص، همچنان به کار خود ادامه می‌دهد. این tag باید ابتدا در فایل سیاست (policy file) شما تحت tagOwners تعریف شده باشد، در غیر این صورت دستور رد می‌شود. برچسب‌گذاری همچنین نحوه محاسبه ماشین در طرح اشتراک شما را تغییر می‌دهد، زیرا منابع برچسب‌دار جدا از دستگاه‌های شخصی محاسبه می‌شوند و محدودیت‌های طرح رایگان مشخص می‌کند که این محدودیت‌ها کجا اعمال می‌شوند.

دو تنظیم برای مدیریت ناوگان سرورها اهمیت دارد. کلیدهای گره (node keys) به‌صورت پیش‌فرض پس از 180 روز منقضی می‌شوند (از اکتبر 2026)، و هنگامی که کلیدی منقضی شود، «اتصالات به/از آن endpoint متوقف می‌شود» تا زمانی که دستگاه دوباره احراز هویت کند. یک مدیر سیستم می‌تواند در کنسول مدیریتی گزینه Temporarily extend key را برای یک ماشین منقضی‌شده انتخاب کند که 30 دقیقه فرصت برای ورود مجدد یا غیرفعال‌سازی انقضا فراهم می‌کند. گره‌ای که با یک tag احراز هویت شده باشد، مانند نمونه بالا، به‌طور پیش‌فرض انقضای کلید غیرفعال دارد. برای هر سرور بدون مراقب (unattended) دیگر، ردیف مربوط به ماشین را در کنسول مدیریتی باز کرده و گزینه Disable Key Expiry را انتخاب کنید. قابلیت MagicDNS که برای tailnetهای ایجاد شده در تاریخ 20 اکتبر 2022 یا پس از آن به‌صورت پیش‌فرض فعال است، به هر گره نامی مانند db-1.yak-bebop.ts.net می‌دهد که توسط یک stub resolver در 100.100.100.100 ترجمه می‌شود. به‌جای آدرس‌ها از نام‌ها استفاده کنید، زیرا گره‌ای که دوباره ساخته شود آدرس جدیدی می‌گیرد اما نام خود را حفظ می‌کند.

اگر خودِ عملیات نصب در apt یا مخزن (repository) با شکست مواجه شد، خطاهای رایج نصب Tailscale در Ubuntu راه‌حل‌های آن را پوشش می‌دهد.

دسترسی به سرویسی که روی localhost محدود شده است

اینجاست که tailnet مفید واقع می‌شود و جایی است که کاربران معمولاً با مشکل مواجه می‌شوند. پیوستن به tailnet باعث نمی‌شود سرویسی که روی loopback قرار دارد، قابل دسترس شود.

ss -tlnp | grep 3000

اگر این دستور 127.0.0.1:3000 را چاپ کند، یعنی سوکت فقط بسته‌هایی را می‌پذیرد که مقصد آن‌ها 127.0.0.1 باشد. درخواستی که از یک گره (node) دیگر می‌رسد، با آدرس 100.x این گره خطاب شده است؛ بنابراین هسته سیستم‌عامل هیچ گوش‌دهنده‌ای برای آن ندارد و با یک TCP reset پاسخ می‌دهد. کلاینت پیام Connection refused را گزارش می‌کند. تونل سالم است، اما listener مشکل دارد.

دو راه حل اصولی وجود دارد. سرویس را روی آدرس tailnet گره bind کنید؛ این کار باعث می‌شود سرویس بدون نیاز به پروکسی، از رابط عمومی (public interface) دور بماند: مقدار --bind 100.101.102.104 یا گزینه معادل آن را در پیکربندی خود وارد کنید و برای کانتینر، پورت را به صورت -p 100.101.102.104:3000:3000 منتشر کنید. یا سرویس را روی loopback باقی بگذارید و Tailscale را جلوی آن قرار دهید.

tailscale serve 3000

این کار درخواست‌ها را به http://127.0.0.1:3000 پروکسی می‌کند و پس از فعال‌سازی گواهی‌های HTTPS برای tailnet، آن‌ها را در شبکه داخلی شما با نام ts.net و از طریق HTTPS ارائه می‌دهد. این سرویس برای گره‌های شما خصوصی باقی می‌ماند. نسخه عمومی همین ایده، Funnel است و Tailscale serve در مقابل funnel توضیح می‌دهد که کدام‌یک برای نیاز شما مناسب‌تر است.

دو وظیفه مرتبط دیگر صفحات خاص خود را دارند. دسترسی به یک شبکه خصوصی کامل که Tailscale روی آن نصب نیست، نیازمند یک subnet router روی یک VPS است و هدایت ترافیک اینترنت خروجی یک گره از طریق گره‌ای دیگر، نیازمند یک exit node است.

بستن پورت‌هایی که دیگر به آن‌ها نیاز ندارید

هنگامی که هر مدیر سیستم از طریق tailnet به سرور دسترسی پیدا می‌کند، پورت عمومی 22 دیگر کاربردی ندارد. این همان مزیت عملی است: پورتی که بسته باشد، هدف حملات brute force قرار نمی‌گیرد و لاگ‌های شما دیگر با تلاش‌های ورود پر نمی‌شوند.

ترتیب کار مهم است. ابتدا دسترسی tailnet را اضافه کنید، از یک نشست (session) دوم مطمئن شوید که می‌توانید از طریق آن وارد شوید و تنها پس از آن، قانون عمومی (public rule) را حذف کنید.

sudo ufw allow in on tailscale0
sudo ufw status verbose

پس از آن، قانون عمومی SSH را حذف کرده و با استفاده از نام MagicDNS دوباره متصل شوید. توجه داشته باشید که ufw allow in on tailscale0 در واقع چه کاری انجام می‌دهد: این دستور به هر چیزی که از طریق تونل وارد شود اعتماد می‌کند، بنابراین فایل سیاست (policy file) در Tailscale به جای ufw به ابزار کنترل دسترسی شما تبدیل می‌شود. سیاست خود را با در نظر گرفتن این موضوع بنویسید.

یک هشدار برای کسانی که از کانتینرها استفاده می‌کنند: پورت منتشرشده (published port) در Docker، قوانین NAT مخصوص به خود را نصب کرده و ufw را دور می‌زند، بنابراین یک ufw deny آن را نمی‌بندد. پورت‌های منتشرشده Docker که ufw را دور می‌زنند این مکانیزم را توضیح می‌دهد. انتشار روی آدرس tailnet، همان‌طور که در بالا گفته شد، این مشکل را برطرف می‌کند. اگر برنامه تحت Docker Compose اجرا می‌شود، یک sidecar در Tailscale در استک Compose یک گام فراتر می‌رود و پورت منتشرشده را به‌طور کامل حذف می‌کند، به‌طوری که کانتینر فقط از طریق نام tailnet آن قابل دسترسی باشد.

آنچه Tailscale محافظت می‌کند و آنچه محافظت نمی‌کند

بیان صریح این موضوع ضروری است، زیرا نسخه‌های بازاریابی مرزهای آن را مبهم می‌کنند.

محافظت‌شده: ترافیک بین دو گره (node) به‌صورت سرتاسری با WireGuard رمزنگاری می‌شود و هیچ رله‌ای در میانه مسیر نمی‌تواند آن را بخواند. کلیدهای خصوصی هرگز ماشینی که آن‌ها را تولید کرده است، ترک نمی‌کنند. گره‌ها نیازی به پورت ورودی عمومی ندارند، بنابراین هیچ چیزی روی پورت‌های 22 یا 5432 برای اسکن توسط اینترنت وجود ندارد. دسترسی بین گره‌ها به‌جای کسی که آدرس را می‌داند، توسط یک فایل سیاست (policy file) تعیین می‌شود.

محافظت‌نشده: سرور هماهنگ‌کننده (coordination server) نمودار دستگاه‌های شما را می‌بیند. این متادیتا به‌خودی‌خود حساس است، زیرا نام ماشین‌ها، مالکان، آدرس‌ها و زمان‌های آنلاین بودن، زیرساخت شما را توصیف می‌کنند. این سرور همچنین کلیدها را توزیع می‌کند که ریسک جدی‌تری است. Tailscale مستقیماً می‌گوید: «اگر Tailscale مخرب باشد و به‌طور پنهانی گره‌های جدیدی را به شبکه شما وارد کند، می‌تواند ترافیک را به گره‌های موجود شما ارسال یا از آن‌ها دریافت کند.» ارائه‌دهنده Single Sign-On شما در همان مسیر اعتماد قرار دارد، زیرا هر کسی که بتواند در آنجا هویت جعل کند، می‌تواند یک گره اضافه کند. همچنین یک گرهِ آسیب‌دیده، یک همتا (peer) در داخل tailnet است، بنابراین آنچه در ادامه به آن دسترسی پیدا می‌کند، هر چیزی است که سیاست شما اجازه می‌دهد. اینکه آیا این موارد ریسک قابل قبولی را تشکیل می‌دهند یا خیر، به این بستگی دارد که در برابر چه کسی دفاع می‌کنید و مدل اعتماد کامل هر یک از این موارد را بررسی می‌کند، از جمله اینکه یک حساب کاربری سرقت‌شده واقعاً چه کاری می‌تواند انجام دهد.

دو پاسخ برای ریسک توزیع کلید وجود دارد. اولی tailnet lock است که مستلزم آن است که گره‌های مورد اعتماد موجود، یک گره جدید را به‌صورت رمزنگاری امضا کنند تا سایر گره‌های شما آن را بپذیرند. کنترل پلنی که بدون امضای معتبر، گره‌ای اضافه کند، نادیده گرفته می‌شود. کنسول مدیریت، خط tailscale lock init دقیق را برای گره‌های امضاکننده شما تولید می‌کند و هر گره می‌تواند آنچه را که می‌بیند تأیید کند.

tailscale lock status

همه گره‌ها باید مجموعه یکسانی از کلیدهای امضای مورد اعتماد را گزارش کنند. پاسخ دوم، اجرای کنترل پلن توسط خودتان است. یک سرور هماهنگ‌کننده Headscale که خودتان میزبانی می‌کنید، همان پروتکل را با همان کلاینت‌ها صحبت می‌کند و نمودار دستگاه و توزیع کلید را به سخت‌افزاری که مالک آن هستید منتقل می‌کند. در این صورت، شما مالک پایداری (uptime) آن سرور نیز خواهید بود. اگر هنوز در حال مقایسه کنترل پلن‌های خود-میزبانی‌شده هستید و به این مورد نرسیده‌اید، NetBird یک VPN مش جداگانه است که سرور آن را به‌طور کامل روی یک VPS اجرا می‌کنید.

یک پیش‌فرض که باید در همان روز اول اصلاح شود. یک tailnet جدید به‌صورت سهل‌گیرانه عرضه می‌شود: «سیاست پیش‌فرض tailnet، ارتباط بین تمام دستگاه‌های داخل tailnet را فعال می‌کند.» به‌محض اینکه یک بخش acls اضافه کنید، مدل به «رد پیش‌فرض» تغییر می‌یابد و فقط قوانین شما اجازه عبور می‌یابند.

{
  "tagOwners": {
    "tag:server": ["autogroup:admin"]
  },
  "acls": [
    {"action": "accept", "src": ["autogroup:member"], "dst": ["tag:server:22"]}
  ]
}

این policy به اعضای tailnet اجازه می‌دهد فقط از طریق SSH به سرورهای tagشده دسترسی داشته باشند و به هیچ سرویس دیگری دسترسی نداشته باشند. برای هر سرویس یک rule اضافه کنید و wildcard را باقی نگذارید؛ زیرا wildcard به این معناست که با سرقت کلید یک لپ‌تاپ، مهاجم می‌تواند به database شما دسترسی پیدا کند. اگر هنوز در حال انتخاب یک mesh VPN هستید، نحوه نوشتن چنین ruleهایی یکی از مواردی است که گزینه‌ها واقعاً در آن تفاوت دارند. مقالهٔ مقایسه NetBird و Tailscale این دو مدل policy را همراه با این موضوع که چه کسی control plane را اجرا می‌کند، مقایسه می‌کند.

حالت‌های شکست و پیام‌هایی که مشاهده خواهید کرد

tailscale status همیشه relay را نمایش می‌دهد. دو گره (node) هرگز مسیر مستقیمی ایجاد نکرده‌اند. دستور tailscale netcheck را در هر دو سمت اجرا کنید. UDP: false به این معنی است که ترافیک UDP در خروجی مسدود شده است، بنابراین فقط از طریق relay امکان برقراری ارتباط وجود دارد. MappingVariesByDestIP: true نشان‌دهنده وجود یک NAT سخت‌گیرانه در مسیر است؛ باز کردن پورت UDP 41641 در سمت ورودی (سمتی که کنترل آن را در اختیار دارید) معمولاً این مشکل را حل می‌کند.

گره‌ای که ماه‌ها کار می‌کرد، ناپدید شده است. یک دلیل رایج، انقضای کلید گره (node key) در بازه پیش‌فرض 180 روزه است؛ بنابراین ابتدا وضعیت دستگاه را در کنسول مدیریتی بررسی کنید. اگر وضعیت آن منقضی (expired) ثبت شده است، اجرای sudo tailscale up روی آن دستگاه مشکل را رفع می‌کند و غیرفعال کردن انقضای کلید برای سرورها از تکرار آن جلوگیری خواهد کرد. اگر کلید منقضی نشده است، فایل سیاست (policy file) را بررسی کنید، زیرا توصیه خود Tailscale برای دستگاهی که در tailscale status دیده نمی‌شود، جستجوی قوانینی است که دسترسی را مسدود کرده‌اند.

همتاها (peers) در لیست هستند اما اتصالات با timeout مواجه می‌شوند. اگر tailscale ping پاسخ دریافت می‌کند، یعنی اتصال برقرار است و دلیل احتمالی، سیاست‌هایی است که ترافیک را رد می‌کنند. بخش acls را برای یافتن قانونی که این مبدأ، مقصد و پورت را پوشش می‌دهد، بررسی کنید. بسته رد شده (denied) به‌جای پاسخ‌دهی، دور ریخته می‌شود و به همین دلیل به‌جای Connection refused، با خطای timeout مواجه می‌شوید.

نام‌های MagicDNS ترجمه (resolve) نمی‌شوند. ping db-1 شکست می‌خورد در حالی که ping 100.101.102.104 کار می‌کند. ابتدا تأیید کنید که کلاینت تنظیمات DNS مربوط به Tailscale را می‌پذیرد: گره‌ای که با --accept-dns=false راه‌اندازی شده باشد، هرگز پرس‌وجوهای خود را به stub resolver در 100.100.100.100 نمی‌فرستد. سپس cat /etc/resolv.conf و هر ابزار دیگری روی سیستم که این فایل را تغییر می‌دهد، بررسی کنید. در سیستمی که از systemd-resolved استفاده می‌کند، این فایل معمولاً یک symlink به /run/systemd/resolve/stub-resolv.conf است و عدم وجود 100.100.100.100 در آن طبیعی است. در مواردی که tailscaled مستقیماً فایل را می‌نویسد، یک کلاینت DHCP یا ابزار دیگری که آن را بازنویسی کند، باعث خرابی MagicDNS می‌شود. اگر هیچ‌کدام از این موارد دلیل مشکل نباشد، خطا می‌تواند در پیکربندی DNS محلی یا شبکه باشد. این مشکل در همان دسته‌بندی اختلال DNS داخل تونل WireGuard قرار می‌گیرد.

tailscale up تگ شما را نمی‌پذیرد. تگ مورد نظر در بخش tagOwners در فایل سیاست تعریف نشده است. آن را اضافه کنید و سپس دستور را دوباره اجرا نمایید.

FAQ

آیا Tailscale یک VPN است یا یک شبکه مش (mesh)؟

هر دو واژه دقیق هستند و لایه‌های متفاوتی را توصیف می‌کنند. تونل‌ها از پروتکل WireGuard استفاده می‌کنند که آن را به یک VPN تبدیل می‌کند. توپولوژی شبکه از نوع مش است، زیرا هر گره به‌جای ارسال تمام بسته‌ها از طریق یک سرور مرکزی، مستقیماً با هر گره‌ای که با آن در ارتباط است تونل برقرار می‌کند. سرور هماهنگ‌کننده (coordination server) در مسیر کنترل قرار دارد، نه در مسیر داده؛ بنابراین اگر این سرور از دسترس خارج شود، تونل‌های موجود همچنان ترافیک را منتقل می‌کنند. آنچه در زمان قطعی متوقف می‌شود، پیوستن گره‌های جدید و اعمال تغییرات در کلیدها یا سیاست‌ها است. با این حال، Tailscale به‌صورت پیش‌فرض یک VPN برای حفظ حریم خصوصی نیست؛ وب‌سایت‌ها همچنان آدرس عمومی شما را می‌بینند، مگر اینکه ترافیک خود را از طریق یک exit node ارسال کنید. جزئیات بیشتر در آنچه Tailscale از وب‌سایت‌ها و ISP شما پنهان می‌کند آمده است.

آیا Tailscale می‌تواند ترافیک من را بخواند؟

محتوای ترافیک خیر. ترافیک بین گره‌ها با استفاده از WireGuard به‌صورت سرتاسری (end-to-end) رمزنگاری می‌شود، کلیدهای خصوصی هرگز گره‌ها را ترک نمی‌کنند و رله‌های DERP بسته‌هایی را منتقل می‌کنند که راهی برای رمزگشایی آن‌ها ندارند. Tailscale متادیتای شبکه را مشاهده می‌کند: نام ماشین‌ها، مالکان، کلیدهای عمومی، آدرس‌های endpoint و زمان آنلاین بودن هر گره. این سرویس همچنین کلیدها را توزیع می‌کند، بنابراین یک سرور هماهنگ‌کننده نفوذپذیر می‌تواند سعی کند گره‌ای را وارد شبکه کند که ناوگان شما به آن اعتماد کند. قابلیت Tailnet lock با الزام به امضای دیجیتال از سوی گره‌های مورد اعتماد خودتان، جلوی این کار را می‌گیرد و Headscale نیز کنترل‌کننده میزبانی‌شده را از چرخه حذف می‌کند.

آیا نیاز است پورت‌های فایروال را برای Tailscale باز کنم؟

تقریباً هرگز برای ترافیک ورودی (inbound) نیازی نیست. راهنمای خود Tailscale بیان می‌کند که «در بیشتر مواقع، نیازی به باز کردن هیچ پورت فایروالی ندارید.» برای ترافیک خروجی، یک گره به پورت TCP 443 برای ارتباط با سرور هماهنگ‌کننده و رله‌ها، و همچنین پورت UDP 3478 برای STUN نیاز دارد. تونل‌های مستقیم از پروتکل UDP با پورت مبدأ پیش‌فرض 41641 استفاده می‌کنند. باز کردن پورت UDP 41641 برای ترافیک ورودی اختیاری است و فقط به برقراری موفقیت‌آمیز اتصالات مستقیم در شبکه‌های محدود کمک می‌کند.

چرا سایر گره‌ها نمی‌توانند به سرویس من روی پورت 3000 دسترسی پیدا کنند؟

ابتدا آدرس bind را با دستور ss -tlnp بررسی کنید. سرویسی که روی 127.0.0.1:3000 گوش می‌دهد، اتصالات ورودی به آدرس 100.x شبکه Tailnet را رد می‌کند، زیرا آن سوکت فقط اتصالات loopback را می‌پذیرد و کلاینت با خطای Connection refused مواجه می‌شود. سرویس را روی آدرس Tailnet bind کنید یا از tailscale serve 3000 برای پروکسی کردن آن استفاده کنید. اگر سرویس از قبل روی 0.0.0.0 گوش می‌دهد و اتصال به‌جای رد شدن، با timeout مواجه می‌شود، مشکل از آدرس bind نیست. ابتدا قوانین سیاست‌ها (policy rules) و فایروال‌های میزبان را بررسی کنید، سپس به سراغ فایروال‌های شبکه بروید و مطمئن شوید که احراز هویت هیچ‌کدام از دستگاه‌ها منقضی نشده باشد.

آیا باید به‌جای سرور هماهنگ‌کننده Tailscale از Headscale استفاده کنم؟

زمانی از Headscale استفاده کنید که نمودار دستگاه‌ها یا توزیع کلیدها باید روی زیرساختی باشد که خودتان کنترل می‌کنید، یا زمانی که شبکه Tailnet شما باید بدون وابستگی به هیچ سرویس خارجی کار کند. کلاینت‌ها و پروتکل در هر دو حالت یکسان هستند. هزینه این کار این است که اکنون شما مسئولیت مدیریت سرور هماهنگ‌کننده را بر عهده دارید و قطعی آن مانع از پیوستن گره‌های جدید و اعمال تغییرات در سیاست‌ها می‌شود. برای ناوگان‌های کوچک، استفاده از کنترل‌کننده میزبانی‌شده (hosted control plane) با فعال بودن قابلیت Tailnet lock معمولاً گزینه بهتری است.

آیا این مقاله مفید بود؟