Aplikacja w przestrzeni nazw VPN jest nieosiągalna z sieci LAN
Przestrzeń nazw sieci daje jednemu programowi własny tunel i własną pętlę zwrotną. Publikuj tylko jej port przez skok socat lub parę veth, zamiast przez host.
Twoja usługa działa na maszynie, tunel jest podniesiony, a przeglądarka na biurku nadal czeka na odpowiedź. W zwykłym sensie nic nie jest zepsute: aplikacja nasłuchuje wewnątrz przestrzeni nazw sieci, a ten stos jest niewidoczny dla sieci LAN. Jej pętla zwrotna należy do przestrzeni nazw, więc klient na innej maszynie nie ma adresu, który dociera do portu. Jeden świadomy skok albo jedna para veth załatwia to bez przenoszenia reszty hosta.
Dlaczego nic nie odpowiada na adresie LAN
Przestrzeń nazw to pełny stos sieciowy: interfejsy, trasy, reguły zapory i prywatna pętla zwrotna. Proces uruchomiony przez ip netns exec widzi tylko ten stos i nic więcej, więc adres, do którego się wiąże, jest rozwiązywany wyłącznie wewnątrz przestrzeni nazw. Własny 127.0.0.1 hosta to zupełnie inna pętla zwrotna.
Dlatego curl na hoście zawodzi, a to samo polecenie wewnątrz przestrzeni nazw kończy się sukcesem. Aplikacja jest zdrowa; adresu po prostu nie ma w stosie hosta.
Opublikuj jeden port skokiem socat
socat łączy oba stosy w przestrzeni użytkownika, co wystarcza, gdy musi przejść jeden port TCP. Strona hosta nasłuchuje w sieci LAN i dla każdego przyjętego połączenia uruchamia drugi socat wewnątrz przestrzeni nazw, który łączy się z pętlą zwrotną aplikacji. Wewnętrzny proces dociera do aplikacji dokładnie tak, jak zrobiłby to lokalny klient. Nic w routingu przestrzeni nazw się nie zmienia, więc aplikacja nadal używa tunelu jako jedynego wyjścia.
socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork
Zewnętrzny proces potrzebuje roota lub możliwości wejścia do przestrzeni nazw. Jeśli VPN padnie, aplikacja traci drogę, a opublikowany port zawodzi w stanie zamkniętym, i to jest zachowanie, którego chcesz od więzienia.
Użyj pary veth, gdy przechodzi więcej niż jeden port
Para veth to właściwa odpowiedź, gdy musi przejść kilka portów lub protokołów albo gdy inne hosty muszą inicjować połączenia. Jeden koniec zostaje w hoście, drugi przenosi się do przestrzeni nazw, a mały /30 daje obu stronom stabilny adres. Następnie trasa hosta wysyła adres przestrzeni nazw przez parę.
ip link add veth0 type veth peer name veth1
ip link set veth1 netns vpn
ip addr add 10.77.0.1/30 dev veth0
ip link set veth0 up
ip netns exec vpn ip addr add 10.77.0.2/30 dev veth1
ip netns exec vpn ip link set veth1 up
Nie dodawaj trasy domyślnej przez hosta, jeśli nie zamierzasz zburzyć więzienia. Tunel ma pozostać wyjściem, więc przez parę jest osiągalny tylko opublikowany adres usługi. Daj przestrzeni nazw także własny plik resolvera, bo ip netns exec czyta /etc/netns/vpn/resolv.conf, a bez niego rozwiązywanie nazw w więzieniu jest puste.
Testuj z drugiej maszyny, nie z hosta
Uruchom test z drugiej maszyny, bo host może dotrzeć do lokalnego nasłuchiwacza drogami, które nic nie mówią o sieci LAN. Najpierw sprawdź, do czego aplikacja naprawdę się związała wewnątrz przestrzeni nazw, a potem połącz się z zewnątrz z opublikowanym adresem. Wiązanie ze wszystkimi adresami tam nie poszerza więzienia, bo symbol wieloznaczny nadal należy do przestrzeni nazw, a sieć LAN nie może go zobaczyć.
ip netns exec vpn ss -lntp
Jeśli połączenie z hosta działa, a z sieci LAN nie, brakującym elementem jest skok lub trasa, a nie adres wiązania. Uruchom OpenVPN wewnątrz przestrzeni nazw zamiast przenosić tam działające urządzenie tun, bo przeniesienie interfejsu je wyłącza i może wyczyścić trasy, których potem nie naprawisz z zewnątrz. Trzymaj polecenia odzyskiwania na konsoli, nie w więzieniu.