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

הקמת שרת Headscale עצמאי לניהול רשת Tailscale

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

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. לכן הבחירה תלויה באופן שבו אתם מנסחים כללי גישה ובאופן שבו ממסרים פועלים. לפני התקנת אחד מהם, כדאי להשוות בין NetBird ל־Tailscale בנקודות אלה. להשוואה רחבה יותר בין שני המודלים, ראו כיצד 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 0.29.6 דורשת גרסת לקוח Tailscale 1.80.0 או חדשה יותר.

התקנת headscale מחבילת .deb רשמית

הפרויקט מפרסם חבילות .deb בדף ה-releases ב-GitHub. נכון ל-27 באוקטובר 2026, הגרסה היציבה האחרונה היא 0.29.6, שפורסמה ב-24 באוקטובר 2026. בדקו תחילה את הארכיטקטורה שלכם, כיוון שהיא מצוינת בשם הקובץ.

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

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

HEADSCALE_VERSION="0.29.6"
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. עם זאת, בהתקנה חדשה החבילה אינה מאפשרת (enable) את היחידה, כך שהשירות לא יעלה לאחר אתחול עד שתאפשרו אותו, כפי שמתבצע בשלב ההפעלה מחדש להלן. השירות רץ גם עם התצורה המגיעה כברירת מחדל, המפנה את 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 בעת יצירת כתובות URL לרישום. לקוחות משתמשים בכתובת הבקרה המוגדרת ב---login-server, לכן השתמשו באותו שם ציבורי עם https:// בשני המקומות, ולעולם לא ב-127.0.0.1. התיעוד של headscale מציין כי שימוש ב-HTTP רגיל, או ב-HTTPS בפורט שאינו 443, הוא אפשרי, אך הוא ממליץ בחום על HTTPS בפורט 443 עבור סביבת ייצור, וזהו מצב העבודה המונח ביסוד מדריך זה.

listen_addr הוא המקום שבו התהליך מאזין. השאירו הגדרה זו על 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 enable headscale
sudo systemctl is-active headscale
sudo systemctl is-enabled headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/health

is-active מדפיס active, is-enabled מדפיס enabled, והפקודה curl מדפיסה 200. ההפעלה מחדש היא השלב שבו נטענים העידכונים שלך. Headscale קורא את התצורה שלו פעם אחת, בעת העלייה, לכן התהליך שהחבילה הפעילה ממשיך להשתמש ב-server_url שהגיע עם התוכנה עד שתבצע הפעלה מחדש. sudo systemctl enable --now headscale לא מבצע את הפעולה הזו: השירות כבר רץ, לכן --now start לא משנה דבר והערך הישן נשאר פעיל. הפעלה בעת העלייה היא התפקיד של enable, וזה לא מבוצע עבורך: בהתקנה חדשה החבילה מפעילה את השירות מבלי להפעיל אותו אוטומטית, לכן הרץ את sudo systemctl enable headscale פעם אחת, כפי שצוין לעיל.

