SSD Nodes Learn 8GB RAM — سالی $66
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-01

Headscale: ساخت کنترل‌سرور شخصی برای Tailscale

کنترل‌سرور Tailscale را روی VPS خود اجرا کنید: Headscale را از فایل رسمی .deb نصب کنید، مقدار server_url را پیش از اجرا تنظیم کنید و نخستین node را متصل کنید.

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 را اجرا می‌کند و با استفاده از یک flag، یعنی --login-server، به سرور شما متصل می‌شود.

سرور کنترل بخشی است که می‌داند چه دستگاه‌هایی عضو شبکه هستند. این سرور به هر node یک آدرس از بازه 100.64.0.0/10 اختصاص می‌دهد، کلیدهای عمومی را توزیع می‌کند و به nodeها می‌گوید یکدیگر را از کجا پیدا کنند. تونل‌ها همچنان WireGuard هستند و به‌صورت node-to-node ساخته می‌شوند. ترافیک بین دو ماشین شما از headscale عبور نمی‌کند، مگر اینکه ایجاد مسیر مستقیم ممکن نباشد و nodeها به relay بازگردند.

هر نمونه Headscale یک tailnet، یعنی یک شبکه Tailscale، ارائه می‌کند. این پروژه استفاده از آن را برای استفاده شخصی یا یک سازمان کوچک مناسب می‌داند. اگر سه یا چهار ماشین دارید، یک VPN ساده WireGuard روی VPS متعلق به شما نرم‌افزار کمتری برای اجرا و موارد کمتری برای خرابی دارد. زمانی استفاده از Headscale مزیت پیدا می‌کند که دیگر نخواهید برای هر لپ‌تاپ جدید، یک بلوک [Peer] را به‌صورت دستی بنویسید. برای مقایسه گسترده‌تر این دو مدل، به تفاوت WireGuard و Tailscale مراجعه کنید.

موارد موردنیاز پیش از نصب

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

نصب headscale از بسته رسمی .deb

پروژه بسته‌های .deb را در صفحه انتشارهای GitHub منتشر می‌کند. در July 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 می‌نویسد و یک واحد 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 در هر ثبت کلاینت می‌نویسد. کلاینت‌ها پس از آن همیشه دقیقاً به همان رشته متصل می‌شوند؛ بنابراین این مقدار باید نام عمومی همراه با https:// در ابتدا باشد و هرگز 127.0.0.1 نباشد.

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

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

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

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 هر دو بخش را انجام می‌دهد: سرویس را راه‌اندازی می‌کند و آن را برای اجرا پس از راه‌اندازی مجدد علامت‌گذاری می‌کند.

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

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

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

هر دو خط با headscale شروع می‌شوند؛ این همان کاربر غیرممتازی است که package ایجاد کرده است. noise_private.key هویت سرور برای کلاینت‌های آن است. آن را نگه دارید. اگر آن را حذف کنید، headscale یک هویت جدید تولید می‌کند و هر node باید دوباره register شود.

قرار دادن 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 مربوط به upgrade نیاز دارد:

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 را برمی‌گرداند و همه‌چیز درست به نظر می‌رسد، اما اتصال کنترلی بلندمدت هرگز برقرار نمی‌شود و نودهای شما ابتدا register می‌شوند و سپس آفلاین باقی می‌مانند. اگر مسیر 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 (محیط مدیریت خودکار گواهی) و انتقال به HTTPS استفاده می‌شود و Caddy برای دریافت گواهی به آن نیاز دارد.

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

ایجاد کاربر و کلید preauth

sudo headscale users create alice
sudo headscale users list

دستور headscale یک client است. این دستور از طریق unix socket موجود در /var/run/headscale/headscale.sock با daemon در حال اجرا ارتباط برقرار می‌کند. این socket دارای mode برابر با 0770 است و مالکیت آن به گروه headscale تعلق دارد. در نتیجه، دو نکته وجود دارد. اگر service متوقف باشد، دستور اجرا نمی‌شود. این مورد دلیل دیگری است که ترتیب مراحل در این راهنما اهمیت دارد. همچنین باید sudo داشته باشید، مگر اینکه حساب کاربری خود را به گروه headscale اضافه کنید.

users list در کنار هر نام، یک ID چاپ می‌کند. به این عدد نیاز دارید، زیرا دستور key یک user ID عددی می‌پذیرد، نه نام کاربر.

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

کلید فقط یک‌بار چاپ می‌شود. آن را همین حالا کپی کنید. یک preauth key یک‌بارمصرف است و به‌مدت یک ساعت اعتبار دارد، مگر اینکه خلاف آن را مشخص کنید. بنابراین، تنظیم --expiration 24h در زمان آزمایش همچنان ارزشمند است. برای کلیدی که چندین ماشین را enroll می‌کند، --reusable را اضافه کنید. با چنین کلیدی مانند password رفتار کنید، زیرا هر فردی که آن را در اختیار داشته باشد می‌تواند به شبکه شما بپیوندد.

