SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-09-28

הקמת שרת Headscale עצמאי: מדריך מלא

למדו איך להריץ שרת בקרה ל-Tailscale על גבי VPS. המדריך מפרט התקנת חבילת .deb, הגדרת server_url, הפעלה מחדש וחיבור הצומת הראשון לרשת הפרטית שלכם ללא תלות בשירותים חיצוניים.

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

מהו Headscale

Headscale הוא מימוש בניהול עצמי של שרת הבקרה של Tailscale, כך שהמכונה שמתאמת את הרשת הפרטית שלכם היא שרת VPS שבבעלותכם. זהו פרויקט קהילתי שאינו מופעל על ידי Tailscale Inc. כל מכונה עדיין מריצה את הלקוח הרשמי של tailscale, המופנה לשרת שלכם באמצעות דגל אחד, --login-server.

שרת הבקרה הוא הרכיב שיודע מי שייך לרשת. הוא מקצה לכל צומת כתובת מתוך 100.64.0.0/10, מפיץ מפתחות ציבוריים, ומנחה את הצמתים היכן למצוא זה את זה. המנהרות נשארות מנהרות WireGuard, שנבנות מצומת לצומת. תעבורה בין שתי מכונות שלכם אינה עוברת דרך השרת של Headscale, אלא אם לא ניתן ליצור נתיב ישיר והצמתים נאלצים להשתמש בממסר (relay). הרצת תפקיד התיאום בעצמכם משנה את זהות הגורם שמחזיק בו ולא את היכולות שלו, לכן כדאי להבין מה שרת בקרה יכול ומה הוא לא יכול להשיג במודל זה לפני שמתייחסים למעבר כאל הישג אבטחה כשלעצמו.

Headscale משרת tailnet אחד (רשת Tailscale אחת) לכל מופע, מה שהפרויקט מגדיר כמתאים לשימוש אישי או לארגון קטן. עם שלוש או ארבע מכונות, VPN מבוסס WireGuard פשוט על VPS שבבעלותכם דורש הרצת פחות תוכנה ופחות רכיבים שעלולים להתקלקל. Headscale משתלם כאשר אינכם רוצים לכתוב בלוק [Peer] ידנית עבור כל מחשב נייד חדש. עלות היא לעיתים קרובות הגורם שמניע אנשים לחפש פתרון מלכתחילה, לכן כדאי לקרוא מה התוכנית החינמית המנוהלת באמת כוללת לפני שאתם מקימים שרת, שכן מספר מכונות אישיות בדרך כלל נכנסות למסגרת זו. אם כבר עברתם את התקרה הזו, בצעו את החישוב מול עלות התוכניות בתשלום, שהיא לפי משתמש ולא לפי מכשיר, כיוון שמשק בית בחשבון אחד יכול להישאר זול זמן רב לאחר שמספר המכשירים מפסיק להיות רלוונטי. אם אתם מעוניינים במישור בקרה בניהול עצמי אך מעדיפים לקוח משלכם וממשק אינטרנטי לניהול עמיתים במקום תחליף ישיר ל-Tailscale, NetBird על גבי VPS יחיד היא החלופה שכדאי לשקול. להשוואה רחבה יותר בין שני המודלים, ראו במה שונים 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 בדף ה-releases ב-GitHub. נכון ליולי 2026, הגרסה העדכנית היא 0.29.3. בדקו תחילה את הארכיטקטורה שלכם, כיוון שהיא מופיעה בשם הקובץ.

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

פקודה זו מדפיסה amd64 בשרת VPS רגיל מבוסס x86, ו-arm64 בשרתים מסוג Ampere או Graviton. הציבו את התוצאה במשתנה להלן.

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, ולאחר מכן מפעילה את השירות. לכן, headscale כבר רץ ברגע ש-apt מסיים את פעולתו, ו-sudo systemctl is-active headscale מדפיס active. עם זאת, הוא רץ עם תצורת ברירת המחדל, המצביעה את server_url על http://127.0.0.1:8080, כתובת שאף לקוח שלכם אינו יכול להגיע אליה. דבר עדיין אינו חשוף, כיוון ש-listen_addr המוגדר כברירת מחדל מאזין גם הוא ל-loopback בלבד, אך אל תצרפו אף לקוח לפני שתגדירו את server_url ותפעילו מחדש את השירות, כפי שמתואר בשני השלבים הבאים.

