Konfiguracja routera podsieci Tailscale na VPS
Instrukcja konfiguracji routera podsieci na VPS. Dowiedz się jak poprawnie włączyć przekierowanie pakietów IP, użyć flagi --accept-routes oraz trwale skonfigurować routing w Linux.
Funkcja routera podsieci Tailscale
Router podsieci Tailscale to urządzenie, które ogłasza cały zakres prywatnych adresów IP wewnątrz sieci tailnet, dzięki czemu każde urządzenie w tej sieci może uzyskać dostęp do adresów z tego zakresu, nawet jeśli nie jest na nich zainstalowany program Tailscale. Tailnet to prywatna sieć Tailscale, czyli zbiór urządzeń zalogowanych na jedno konto lub w jednej organizacji. Węzeł wyjściowy (exit node) to funkcja często mylona z routerem podsieci, mimo że realizuje odwrotne zadanie. Przekierowuje on cały ruch urządzenia przez VPS, dzięki czemu VPS staje się bramą wyjściową tego urządzenia do publicznego Internetu.
Każde zdanie opisuje jedno zagadnienie. Router podsieci sprawia, że sieć prywatna staje się dostępna z poziomu tailnet. Węzeł wyjściowy zmienia punkt wyjścia publicznego ruchu sieciowego. Jeśli poszukiwanym rozwiązaniem jest druga opcja, należy zapoznać się z instrukcją uruchamiania węzła wyjściowego Tailscale na VPS. Są to odrębne flagi i jeden VPS może pełnić obie te funkcje jednocześnie, jednak rozwiązują one inne problemy i ulegają awariom w różny sposób.
Kiedy VPS wymaga routera podsieci
Typowym przypadkiem jest sieć prywatna udostępniona przez dostawcę. VPS posiada adres publiczny oraz drugi interfejs w segmencie prywatnym, a pozostałe serwery w tym segmencie nie mają adresów publicznych: baza danych pod 10.0.0.20, cel kopii zapasowych pod 10.0.0.30. Instalacja Tailscale na jednym VPS i ogłoszenie 10.0.0.0/24 pozwala laptopowi na bezpośredni dostęp do tych prywatnych adresów. W segmencie nic się nie zmienia, a baza danych nadal nie posiada adresu publicznego.
Drugi przypadek to sieć znajdująca się za VPS. Sieć LAN (local area network) w domu lub biurze za własnym routerem albo szafa rack z urządzeniami, na których nie można uruchomić Tailscale, takimi jak zarządzalny przełącznik lub stary NAS z zablokowanym oprogramowaniem układowym. Jeden komputer z systemem Linux w tej sieci staje się routerem podsieci dla wszystkich pozostałych urządzeń.
Oba przypadki mają jeden wspólny wymóg. Router podsieci musi mieć możliwość połączenia z zakresem, który ogłasza, przy użyciu własnej tablicy routingu i własnej zapory sieciowej. Tailscale nie tworzy tego połączenia. Przekazuje ruch do routera i oddaje go do jądra systemu w celu dalszego przesyłania.
Instalacja Tailscale i weryfikacja trasy lokalnej
curl -fsSL https://tailscale.com/install.sh | shSkrypt wykrywa dystrybucję, dodaje repozytorium pakietów Tailscale, instaluje polecenie tailscale oraz demona tailscaled, a następnie aktywuje usługę. Należy potwierdzić to za pomocą systemctl is-active tailscaled, co powinno zwrócić active.
Przed wykonaniem jakichkolwiek innych czynności należy sprawdzić, czy VPS ma dostęp do sieci, która ma być udostępniana.
ip route show
ping -c3 10.0.0.20ip route show musi wyświetlić prywatny zakres na rzeczywistym interfejsie, na przykład 10.0.0.0/24 dev enp7s0 proto kernel scope link src 10.0.0.5. Jeśli polecenie ping nie powiedzie się na tym etapie, bezpośrednio na routerze, żadna flaga Tailscale nie rozwiąże problemu. Przyczyną jest konfiguracja sieci VPS lub zapora sieciowa na hoście docelowym. Należy to naprawić w pierwszej kolejności, ponieważ od tego zależą wszystkie późniejsze testy.
Włączanie przekazywania IP i zapewnienie trwałości ustawień po restarcie
Maszyna z systemem Linux odrzuca każdy pakiet, który nie jest zaadresowany bezpośrednio do niej, chyba że włączono funkcję przekazywania (forwarding). Przekazywanie pakietów innych maszyn jest podstawowym zadaniem routera podsieci, dlatego ten krok jest obowiązkowy.
echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.confSprawdź stan za pomocą sysctl net.ipv4.ip_forward, co powinno zwrócić net.ipv4.ip_forward = 1.
Często ten krok jest wykonywany tylko częściowo. Polecenie sudo sysctl -w net.ipv4.ip_forward=1 działa natychmiast, ale ustawienie znika po restarcie systemu. W rezultacie router podsieci działa przez kilka tygodni, a następnie przestaje funkcjonować po restarcie wymuszonym aktualizacją jądra. Kłopotliwe jest to, że na pierwszy rzut oka wszystko wydaje się sprawne. tailscale status nadal pokazuje węzeł jako aktywny, konsola administratora potwierdza zatwierdzenie trasy, a klienci mają zainstalowaną trasę. Pakiety docierają do VPS, a jądro odrzuca je bez rejestrowania jakichkolwiek zdarzeń. Zapisanie wartości w /etc/sysctl.d/99-tailscale.conf zapewnia ich przywrócenie po restarcie.
Jeśli ogłaszasz trasy przy wyłączonym przekazywaniu, tailscale up wyświetli ostrzeżenie w momencie uruchomienia, zawierające komunikat zbliżony do Warning: IPv4 forwarding is disabled. Subnet routes and exit nodes may not work correctly.. Przeczytaj dane wyjściowe tego polecenia, zamiast je ignorować.
Ogłaszanie tras
sudo tailscale up --advertise-routes=10.0.0.0/24Na serwerze VPS, który jest już zalogowany do sieci tailnet, należy zmienić ustawienie w miejscu:
sudo tailscale set --advertise-routes=10.0.0.0/24Do każdej późniejszej zmiany należy używać tailscale set. Ponowne uruchomienie tailscale up z pojedynczą flagą resetuje flagi, które nie zostały powtórzone, a interfejs CLI blokuje operację, zwracając błąd informujący, że zmiana ustawień w ten sposób wymaga podania wszystkich flag innych niż domyślne. tailscale set zmienia jedno ustawienie, pozostawiając resztę bez zmian.
Kilka zakresów należy umieścić na jednej liście rozdzielonej przecinkami, bez spacji: --advertise-routes=10.0.0.0/24,192.168.50.0/24. Każdy wpis musi być adresem sieci w notacji CIDR (classless inter-domain routing, format 10.0.0.0/24). Wpisanie przez pomyłkę własnego adresu hosta, 10.0.0.5/24, zostanie odrzucone, ponieważ bity po prefiksie nie są wyzerowane, a komunikat błędu wskazuje prefiks, który prawdopodobnie był zamierzony. Aby zatrzymać ogłaszanie tras, należy ustawić pustą listę za pomocą sudo tailscale set --advertise-routes=.
Zatwierdzanie trasy w konsoli administracyjnej
Ogłoszenie trasy jest żądaniem, a nie zmianą. Dopóki administrator jej nie zatwierdzi, żaden klient nie otrzyma trasy i żaden adres z tego zakresu nie będzie osiągalny. Jest to działanie celowe, ponieważ maszyna, która może samodzielnie dodać się do tablicy routingu wszystkich urządzeń, mogłaby przejmować ruch dla dowolnego zakresu.
Zatwierdź trasę na stronie Machines w konsoli administracyjnej. VPS zostanie wyświetlony z etykietą subnet. Rozwiń jego wiersz, znajdź sekcję subnets, edytuj ustawienia tras, zaznacz odpowiednią trasę i zapisz zmiany.
Zatwierdzenie odbywa się dla każdego prefiksu z osobna. Jeśli ogłosisz 10.0.0.0/24 dzisiaj, a 192.168.50.0/24 w przyszłym miesiącu, nowy prefiks pojawi się jako niezatwierdzony, podczas gdy stary będzie nadal działał. Zatwierdzona i zignorowana trasa wyglądają z perspektywy VPS identycznie, dlatego przed rozpoczęciem jakiegokolwiek debugowania sprawdź stan w konsoli.
Możesz pominąć krok ręczny, stosując blok autoApprovers w pliku polityki tailnet:
{
"autoApprovers": {
"routes": {
"10.0.0.0/24": ["tag:subnet-router"]
}
}
}Następnie uruchom węzeł z tym tagiem, sudo tailscale up --advertise-routes=10.0.0.0/24 --advertise-tags=tag:subnet-router, a trasa zostanie zatwierdzona w momencie jej ogłoszenia. Tag musi najpierw istnieć w sekcji tagOwners tego samego pliku polityki. Warto to skonfigurować, jeśli VPS jest przebudowywany ze skryptu, ponieważ przebudowany węzeł jest traktowany jako nowy i jego trasy ponownie wymagają zatwierdzenia.
Dlaczego klienci Linux ignorują trasę bez --accept-routes
Trasa jest obecnie rozgłaszana i zatwierdzona. Telefon oraz komputer Mac mogą uzyskać dostęp do 10.0.0.20. Laptop z systemem Linux nie może, a konsola administratora nie wskazuje na żaden problem.
Akceptacja trasy podsieci oznacza wpisanie odpowiednich pozycji do tablicy routingu klienta. W systemach Android, iOS, macOS, tvOS oraz Windows klient Tailscale wykonuje to automatycznie. W systemie Linux tak się nie dzieje, ponieważ maszyna z systemem Linux często pełni rolę serwera lub routera, którego tablica routingu została celowo skonfigurowana. Ciche wstawienie trasy /24 pobranej z sieci mogłoby zakłócić ruch, który ta maszyna już obsługuje. Dlatego w systemie Linux należy wyrazić zgodę na każdym kliencie:
sudo tailscale set --accept-routesNastępnie należy sprawdzić, gdzie trafiła trasa:
ip route show table 52
ip route get 10.0.0.20Tailscale w systemie Linux nie umieszcza zaakceptowanych tras w głównej tablicy routingu. Umieszcza je w tablicy routingu 52 i instaluje reguły polityki, widoczne za pomocą ip rule show w zakresie priorytetów od 5210 do 5270, które kierują niedopasowane pakiety do tej tablicy. Zatem polecenie ip route show samodzielnie nigdy nie wyświetli 10.0.0.0/24, a użytkownik sprawdzający tylko to polecenie uzna, że --accept-routes nie wykonało żadnej akcji. ip route show table 52 to polecenie, które pokazuje stan faktyczny i powinno wyświetlić rozgłaszany zakres na tailscale0.
Warto znać jeden wyjątek. Jeśli ten węzeł Linux jest jednocześnie drugim routerem podsieci dla własnej sieci lokalnej, --accept-routes spowoduje, że będzie on wysyłał ruch dla własnej, bezpośrednio podłączonej podsieci przez drugi router, zamiast przez własny interfejs. W przypadku routera w trybie gotowości (standby) w parze wysokiej dostępności, należy pozostawić --accept-routes wyłączone i ograniczyć się wyłącznie do rozgłaszania.
Tryb awarii: dwa routery ogłaszające nakładające się zakresy
Dwa routery podsieci nie mogą ogłaszać identycznych zakresów. Nakładające się zakresy o różnych długościach prefiksu są dozwolone, a Tailscale wybiera najbardziej szczegółowe dopasowanie. Gdy router A ogłasza 10.0.0.0/24, a router B ogłasza 10.0.0.0/16, ruch do 10.0.0.20 trafia do A.
Użytkowników zaskakuje zachowanie systemu, gdy A przechodzi w tryb offline. Tailscale nie przełącza się automatycznie na mniej szczegółową trasę. Ruch do 10.0.0.20 zostaje wstrzymany, podczas gdy ruch do 10.1.0.20 nadal działa przez B. Objaw wygląda jak awaria połowy sieci prywatnej, a przyczyną jest węzeł offline utrzymujący bardziej szczegółowy prefiks. Aby uzyskać mechanizm failover, należy skonfigurować szerszy router tak, aby ogłaszał również węższe prefiksy, dzięki czemu oba urządzenia będą obsługiwać te same adresy.
Drugi rodzaj nakładania się występuje bliżej klienta. Korzystanie z sieci hotelowej w 192.168.1.0/24, podczas gdy własny router podsieci ogłasza 192.168.1.0/24, powoduje rywalizację o te same miejsca docelowe. O tym, który z nich wygra, decyduje platforma. W systemie Linux należy zainstalować regułę przed regułą Tailscale, aby adresy lokalne korzystały z głównej tablicy routingu:
sudo ip rule add to 192.168.1.0/24 priority 2500 lookup mainTa reguła nie jest trwała i znika po kolejnym uruchomieniu systemu. Prawidłowym rozwiązaniem jest wybór zakresu prywatnego, który nie występuje w typowych sieciach publicznych. 192.168.0.0/24 oraz 192.168.1.0/24 to wartości domyślne w większości routerów domowych, dlatego należy wybrać adresację z zakresu 10.0.0.0/8, która została ustalona świadomie. Ta sama kolizja powoduje awarię w przypadku standardowego połączenia WireGuard VPN skonfigurowanego ręcznie, z tego samego powodu: wygrywa bardziej szczegółowa trasa lokalna, więc ruch nigdy nie trafia do tunelu.
Tryb awarii: DNS wskazuje adres, dla którego brak trasy
Ten problem jest trudny w diagnostyce, ponieważ żaden komponent nie zgłasza błędu. Nazwa zostaje rozwiązana, a połączenie kończy się przekroczeniem czasu oczekiwania.
Załóżmy, że db.internal.example.com rozwiązuje się do 10.0.5.20 za pośrednictwem prywatnego serwera nazw, a użytkownik ogłosił 10.0.0.0/24. Wyszukiwanie kończy się sukcesem, ponieważ rozwiązywanie nazw DNS (domain name system) oraz trasowanie IP to odrębne etapy, z których żaden nie weryfikuje drugiego. Następnie pakiet skierowany do 10.0.5.20 nie znajduje pasującej trasy w sieci tailnet, więc opuszcza ją przez domyślną bramę klienta i znika.
Dwie komendy pozwalają rozdzielić te dwa etapy:
nslookup db.internal.example.com
ip route get 10.0.5.20Jeśli wyszukiwanie zwraca adres, ale ip route get nie odpowiada za pomocą dev tailscale0, oznacza to, że nazwa jest poprawna, natomiast brakuje trasy. Należy ogłosić zakres obejmujący dany adres, używając 10.0.0.0/16 lub drugiego jawnego prefiksu, a następnie zatwierdzić nowy prefiks w konsoli.
Istnieje analogiczna pułapka na samym serwerze nazw. Jeśli w konsoli administracyjnej ustawiono globalny serwer nazw pod prywatnym adresem, takim jak 10.0.0.53, adres ten musi znajdować się wewnątrz zatwierdzonej trasy, w przeciwnym razie urządzenia nie będą w stanie połączyć się z resolverem. Włączenie opcji nadpisującej lokalne serwery DNS przy jednoczesnym wskazaniu resolvera, do którego nikt nie ma dostępu, spowoduje natychmiastową utratę rozwiązywania nazw na wszystkich urządzeniach w sieci tailnet, włącznie z tymi, które działały chwilę wcześniej. Najpierw należy ogłosić i zatwierdzić trasę do resolvera, a dopiero potem zmienić ustawienia DNS. Jeśli DNS wewnątrz tunelu jest elementem sprawiającym ciągłe problemy, sposób, w jaki DNS ulega awarii w tunelu WireGuard opisuje ten sam mechanizm bez uwzględniania warstwy koordynacji.
Source NAT i połączenia typu site-to-site
Domyślnie router podsieci nadpisuje adres źródłowy każdego przekazywanego pakietu własnym adresem prywatnym. Jest to SNAT (source network address translation), który zapewnia poprawne działanie odpowiedzi bez konieczności wprowadzania zmian w sieci prywatnej: baza danych pod adresem 10.0.0.20 odpowiada do VPS, do którego potrafi dotrzeć. Kosztem tego rozwiązania jest fakt, że baza danych widzi każde połączenie tailnet jako pochodzące z VPS, przez co reguły zapory ogniowej oparte na źródle oraz logi dostępu nie dostarczają użytecznych informacji.
Wyłącz tę funkcję w systemie Linux, jeśli chcesz zachować rzeczywisty adres tailnet klienta:
sudo tailscale set --snat-subnet-routes=falseHosty w sieci prywatnej wymagają wówczas trasy powrotnej do 100.64.0.0/10, czyli zakresu adresów przydzielanego urządzeniom przez Tailscale, wskazującej na router podsieci. Bez tej trasy zwrotnej odpowiedzi trafiają do domyślnej bramy i nigdy nie docierają do celu, co powoduje zawieszanie się połączeń po przesłaniu pierwszego pakietu. Dodaj trasę statyczną na bramie sieci prywatnej lub pozostaw włączony SNAT.
Połączenie typu site-to-site to sytuacja, w której dwa routery podsieci wykonują tę operację jednocześnie, każdy ogłaszając własną sieć i akceptując sieć drugiego:
sudo tailscale up --advertise-routes=10.0.0.0/24 --snat-subnet-routes=false --accept-routesUruchom odpowiednie polecenie na drugim routerze, używając jego własnego zakresu adresów. Oba zakresy muszą być różne. Jeśli duże transfery ulegają zawieszeniu, podczas gdy ssh i ping działają poprawnie, przyczyną jest MSS (maximum segment size), czyli największy fragment danych przenoszony przez pakiet TCP. Narzut tunelu sprawia, że przekazywane pakiety stają się zbyt duże dla niektórych łączy pośrednich, a zastosowanie clamping rozwiązuje ten problem:
sudo iptables -t mangle -A FORWARD -o tailscale0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuZapisz tę regułę za pomocą iptables-persistent, w przeciwnym razie zniknie ona po następnym uruchomieniu systemu.
Utrzymanie ciągłości działania
Klucze węzłów wygasają domyślnie po 180 dniach, począwszy od sierpnia 2026 roku. Gdy klucz na routerze podsieci wygaśnie, węzeł wylogowuje się, a cały anonsowany zakres staje się nieosiągalny, bez żadnej zmiany w konfiguracji, która mogłaby to wyjaśnić. Należy wyłączyć wygasanie klucza dla tej maszyny na stronie Machines w konsoli administracyjnej, a następnie odnotować ten fakt.
Tailscale preferuje bezpośrednie połączenie między węzłami i przełącza się na serwery przekaźnikowe (relay), gdy nie może go nawiązać. Przekaźniki działają, ale zwiększają opóźnienia. VPS z publicznym adresem to prosty przypadek: należy zezwolić na ruch przychodzący UDP 41641, a większość węzłów połączy się bezpośrednio. Jeśli ufw zarządza firewallem, reguły ufw faktycznie wymagane przez VPS zawierają odpowiednią składnię.
Reguły dostępu stanowią drugą połowę konfiguracji. W domyślnej sieci tailnet każde urządzenie ma dostęp do każdego innego, więc zatwierdzona trasa działa automatycznie. Po utworzeniu polityki ACL, strona docelowa reguły musi wskazywać prywatny zakres, ponieważ 10.0.0.20 nie jest adresem tailnet i nie jest objęty regułami zapisanymi dla adresów IP lub tagów tailnet.
Na koniec należy zdecydować, czy korzystać z serwera koordynacji, którego nie obsługujemy samodzielnie. Płaszczyzna sterowania Tailscale to usługa hostowana. Klucze pozostają na maszynach, ale konto i plik polityki znajdują się w chmurze. Uruchomienie Headscale, samodzielnie hostowanego serwera kontrolnego Tailscale pozwala zachować kontrolę na własnym VPS, kosztem konieczności jego utrzymania. Innym rozwiązaniem tego problemu jest rezygnacja z klientów Tailscale na rzecz samodzielnego hostowania serwera VPN NetBird, co umieszcza warstwę koordynacji oraz własne klienty typu mesh na jednej maszynie pod pełną kontrolą. Jeśli wybór między tym modelem a ręczną konfiguracją nadal trwa, porównanie WireGuard i Tailscale wyjaśnia, co oferuje warstwa koordynacji i jakie są jej koszty.
FAQ
Jaka jest różnica między routerem podsieci a węzłem wyjściowym?
Router podsieci ogłasza zakres prywatnych adresów, dzięki czemu urządzenia w sieci tailnet mogą łączyć się z maszynami, na których nie działa Tailscale. Węzeł wyjściowy (exit node) ogłasza się jako trasa do całego internetu, więc urządzenie kieruje cały swój ruch przez publiczny adres tego węzła. Jeden VPS może pełnić obie te funkcje. Są to oddzielne flagi, --advertise-routes oraz --advertise-exit-node, a każda z nich wymaga osobnego zatwierdzenia w konsoli administracyjnej.
Dlaczego mój klient Linux ignoruje ogłoszoną trasę podsieci?
Klienci Linux nie akceptują tras podsieci, dopóki nie zostanie to jawnie skonfigurowane. Uruchom sudo tailscale set --accept-routes na kliencie. Następnie sprawdź stan za pomocą ip route show table 52, a nie ip route show. Tailscale instaluje zaakceptowane trasy w tablicy routingu 52 i uzyskuje do nich dostęp poprzez reguły polityki, dlatego główna tablica ich nie wyświetla, a działająca trasa może wyglądać na nieobecną.
Moja podsieć przestała działać po restarcie. Co uległo awarii?
Najprawdopodobniej przekazywanie pakietów IP (IP forwarding). Wartość ustawiona za pomocą sysctl -w nie przetrwa restartu, dlatego należy zapisać ją w /etc/sysctl.d/99-tailscale.conf i potwierdzić za pomocą sysctl net.ipv4.ip_forward. Jeśli przekazywanie jest włączone, a zakres nadal pozostaje nieosiągalny, sprawdź węzeł w konsoli administracyjnej. Klucze węzłów wygasają domyślnie po 180 dniach, a wygasły router podsieci wygląda jak błąd sieci, a nie problem z kontem.
Czy dwa routery podsieci mogą ogłaszać ten sam zakres?
Nie identyczne zakresy. Nakładające się zakresy o różnych długościach prefiksów są dopuszczalne, a pierwszeństwo ma ten najbardziej szczegółowy. Przełączanie awaryjne wymaga uwagi: gdy router obsługujący bardziej szczegółowy prefiks przejdzie w tryb offline, Tailscale nie przełączy się automatycznie na szerszą trasę, przez co ruch zostanie przerwany. Aby uzyskać rzeczywistą parę rezerwową, oba routery muszą ogłaszać te same szczegółowe prefiksy.
Nazwa hosta jest rozpoznawana, ale połączenie przekracza limit czasu. Dlaczego?
Rozpoznawanie DNS i routing to oddzielne etapy. Nazwa może zostać rozpoznana jako adres, którego nie obejmuje żadna zatwierdzona trasa, przez co pakiet opuszcza urządzenie przez domyślną bramę klienta. Uruchom ip route get <address> na kliencie. Jeśli odpowiedź nie zawiera dev tailscale0, ogłoś zakres obejmujący ten adres i zatwierdź nowy prefiks w konsoli administracyjnej.