اتصال نخستین کاربر با --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 یکسان باشد؛ طرح نشانی نیز باید شامل آن باشد و نباید اسلش انتهایی وجود داشته باشد. این مقادیر به‌صورت رشته‌ای مقایسه می‌شوند. ناهماهنگی باعث می‌شود کاربر ابتدا در برابر یک نشانی ثبت شود و سپس از آن خواسته شود با نشانی دیگری ارتباط برقرار کند.

دستگاهی که پیش‌تر در سرویس میزبانی‌شده 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

این روش برای لپ‌تاپ شخصی شما مناسب‌تر است. برای هر چیزی که به‌صورت اسکریپتی اجرا می‌شود، کلیدهای پیش‌احراز بهتر هستند؛ زیرا نیازی نیست انسانی در حال نظارت باشد.

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

DERP (رله رمزگذاری‌شده مشخص‌شده برای بسته‌ها) مسیر جایگزین است. وقتی دو گره نمی‌توانند یک اتصال مستقیم 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 را restart کنید و پورت STUN (ابزارهای پیمایش نشست برای NAT) را با sudo ufw allow 3478/udp باز کنید. فایل پیکربندی این الزام را صریح بیان می‌کند: server_url باید از https استفاده کند، زیرا DERP به TLS نیاز دارد. خالی‌کردن فهرست derp.urls، رله‌های Tailscale را از نقشه حذف می‌کند. اگر این کار را بدون یک رله embedded فعال انجام دهید، هر جفت گرهی که نتواند مستقیماً متصل شود، اصلاً نمی‌تواند متصل شود.

از سمت یک client، tailscale netcheck تأخیر هر ناحیه رله‌ای را که می‌شناسد نمایش می‌دهد و tailscale status هر peer را با یکی از دو وضعیت علامت‌گذاری می‌کند: direct همراه با یک نشانی، یا relay همراه با یک کد ناحیه. اگر یک peer روی relay باقی بماند، مشکل از NAT است، نه از headscale.

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

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

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

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

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

برای مشاهده سمت server هنگام آزمایش، روی VPS دستور sudo journalctl -u headscale -f را اجرا کنید و در client، tailscaled را restart کنید. nodeای که به headscale دسترسی پیدا کند، بلافاصله log تولید می‌کند. سکوت به این معناست که request به مقصد نمی‌رسد؛ بنابراین پیش از بررسی headscale، DNS، firewall و proxy را بررسی کنید.

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

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

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

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

وقتی کسی لپ‌تاپ خود را گم می‌کند، این کار را به‌صورت دستی انجام دهید. sudo headscale nodes list شناسه را نمایش می‌دهد، سپس sudo headscale nodes expire -i 3 آن نود را از سیستم خارج می‌کند و 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، مسیر ارتقا سخت‌گیرانه است. ردکردن یک نسخه فرعی مسدود است و بازگشت به نسخه فرعی قدیمی‌تر نیز مجاز نیست. هر بار فقط یک نسخه فرعی ارتقا دهید، پیش از هر مرحله پشتیبان بگیرید و ابتدا یادداشت‌های انتشار همان نسخه را بخوانید؛ زیرا همان انتشار رفتار خط‌مشی ACL را تغییر داده و چند کلید پیکربندی را جابه‌جا کرده است.

FAQ

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

این بسته unit را نصب می‌کند، اما سرویس را متوقف باقی می‌گذارد و مقدار پیش‌فرض /etc/headscale/config.yaml به‌جای یک پیکربندی قابل‌استفاده، یک الگو است. ابتدا 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 پیش از اتصال به یک پورت، کل فایل را تجزیه می‌کند.

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

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

آیا traffic من از headscale server عبور می‌کند؟

معمولاً خیر. Headscale شبکه را هماهنگ می‌کند و keyها و addressها را اختصاص می‌دهد، اما data path مستقیماً از طریق WireGuard بین nodeهای شما برقرار می‌شود. Traffic فقط زمانی مسیر غیرمستقیم پیدا می‌کند که دو node نتوانند مستقیماً به یکدیگر دسترسی داشته باشند و به یک DERP relay برگردند. در پیکربندی ارائه‌شده، این relayها متعلق به Tailscale و عمومی هستند. برای مشاهده وضعیت یک peer مشخص، tailscale status را روی یک node اجرا کنید تا ببینید peer در وضعیت direct قرار دارد یا روی یک relay است.

چرا node من پس از ثبت، offline باقی می‌ماند؟

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

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

در عمل، بله. Clientها به هر رشته‌ای که در server_url قرار دهید متصل می‌شوند، certificateها برای nameها صادر می‌شوند، نه برای bare IP addressها، و فایل پیکربندی تصریح می‌کند که DERP به TLS نیاز دارد. استفاده از یک domain به همراه Caddy حدود پنج دقیقه زمان می‌برد و یک HTTPS endpoint در اختیار شما قرار می‌دهد که به‌صورت خودکار renew می‌شود. اجرای control server روی HTTP معمولی باعث می‌شود تمام ارتباط هر client با آن، به‌صورت آشکار از طریق اینترنت عبور کند.

#headscale#tailscale#wireguard#vpn#self-hosting