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

آموزش راه اندازی Headscale برای سرور کنترل Tailscale

با نصب Headscale روی VPS خود، کنترل کامل شبکه Tailscale را در دست بگیرید. این راهنما نحوه نصب فایل .deb، تنظیم دقیق server_url و اتصال اولین گره به سرور شخصی را شرح می‌دهد.

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 30, 2026.

Headscale چیست

Headscale یک پیاده‌سازی خودمیزبان (self-hosted) از سرور کنترل Tailscale است؛ بنابراین ماشینی که شبکه خصوصی شما را هماهنگ می‌کند، یک VPS است که مالکیت آن با شماست. این یک پروژه جامعه‌محور است و توسط Tailscale Inc اداره نمی‌شود. هر ماشین همچنان کلاینت رسمی tailscale را اجرا می‌کند که با یک فلگ، یعنی --login-server، به سرور شما اشاره می‌کند.

سرور کنترل بخشی است که می‌داند چه کسی به شبکه تعلق دارد. این سرور به هر گره (node) یک آدرس از محدوده 100.64.0.0/10 اختصاص می‌دهد، کلیدهای عمومی را توزیع می‌کند و به گره‌ها می‌گوید که یکدیگر را کجا پیدا کنند. تونل‌ها همچنان WireGuard باقی می‌مانند و به‌صورت گره‌به‌گره ایجاد می‌شوند. ترافیک بین دو ماشین شما از طریق سرور headscale عبور نمی‌کند، مگر اینکه مسیر مستقیمی ایجاد نشود و گره‌ها به یک رله (relay) متوسل شوند. اجرای این نقش هماهنگ‌کننده توسط خودتان، تغییر می‌دهد که چه کسی آن را در اختیار دارد، نه اینکه آن نقش قادر به انجام چه کاری است؛ بنابراین پیش از آنکه این جابجایی را به تنهایی یک پیروزی امنیتی تلقی کنید، ارزش دارد که بدانید یک سرور کنترل در این مدل به چه چیزی دسترسی دارد و به چه چیزی ندارد.

Headscale در هر نمونه (instance) به یک tailnet (یک شبکه Tailscale) سرویس می‌دهد که پروژه آن را برای استفاده شخصی یا یک سازمان کوچک مناسب می‌داند. با سه یا چهار ماشین، یک VPN ساده WireGuard روی یک VPS شخصی نرم‌افزار کمتری برای اجرا و خرابی‌های کمتری دارد. Headscale زمانی ارزش خود را نشان می‌دهد که دیگر نخواهید برای هر لپ‌تاپ جدید، یک بلاک [Peer] را به‌صورت دستی بنویسید. هزینه اغلب همان چیزی است که افراد را در وهله اول به جستجو وامی‌دارد، بنابراین پیش از راه‌اندازی سرور، ارزش دارد که بخوانید طرح رایگان میزبانی‌شده واقعاً چه مواردی را پوشش می‌دهد، زیرا تعداد انگشت‌شماری از ماشین‌های شخصی معمولاً در آن جای می‌گیرند. اگر از آن سقف عبور کرده‌اید، محاسبات را در برابر هزینه طرح‌های پولی که به ازای هر کاربر است نه هر دستگاه انجام دهید، زیرا یک خانواده با یک حساب کاربری می‌تواند مدت‌ها پس از اینکه تعداد دستگاه‌ها دیگر اهمیتی ندارد، ارزان باقی بماند. اگر یک صفحه کنترل خودمیزبان می‌خواهید اما ترجیح می‌دهید به جای یک جایگزین مستقیم برای Tailscale، کلاینت خودتان و یک رابط وب برای مدیریت همتایان (peers) داشته باشید، NetBird روی یک VPS واحد جایگزینی است که ارزش بررسی دارد. برای مقایسه گسترده‌تر این دو مدل، تفاوت WireGuard و Tailscale را ببینید.

پیش‌نیازهای پیش از نصب

  • یک سرور مجازی (VPS) با سیستم‌عامل Ubuntu 24.04، دارای آدرس IPv4 عمومی و دسترسی sudo. اگر سرور جدید است، ابتدا مراحل ده دقیقه اول کار با یک سرور مجازی جدید را انجام دهید.
  • یک رکورد DNS از نوع A که به آن آدرس اشاره می‌کند. این راهنما از headscale.example.com استفاده می‌کند.
  • یک دامنه یا زیردامنه دوم برای MagicDNS. این راهنما از tailnet.example.net استفاده می‌کند. این دامنه نباید با دامنه‌ای که در server_url استفاده شده، یکسان باشد.
  • یک دستگاه کلاینت برای اتصال، که سیستم‌عامل آن Linux، macOS، Windows، Android یا iOS باشد.