הגדרת 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 הוא המקום שבו התהליך מאזין (bind). השאירו אותו על loopback. שרת reverse proxy על אותו שרת יבצע TLS termination ויעביר את התעבורה אליו, כך שאין צורך ששום גורם מחוץ לשרת יגיע לפורט 8080.

base_domain הוא הסיומת של MagicDNS, המתחם שתחתיו יקבלו הצמתים שלכם שמות. עליו להיות שם מתחם מלא (FQDN) ללא נקודה בסופו, ועליו להיות מתחם שונה מזה שב-server_url, שכן אחרת מרחבי השמות יתנגשו.

השאירו את סעיף מסד הנתונים ללא שינוי. ברירת המחדל היא SQLite ב-/var/lib/headscale/db.sqlite, בתוך תיקייה שהחבילה יצרה ושנמצאת בבעלותה; SQLite מספיק עבור tailnet בגודל זה.

הפעלה מחדש של headscale ואימות פעולתו

sudo systemctl restart 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. ההפעלה מחדש היא השלב שבו נטענים השינויים שביצעת. headscale קורא את קובץ התצורה שלו פעם אחת בלבד, בעת העלייה, לכן התהליך שהותחל על ידי החבילה ממשיך להשתמש בערכים המקוריים (shipped) של server_url עד לביצוע הפעלה מחדש. הפקודה sudo systemctl enable --now headscale אינה מבצעת פעולה זו: החבילה כבר הגדירה והפעילה את השירות, לכן פקודה זו אינה משנה דבר והערך הישן נותר פעיל. העלייה בעת האתחול כבר מוגדרת, והפקודה sudo systemctl is-enabled headscale מדפיסה enabled כדי לאשר זאת.

אם is-active מדפיסה משהו שאינו active, או אם curl אינה מדפיסה 200, יש לקרוא את הלוגים באמצעות sudo journalctl -u headscale -n 50 --no-pager. כשל בשלב זה נובע כמעט תמיד מקובץ התצורה, שכן headscale מנתח את הקובץ במלואו לפני פתיחת ה-socket; לכן, הזחה (indent) שגויה או מפתח לא מוכר עוצרים את התהליך לפני שהשירות מתחיל להאזין. יש לתקן את הקובץ ולאחר מכן להריץ sudo systemctl restart headscale. כל שינוי תצורה עתידי יחייב הפעלה מחדש דומה. הלקוחות יתחברו מחדש באופן עצמאי לאחר מכן. אם יחידות systemd אינן מוכרות לך, המדריך הרצת שירותים וטיימרים עצמאיים עם systemd מכסה את הפקודות ששימשו כאן.

בדוק את קובצי המצב בזמן שאתה ב-shell:

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

שתי השורות מתחילות ב-headscale, המשתמש ללא הרשאות מיוחדות שנוצר על ידי החבילה. noise_private.key הוא הזהות של השרת מול הלקוחות שלו. שמור עליו. אם תמחק אותו, headscale ייצור זהות חדשה וכל צומת יצטרך לבצע רישום מחדש.

הצבת TLS לפני headscale

על לקוחות להגיע אל server_url באמצעות HTTPS. השימוש ב-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 כאשר הקובץ עובר ניתוח (parse) בהצלחה. אזהרה על כך שהקובץ אינו מעוצב היא קוסמטית בלבד. מהמחשב הנייד שלכם, curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health אמור גם הוא להדפיס 200. בדיקה יחידה זו מוכיחה ש-DNS, ה-firewall, התעודה וה-proxy פועלים יחד כנדרש.

להלן פרט ה-proxy שגורם לאנשים לאבד ערב שלם. חיבור הבקרה של Tailscale הוא מסוג HTTP upgrade, הוא מתחיל ב-POST ולא ב-GET, והערך של ה-header מסוג Upgrade הוא tailscale-control-protocol. Caddy מעביר זאת ללא הגדרה נוספת. nginx אינו עושה זאת, לכן חזית (front end) של nginx זקוקה ל-upgrade 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 והכל נראה תקין, בעוד חיבור הבקרה ארוך-הטווח לעולם אינו נוצר והצמתים שלכם נרשמים אך נשארים במצב offline. אם בחרתם בנתיב של 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 challenge של ACME (סביבת ניהול תעודות אוטומטית) ועבור הפניה ל-HTTPS; שירות Caddy זקוק לו כדי להנפיק תעודה מלכתחילה.

