SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

Jak zainstalować Headscale na własnym serwerze VPS

Wdrożenie własnego serwera sterującego Headscale pozwala na pełną kontrolę nad siecią typu mesh. Artykuł wyjaśnia instalację pakietu .deb oraz konfigurację parametru server_url.

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

Czym jest headscale

Headscale to samodzielnie hostowana implementacja serwera sterującego Tailscale, dzięki czemu maszyną koordynującą sieć prywatną jest posiadany przez użytkownika VPS. Jest to projekt społecznościowy, niezarządzany przez Tailscale Inc. Każda maszyna nadal korzysta z oficjalnego klienta tailscale, skierowanego na własny serwer za pomocą jednej flagi, --login-server.

Serwer sterujący to komponent, który posiada wiedzę o przynależności do sieci. Przydziela każdemu węzłowi adres z puli 100.64.0.0/10, dystrybuuje klucze publiczne i informuje węzły, gdzie mogą się nawzajem odnaleźć. Tunele pozostają oparte na WireGuard i są budowane bezpośrednio między węzłami. Ruch między dwiema maszynami nie przechodzi przez serwer headscale, chyba że nie można nawiązać bezpośredniego połączenia i węzły przełączą się na przekaźnik (relay). Samodzielne pełnienie roli koordynatora zmienia jedynie podmiot sprawujący kontrolę, a nie zakres jego możliwości, dlatego warto zrozumieć do czego serwer sterujący ma dostęp w tym modelu, zanim potraktuje się tę zmianę jako samodzielny wzrost bezpieczeństwa.

Headscale obsługuje jedną sieć tailnet (jedną sieć Tailscale) na instancję, co według twórców projektu jest rozwiązaniem odpowiednim do użytku osobistego lub dla małych organizacji. W przypadku trzech lub czterech maszyn, zwykły VPN WireGuard na własnym VPS oznacza mniej oprogramowania do utrzymania i mniejszą liczbę potencjalnych punktów awarii. Headscale zyskuje na znaczeniu, gdy użytkownik nie chce ręcznie tworzyć bloków [Peer] dla każdego nowego laptopa. Często to koszty skłaniają do poszukiwań alternatyw, dlatego warto sprawdzić co faktycznie obejmuje darmowy plan hostowany, zanim zdecydujesz się na własny serwer, ponieważ kilka urządzeń osobistych zazwyczaj mieści się w jego limitach. Jeśli przekroczyłeś już ten limit, porównaj koszty z cenami planów płatnych, które są naliczane za użytkownika, a nie za urządzenie, ponieważ gospodarstwo domowe korzystające z jednego konta może utrzymać niskie koszty długo po tym, jak liczba urządzeń przestanie mieć znaczenie. Jeśli potrzebujesz samodzielnie hostowanej płaszczyzny sterowania, ale wolisz własnego klienta i interfejs WWW do zarządzania węzłami zamiast bezpośredniego zamiennika Tailscale, NetBird na pojedynczym VPS jest alternatywą wartą rozważenia. Szersze porównanie obu modeli znajduje się w sekcji jak różnią się WireGuard i Tailscale.

Wymagania wstępne przed instalacją

  • Serwer VPS z systemem Ubuntu 24.04, publicznym adresem IPv4 oraz dostępem sudo. Jeśli serwer jest nowy, należy najpierw wykonać kroki opisane w pierwsze dziesięć minut na nowym serwerze VPS.
  • Rekord DNS typu A wskazujący na ten adres. W tym przewodniku użyto headscale.example.com.
  • Druga domena lub subdomena dla MagicDNS. W tym przewodniku użyto tailnet.example.net. Nie może to być ta sama domena, która została użyta w server_url.
  • Jedno urządzenie klienckie do połączenia, z systemem Linux, macOS, Windows, Android lub iOS.

Instalacja headscale z oficjalnego pakietu .deb