نصب headscale از طریق فایل .deb رسمی

این پروژه بسته‌های .deb را در صفحه GitHub releases خود منتشر می‌کند. تا ژوئیه 2026، نسخه فعلی 0.29.3 است. ابتدا معماری سیستم خود را بررسی کنید، زیرا نام فایل به آن بستگی دارد.

sudo apt update
sudo apt install -y wget
dpkg --print-architecture

این دستور در یک VPS معمولی x86 عبارت amd64 و در پلن‌های نوع Ampere یا Graviton عبارت arm64 را چاپ می‌کند. پاسخ را در متغیر زیر قرار دهید.

HEADSCALE_VERSION="0.29.3"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \\
  "https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install -y ./headscale.deb
headscale version

وجود ./ در ابتدای نام فایل الزامی است. بدون آن، apt به دنبال بسته‌ای به نام headscale.deb در مخازن شما می‌گردد و با خطا مواجه می‌شود.

این بسته یک کاربر سیستمی به نام headscale ایجاد می‌کند، یک فایل /etc/headscale/config.yaml پیش‌فرض می‌نویسد و یک unit برای systemd نصب می‌کند. این بسته سرویس را شروع نمی‌کند و این ترتیب صحیح است. پیکربندی پیش‌فرض، server_url را به http://127.0.0.1:8080 اشاره می‌دهد که آدرسی نیست که کلاینت‌های شما بتوانند به آن دسترسی داشته باشند؛ بنابراین اگر سرویس در حال حاضر اجرا شود، تنظیمات آن نادرست خواهد بود. اجرای دستور sudo systemctl is-active headscale در این مرحله، inactive را چاپ می‌کند. این مورد انتظار است و خطا محسوب نمی‌شود.

پیش از شروع سرویس، server_url را پیکربندی کنید

فایل /etc/headscale/config.yaml را با استفاده از sudo nano /etc/headscale/config.yaml ویرایش کنید، یا همان سه تغییر را با sed اعمال نمایید. یک نسخه پشتیبان از فایل اصلی تهیه کنید؛ زیرا این فایل طولانی است، توضیحات فراوانی دارد و بهترین مرجع شما برای سایر تنظیمات محسوب می‌شود.

sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.orig
sudo sed -i 's|^server_url:.*|server_url: https://headscale.example.com|' /etc/headscale/config.yaml
sudo sed -i 's|^listen_addr:.*|listen_addr: 127.0.0.1:8080|' /etc/headscale/config.yaml
sudo sed -i 's|^  base_domain:.*|  base_domain: tailnet.example.net|' /etc/headscale/config.yaml
sudo grep -E '^(server_url|listen_addr):|^  base_domain:' /etc/headscale/config.yaml

server_url آدرسی است که headscale در هر ثبت‌نام کلاینت درج می‌کند. کلاینت‌ها پس از آن همواره با همان رشته متصل می‌شوند، بنابراین باید نام عمومی (public name) همراه با https:// در ابتدای آن باشد و هرگز از 127.0.0.1 استفاده نکنید.

listen_addr محلی است که پردازش روی آن bind می‌شود. آن را روی loopback باقی بگذارید. یک reverse proxy روی همان سرور، TLS (امنیت لایه انتقال) را مدیریت کرده و درخواست‌ها را به آن هدایت می‌کند، بنابراین هیچ منبعی خارج از سرور نیازی به دسترسی مستقیم به پورت 8080 ندارد.

base_domain پسوند MagicDNS است، دامنه‌ای که گره‌های (nodes) شما تحت آن نام‌گذاری می‌شوند. این مقدار باید یک نام دامنه کاملاً واجد شرایط (FQDN) بدون نقطه در انتها باشد و باید با دامنه موجود در server_url متفاوت باشد، زیرا در غیر این صورت فضای نام این دو با هم تداخل پیدا می‌کند.