פורט 8080 נשאר סגור. listen_addr הוא 127.0.0.1:8080, לכן ה-proxy ניגש ל-headscale דרך ממשק ה-loopback ולא נדרש כל חוק firewall. פתיחת פורט 8080 לאינטרנט חושפת את ערוץ הבקרה בטקסט גלוי ואינה מועילה בדבר. זכרו שרוב ספקי הענן מפעילים firewall נוסף בלוח הבקרה שלהם, בנפרד מ-UFW, כך שפורט יכול להיות פתוח בשרת אך עדיין חסום בקצה הרשת. המדריך יסודות ה-firewall של UFW ב-VPS מפרט את תחביר החוקים.

יצירת משתמש ומפתח preauth

sudo headscale users create alice
sudo headscale users list

הפקודה headscale היא לקוח. היא מתקשרת עם ה-daemon הפעיל דרך ה-unix socket בנתיב /var/run/headscale/headscale.sock, אשר מוגדר במצב 0770 ושייך לקבוצה headscale. מכך נובעים שני דברים. הפקודה נכשלת כאשר השירות אינו פעיל, וזו הסיבה הנוספת לכך שסדר הפעולות במדריך זה חשוב; כמו כן, נדרשות הרשאות sudo אלא אם תוסיפו את חשבונכם לקבוצה headscale.

הפקודה users list מדפיסה מזהה (ID) לצד כל שם. עליכם להשתמש במספר זה, כיוון שפקודת המפתח מקבלת מזהה משתמש מספרי ולא שם.

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

המפתח מודפס פעם אחת בלבד. העתיקו אותו כעת. מפתח preauth הוא לשימוש חד-פעמי ותקף לשעה אחת אלא אם צוין אחרת, לכן כדאי להגדיר --expiration 24h כל עוד אתם בשלב הבדיקות. הוסיפו את הדגל --reusable עבור מפתח המיועד לרישום מספר מכונות, והתייחסו אליו כאל סיסמה, שכן כל מי שמחזיק בו יכול להצטרף לרשת שלכם.

חיבור הלקוח הראשון באמצעות --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 מציג את הצומת עם ה-ID שלו, המשתמש שלו ומצבו המקוון.

הערך של --login-server חייב להתאים בדיוק ל-server_url, כולל הסכימה וללא לוכסן (slash) בסוף. הערכים מושווים כמחרוזות, ואי-התאמה משמעותה שהלקוח נרשם מול כתובת אחת ואז מתבקש לתקשר עם כתובת אחרת.

מכונה שהייתה מחוברת בעבר לשירות המנוהל של 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 עדיפים לכל תהליך מתוסרט, כיוון שאין צורך בנוכחות אדם. ברגע שה-VPS עצמו הוא צומת, הוא יכול גם להעביר את תעבורת האינטרנט של המכונות האחרות שלכם, וזהו הגדרת צומת יציאה (exit node), עם ההבדל היחיד שאתם מאשרים את הנתיב המפורסם בשרת באמצעות הפקודה headscale במקום בקונסולת ניהול מנוהלת. אם מה שאתם רוצים הוא גישה לרשת פרטית שנמצאת מאחורי ה-VPS ולא דרך יציאה לאינטרנט, אותו שלב אישור מכסה את פרסום רשת המשנה (subnet) הזו לשאר ה-tailnet שלכם. פרסום יישום בודד מצומת, במקום ניתוב רשתות שלמות דרכו, הוא משימה שונה, ו-serve ו-funnel הן שתי הדרכים לעשות זאת, אם כי שתיהן נשענות על מנגנון התעודות וה-ingress של Tailscale עצמה, לכן התייחסו אליהן כאל תכונות של tailnet מנוהל ולא כמשהו ש-headscale מספקת לכם.

DERP, ומה מעביר תעבורה כאשר נתיב ישיר נכשל