Projekt publikuje pakiety .deb na swojej stronie wydań w serwisie GitHub. Według stanu na lipiec 2026 r. aktualnym wydaniem jest 0.29.3. Najpierw należy sprawdzić architekturę systemu, ponieważ jest ona zawarta w nazwie pliku.

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

Polecenie to zwraca amd64 na standardowym serwerze VPS x86 oraz arm64 w przypadku planów typu Ampere lub Graviton. Wynik należy przypisać do poniższej zmiennej.

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

Znak ./ przed nazwą pliku jest wymagany. Bez niego apt szuka pakietu o nazwie headscale.deb w repozytoriach, co kończy się niepowodzeniem.

Pakiet tworzy użytkownika systemowego headscale, zapisuje domyślny plik /etc/headscale/config.yaml oraz instaluje jednostkę systemd. Usługa nie jest uruchamiana automatycznie, co jest prawidłowym zachowaniem. Dostarczona konfiguracja wskazuje server_url na http://127.0.0.1:8080, co nie jest adresem dostępnym dla żadnego z klientów, więc uruchomienie usługi w tym momencie byłoby błędne, nawet gdyby wystartowała. Wykonanie sudo systemctl is-active headscale na tym etapie zwraca inactive. Jest to zachowanie oczekiwane, a nie błąd.

Skonfiguruj server_url przed uruchomieniem usługi

Edytuj /etc/headscale/config.yaml za pomocą sudo nano /etc/headscale/config.yaml lub wprowadź te same trzy zmiany przy użyciu sed. Zachowaj kopię oryginału, ponieważ plik jest długi, zawiera liczne komentarze i stanowi najlepsze źródło informacji o pozostałych ustawieniach.

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 to adres, który headscale wpisuje do każdej rejestracji klienta. Klienci będą łączyć się z tym konkretnym ciągiem znaków, dlatego musi to być nazwa publiczna z prefiksem https://, a nigdy 127.0.0.1.

listen_addr to adres, na którym proces nasłuchuje. Pozostaw go na interfejsie loopback. Reverse proxy na tym samym serwerze kończy połączenie TLS (transport layer security) i przekazuje ruch dalej, więc żaden zewnętrzny host nie musi mieć dostępu do portu 8080.

base_domain to sufiks MagicDNS, czyli domena, w której węzły otrzymują swoje nazwy. Musi to być w pełni kwalifikowana nazwa domeny (FQDN) bez kropki na końcu i musi być inna niż domena w server_url, w przeciwnym razie przestrzenie nazw będą kolidować.

Sekcję bazy danych pozostaw bez zmian. Domyślnie używany jest SQLite w /var/lib/headscale/db.sqlite, w katalogu utworzonym i zarządzanym przez pakiet, co jest wystarczające dla tailnetu tej wielkości.

Uruchomienie headscale i weryfikacja działania

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 wyświetla active, a curl wyświetla 200. enable --now wykonuje obie te czynności: uruchamia usługę i oznacza ją do automatycznego startu po restarcie systemu.

Jeśli is-active wyświetla failed, należy odczytać dziennik za pomocą sudo journalctl -u headscale -n 50 --no-pager. Awaria na tym etapie niemal zawsze wynika z błędów w pliku konfiguracyjnym, ponieważ headscale analizuje cały plik przed otwarciem gniazda. Nieprawidłowe wcięcie lub nieznany klucz zatrzymują proces, zanim jakakolwiek usługa zacznie nasłuchiwać. Należy poprawić plik, a następnie wykonać sudo systemctl restart headscale. Każda późniejsza zmiana konfiguracji wymaga tego samego restartu. Klienci połączą się ponownie automatycznie. Jeśli jednostki systemd są nowym zagadnieniem, uruchamianie własnych usług i timerów za pomocą systemd zawiera opis użytych tutaj poleceń.

Podczas pracy w powłoce warto sprawdzić pliki stanu:

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

Obie linie zaczynają się od headscale, czyli użytkownika bez uprawnień administracyjnych utworzonego przez pakiet. noise_private.key to tożsamość serwera dla jego klientów. Należy ją zachować. Usunięcie tego pliku spowoduje wygenerowanie nowej tożsamości przez headscale, co wymusi ponowną rejestrację wszystkich węzłów.