بخش پایگاه داده را تغییر ندهید. مقدار پیش‌فرض SQLite در مسیر /var/lib/headscale/db.sqlite است، در دایرکتوری که توسط بسته ایجاد شده و مالکیت آن را در اختیار دارد؛ و برای یک tailnet با این ابعاد، SQLite کافی است.

راه‌اندازی headscale و اطمینان از اجرای آن

sudo systemctl enable --now headscale
sudo systemctl is-active headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/health

دستور is-active عبارت active را چاپ می‌کند و curl عبارت 200 را نمایش می‌دهد. دستور enable --now هر دو بخش کار را انجام می‌دهد: سرویس را اجرا کرده و آن را برای شروع خودکار پس از reboot علامت‌گذاری می‌کند.

اگر is-active عبارت failed را چاپ کرد، لاگ‌های journal را با sudo journalctl -u headscale -n 50 --no-pager بخوانید. شکست در این مرحله تقریباً همیشه به دلیل فایل پیکربندی است، زیرا headscale پیش از باز کردن سوکت، کل فایل را پارس می‌کند؛ بنابراین یک تورفتگی اشتباه یا یک کلید ناشناخته، فرآیند را پیش از آنکه سرویس روی پورتی گوش دهد، متوقف می‌کند. فایل را اصلاح کرده و سپس sudo systemctl restart headscale را اجرا کنید. هر تغییر پیکربندی در آینده نیز به همین restart نیاز دارد. کلاینت‌ها پس از آن به‌طور خودکار دوباره متصل می‌شوند. اگر با unitهای systemd آشنا نیستید، اجرای سرویس‌ها و تایمرهای شخصی با systemd دستورات استفاده‌شده در اینجا را پوشش می‌دهد.

هنگامی که در shell هستید، فایل‌های وضعیت را بررسی کنید:

stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.key

هر دو خط با headscale شروع می‌شوند که همان کاربر بدون دسترسی ویژه (unprivileged) است که توسط بسته ایجاد شده است. فایل noise_private.key هویت سرور برای کلاینت‌هایش است. آن را حفظ کنید. اگر آن را حذف کنید، headscale یک هویت جدید تولید می‌کند و تمام گره‌ها (nodes) باید دوباره ثبت‌نام کنند.

قرار دادن TLS در مقابل headscale

کلاینت‌ها باید از طریق HTTPS به server_url دسترسی پیدا کنند. Caddy کوتاه‌ترین مسیر است، زیرا گواهی را به‌صورت خودکار درخواست و تمدید می‌کند.

sudo apt install -y caddy

بخش /etc/caddy/Caddyfile را با بلوک موجود در مستندات headscale جایگزین کنید:

headscale.example.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up True-Client-IP {remote_host}
        header_up X-Real-IP {remote_host}
    }
}
sudo caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl is-active caddy

دستور validate در صورت صحت ساختار فایل، adapted config to JSON را چاپ می‌کند. هشدار مربوط به فرمت‌بندی فایل صرفاً جنبه ظاهری دارد. از لپ‌تاپ خود، دستور curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health نیز باید 200 را چاپ کند. این بررسی واحد ثابت می‌کند که DNS، فایروال، گواهی و پروکسی همگی به‌درستی با هم کار می‌کنند.

در اینجا جزئیات پروکسی وجود دارد که معمولاً باعث اتلاف وقت کاربران می‌شود. اتصال کنترل Tailscale یک HTTP upgrade است، با یک درخواست POST به‌جای GET شروع می‌شود و مقدار هدر Upgrade برابر با tailscale-control-protocol است. Caddy این مورد را بدون پیکربندی اضافی عبور می‌دهد. اما nginx این کار را نمی‌کند، بنابراین یک front-end از نوع nginx به map ارتقا نیاز دارد:

map $http_upgrade $connection_upgrade {
    default keep-alive;
    ''      close;
}

server {
    listen 443 ssl;
    server_name headscale.example.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        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_buffering off;
        proxy_pass http://127.0.0.1:8080;
    }
}

اگر این خطوط را حذف کنید، درخواست‌های معمولی همچنان موفقیت‌آمیز خواهند بود؛ به همین دلیل است که /health کد 200 را برمی‌گرداند و همه‌چیز درست به نظر می‌رسد، در حالی که اتصال کنترل طولانی‌مدت هرگز برقرار نمی‌شود و گره‌های شما پس از ثبت‌نام، آفلاین باقی می‌مانند. اگر مسیر nginx را انتخاب می‌کنید، Certbot روی Ubuntu 24.04 با nginx بخش مربوط به گواهی را پوشش می‌دهد.

