Din tjänst körs på maskinen, tunneln är uppe, och ändå väntar webbläsaren på ditt skrivbord fortfarande på svar. Ingenting är trasigt i vanlig mening: applikationen lyssnar inuti ett nätverksnamnrymde, och den stacken är osynlig för LAN. Dess loopback tillhör namnrymden, så en klient på en annan maskin har ingen adress som når porten. Ett medvetet hopp, eller ett veth-par, löser det utan att flytta resten av värden.

Varför ingenting svarar på LAN-adressen

Ett namnrymde är en komplett nätverksstack: gränssnitt, rutter, brandväggsregler och en privat loopback. En process som startas via ip netns exec ser den stacken och inget annat, så adressen den binder till löses bara inuti namnrymden. Värdens egen 127.0.0.1 är en helt annan loopback.

Därför misslyckas curl på värden medan samma kommando inuti namnrymden lyckas. Applikationen är frisk; adressen finns helt enkelt inte i värdens stack.

Publicera en port med ett socat-hopp

socat bryggar de två stackarna i användarutrymmet, vilket räcker när en enda TCP-port måste korsa. Värdsidan lyssnar på LAN och startar för varje accepterad anslutning en andra socat inuti namnrymden som ansluter till appens loopback. Den inre processen når applikationen precis som en lokal klient skulle göra. Ingenting i namnrymdens routing ändras, så appen fortsätter att använda tunneln som sin enda utgång.

socat TCP-LISTEN:9100,reuseaddr,fork EXEC:'ip netns exec vpn socat STDIO tcp-connect:127.0.0.1:9100',nofork

Den yttre processen behöver root eller behörigheten att gå in i namnrymden. Om VPN:et faller tappar appen sin väg och den publicerade porten misslyckas stängt, och det är beteendet du vill ha från ett fängelse.

Använd ett veth-par när mer än en port korsar

Ett veth-par är rätt svar när flera portar eller protokoll måste korsa, eller när andra värdar måste initiera anslutningar. Den ena änden stannar i värden, den andra flyttas in i namnrymden, och en liten /30 ger båda sidor en stabil adress. En värdsrutt skickar sedan namnrymdens adress över paret.

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

Lägg inte till en standardrutt genom värden om du inte tänker bryta fängelset. Tunneln ska förbli utgången, så bara den publicerade tjänsteadressen är nåbar över paret. Ge namnrymden också en egen resolver-fil, eftersom ip netns exec läser /etc/netns/vpn/resolv.conf och utan den är namuppslagningen i fängelset tom.

Testa från en annan maskin, inte från värden

Kör testet från en annan maskin, eftersom värden kan nå en lokal lyssnare via vägar som inte säger något om LAN. Kontrollera först vad applikationen faktiskt band till inuti namnrymden, anslut sedan utifrån till den publicerade adressen. Att binda till varje adress där vidgar inte fängelset, eftersom jokertecknet fortfarande tillhör namnrymden och LAN kan inte se det.

ip netns exec vpn ss -lntp

Om anslutningen från värden fungerar och den från LAN inte gör det, är den saknade delen hoppet eller rutten, inte bindningsadressen. Starta OpenVPN inuti namnrymden i stället för att flytta in en levande tun-enhet, eftersom flytten av gränssnittet stänger av den och kan rensa rutter som du sedan inte kan reparera utifrån. Håll återställningskommandona på konsolen, inte i fängelset.

Relaterade artiklar