Umieszczenie TLS przed headscale

Klienci muszą łączyć się z server_url przez HTTPS. Caddy jest najkrótszą drogą, ponieważ samodzielnie żąda certyfikatu i go odnawia.

sudo apt install -y caddy

Zastąp /etc/caddy/Caddyfile blokiem z dokumentacji 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 wyświetla adapted config to JSON, gdy plik zostanie poprawnie przeanalizowany. Ostrzeżenie o braku formatowania ma charakter kosmetyczny. Z poziomu laptopa polecenie curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health również powinno zwrócić 200. Ten pojedynczy test potwierdza, że DNS, firewall, certyfikat i proxy współpracują poprawnie.

Oto szczegół konfiguracji proxy, który często kosztuje użytkowników cały wieczór pracy. Połączenie kontrolne Tailscale to HTTP upgrade, inicjowane metodą POST zamiast GET, a wartość nagłówka Upgrade wynosi tailscale-control-protocol. Caddy przekazuje to bez dodatkowej konfiguracji. nginx tego nie robi, więc frontend nginx wymaga mapy 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;
    }
}

Pominięcie tych linii sprawia, że zwykłe żądania nadal kończą się powodzeniem, dlatego /health zwraca 200 i wszystko wygląda poprawnie, podczas gdy długotrwałe połączenie kontrolne nigdy nie zostaje nawiązane, a węzły rejestrują się i pozostają w trybie offline. W przypadku wyboru nginx, Certbot na Ubuntu 24.04 z nginx opisuje kwestię certyfikatów.

Które porty otworzyć w UFW

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

Port 443 obsługuje całą komunikację z klientami. Port 80 służy wyłącznie do wyzwania HTTP w ramach ACME (automatic certificate management environment) oraz do przekierowania na HTTPS; Caddy wymaga go do uzyskania certyfikatu.

Port 8080 pozostaje zamknięty. listen_addr to 127.0.0.1:8080, więc proxy łączy się z headscale przez interfejs loopback i reguła firewalla nie jest wymagana. Otwarcie portu 8080 na świat zapewnia klientom kanał sterowania przesyłany otwartym tekstem i nie przynosi żadnych korzyści. Należy pamiętać, że większość dostawców utrzymuje drugi firewall w panelu zarządzania, niezależny od UFW, więc port może być otwarty na serwerze, a mimo to zablokowany na brzegu sieci. Podstawy firewalla UFW na VPS szczegółowo omawia składnię reguł.

Utworzenie użytkownika i klucza preauth

sudo headscale users create alice
sudo headscale users list

Polecenie headscale jest klientem. Komunikuje się ono z działającym demonem poprzez gniazdo unixowe w /var/run/headscale/headscale.sock, które posiada uprawnienia 0770 i należy do grupy headscale. Wynikają z tego dwie kwestie. Polecenie kończy się niepowodzeniem, gdy usługa jest zatrzymana, co stanowi drugi powód, dla którego kolejność działań w tym przewodniku jest istotna. Wymaga ono również uprawnień sudo, chyba że dodasz własne konto do grupy headscale.

users list wyświetla identyfikator obok każdej nazwy. Ten numer jest niezbędny, ponieważ polecenie klucza wymaga numerycznego ID użytkownika, a nie nazwy.

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

Klucz jest wyświetlany tylko raz. Skopiuj go teraz. Klucz preauth jest jednorazowy i ważny przez jedną godzinę, chyba że określono inaczej, dlatego warto ustawić --expiration 24h podczas testów. Dodaj --reusable dla klucza, który rejestruje wiele maszyn i traktuj go jak hasło, ponieważ każdy, kto go posiada, może dołączyć do Twojej sieci.

Podłączanie pierwszego klienta za pomocą --login-server