کدام پورت‌ها را در UFW باز کنیم

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

پورت 443 تمامی ارتباطات کلاینت‌ها را منتقل می‌کند. پورت 80 صرفاً برای چالش HTTP در ACME (محیط مدیریت خودکار گواهی) و هدایت (redirect) به HTTPS وجود دارد و Caddy برای دریافت گواهی به آن نیاز دارد.

پورت 8080 باید بسته بماند. listen_addr برابر با 127.0.0.1:8080 است، بنابراین پروکسی از طریق رابط loopback به headscale دسترسی پیدا می‌کند و هیچ قانون فایروالی در این میان دخیل نیست. باز کردن پورت 8080 به روی اینترنت، یک کانال کنترلی متنی (cleartext) در اختیار کلاینت‌ها قرار می‌دهد و هیچ مزیتی ندارد. به یاد داشته باشید که اکثر ارائه‌دهندگان، یک فایروال دوم در پنل مدیریتی خود دارند که از UFW جداست؛ بنابراین ممکن است یک پورت روی سرور باز باشد اما در لبه شبکه بسته بماند. اصول اولیه فایروال UFW در VPS سینتکس قوانین را با جزئیات بیشتری بررسی می‌کند.

Create a user and a preauth key

sudo headscale users create alice
sudo headscale users list

The headscale command is a client. It talks to the running daemon over the unix socket at /var/run/headscale/headscale.sock, which is mode 0770 and owned by the headscale group. Two things follow from that. The command fails while the service is stopped, which is the other reason the ordering in this guide matters, and it needs sudo unless you add your own account to the headscale group.

users list prints an ID next to each name. You need that number, because the key command takes a numeric user ID and not a name.

sudo headscale preauthkeys create --user 1 --expiration 24h

The key is printed once. Copy it now. A preauth key is single use and valid for one hour unless you say otherwise, so --expiration 24h is worth setting while you are still testing. Add --reusable for a key that enrolls several machines, and treat that one like a password, because anyone holding it can join your network.

اتصال اولین کلاینت با استفاده از --login-server

روی ماشینی که می‌خواهید به شبکه اضافه کنید:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --login-server https://headscale.example.com --auth-key 'hskey-auth-PASTE-YOUR-KEY-HERE'
tailscale status
tailscale ip -4

tailscale ip -4 آدرسی را که headscale اختصاص داده است چاپ می‌کند، چیزی شبیه به 100.64.0.1. در سمت سرور، sudo headscale nodes list گره را به همراه شناسه، کاربر و وضعیت آنلاین بودن آن نمایش می‌دهد.

مقدار --login-server باید دقیقاً با server_url مطابقت داشته باشد، شامل طرح (scheme) و بدون هیچ اسلش اضافه در انتها. این مقادیر به صورت رشته‌ای مقایسه می‌شوند و عدم تطابق به این معناست که کلاینت با یک آدرس ثبت‌نام می‌کند و سپس دستور می‌گیرد که با آدرس دیگری ارتباط برقرار کند.

ماشینی که قبلاً به سرویس میزبانی‌شده Tailscale متصل بوده، همان ورود را حفظ می‌کند. ابتدا روی آن sudo tailscale logout را اجرا کنید و سپس tailscale up را با --login-server به کار ببرید.

اگر --auth-key را حذف کنید، کلاینت یک URL چاپ می‌کند. آن را باز کنید؛ صفحه شناسه مربوط به آن تلاش برای ثبت‌نام را نشان می‌دهد که باید آن را در سرور تأیید کنید:

sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGE

