Tailscale — prywatna sieć WireGuard bez konfigurowania VPN-a
Siatka peer-to-peer na WireGuardzie, w której serwer koordynujący wymienia klucze publiczne, ale nie widzi ruchu — bez przekierowań portów i bez plików konfiguracyjnych per osoba. Rozbieramy podział na otwartego klienta i zamkniętą warstwę sterowania, rolę przekaźników DERP, subnet routery, ACL-e i Tailscale SSH. Do tego pełna analiza Headscale jako otwartej alternatywy dla warstwy sterowania: co obsługuje, czego nie i dlaczego jego autorzy sami zawężają zakres do jednej sieci.
Klasyczny VPN dla zespołu wygląda tak. Serwer OpenVPN albo WireGuard na VPS-ie, plik konfiguracyjny generowany osobno dla każdej osoby i każdej maszyny, przekierowanie portu, reguły zapory — i cały ruch przechodzący przez ten jeden punkt. Działa. Ma tylko trzy koszty, których na starcie nie widać.
Pierwszy: konfiguracja rośnie liniowo. Każda nowa osoba to nowy klucz, nowy plik i nowa pozycja na liście, którą ktoś musi pamiętać. Osoba odchodząca z firmy to ręczne unieważnienie w miejscu, o którym nikt nie pamięta. Drugi: ruch nadmiarowo krąży. Dwie maszyny w tej samej serwerowni komunikują się przez węzeł VPN stojący w innym kraju, bo tak wygląda topologia gwiazdy. Trzeci: NAT. Dwie maszyny, z których żadna nie ma publicznego adresu, nie zestawią połączenia bez pośrednika — a to jest sytuacja domyślna dla laptopa w kawiarni i serwera za routerem klienta.
Tailscale (github.com/tailscale/tailscale) rozwiązuje wszystkie trzy inną architekturą: buduje siatkę peer-to-peer na WireGuardzie, w której węzły łączą się bezpośrednio, a osobny serwer koordynujący zajmuje się wyłącznie wymianą kluczy publicznych i polityką dostępu — nie przechodzi przez niego ruch.
Poniżej: jak to działa, gdzie leży granica między częścią otwartą i zamkniętą (to jest najważniejsza informacja w całym wpisie), co realnie daje plan darmowy, oraz pełna analiza Headscale — otwartej implementacji warstwy sterowania, wraz z tym, czego w niej nie ma i dlaczego jej autorzy sami zawężają zakres.
Co jest otwarte, a co nie
To rozstrzygnięcie trzeba postawić na początku, bo bez niego cała reszta bywa źle rozumiana. Tailscale jest produktem komercyjnym z otwartym klientem, a nie projektem open source z komercyjnym wsparciem. Projekt mówi to wprost na osobnej stronie o otwartości kodu.
Otwarte (BSD-3-Clause):
- demon
tailscaledi narzędzietailscale— na wszystkich platformach, - klient dla Linuksa i Androida w całości; dla Windowsa i macOS-a bez nakładki graficznej (same nakładki na tych systemach nie są otwarte),
- serwery przekaźnikowe DERP — i można je hostować samodzielnie, co jeszcze wróci.
Zamknięte:
- serwer koordynujący, czyli cała warstwa sterowania. To ona jest produktem, który Tailscale sprzedaje jako usługę zarządzaną.
Warto docenić, że w sprawie self-hostingu Tailscale sam odsyła do Headscale — niezależnej, otwartej implementacji serwera koordynującego, którą współtworzą pracownicy Tailscale, ale której firma nie kontroluje. To rzadka i uczciwa postawa; wracamy do niej w osobnym rozdziale.
Stan projektu
Dane z API GitHuba na 22 września 2026:
- 36 280 gwiazdek i 3169 forków, kod w Go, licencja BSD-3-Clause,
- repozytorium założone 31 stycznia 2020, ostatni commit z 9 września 2026,
- najnowsze wydanie
v1.102.3z 20 sierpnia 2026, a równolegle utrzymywana jest starsza linia —v1.98.10wyszło 28 lipca, - 67 commitów w trzy tygodnie — rozwój prowadzi firma na pełnych etatach i widać to w tempie,
- 4552 otwarte zgłoszenia. Liczba wygląda alarmująco, ale README wyjaśnia jej pochodzenie: projekt prosi o zgłaszanie w tym trackerze problemów zarówno z kodem, jak i z usługą hostowaną. To jest tracker produktu, nie tylko biblioteki.
Rola serwera koordynującego
Najprecyzyjniejszy opis, jaki znaleźliśmy, pochodzi paradoksalnie z dokumentacji Headscale i wart jest przytoczenia, bo tłumaczy, dlaczego zamknięta warstwa sterowania nie oznacza oddania danych. Serwer sterowania:
- działa jako punkt wymiany kluczy publicznych WireGuarda dla węzłów sieci,
- przydziela adresy IP klientom,
- tworzy granice między użytkownikami,
- umożliwia udostępnianie maszyn między użytkownikami,
- eksponuje trasy ogłaszane przez węzły.
Czego na tej liście nie ma: przenoszenia ruchu. Dane lecą bezpośrednio między węzłami, zaszyfrowane WireGuardem, a warstwa sterowania widzi metadane — kto istnieje, jakie ma adresy, kto z kim ma prawo się łączyć — nie treść. To istotna różnica, ale trzeba ją nazwać dokładnie: topologia i wzorce połączeń są widoczne dla dostawcy, a dla części klientów to właśnie jest rozstrzygające.
Sieć w terminologii Tailscale nazywa się tailnetem i jest prywatną siecią przypisaną użytkownikowi albo organizacji.
Gdy bezpośrednie połączenie nie działa: DERP
Przebijanie NAT-u udaje się w większości przypadków, ale nie we wszystkich — symetryczny NAT po obu stronach potrafi to uniemożliwić. Wtedy wchodzą przekaźniki DERP (Designated Encrypted Relay for Packets), które retransmitują zaszyfrowany ruch, nie mając do niego wglądu.
I tu jest fakt, którego wiele osób nie zna, a który zmienia rachunek zaufania: serwery DERP są otwarte i można je hostować samodzielnie. Oznacza to, że nawet przy korzystaniu z hostowanej warstwy sterowania ścieżkę awaryjną dla ruchu da się trzymać u siebie. Jeśli zależy nam, żeby pakiety nigdy nie przechodziły przez infrastrukturę dostawcy — także w scenariuszu awaryjnym — jest to osiągalne bez rezygnacji z reszty.
Funkcje, które realnie zmieniają pracę
Lista jest długa, ale cztery pozycje zmieniają sposób pracy zespołu, a nie tylko dodają wygody.
Subnet router. Jedna maszyna w sieci ogłasza całą podsieć, dzięki czemu pozostałe maszyny są dostępne bez instalowania na nich klienta. To jest odpowiedź na najczęstszy problem w pracy dla klienta: dostęp do jego infrastruktury bez ingerencji w każdy jego serwer. Jeden węzeł, jedna zgoda, cała podsieć osiągalna.
Exit node. Cały ruch urządzenia idzie przez wskazany węzeł — czyli klasyczne zachowanie VPN-a, dostępne wtedy, gdy jest naprawdę potrzebne, a nie jako domyślne. Warto o tym pamiętać, bo exit node przywraca wszystkie wady topologii gwiazdy: pojedynczy punkt i dodatkową latencję.
ACL-e. Polityki dostępu są konfiguracją tailnetu, nie regułami zapory rozsianymi po maszynach. Odwołują się do tagów, nie do adresów IP — co oznacza, że reguła „serwery aplikacyjne mogą łączyć się z bazą" pozostaje prawdziwa po wymianie maszyn.
Tailscale SSH. Uwierzytelnianie oparte na tożsamości z tailnetu zamiast na rozdanych kluczach. Znika cała klasa pracy: dopisywanie kluczy do authorized_keys, usuwanie ich po odejściu osoby z zespołu i pytanie „czy ten klucz na pewno jeszcze jest potrzebny".
Poza tym: MagicDNS (nazwy maszyn zamiast adresów), Funnel i Serve (wystawienie usługi z tailnetu do internetu albo tylko wewnątrz sieci), Taildrop (przesyłanie plików między urządzeniami), a także klucze wstępnej autoryzacji i węzły efemeryczne — te dwa są kluczem do użycia w CI i w kontenerach.
Subnet router w praktyce
Skoro to najbardziej użyteczna funkcja w pracy dla klienta, warto pokazać dokładne kroki. Najpierw przekazywanie pakietów na maszynie, która ma ogłaszać podsieć — bez tego nic nie zadziała, a objaw jest niejasny:
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.confPotem ogłoszenie tras z tej maszyny:
sudo tailscale set --advertise-routes=10.0.0.0/24,192.168.50.0/24I dwie rzeczy po drugiej stronie. Trasy trzeba zatwierdzić — ogłoszenie samo nie wystarcza, zatwierdzenie odbywa się w konsoli administracyjnej (albo automatycznie, jeśli skonfigurujemy autoApprovers). A na klientach linuksowych trzeba jawnie włączyć przyjmowanie tras:
sudo tailscale set --accept-routesNa macOS, Windowsie, iOS, Androidzie i tvOS trasy są wykrywane automatycznie — tylko Linux wymaga tej flagi, co jest najczęstszym powodem sytuacji „u kolegi działa, u mnie nie".
Jeszcze jeden szczegół, przydatny przy diagnostyce po stronie klienta: domyślnie ruch przechodzący przez subnet router jest maskowany (SNAT), więc w logach docelowego serwera zobaczymy adres routera, nie adres źródłowy. Zachowanie oryginalnego adresu włącza się flagą:
tailscale up --snat-subnet-routes=falsePolityki jako plik, nie jako reguły na maszynach
ACL-e tailnetu opisuje jeden plik polityki w formacie JSON, z sekcjami acls, groups, tagOwners, ssh i autoApprovers. Model jest domyślnie odmawiający — jedyną dozwoloną akcją jest accept, więc wszystko, czego nie dopuścimy jawnie, jest zabronione.
{
"groups": {
"group:dev": ["anna@example.com", "piotr@example.com"]
},
"tagOwners": {
"tag:web": ["group:dev"],
"tag:db": ["group:dev"]
},
"acls": [
{
"action": "accept",
"src": ["group:dev"],
"proto": "tcp",
"dst": ["tag:web:80,443"]
},
{
"action": "accept",
"src": ["tag:web"],
"proto": "tcp",
"dst": ["tag:db:3306"]
}
],
"ssh": [
{
"action": "accept",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["autogroup:nonroot"]
}
]
}Zwróć uwagę na drugą regułę: serwery aplikacyjne mają dostęp do bazy, ale ludzie nie — i jest to zapisane raz, tagami, a nie regułą zapory powtórzoną na każdej maszynie. Po wymianie serwera aplikacyjnego wystarczy nadać nowej maszynie tag web i polityka nadal obowiązuje.
Blok ssh w powyższym przykładzie realizuje sensowną domyślną zasadę: członkowie tailnetu mogą łączyć się po SSH z własnymi urządzeniami, na konta inne niż root. To dobry punkt startowy — reguły rozszerza się potem świadomie, a nie odwrotnie.
Plan darmowy i cennik
To jest część, która przy ocenie narzędzia dla małego zespołu przesądza — i wypada nietypowo korzystnie.
Personal — 0 USD, bezterminowo. Do 6 użytkowników, nieograniczona liczba urządzeń użytkownika, dostęp do prawie wszystkich funkcji. Limity, o których trzeba wiedzieć: 3 grupy ACL, 50 tagowanych zasobów i 1000 minut miesięcznie na zasoby efemeryczne. Wyłączone są: zaawansowane role użytkowników, automatyczne zarządzanie kontami przez SCIM, integracje sprawdzające stan urządzenia i logi przepływów sieciowych.
Standard — 8 USD za użytkownika miesięcznie: nieograniczeni użytkownicy, SCIM, 10 grup ACL, zaawansowane role, konfiguracja przez MDM, integracje stanu urządzenia. Premium — 18 USD za użytkownika miesięcznie: 300 grup ACL, 10 000 minut efemerycznych, dostęp „just-in-time", zaawansowany SSH, logi przepływów sieciowych i ich strumieniowanie, priorytetowe wsparcie. Enterprise — cennik indywidualny.
Wniosek praktyczny dla agencji: plan darmowy jest realnie użyteczny, a nie demonstracyjny. Sześciu użytkowników i nieograniczona liczba urządzeń pokrywa większość małych zespołów. Progiem nie jest liczba maszyn — jest nim liczba osób oraz limit 50 tagowanych zasobów, w który przy rozbudowanej infrastrukturze wchodzi się szybciej, niż w limit użytkowników.
Headscale — otwarta warstwa sterowania
Skoro zamknięty jest tylko serwer koordynujący, naturalne pytanie brzmi: da się go zastąpić? Odpowiedź to Headscale (github.com/juanfont/headscale) — i jest to projekt zaskakująco duży.
Dane z API GitHuba na 22 września 2026:
- 43 690 gwiazdek — czyli więcej niż repozytorium klienta Tailscale, co samo w sobie mówi coś o zapotrzebowaniu na self-hosting w tej kategorii,
- 2555 forków, kod w Go, licencja BSD-3-Clause,
- repozytorium założone 21 czerwca 2020, ostatni commit z 9 września 2026,
- najnowsze wydanie
v0.29.3z 29 lipca 2026 — numeracja poniżej jedynki jest tu świadoma i warto ją traktować poważnie, - 142 otwarte zgłoszenia.
Relacja z Tailscale jest opisana w README wzorowo przejrzyście: projekt nie jest powiązany z Tailscale Inc., ale jeden z aktywnych opiekunów jest zatrudniony w Tailscale i ma zgodę na pracę nad Headscale w godzinach pracy, a jego wkład jest recenzowany przez pozostałych opiekunów. Kierunek projektu ustalają opiekunowie wspólnie, a zasadą przewodnią jest służenie społeczności self-hosterów przy utrzymaniu projektu w zdrowiu.
Zakres jest celowo węższy — i to trzeba przeczytać przed decyzją
Headscale deklaruje swój cel wprost i jest to najważniejsze zdanie dla każdego, kto rozważa go w kontekście firmowym: celem jest dostarczenie self-hosterom, entuzjastom i hobbystom otwartego serwera do ich projektów i laboratoriów, implementującego wąski zakres — jedną sieć (jeden tailnet), odpowiednią do użytku osobistego albo małej organizacji open source.
Dla agencji obsługującej wielu klientów w odseparowanych sieciach jest to ograniczenie architektoniczne, nie brakująca funkcja. Odpowiedzią jest osobna instancja Headscale na klienta — co jest wykonalne, ale trzeba to policzyć w kosztach utrzymania, zanim padnie decyzja.
Co Headscale obsługuje
Lista jest szeroka i pokrywa praktycznie całą warstwę sieciową:
- MagicDNS z globalnymi i ograniczonymi serwerami nazw,
- dwustos IPv4/IPv6,
- subnet routery i węzły wyjściowe z filtrowaniem tras oraz automatycznym zatwierdzaniem tras,
- ACL-e i polityki dostępu, wraz z atrybutami węzłów i testowaniem polityk,
- Tailscale SSH,
- Taildrop i Taildrive,
- rejestrację węzłów przez przeglądarkę i klucze wstępnej autoryzacji,
- jednokrotne logowanie przez OpenID Connect z podstawową rejestracją,
- tagi i węzły efemeryczne,
- wbudowany serwer DERP oraz przekaźniki peer.
Czego nie obsługuje
Trzy braki i jedno ograniczenie częściowe, każde istotne w innym scenariuszu:
- Funnel — brak. Wystawienie usługi z tailnetu do publicznego internetu nie działa,
- Serve — brak,
- logi przepływów sieciowych — brak,
- OpenID Connect działa, ale grup OIDC nie da się użyć w ACL-ach. To jest ograniczenie, które boli najbardziej przy większym zespole: tożsamości i grupy mamy u dostawcy tożsamości, a polityki dostępu trzeba utrzymywać osobno, bez powiązania z tymi grupami.
Ostrzeżenie operacyjne, którego nikt się nie spodziewa
README zawiera zdanie, które warto przeczytać dwa razy, bo jest odwrotnością domyślnego odruchu każdego zespołu DevOps: projekt nie wspiera ani nie zachęca do uruchamiania Headscale za reverse proxy oraz w kontenerze.
Trudno o wyraźniejszy sygnał, jak działa wsparcie w tym projekcie. Można to zignorować i wielu ludzi ignoruje — ale wtedy przy problemie jesteśmy poza obszarem, w którym opiekunowie pomogą. Dla wdrożenia produkcyjnego oznacza to instalację natywną, na maszynie, z certyfikatem obsługiwanym przez samą aplikację.
Jak to zestawić w praktyce
Cztery scenariusze i rekomendacja do każdego.
- Mały zespół, do sześciu osób, nie chce utrzymywać kolejnej usługi → hostowany Tailscale na planie darmowym. Warstwa sterowania nie widzi ruchu, więc nie jest to równoważne z oddaniem danych do chmury — ale widzi topologię, i to trzeba świadomie zaakceptować,
- Wymóg formalny „nic nie wychodzi poza naszą infrastrukturę", własny albo postawiony przez klienta → Headscale, z zaakceptowaniem braku Funnel i Serve oraz rozdzielenia grup OIDC od ACL-i,
- Kilku klientów w odseparowanych sieciach → hostowany Tailscale z osobnymi tailnetami albo osobna instancja Headscale na klienta, bo jeden Headscale obsługuje jedną sieć,
- Chcemy, żeby ruch nigdy nie przechodził przez infrastrukturę dostawcy, także awaryjnie → własny serwer DERP. Działa w obu wariantach, bo DERP jest otwarty.
Konkrety dla naszego stacku
Cztery zastosowania, które w pracy z aplikacjami w Laravelu wracają regularnie.
1. Panel administracyjny bez wystawiania go do internetu. To jest najlepszy i najczęstszy przypadek użycia. Panel w Filamencie, kolejki w Horizonie, Telescope, klient bazy — wszystko to może nasłuchiwać na adresie z tailnetu, a nie na publicznym interfejsie. Zamiast zabezpieczać publicznie dostępny panel, przestajemy go publikować — a to jest różnica jakościowa, nie ilościowa: nie ma czego skanować i nie ma czego zgadywać.
2. Dostęp do bazy z maszyny deweloperskiej. Bez tunelu SSH, bez otwierania portu bazy na świat i bez listy dozwolonych adresów IP aktualizowanej za każdym razem, gdy komuś zmieni się adres w domu. Klient bazy łączy się z nazwą maszyny z MagicDNS.
3. CI wchodzące do sieci na chwilę. Zadanie w pipeline'ie dołącza do tailnetu kluczem wstępnej autoryzacji jako węzeł efemeryczny, wykonuje migracje albo wdrożenie i znika. Nie zostaje po nim ani wpis na liście urządzeń, ani klucz do unieważnienia. Uwaga budżetowa: na planie darmowym zasoby efemeryczne mają limit 1000 minut miesięcznie, co przy częstych pipeline'ach warto policzyć.
4. Subnet router w środowisku klienta. Jedna maszyna z klientem Tailscale ogłasza podsieć klienta i cała jego infrastruktura staje się dla nas osiągalna, bez instalowania czegokolwiek na pozostałych serwerach. Przy pracy z cudzą infrastrukturą to często jedyny wariant, na który klient się zgodzi.
Pułapki
- Warstwa sterowania jest zamknięta i hostowana. Ruchu nie widzi, ale widzi metadane: jakie urządzenia istnieją, jakie mają adresy i które z którymi się łączą. Przy części klientów to jest argument rozstrzygający i lepiej postawić go na stole samemu,
- Headscale ma z założenia węższy zakres — jedna sieć na instancję, cel zdefiniowany jako self-hosterzy i hobbyści. To nie zarzut, to zapisany zakres,
- Headscale nie wspiera reverse proxy ani kontenerów, co wywraca typowy schemat wdrożenia,
- W Headscale nie ma Funnel ani Serve, a grup OIDC nie użyjesz w ACL-ach,
- Nakładki graficzne na Windowsie i macOS nie są otwarte — sam demon i CLI są, ale interfejs użytkownika na tych systemach nie,
- Plan darmowy ma trzy limity, które łatwo przeoczyć: sześciu użytkowników, trzy grupy ACL i pięćdziesiąt tagowanych zasobów. Ten ostatni wyczerpuje się pierwszy przy rozbudowanej infrastrukturze,
- Exit node przywraca topologię gwiazdy razem z jej latencją i pojedynczym punktem awarii. Używaj go tam, gdzie jest naprawdę potrzebny,
- Uzależnienie warto ograniczyć. Gdy cała droga dostępu do infrastruktury stoi na tailnecie, awaria warstwy sterowania oznacza brak możliwości dołączania nowych węzłów. Istniejące połączenia działają dalej, ale zapasowa droga wejścia na krytyczne maszyny — choćby konsola u dostawcy — powinna istnieć i być przetestowana,
- 4552 otwarte zgłoszenia to tracker obsługujący również usługę hostowaną, więc nie jest to miara jakości kodu — ale jest miarą tego, ile trwa znalezienie odpowiedzi na własny problem.
Podsumowanie
Tailscale rozwiązuje problem dostępu do infrastruktury lepiej niż klasyczny VPN, bo atakuje jego źródło: topologię gwiazdy i ręczne zarządzanie kluczami. Płaci się za to zależnością od zamkniętej warstwy sterowania — i to jest jedyna decyzja, którą trzeba w tej sprawie podjąć świadomie. Co z tego wynika:
- Otwarte są klient, CLI i przekaźniki DERP na licencji BSD-3-Clause; zamknięty jest serwer koordynujący i nakładki graficzne na Windowsie oraz macOS,
- Warstwa sterowania nie przenosi ruchu — wymienia klucze publiczne, przydziela adresy, ustala granice i eksponuje trasy. Widzi metadane, nie treść,
- Plan darmowy jest realnie użyteczny — sześciu użytkowników i nieograniczone urządzenia; pierwszy ogranicznik to zwykle pięćdziesiąt tagowanych zasobów, nie liczba osób,
- Headscale to poważna alternatywa — 43 690 gwiazdek, BSD-3-Clause, obsługa MagicDNS, ACL-i, Tailscale SSH, subnet routerów, tagów, węzłów efemerycznych i wbudowanego DERP-a,
- Ale Headscale celowo obsługuje jedną sieć i nie ma Funnel, Serve ani grup OIDC w ACL-ach. Przy wielu klientach to osobna instancja na każdego,
- Postaw własny DERP, jeśli ruch nie może przechodzić przez infrastrukturę dostawcy nawet awaryjnie — to działa również przy hostowanej warstwie sterowania,
- Najlepszy pierwszy przypadek użycia to przestanie publikować panele administracyjne i wystawić je wyłącznie w tailnecie,
- Do CI używaj kluczy wstępnych i węzłów efemerycznych, pamiętając o limicie tysiąca minut miesięcznie na planie darmowym,
- Polityki trzymaj w pliku ACL z tagami, nie w regułach zapory na maszynach — reguła „serwery aplikacyjne mają dostęp do bazy, ludzie nie" przeżywa wtedy wymianę serwerów,
- Na klientach linuksowych pamiętaj o
--accept-routes— pozostałe systemy wykrywają trasy same i to jest najczęstsza przyczyna „u kolegi działa", - Subnet router zamiast klienta na każdej maszynie przy pracy w infrastrukturze klienta,
- Zachowaj zapasową drogę wejścia na krytyczne maszyny i sprawdź, że działa, zanim będzie potrzebna.
Licencja: otwarta część Tailscale — demon, narzędzie wiersza poleceń i serwery DERP — jest rozpowszechniana na licencji BSD 3-Clause, permisywnej, bez copyleftu, wymagającej jedynie zachowania noty o prawach autorskich i zakazującej używania nazwy autorów do promowania produktów pochodnych bez zgody. Ten ostatni warunek to trzecia klauzula, od której licencja bierze nazwę, i przy narzędziu z rozpoznawalną marką warto o niej pamiętać. Headscale jest na tej samej licencji. Komercyjne użycie obu jest więc bez zastrzeżeń: instalacja u siebie i u klientów, modyfikacje bez obowiązku publikacji, wbudowanie w świadczoną usługę. Granicą nie jest tu licencja, a architektura: korzystając z hostowanej warstwy sterowania, korzystamy z zamkniętego oprogramowania jako usługi — z cennikiem, regulaminem i zależnością, których żadna licencja otwartego klienta nie zmienia. Headscale jest odpowiedzią na dokładnie tę zależność i dlatego, mimo węższego zakresu, ma dziś więcej gwiazdek niż klient, którego obsługuje.