DERP (ר"ת של designated encrypted relay for packets) הוא נתיב הגיבוי. כאשר שני צמתים אינם מצליחים לפתוח חיבור WireGuard ישיר, בדרך כלל משום ששניהם נמצאים מאחורי NAT (תרגום כתובות רשת) מחמיר, הם שולחים חבילות מידע דרך ממסר (relay). הממסר אינו מחזיק במפתחות, ולכן אין באפשרותו לקרוא את התעבורה שלכם. הוא אמנם רואה אילו צמתים מתקשרים וכמה נתונים עוברים ביניהם.

חשוב להבין מה עושה תצורת ברירת המחדל. Headscale מופץ כשהוא מצביע על https://controlplane.tailscale.com/derpmap/default עם auto_update_enabled: true ו-update_frequency: 3h, כך שמישור הבקרה (control plane) הוא שלכם, בעוד שהממסרים הם של Tailscale. עבור רוב האנשים זו פשרה הוגנת. אם זה לא מתאים לכם, הריצו ממסר משלכם.

כדי להריץ ממסר משלכם, הגדירו את enabled: true תחת derp.server בקובץ config.yaml, בצעו restart ל-headscale, ופתחו את פורט ה-STUN (session traversal utilities for NAT) באמצעות sudo ufw allow 3478/udp. קובץ התצורה מצהיר על הדרישה בבירור: ה-server_url חייב להשתמש ב-https, כיוון ש-DERP דורש TLS. ריקון רשימת ה-derp.urls מסיר את הממסרים של Tailscale מהמפה, ואם תעשו זאת ללא ממסר מוטמע תקין, כל זוג צמתים שאינו יכול להתחבר ישירות לא יוכל להתחבר כלל.

מהצד של הלקוח, הפקודה tailscale netcheck מדפיסה את השיהוי (latency) לכל אזור ממסר מוכר, ו-tailscale status מסמנת כל עמית (peer) כ-direct עם כתובת או כ-relay עם קוד אזור. עמית שתקוע על relay סובל מבעיית NAT, לא מבעיה ב-headscale. עמית שמוגדר כ-direct ועדיין איטי הוא שאלה אחרת, ו-התשובה המקובלת שם היא MTU ולא המנהרה עצמה.

מדוע צומת (node) מופיע כלא מקוון (offline)?

ה־proxy חוסם את ה־upgrade. זוהי הסיבה הנפוצה ביותר, והסימן המזהה שלה הוא שכל שאר הרכיבים נראים תקינים: /health מחזיר 200, headscale nodes list מציג את הצומת, אך הצומת לעולם אינו הופך למקוון. חיבור הבקרה הוא בקשת POST הנושאת Upgrade: tailscale-control-protocol, ו־proxy שאינו מעביר אותה קוטע את הערוץ היחיד שמדווח על מצב הצומת. השוו את תצורת ה־nginx שלכם מול בלוק ה-map שלעיל, או עברו ל-Caddy כדי לשלול בעיות ב-proxy.

הערך 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. לקוח שאינו מצליח לבצע resolution או להגיע לדומיין שלכם יתעד שם את הניסיונות החוזרים שלו.

המפתח פג תוקף. נושא זה מכוסה בסעיף הבא.

כדי לנטר את צד השרת בזמן הבדיקה, הריצו sudo journalctl -u headscale -f על ה-VPS והפעילו מחדש את tailscaled בלקוח. צומת שמגיע ל-headscale מייצר שורות לוג באופן מיידי. שתיקה מעידה על כך שהבקשה אינה מגיעה, לכן בדקו את ה-DNS, ה-firewall וה-proxy לפני שתבדקו את headscale.

תפוגת מפתח, והצומת שמפסיק לעבוד שבועות לאחר מכן

קיימים שני סוגי תפוגה נפרדים, וערבוב ביניהם גוזל זמן יקר.

מפתחות Preauth פגים במהירות מעצם תכנונם. ברירת המחדל היא שעה אחת ושימוש אחד. אם tailscale up מסרב לקבל את המפתח, צרו מפתח חדש בשרת במקום לערוך הגדרות כלשהן בצד הלקוח.

מפתחות צומת (Node keys) הם החלק בעל אורך החיים הארוך. סעיף node בתוך config.yaml מגדיר את expiry: 0, והערך 0 משמעותו שאין תפוגת ברירת מחדל: צומת רשום נשאר תקף עד שתפוגיגו אותו ידנית. צמתים מתויגים (Tagged nodes) לעולם אינם פגים. הגדירו את expiry: 180d אם ברצונכם שרישומים יפוגו עם הזמן, אך הבינו את המשמעות: כל צומת שאינו מתויג יזדקק ל-sudo tailscale up --login-server https://headscale.example.com --force-reauth לפי לוח זמנים זה, ושרת ללא ממשק (headless) שאף אחד לא מבצע בו אימות מחדש ינותק מהרשת באופן אוטומטי.

בצעו זאת ידנית כאשר מישהו מאבד מחשב נייד. הפקודה sudo headscale nodes list תציג לכם את ה-ID, לאחר מכן 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, נתיב השדרוג הוא קשיח. דילוג על גרסה משנית (minor version) חסום, וכך גם שדרוג לאחור לגרסה משנית ישנה יותר. עברו גרסה משנית אחת בכל פעם, בצעו גיבוי לפני כל שלב, וקראו תחילה את הערות השחרור של אותה גרסה, כיוון שאותו שחרור שינה את התנהגות מדיניות ה-ACL והעביר מספר מפתחות תצורה.

FAQ

האם headscale רץ מיד לאחר התקנת חבילת ה-.deb?

כן. החבילה מפעילה את השירות מיד עם סיום ההתקנה, תוך שימוש ב-/etc/headscale/config.yaml המוגדר כברירת מחדל, המאזין ל-loopback בלבד ומגדיר את server_url ל-http://127.0.0.1:8080. כתובת זו אינה שימושית ללקוחות, לכן יש לערוך את server_url, listen_addr ו-base_domain, ולאחר מכן להריץ את sudo systemctl restart headscale ולאשר עם sudo systemctl is-active headscale. חובה לבצע restart: headscale קורא את הקובץ רק בעת העלייה, ו-enable --now על שירות שכבר רץ לא משנה דבר. אם השירות נכשל לאחר האתחול, sudo journalctl -u headscale -n 50 --no-pager יציג את מקור הבעיה; בשלב זה מדובר כמעט תמיד בשגיאת YAML, כיוון ש-headscale מנתח את כל הקובץ לפני שהוא מבצע bind לפורט.

האם עליי להתקין את לקוח Tailscale הרגיל על המכונות שלי?

כן. Headscale מחליף רק את שרת הבקרה. כל צומת מריץ את הלקוח הרשמי של Tailscale, ואתה מפנה אותו לשרת שלך באמצעות sudo tailscale up --login-server https://headscale.example.com. דגל זה קיים בלקוח הסטנדרטי, כך שאין צורך בביצוע patch או בבנייה מחדש.

האם התעבורה שלי עוברת דרך שרת ה-headscale?

בדרך כלל לא. Headscale מתאם את הרשת ומחלק מפתחות וכתובות, בעוד נתיב הנתונים הוא WireGuard ישיר בין הצמתים שלך. התעבורה מבצעת מעקף רק כאשר שני צמתים אינם יכולים להגיע זה לזה ישירות ועוברים להשתמש ב-DERP relay; בתצורה שמגיעה עם התוכנה, אלו הם השרתים הציבוריים של Tailscale. הרץ tailscale status על צומת כדי לראות אם עמית מסוים הוא direct או נמצא על relay.

מדוע הצומת שלי נשאר במצב offline לאחר הרישום?

צומת שמופיע ב-headscale nodes list אך לעולם לא עובר למצב online, בדרך כלל איבד את חיבור הבקרה שלו ב-reverse proxy. חיבור זה הוא HTTP upgrade שנשלח כ-POST עם ה-header Upgrade: tailscale-control-protocol, ו-nginx מפיל אותו אלא אם כן תוסיף את בלוק ה-map $http_upgrade $connection_upgrade ואת שורות ה-proxy_set_header התואמות. Caddy מעביר אותו ללא צורך בתצורה נוספת, מה שהופך אותו לדרך מהירה לבדוק אם ה-proxy הוא מקור התקלה.

האם אני זקוק לשם מתחם ול-TLS עבור headscale?

בפועל, כן. לקוחות מתחברים לכל מחרוזת שתגדיר ב-server_url, תעודות מונפקות עבור שמות ולא עבור כתובות IP חשופות, וקובץ התצורה מציין ש-DERP מחייב TLS. שם מתחם יחד עם Caddy דורשים כחמש דקות עבודה ומספקים לך נקודת קצה ב-HTTPS שמתחדשת מעצמה. הרצת שרת הבקרה על גבי HTTP רגיל משמעותה שכל תקשורת של לקוח מולו עוברת באינטרנט בטקסט גלוי.