این فرم برای لپ‌تاپ شخصی شما مناسب‌تر است. کلیدهای پیش‌تأیید (Preauth keys) برای هر نوع اسکریپت‌نویسی بهتر هستند، زیرا نیازی به نظارت انسانی ندارند. هنگامی که خود VPS به یک گره تبدیل شد، می‌تواند ترافیک اینترنت سایر ماشین‌های شما را نیز هدایت کند، که این همان راه‌اندازی گره خروجی (exit node) است، با این تفاوت که شما مسیر تبلیغ‌شده را به جای کنسول مدیریت میزبانی‌شده، با دستور headscale در سرور تأیید می‌کنید. اگر هدف شما دسترسی به یک شبکه خصوصی پشت آن VPS است و نه راهی به سمت اینترنت، همان مرحله تأیید، تبلیغ آن زیرشبکه به بقیه tailnet را پوشش می‌دهد. انتشار یک برنامه از یک گره، به جای مسیریابی کل شبکه‌ها از طریق آن، کار متفاوتی است و serve و funnel دو روش انجام این کار هستند؛ اگرچه هر دو به زیرساخت گواهی و ورودی خود Tailscale متکی هستند، بنابراین آن‌ها را به عنوان ویژگی‌های tailnet میزبانی‌شده در نظر بگیرید، نه چیزی که headscale مستقیماً در اختیار شما قرار می‌دهد.

DERP و آنچه ترافیک را در صورت شکست مسیر مستقیم، رله می‌کند

DERP (مخفف designated encrypted relay for packets) مسیر جایگزین (fallback) است. هنگامی که دو گره نمی‌توانند یک اتصال مستقیم WireGuard برقرار کنند، معمولاً به این دلیل که هر دو پشت NAT (ترجمه آدرس شبکه) سخت‌گیرانه قرار دارند، بسته‌ها را از طریق یک رله ارسال می‌کنند. رله هیچ کلیدی در اختیار ندارد، بنابراین نمی‌تواند ترافیک شما را بخواند. رله فقط می‌بیند که کدام گره‌ها با هم در ارتباط هستند و چه حجمی از داده جابه‌جا می‌شود.

در مورد عملکرد پیکربندی پیش‌فرض شفاف باشید. Headscale به‌صورت پیش‌فرض به https://controlplane.tailscale.com/derpmap/default با auto_update_enabled: true و update_frequency: 3h اشاره می‌کند، بنابراین کنترل پلین (control plane) متعلق به شماست، در حالی که رله‌ها متعلق به Tailscale هستند. برای اکثر کاربران، این یک معامله منصفانه است. اگر چنین نیست، رله خودتان را راه‌اندازی کنید.

برای اجرای رله اختصاصی، enabled: true را در بخش derp.server در فایل config.yaml تنظیم کنید، headscale را ری‌استارت کنید و پورت STUN (مخفف session traversal utilities for NAT) را با sudo ufw allow 3478/udp باز کنید. فایل پیکربندی این الزام را به‌وضوح بیان می‌کند: server_url باید از https استفاده کند، زیرا DERP به TLS نیاز دارد. خالی کردن لیست derp.urls، رله‌های Tailscale را از نقشه حذف می‌کند؛ اگر این کار را بدون داشتن یک رله داخلی فعال انجام دهید، هر جفت گره‌ای که نتواند مستقیماً متصل شود، اصلاً قادر به برقراری ارتباط نخواهد بود.

از سمت client، tailscale netcheck تأخیر را تا هر ناحیهٔ relay که می‌شناسد نمایش می‌دهد و tailscale status هر peer را با یکی از این دو وضعیت علامت‌گذاری می‌کند: direct همراه با یک address یا relay همراه با یک کد ناحیه. اگر یک peer روی relay گیر کند، مشکل از NAT است، نه از headscale. اگر peer در وضعیت direct باشد و همچنان کند کار کند، موضوع متفاوتی مطرح است؛ پاسخ معمول در این حالت MTU است، نه خود tunnel.

چرا یک نود (node) به صورت آفلاین نمایش داده می‌شود؟

پراکسی درخواست ارتقا (upgrade) را مسدود می‌کند. این مورد رایج‌ترین دلیل است و نشانه آن این است که سایر بخش‌ها سالم به نظر می‌رسند: /health کد 200 برمی‌گرداند، headscale nodes list نود را نشان می‌دهد، اما نود هرگز آنلاین نمی‌شود. اتصال کنترلی یک درخواست POST است که حاوی Upgrade: tailscale-control-protocol می‌باشد و پراکسی که آن را فوروارد نکند، تنها کانالی را که وضعیت نود را گزارش می‌دهد، قطع می‌کند. پیکربندی nginx خود را با بلوک map بالا مقایسه کنید یا برای اطمینان از عدم مشکل در پراکسی، از Caddy استفاده کنید.

مقدار server_url پس از ثبت‌نام نودها تغییر کرده است. نودها همچنان از مقداری که در زمان ثبت‌نام دریافت کرده‌اند استفاده می‌کنند. اگر این مقدار را ویرایش کرده‌اید، دستور sudo tailscale up --login-server https://headscale.example.com --force-reauth را روی هر نود اجرا کنید.