Na maszynie, którą chcesz dołączyć:

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 wyświetla adres przypisany przez headscale, na przykład 100.64.0.1. Po powrocie na serwer, sudo headscale nodes list pokazuje węzeł wraz z jego identyfikatorem, użytkownikiem oraz stanem połączenia.

Wartość --login-server musi dokładnie odpowiadać server_url, wliczając w to schemat oraz brak ukośnika na końcu. Porównywane są one jako ciągi znaków, więc niezgodność oznacza, że klient rejestruje się pod jednym adresem, a następnie otrzymuje polecenie komunikacji z innym.

Maszyna, która była wcześniej zalogowana do usługi hostowanej Tailscale, zachowuje to logowanie. Uruchom na niej najpierw sudo tailscale logout, a następnie wykonaj tailscale up z flagą --login-server.

Jeśli pominiesz --auth-key, klient wyświetli adres URL. Otwórz go, a strona pokaże identyfikator tej próby rejestracji, który zatwierdzasz na serwerze:

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

Ten formularz jest wygodniejszy w przypadku własnego laptopa. Klucze preauth są lepsze dla wszelkich skryptów, ponieważ nie wymagają nadzoru użytkownika. Gdy sam VPS stanie się węzłem, może również obsługiwać ruch internetowy Twoich pozostałych maszyn, co opisano w konfiguracji węzła wyjściowego (exit node), z tą różnicą, że zatwierdzasz anonsowaną trasę na serwerze za pomocą polecenia headscale, zamiast robić to w hostowanej konsoli administracyjnej. Jeśli Twoim celem jest dostęp do sieci prywatnej znajdującej się za tym VPS-em, a nie wyjście do Internetu, ten sam krok zatwierdzenia dotyczy anonsowania podsieci dla reszty Twojej sieci tailnet. Publikowanie pojedynczej aplikacji z węzła, zamiast trasowania przez niego całych sieci, to inne zadanie, a serve oraz funnel to dwa sposoby na jego realizację. Obie te metody opierają się na własnym mechanizmie certyfikatów i ruchu przychodzącego Tailscale, więc należy traktować je jako funkcje hostowanego tailnetu, a nie jako narzędzia dostarczane bezpośrednio przez headscale.

DERP oraz mechanizm przekazywania ruchu w przypadku awarii połączenia bezpośredniego

DERP (designated encrypted relay for packets) stanowi ścieżkę zapasową. Gdy dwa węzły nie mogą nawiązać bezpośredniego połączenia WireGuard, zazwyczaj z powodu pracy za restrykcyjnym NAT (network address translation), przesyłają pakiety za pośrednictwem przekaźnika. Przekaźnik nie posiada kluczy, więc nie może odczytać przesyłanych danych. Rejestruje jedynie, które węzły komunikują się ze sobą oraz wielkość przesyłanego ruchu.

Należy jasno określić działanie konfiguracji domyślnej. Headscale jest dostarczany z ustawieniami wskazującymi na https://controlplane.tailscale.com/derpmap/default przy użyciu auto_update_enabled: true oraz update_frequency: 3h, co oznacza, że płaszczyzna sterowania należy do użytkownika, natomiast przekaźniki do Tailscale. Dla większości użytkowników jest to akceptowalny kompromis. Jeśli jednak jest inaczej, należy uruchomić własny przekaźnik.

Aby uruchomić własny przekaźnik, należy ustawić enabled: true w sekcji derp.server w pliku config.yaml, zrestartować headscale i otworzyć port STUN (session traversal utilities for NAT) za pomocą sudo ufw allow 3478/udp. Plik konfiguracyjny jasno określa wymaganie: server_url musi korzystać z https, ponieważ DERP wymaga TLS. Opróżnienie listy derp.urls usuwa przekaźniki Tailscale z mapy. Jeśli zostanie to wykonane bez działającego wbudowanego przekaźnika, każda para węzłów, która nie może połączyć się bezpośrednio, utraci możliwość komunikacji.

