Uruchamiasz na telefonie dystrybucję Linuksa pod chroot, instalujesz w niej klienta VPN, a powłoka ogłasza, że tunel jest gotowy. Potem przełączasz się na przeglądarkę i ruch wychodzi przez dane komórkowe, jakby nic się nie stało. Albo odwrotnie: każda aplikacja na telefonie traci łączność, bo klient dodał trasę domyślną w przestrzeni nazw, której Android faktycznie używa. Oba objawy pochodzą z tego samego brakującego elementu i żaden nie jest błędem klienta VPN.

Powłoka mówi, że połączono, aplikacje się nie zgadzają

Pierwszy wynik jest typowy. Tunel w przestrzeni użytkownika otwarty z chroot może dokończyć uzgadnianie, wypisać statystyki i przenosić ruch generowany przez tę samą powłokę, podczas gdy aplikacje Androida nadal korzystają z domyślnej sieci telefonu. Nic ich nie przechwytuje, bo nic nie powiedziało Androidowi, że istnieje VPN.

Drugi wynik jest niebezpieczny. Jeśli chroot dzieli przestrzeń nazw sieci Androida, co dzieje się domyślnie, proces z wystarczającymi uprawnieniami może dodać trasy i interfejs TUN, które wpływają na cały telefon. Wtedy tunel działa dla każdej aplikacji, także tych, których nie zamierzałeś routować, a łączność telefonu zależy teraz od demona bez zarządzania cyklem życia, bez wskaźnika połączenia i bez polityki zawsze włączonego VPN.

Który z dwóch przypadków masz, można ustalić jednym poleceniem. Porównaj ip route wewnątrz chroot z tym samym poleceniem z powłoki Androida na zewnątrz. Identyczne wyjście oznacza, że chroot jest w przestrzeni nazw gospodarza: każda zmiana sieci, którą wprowadzi, dotyczy całego telefonu. Inne wyjście oznacza, że launcher utworzył dla niego przestrzeń nazw, a jego tunel jest dla Androida niewidoczny z samej konstrukcji.

Co chroot zmienił, a czego nie

ObjectEffect of a chroot
Pathname resolutionChanged: lookups start at the new root
Kernel and driversUnchanged: the phone's kernel, its TUN driver, its limits
Network namespaceUnchanged unless the launcher creates one
Android VPN registrationUnchanged: no app consented, no VPN is selected

Wywołanie systemowe chroot robi jedną rzecz: zmienia katalog używany do rozwiązywania nazw ścieżek. Strona man mówi wprost, że nie jest to granica bezpieczeństwa, i nie wspomina nic o interfejsach, trasach ani stanie VPN. Wszystko, czego ludzie oczekują od kontenera Linuksa — prywatny stos sieciowy, filtrowany system plików, limity zasobów — pochodzi z innych mechanizmów, których launcher mógł użyć albo nie.

Dlatego twierdzenia, że chroot izoluje VPN, zwykle odpowiadają na niewłaściwe pytanie. Istotne pytanie brzmi, w jakiej przestrzeni nazw działa proces i do jakiej domeny SELinux jest ograniczony, a oba są właściwościami sposobu uruchomienia, nie słowa chroot.

TUN potrzebuje trzech rzeczy, a węzeł urządzenia to tylko jedna

Tradycyjny tunel w przestrzeni użytkownika potrzebuje urządzenia TUN, które może otworzyć, wsparcia jądra dla tego urządzenia oraz uprawnienia do konfiguracji interfejsu i tras. To odrębne wymagania, a utworzenie nazwy ścieżki pod /dev nie spełnia samo w sobie żadnego z nich:

ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun

W Androidzie jądro zwykle ma wkompilowane wsparcie TUN, bo korzysta z niego sama usługa VPN platformy, ale to nie znaczy, że twój proces może z niego korzystać. Konfiguracja interfejsu wymaga zdolności administrowania siecią, a SELinux decyduje, czy proces w ogóle może dotrzeć do węzła urządzenia. Odmowa wygląda jak błąd uprawnień bez oczywistej przyczyny, a odpowiedź jest w dzienniku audytu:

dmesg | grep avc
logcat -d | grep "avc: denied"

Root tego nie rozwiązuje. SELinux ogranicza procesy działające jako uid 0 dokładnie tak samo jak inne, więc chroot uruchomiony z powłoki root nadal może zostać pozbawiony urządzenia, które widzi. Wyłączenie egzekwowania, aby zadziałał stary instalator, to decyzja dla całego telefonu ze skutkami daleko wykraczającymi poza tunel i nie jest naprawą przestarzałego pliku binarnego.

Dlaczego aplikacje Androida ignorują twój tunel

Wspieranym modelem Androida jest aplikacja VPN, która rejestruje się przez usługę VPN platformy, raz prosi użytkownika o zgodę i otrzymuje deskryptor pliku swojego tunelu. Platforma kieruje potem ruch do tego deskryptora i egzekwuje zakres aplikacji wybrany przez użytkownika lub administratora, dlatego ten sam mechanizm może działać per aplikacja, per profil i być łączony z ustawieniami zawsze włączonego VPN oraz blokowania bez VPN. Przewodnik po tworzeniu VPN w Androidzie opisuje to uzgadnianie, a kluczowe jest to, że to rejestracja, a nie sztuczka routingu.

Demon wewnątrz chroot nigdy się nie rejestruje. Nie ma okna zgody, nie ma ikony klucza na pasku stanu, nie ma listy dołączania ani wykluczania per aplikacja i nie ma udziału w polityce zawsze włączonego VPN. Aplikacje nadal więc korzystają z domyślnej sieci, a tunel przenosi tylko to, co wysyła sama powłoka.

Droga w drugą stronę też nie pomaga. Wpychanie tras do przestrzeni nazw gospodarza przechwytuje wszystko, łącznie z ruchem, który platforma chciała zachować lokalnie, i robi to bez kontroli per aplikacja i bez możliwości zobaczenia albo cofnięcia tego przez użytkownika. Nie ma ustawienia pośredniego, w którym demon chroot routuje ruch tylko jednej aplikacji.

Zgodność binarna to osobny mur

Nawet gdy strona sieciowa jest ciekawa, plik wykonywalny ma własne wymagania: architekturę CPU, dynamiczny loader, bibliotekę C i oczekiwane możliwości jądra. Android używa bionic, a nie glibc, a stary plik binarny zbudowany dla dystrybucji desktopowej może potrzebować bibliotek, których na urządzeniu już nie ma.

Podlinkowanie nazwy pliku biblioteki do nowszej wersji nie tworzy zgodności ABI, a zarchiwizowana biblioteka kryptograficzna z pakietu sprzed dekady nie jest utrzymywanym komponentem. Jeśli plan na tym polega, plan polega na uruchamianiu nieutrzymywanego kodu z uprawnieniami sieciowymi na telefonie.

Udowodnij to w kontekście Androida i posprzątaj po sobie

Testuj to, na czym naprawdę ci zależy, od strony, która ma znaczenie: otwórz konkretną aplikację, dotrzyj do konkretnego prywatnego celu, potwierdź, który resolver odpowiedział, następnie rozłącz tunel i potwierdź udokumentowane zachowanie. Wynik z terminala wewnątrz chroot jest dowodem wyłącznie o kontekście wykonania tego terminala i niczym więcej.

Jeśli podczas eksperymentów zmieniałeś trasy gospodarza, przywróć je i zapisz, co zmieniłeś. Potem sprawdź, czy telefon ma skonfigurowany zawsze włączony VPN, bo starszy eksperyment, który zostawił regułę, może po miesiącach wyglądać jak awaria platformy.

Do rzeczywistej potrzeby zdalnego dostępu użyj wspieranego klienta usługi albo zatwierdzonego projektu bramy. Warto zapytać nie o to, czy da się uruchomić instalator z rootem, ale o to, czy wspierana implementacja przenosi potrzebne aplikacje przez zamierzoną granicę, nie zostawiając na urządzeniu bezpańskich uprzywilejowanych zmian.

Powiązane artykuły