کلاینت در حال اجرا نیست. روی نود، دستورات sudo systemctl is-active tailscaled و sudo journalctl -u tailscaled -n 50 --no-pager را بررسی کنید. کلاینتی که نتواند دامنه شما را resolve کند یا به آن دسترسی داشته باشد، تلاش‌های مجدد خود را در آنجا ثبت می‌کند.

کلید منقضی شده است. این مورد در بخش بعدی توضیح داده شده است.

برای مشاهده سمت سرور در حین تست، دستور sudo journalctl -u headscale -f را روی VPS اجرا کرده و tailscaled را روی کلاینت ری‌استارت کنید. نودی که به headscale برسد، بلافاصله خطوط لاگ تولید می‌کند. سکوت به این معنی است که درخواست به مقصد نمی‌رسد؛ بنابراین پیش از بررسی headscale، وضعیت DNS، فایروال و پراکسی را کنترل کنید.

انقضای کلید و نودی که پس از چند هفته از کار می‌افتد

دو نوع انقضای مجزا وجود دارد و اشتباه گرفتن آن‌ها باعث اتلاف وقت می‌شود.

کلیدهای Preauth طبق طراحی، به‌سرعت منقضی می‌شوند. مقدار پیش‌فرض یک ساعت و یک بار استفاده است. اگر tailscale up کلید را رد کرد، به‌جای ویرایش هر چیزی در کلاینت، یک کلید جدید روی سرور تولید کنید.

کلیدهای Node بخش با عمر طولانی هستند. بخش node در config.yaml مقدار expiry: 0 را تعیین می‌کند و 0 به معنای عدم وجود انقضای پیش‌فرض است: یک نود ثبت‌شده تا زمانی که آن را منقضی نکنید، معتبر باقی می‌ماند. نودهای دارای Tag هرگز منقضی نمی‌شوند. اگر می‌خواهید ثبت‌نام‌ها پس از مدتی منقضی شوند، expiry: 180d را تنظیم کنید، اما بدانید چه درخواستی دارید: در این صورت هر نود بدون Tag باید طبق آن زمان‌بندی sudo tailscale up --login-server https://headscale.example.com --force-reauth شود و یک سرور headless که کسی مجدداً در آن احراز هویت نکند، به‌طور خودکار از شبکه خارج خواهد شد.

هنگامی که شخصی لپ‌تاپ خود را گم می‌کند، این کار را به‌صورت دستی انجام دهید. sudo headscale nodes list شناسه (ID) را به شما می‌دهد، سپس sudo headscale nodes expire -i 3 آن نود را از سیستم خارج (logout) می‌کند و sudo headscale nodes delete -i 3 آن را به‌طور کامل از شبکه حذف می‌نماید.

پشتیبان‌گیری و ارتقا

/var/lib/headscale و /etc/headscale در کنار هم کل سرور را تشکیل می‌دهند. پیش از کپی کردن آن‌ها، سرویس را متوقف کنید؛ زیرا ممکن است SQLite در حال نوشتن داده باشد و پایگاه داده‌ای که تحت بار کپی شود، دچار ناسازگاری گردد.

sudo systemctl stop headscale
sudo tar czf /root/headscale-state.tgz -C /var/lib headscale
sudo tar czf /root/headscale-config.tgz -C /etc headscale
sudo systemctl start headscale
sudo chmod 600 /root/headscale-*.tgz

هر دو فایل را از روی سرور منتقل کنید. این فایل‌ها حاوی کلیدهای خصوصی و تمامی ثبت‌نام‌ها هستند، بنابراین باید همان‌قدر که از خود سرور محافظت می‌کنید، از آن‌ها نیز مراقبت کنید. پشتیبان‌گیری با restic از یک VPS نحوه انجام این کار را به‌صورت زمان‌بندی‌شده و رمزنگاری‌شده توضیح می‌دهد.