אם is-active מדפיס משהו שאינו active, או אם curl לא מדפיס 200, קרא את ה-journal באמצעות sudo journalctl -u headscale -n 50 --no-pager. כשל בשלב זה נובע כמעט תמיד מקובץ התצורה, כיוון ש-headscale מנתח את הקובץ במלואו לפני פתיחת ה-socket; לכן, הזחה שגויה או הגדרה לא תקינה שנדרשת עוצרים את התהליך לפני שכל פורט הופך לזמין להאזנה. תקן את הקובץ, ולאחר מכן 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 חייבת להעביר את ה-headers‏ Upgrade ו-Connection במפורש. התיעוד של headscale מבצע זאת באמצעות מפת שדרוג (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 והכל נראה תקין, בעוד שחיבור הבקרה לעולם אינו נוצר: צמתים חדשים אינם יכולים להירשם, וצמתים קיימים אינם יכולים להתחבר מחדש ולדווח על מצב מקוון. אם בחרתם בנתיב של 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 מעביר את כל חיבורי הבקרה של הלקוחות אל headscale. אם תפעילו בהמשך את ה-DERP relay המובנה, הוא יזדקק גם ל-3478/udp, כפי שמפורט בהמשך. פורט 80 משמש עבור אתגר ה-HTTP של ACME (ניהול תעודות אוטומטי) ועבור הפניה ל-HTTPS. ‏Caddy יכול להנפיק תעודה גם כשפורט 80 סגור, באמצעות אתגר TLS-ALPN בפורט 443, אך כאשר פורט 80 פתוח שני האתגרים זמינים ובקשות http:// רגילות מופנות ליעדן.

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

השתמשו בכתובת ה-HTTPS הציבורית מתוך server_url עבור --login-server. הלקוח מסיר לוכסנים (slashes) בסוף ה-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

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

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

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

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

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

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

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

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

כתובת הבקרה הציבורית השתנתה. צמתים ממשיכים לנסות להתחבר לכתובת שהוגדרה עם --login-server; שינוי של 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 בלקוח. בדקו גם את ה-journal של הלקוח: בקשה שמגיעה ל-headscale לא בהכרח תייצר שורה ברמת ה-log המוגדרת כברירת מחדל, לכן שתיקה בלוג של השרת אינה מוכיחה בהכרח כשל ב-DNS, ב-firewall או ב-proxy.

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

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

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

מפתחות צומת (Node keys) הם החלק בעל אורך החיים הארוך. המקטע node בתוך config.yaml מגדיר את expiry: 0, כאשר 0 משמעותו שאין פקיעת תוקף כברירת מחדל; עם זאת, פקיעת תוקף מפורשת מצד הלקוח או פקיעת תוקף מסוג OIDC עדיין עשויות לחול. צמתים מתויגים (Tagged nodes) פטורים מפקיעת תוקף אוטומטית, אם כי מנהל מערכת יכול להורות על פקיעת תוקפם באופן ידני. הגדירו את expiry: 180d אם ברצונכם לקבוע ברירת מחדל של 180 ימים עבור רישומים שאינם מתויגים, אך פקיעת תוקף שנתבקשה על ידי הלקוח מקבלת עדיפות, ו־OIDC יכול לדרוס את ברירת המחדל. שינוי הגדרה זו אינו משנה רטרואקטיבית רישומים קיימים. צומת עם תאריך פקיעה דורש אימות מחדש לפני המועד האחרון, באמצעות 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

העבירו את שני הקבצים מחוץ לשרת. הם מכילים את מפתחות ה-private keys ואת כל הרישומים, לכן הם דורשים את אותה רמת הגנה כמו השרת עצמו. המדריך גיבויי restic משרת VPS מסביר כיצד לבצע זאת באופן מתוזמן ומוצפן.

שדרוגים חוזרים על תהליך ההתקנה: הורידו את .deb ו-sudo apt install ./headscale.deb החדשים, לאחר מכן בצעו הפעלה מחדש והריצו שוב את בדיקות is-active ו-/health. מאז גרסה 0.29 נתיב השדרוג הוא קשיח. דילוג על גרסה משנית (minor version) חסום, וכך גם שדרוג לאחור לגרסה משנית ישנה יותר. עברו גרסה משנית אחת בכל פעם, בצעו גיבוי לפני כל שלב, וקראו תחילה את הערות השחרור (release notes) של אותה גרסה, כיוון שאותו שחרור שינה את התנהגות מדיניות ה-ACL והעביר מספר מפתחות תצורה. גרסה 0.29.6 כוללת גם עדכוני אבטחה לאימות תעודות ולתלויות (dependencies), לכן התקנות 0.29 קיימות צריכות להחיל את עדכון ה-patch הזה.

FAQ

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

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

האם עליי להתקין את לקוח 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 מפיל אותו אלא אם כן אתם מעבירים את ה-headers ‏Upgrade ו-Connection במפורש עם proxy_set_header, מה שהתצורה לעיל מבצעת דרך בלוק ה-map $http_upgrade $connection_upgrade שלה. השמטת ה-headers הללו גם מונעת מצמתים חדשים להירשם. Caddy מעביר אותם ללא תצורה נוספת, מה שהופך אותו לדרך מהירה לבדוק אם ה-proxy הוא מקור התקלה.

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

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

האם המאמר הזה היה מועיל?