OpenVPN w Dockerze nie może otworzyć /dev/net/tun: czego brakuje
Węzeł TUN i uprawnienie sieciowe to dwa osobne uprawnienia. Otwórz oba, a potem przeczytaj kolejny błąd na jego własnych warunkach, zamiast powtarzać tę samą poprawkę.
Obrazy kontenerów mogą zawierać wszystkie potrzebne pliki binarne i konfiguracyjne OpenVPN, a mimo to zawieść przy pierwszym wywołaniu sieciowym. Błąd wymienia /dev/net/tun, ponieważ aplikacja poprosiła jądro o interfejs TUN, a kontener nie miał ani węzła urządzenia, ani możliwości jego utworzenia. To dwa osobne uprawnienia, a naprawa jednego zostawia drugie dokładnie tam, gdzie było.
Rozdzielenie ich wymaga po jednej komendzie na każde. Późniejszy komunikat błędu mówi, na której granicy naprawdę stałeś.
Węzeł urządzenia i uprawnienie to dwoje drzwi
Węzeł urządzenia jest obiektem systemu plików, więc kontener musi go widzieć we własnej przestrzeni nazw montowania. Uprawnienie to zezwolenie, więc proces potrzebuje CAP_NET_ADMIN w przestrzeni nazw, w której powstanie interfejs. Przekazanie urządzenia bez uprawnienia daje węzeł, który się otwiera, i ioctl, który zawodzi. Przyznanie uprawnienia bez urządzenia zostawia aplikację bez możliwości otwarcia czegokolwiek, dlatego oba zwykle występują razem w przykładach.
Ustawienie devices w Dockerze mapuje urządzenie hosta do kontenera, a cap_add dostosowuje zbiór uprawnień. Bind mount tej samej ścieżki stawia plik w polu widzenia bez stosowania semantyki dostępu do urządzenia.
Odtwórz to poza plikiem Compose
Przed edycją usługi sprawdź, czy host ma urządzenie i czy goły kontener potrafi utworzyć interfejs. Poniższa komenda jest celowo minimalna, a jej jedynym celem jest oddzielenie problemu hosta od problemu compose. Jeśli zawiedzie, żadna zmiana compose nie pomoże.
ls -l /dev/net/tun
docker run --rm --cap-add NET_ADMIN --device /dev/net/tun:/dev/net/tun alpine sh -c 'apk add -q iproute2 && ip tuntap add dev tun9 mode tun && ip link show tun9'
Brak węzła na hoście oznacza, że moduł tun jest niedostępny, co jest poprawką po stronie hosta, a nie kontenera. Węzeł, który istnieje, ale nie daje się otworzyć w kontenerze, wskazuje na dostęp do urządzenia, a komunikat powie permission denied zamiast no such file. Kolejność tych dwóch niepowodzeń to cała diagnoza. Zapisz, które widziałeś, zanim zmienisz jakąkolwiek flagę.
Błędy po TUN to inne problemy
Gdy tylko pojawi się interfejs, następne niepowodzenie ma innego właściciela. Błędy uwierzytelniania oznaczają, że tunel dotarł do serwera i poświadczenia zostały odrzucone, więc zmiany uprawnień nie pomogą. Tunel, który się zestawia, podczas gdy aplikacje nadal zawodzą, wskazuje na trasy, przekazywanie, rozwiązywanie DNS wewnątrz kontenera lub własny układ sieci kontenera. Każdy z tych punktów to zwykłe pytanie sieciowe, na które uprawnienie TUN nie potrafi odpowiedzieć. Powtarzanie pierwotnego testu po każdej zmianie zapobiega zlewaniu się niepowodzeń w jedno wrażenie.
Kopiowanie każdego ustawienia z działającego przykładu to sposób, w jaki minimalna poprawka staje się nieczytelną definicją usługi. Przenieś tylko te, których potrzebuje to wdrożenie, i zapisz, dlaczego każde tam jest.
Sprawdź interfejs wewnątrz kontenera
Sprawdź interfejs i zbiór uprawnień od wewnątrz działającego kontenera, a nie z hosta. Poniższe komendy pokazują węzeł urządzenia, listę uprawnień i to, czy interfejs da się w ogóle utworzyć. Uruchom je w tym samym kontenerze, który uruchamia klienta, i zainstaluj narzędzia, jeśli obraz jest minimalny.
ls -l /dev/net/tun
capsh --print | grep -i net_admin
ip link add dev tun9 type tun && ip link show tun9
Uprawnienie obecne w bounding set, ale nieobecne w effective set, zachowuje się inaczej niż takie, którego nigdy nie przyznano, a capsh pokazuje oba. Jeśli węzeł istnieje i uprawnienie jest, a tworzenie nadal zawodzi, środowisko uruchomieniowe wymusza coś innego, na przykład profil seccomp lub politykę AppArmor, która ogranicza operację. To trzecia granica, udokumentowana przez środowisko uruchomieniowe, a nie przez aplikację.
Zapisz flagi kontenera, obraz i dokładny błąd z każdej próby. Następna osoba, która przeczyta tę notatkę, będzie wiedzieć, które drzwi były zamknięte, bez powtarzania całego śledztwa.