برای ارتقا، مراحل نصب را تکرار کنید: .deb و sudo apt install ./headscale.deb جدید را دانلود کرده، سپس سرویس را ری‌استارت کنید و بررسی‌های is-active و /health را دوباره اجرا نمایید. از نسخه 0.29 به بعد، مسیر ارتقا سخت‌گیرانه است. پرش از یک نسخه فرعی (minor version) مسدود شده است و بازگشت به نسخه‌های فرعی قدیمی‌تر نیز امکان‌پذیر نیست. هر بار فقط یک نسخه فرعی ارتقا دهید، پیش از هر مرحله یک نسخه پشتیبان تهیه کنید و ابتدا یادداشت‌های انتشار (release notes) همان نسخه را مطالعه نمایید؛ چرا که در همان نسخه، رفتار سیاست‌های ACL تغییر کرده و چندین کلید پیکربندی جابه‌جا شده‌اند.

FAQ

چرا headscale بلافاصله پس از نصب فایل .deb اجرا نمی‌شود؟

بستهٔ نصب، unit مربوطه را نصب می‌کند اما سرویس را در حالت متوقف باقی می‌گذارد و فایل پیش‌فرض /etc/headscale/config.yaml بیشتر یک الگو (template) است تا یک پیکربندی عملیاتی. ابتدا فایل‌های server_url، listen_addr و base_domain را ویرایش کنید، سپس دستور sudo systemctl enable --now headscale را اجرا کرده و با sudo systemctl is-active headscale وضعیت را تأیید کنید. اگر همچنان با خطا مواجه شدید، sudo journalctl -u headscale -n 50 --no-pager علت مشکل را مشخص می‌کند؛ در این مرحله، مشکل تقریباً همیشه یک خطای YAML است، زیرا headscale پیش از bind کردن پورت، کل فایل را پارس می‌کند.

آیا همچنان باید کلاینت معمولی Tailscale را روی سیستم‌هایم نصب کنم؟

بله. Headscale فقط جایگزین سرور کنترل (control server) می‌شود. هر گره (node) کلاینت رسمی Tailscale را اجرا می‌کند و شما با استفاده از sudo tailscale up --login-server https://headscale.example.com آن را به سرور خود متصل می‌کنید. این flag در کلاینت استاندارد وجود دارد، بنابراین نیازی به وصله کردن یا کامپایل مجدد نیست.

آیا ترافیک من از سرور headscale عبور می‌کند؟

معمولاً خیر. Headscale شبکه را هماهنگ کرده و کلیدها و آدرس‌ها را توزیع می‌کند، در حالی که مسیر داده (data path) یک ارتباط WireGuard مستقیم بین گره‌های شماست. ترافیک تنها زمانی مسیر انحرافی طی می‌کند که دو گره نتوانند مستقیماً به یکدیگر متصل شوند و به یک رلهٔ DERP متوسل شوند؛ در پیکربندی پیش‌فرض، این رله‌ها همان سرورهای عمومی Tailscale هستند. دستور tailscale status را روی یک گره اجرا کنید تا ببینید آیا یک peer خاص به صورت direct متصل است یا از طریق relay.

چرا گره من پس از ثبت‌نام (register) همچنان آفلاین می‌ماند؟

گره‌ای که در headscale nodes list ظاهر می‌شود اما آنلاین نمی‌شود، معمولاً اتصال کنترلی خود را در reverse proxy از دست داده است. آن اتصال یک HTTP upgrade است که به صورت POST با هدر Upgrade: tailscale-control-protocol ارسال می‌شود و nginx آن را رد می‌کند، مگر اینکه بلوک map $http_upgrade $connection_upgrade و خطوط منطبق proxy_set_header را اضافه کنید. Caddy این درخواست را بدون نیاز به پیکربندی اضافی هدایت می‌کند، که این موضوع راهی سریع برای تست این است که آیا مشکل از proxy است یا خیر.

آیا برای headscale به نام دامنه و TLS نیاز دارم؟

در عمل، بله. کلاینت‌ها به هر رشته‌ای که در server_url قرار دهید متصل می‌شوند، گواهی‌ها برای نام‌ها صادر می‌شوند نه برای آدرس‌های IP خام، و فایل پیکربندی نیز تصریح می‌کند که DERP به TLS نیاز دارد. داشتن یک دامنه به همراه Caddy حدود پنج دقیقه زمان می‌برد و یک endpoint با HTTPS به شما می‌دهد که به‌طور خودکار تمدید می‌شود. اجرای سرور کنترل روی HTTP ساده به این معنی است که تمام مکالمات کلاینت با آن، به صورت متن آشکار (clear text) از اینترنت عبور می‌کند.