Z poziomu klienta tailscale netcheck wyświetla opóźnienie do każdego znanego regionu przekaźnika, a tailscale status oznacza każdego peera jako direct z adresem albo relay z kodem regionu. Peer pozostający w stanie relay wskazuje na problem z NAT, a nie z headscale. Peer, który ma stan direct i nadal działa wolno, wymaga osobnej diagnozy; zwykle przyczyną jest MTU, a nie sam tunel.

Dlaczego węzeł jest widoczny jako offline?

Proxy odrzuca upgrade połączenia. Jest to częsta przyczyna, której sygnałem jest poprawny stan pozostałych elementów: /health zwraca 200, headscale nodes list wyświetla węzeł, a węzeł nigdy nie przechodzi w stan online. Połączenie sterujące to żądanie POST zawierające Upgrade: tailscale-control-protocol, a proxy, które go nie przekazuje, zrywa jedyny kanał raportujący stan węzła. Porównaj konfigurację nginx z powyższym blokiem map lub przejdź na Caddy, aby wykluczyć problem z proxy.

server_url uległo zmianie po zarejestrowaniu węzłów. Węzły próbują łączyć się z wartością, którą otrzymały podczas rejestracji. Jeśli została ona zmieniona, uruchom sudo tailscale up --login-server https://headscale.example.com --force-reauth na każdym węźle.

Klient nie jest uruchomiony. Na węźle sprawdź sudo systemctl is-active tailscaled oraz sudo journalctl -u tailscaled -n 50 --no-pager. Klient, który nie może rozwiązać nazwy domeny lub uzyskać do niej dostępu, zapisuje tam swoje ponowne próby połączenia.

Klucz wygasł. Zagadnienie to zostało omówione w następnej sekcji.

Aby monitorować stronę serwera podczas testów, uruchom sudo journalctl -u headscale -f na VPS i zrestartuj tailscaled na kliencie. Węzeł, który nawiąże połączenie z headscale, natychmiast wygeneruje wpisy w logach. Brak logów oznacza, że żądanie nie dociera do serwera, dlatego przed analizą headscale sprawdź DNS, firewall oraz proxy.

Wygasanie kluczy a węzeł, który przestaje działać po kilku tygodniach

Istnieją dwa oddzielne terminy wygasania, a ich mylenie prowadzi do marnowania czasu.

Klucze preauth wygasają szybko zgodnie z założeniem. Domyślnie jest to jedna godzina i jedno użycie. Jeśli tailscale up odrzuca klucz, należy wygenerować nowy na serwerze, zamiast edytować cokolwiek po stronie klienta.

Klucze węzłów (node keys) to długoterminowa część konfiguracji. Sekcja node w config.yaml ustawia expiry: 0, a wartość 0 oznacza brak domyślnego wygasania: zarejestrowany węzeł pozostaje ważny, dopóki nie zostanie ręcznie wygaszony. Węzły z tagami nigdy nie wygasają. Należy ustawić expiry: 180d, jeśli wymagane jest, aby rejestracje traciły ważność po określonym czasie. Należy przy tym pamiętać, że każdy węzeł bez tagu będzie wymagał sudo tailscale up --login-server https://headscale.example.com --force-reauth zgodnie z tym harmonogramem, a serwer bez nadzoru, na którym nikt nie przeprowadzi ponownej autoryzacji, zostanie automatycznie usunięty z sieci.

W przypadku utraty laptopa należy wykonać te czynności ręcznie. Polecenie sudo headscale nodes list pozwala uzyskać identyfikator, sudo headscale nodes expire -i 3 wylogowuje dany węzeł, a sudo headscale nodes delete -i 3 całkowicie usuwa go z sieci.

Kopie zapasowe i aktualizacje

/var/lib/headscale oraz /etc/headscale stanowią łącznie cały serwer. Przed ich skopiowaniem należy zatrzymać usługę, ponieważ SQLite może wykonywać zapisy w locie, a baza danych skopiowana pod obciążeniem może być niespójna.

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

