Evitar que la aplicación utilice todas las IP en el puerto (0.0.0.0:34964)

Evitar que la aplicación utilice todas las IP en el puerto (0.0.0.0:34964)

Tengo dos aplicaciones que usan el mismo puerto para comunicación de red (34964). Tengo control sobre (código fuente) la primera aplicación y usa 192.168.0.4:34964. Mientras que la otra aplicación intenta usar/"reclamar" todas las direcciones IP (0.0.0.0:34964), pero no tengo control sobre ésta. Cada aplicación funciona ejecutándose sola, sin embargo, cuando intento ejecutarlas al mismo tiempo, aparece un error: No se pudo vincular la dirección.

Pregunta

¿Hay alguna forma de evitar que la segunda aplicación use/reclame todas las direcciones IP (0.0.0.0) y en su lugar use 192.168.0.5? ¿Ya sea antes de iniciarlo o encapsulándolo en un espacio de nombres de red?

No he probado nada y se me han acabado las ideas...

Versión más detallada: Dos aplicaciones para comunicarse en dos redes Profinet separadas. La primera aplicación actúa como un dispositivo Profinet y se comunica con un controlador Siemens Profinet, tengo acceso al código fuente de esta aplicación. La segunda aplicación debería actuar como un controlador Profinet que se comunica con un dispositivo Profinet Siemens. Actualmente estoy usando Codesys para esto y no tengo acceso para cambiar el código fuente.

Respuesta1

Tienes pocas opciones.

LD_PRELOAD

Podría usar una LD_PRELOADbiblioteca para interceptar la bind()llamada del sistema y forzar el enlace a una dirección específica. Un ejemplo de eso eseste, que compilas así:

gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

Y úsalo así:

BIND_ADDR=127.0.0.1 LD_PRELOAD=./bind.so /path/to/myprogram

Espacios de nombres de red con Docker

También puede optar por ejecutar su programa dentro de su propio espacio de nombres de red. Elmás fácilUna forma de hacerlo sería crear una imagen de Docker para su aplicación y luego ejecutarla en Docker y utilizar las capacidades de mapeo de puertos de Docker para exponer el servicio en la IP del host de su elección.

Aqui hay dragones

Recomiendo encarecidamente una de las soluciones anteriores. Solo incluyo lo siguiente porque preguntaste sobre los espacios de nombres de la red.

Espacios de nombres de red con macvlan

Si quieres hacerlo sin Docker, es posible pero con un poco más de trabajo. Primero, cree un nuevo espacio de nombres de red:

# ip netns add myns

Luego cree una macvlaninterfaz asociada con una de sus interfaces de host y colóquela en el espacio de nombres:

# ip link add myiface link eth0 type macvlan mode bridge
# ip link set myiface netns myns

Y asígnale una dirección en tu red local:

# ip netns exec myns \
  ip addr add 192.168.0.4/24 dev myiface
# ip netns exec myns \
  ip link set myiface up

Y cree reglas de enrutamiento apropiadas dentro del espacio de nombres (sustituyendo su dirección de puerta de enlace real por 192.168.0.1):

# ip netns exec myns \
  ip route add default via 192.168.0.1

Ahora, ejecute su programa dentro del espacio de nombres de la red:

# ip netns exec myns \
  /path/to/myprogram

Ahora su programa se está ejecutando y se vinculará solo a 192.168.0.4, porque esa es la única dirección visible dentro del espacio de nombres. ¡Pero! Tenga en cuenta la limitación de mavclanlas interfaces: si bien otros hosts de su red podrán conectarse al servicio, usted no podrá conectarse a esa dirección desde el host en el que se está ejecutando (a menos que cree otra macvlaninterfaz en el host). y enrutar conexiones a 192.168.0.4través de esa interfaz).

Espacios de nombres de red con interfaces veth

En lugar de utilizar macvlaninterfaces, puede crear un vethpar de interfaces, con un extremo del par dentro de un espacio de nombres de red y el otro en su host. Utilizará enmascaramiento de IP para pasar paquetes desde el espacio de nombres a su red local.

Cree el espacio de nombres de la red:

# ip netns add myns

Cree un par de interfaces:

# ip link add myiface-in type veth peer name myiface-out

Asigne un extremo del par al espacio de nombres de su red:

# ip link setns myiface-in myns

Configure una dirección en cada extremo del par y muestre los enlaces:

# ip addr add 192.168.99.1/24 dev myiface-out
# ip link set myiface-out up
# ip netns exec myns ip addr add 192.168.99.2/24 dev myiface-in
# ip netns exec myns ip link set myiface-in up

Configure el enmascaramiento de IP en su host. Esto redirigirá los paquetes entrantes 192.168.0.4a su espacio de nombres:

# iptables -t nat -A PREROUTING -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2
# iptables -t nat -A OUTPUT -d 192.168.0.4 -p tcp --dport 34964 -j DNAT --to-destination 192.168.99.2

Y esto enmascarará los paquetes salientes:

# iptables -t nat -A POSTROUTING -s 192.168.99.2 -j MASQUERADE

Deberá asegurarse de tener habilitado el reenvío de IP en su host ( sysctl -w net.ipv4.ip_forward=1) y que su FORWARDcadena de iptables permita reenviar la conexión ( iptables -A FORWARD -d 192.168.99.2 -j ACCEPT, teniendo en cuenta que las reglas se procesan en secuencia, por lo que una regla de rechazoanteséste tendrá prioridad).

información relacionada