O teu servizo funciona na máquina, o túnel está activo e, aínda así, o navegador do teu escritorio segue agardando resposta. Nada está roto no sentido habitual: a aplicación escoita dentro dun espazo de nomes de rede, e esa pila é invisible para a LAN. O seu bucle local pertence ao espazo de nomes, así que un cliente noutra máquina non ten ningún enderezo que chegue ao porto. Un salto deliberado, ou un par veth, arranxa isto sen mover o resto do servidor.

Por que nada responde no enderezo da LAN

Un espazo de nomes é unha pila de rede completa: interfaces, rutas, regras de cortafogos e un bucle local privado. Un proceso lanzado mediante ip netns exec ve esa pila e nada máis, así que o enderezo ao que se liga resólvese só dentro do espazo de nomes. O propio 127.0.0.1 do servidor é un bucle local completamente distinto.

Por iso curl falla no servidor mentres o mesmo comando dentro do espazo de nomes ten éxito. A aplicación está sana; o enderezo simplemente non existe na pila do servidor.

Publica un só porto cun salto de socat

socat une as dúas pilas no espazo de usuario, o que abonda cando ten que cruzar un único porto TCP. O lado do servidor escoita na LAN e, por cada conexión aceptada, inicia un segundo socat dentro do espazo de nomes que se conecta ao bucle local da aplicación. O proceso interno chega á aplicación exactamente como o faría un cliente local. Nada do encamiñamento do espazo de nomes cambia, así que a aplicación segue usando o túnel como única saída.

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

O proceso externo necesita root ou a capacidade de entrar no espazo de nomes. Se a VPN cae, a aplicación perde o seu camiño e o porto publicado falla pechado, que é o comportamento que queres dunha gaiola.

Usa un par veth cando cruza máis dun porto

Un par veth é a resposta correcta cando deben cruzar varios portos ou protocolos, ou cando outros servidores necesitan iniciar conexións. Un extremo queda no servidor, o outro pasa ao espazo de nomes, e un /30 pequeno dá a ambos os lados un enderezo estable. Despois unha ruta do servidor envía o enderezo do espazo de nomes polo 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

Non engadas unha ruta por defecto a través do servidor a non ser que queiras romper a gaiola. O túnel debe seguir sendo a saída, así que polo par só é accesible o enderezo do servizo publicado. Dálle tamén ao espazo de nomes o seu propio ficheiro de resolución, porque ip netns exec le /etc/netns/vpn/resolv.conf e sen el a resolución de nomes dentro da gaiola queda baleira.

Proba desde outra máquina, non desde o servidor

Executa a proba desde unha segunda máquina, porque o servidor pode chegar a un receptor local por camiños que non din nada da LAN. Comproba primeiro a que se ligou realmente a aplicación dentro do espazo de nomes e logo conéctate ao enderezo publicado desde fóra. Ligarse a todos os enderezos alí non ensancha a gaiola, porque o comodín segue pertencendo ao espazo de nomes e a LAN non pode velo.

ip netns exec vpn ss -lntp

Se a conexión desde o servidor funciona e a da LAN non, a peza que falta é o salto ou a ruta, non o enderezo de ligazón. Inicia OpenVPN dentro do espazo de nomes en lugar de mover alí un dispositivo tun vivo, xa que mover a interface desactívao e pode borrar rutas que despois non poderás reparar desde fóra. Mantén os comandos de recuperación na consola, non dentro da gaiola.

Artigos relacionados