Przenieś oba pliki poza serwer. Zawierają one klucze prywatne oraz wszystkie rejestracje, dlatego wymagają takiej samej ochrony jak sam serwer. kopie zapasowe restic z VPS opisuje, jak wykonywać to zadanie w sposób zaplanowany i zaszyfrowany.

Aktualizacje powtarzają proces instalacji: pobierz nowe .deb, sudo apt install ./headscale.deb, a następnie zrestartuj i ponownie uruchom testy is-active oraz /health. Od wersji 0.29 ścieżka aktualizacji jest rygorystyczna. Pomijanie wersji podrzędnej (minor) jest zablokowane, podobnie jak przywracanie starszej wersji podrzędnej. Przechodź o jedną wersję podrzędną na raz, wykonuj kopię zapasową przed każdym krokiem i najpierw zapoznaj się z informacjami o wydaniu (release notes) danej wersji, ponieważ to samo wydanie zmieniło zachowanie polityki ACL i przeniosło kilka kluczy konfiguracyjnych.

FAQ

Dlaczego headscale nie uruchamia się zaraz po instalacji pakietu .deb?

Pakiet instaluje jednostkę systemd, ale pozostawia usługę zatrzymaną, a domyślny /etc/headscale/config.yaml jest jedynie szablonem, a nie gotową konfiguracją. Najpierw należy edytować server_url, listen_addr oraz base_domain, a następnie wykonać sudo systemctl enable --now headscale i potwierdzić stan za pomocą sudo systemctl is-active headscale. Jeśli usługa nadal nie startuje, sudo journalctl -u headscale -n 50 --no-pager wskaże przyczynę. Na tym etapie niemal zawsze jest to błąd składni YAML, ponieważ headscale analizuje cały plik przed powiązaniem portu.

Czy na urządzeniach nadal instaluje się standardowy klient Tailscale?

Tak. Headscale zastępuje wyłącznie serwer sterujący. Każdy węzeł korzysta z oficjalnego klienta Tailscale, który wskazuje się na własny serwer za pomocą sudo tailscale up --login-server https://headscale.example.com. Flaga ta jest dostępna w standardowym kliencie, więc nie ma potrzeby modyfikowania ani przebudowywania oprogramowania.

Czy ruch sieciowy przechodzi przez serwer headscale?

Zazwyczaj nie. Headscale koordynuje sieć, przydziela klucze oraz adresy, natomiast ścieżka danych to połączenie WireGuard bezpośrednio między węzłami. Ruch jest przekierowywany tylko wtedy, gdy dwa węzły nie mogą nawiązać bezpośredniego połączenia i korzystają z przekaźnika DERP. W domyślnej konfiguracji używane są publiczne przekaźniki Tailscale. Należy uruchomić tailscale status na węźle, aby sprawdzić, czy dany partner jest direct, czy znajduje się na relay.

Dlaczego węzeł pozostaje w trybie offline po rejestracji?

Węzeł, który widnieje w headscale nodes list, ale nie przechodzi w tryb online, zazwyczaj utracił połączenie sterujące na reverse proxy. Połączenie to jest żądaniem HTTP upgrade wysyłanym jako POST z nagłówkiem Upgrade: tailscale-control-protocol. Nginx odrzuca takie żądania, chyba że dodano blok map $http_upgrade $connection_upgrade oraz odpowiednie linie proxy_set_header. Caddy przekazuje je bez dodatkowej konfiguracji, co czyni go szybkim sposobem na sprawdzenie, czy problem leży po stronie proxy.

Czy do działania headscale wymagana jest domena i TLS?

W praktyce tak. Klienci łączą się z adresem podanym w server_url, certyfikaty wystawiane są dla nazw, a nie dla adresów IP, a plik konfiguracyjny wskazuje, że DERP wymaga TLS. Użycie domeny wraz z Caddy zajmuje około pięciu minut i zapewnia punkt końcowy HTTPS z automatycznym odnawianiem certyfikatów. Uruchomienie serwera sterującego przez zwykłe HTTP oznacza, że każda komunikacja z klientem odbywa się otwartym tekstem przez Internet.