Dos interfaces de red y dos direcciones IP en la misma subred en Linux


22

Recientemente me encontré con una situación en la que necesitaba dos direcciones IP en la misma subred asignada a un host Linux para poder ejecutar dos sitios SSL / TLS. Mi primer enfoque fue usar alias de IP, por ejemplo, usar eth0: 0, eth0: 1, etc., pero nuestros administradores de red tienen algunas configuraciones bastante estrictas para la seguridad que aplastaron esta idea:

  1. Usan la inspección DHCP y normalmente no permiten direcciones IP estáticas. El direccionamiento estático se logra mediante el uso de entradas DHCP estáticas, por lo que la misma dirección MAC siempre obtiene la misma asignación de IP. Esta función se puede deshabilitar por puerto de conmutación si lo solicita y tiene un motivo (afortunadamente, tengo una buena relación con los chicos de la red y esto no es difícil de hacer).
  2. Con el snooping DHCP deshabilitado en el puerto del conmutador, tuvieron que poner una regla en el conmutador que decía que la dirección MAC X podía tener la dirección IP Y. Desafortunadamente, esto tuvo el efecto secundario de decir que la dirección X del MAC SOLO está permitido tener Dirección IP Y. El alias de IP requería que a la dirección MAC X se le asignaran dos direcciones IP, por lo que esto no funcionó.

Puede haber una forma de evitar estos problemas en la configuración del conmutador, pero en un intento por preservar las buenas relaciones con los administradores de la red, intenté encontrar otra forma. Tener dos interfaces de red parecía el siguiente paso lógico. Afortunadamente, este sistema Linux es una máquina virtual, por lo que pude agregar fácilmente una segunda interfaz de red (sin reiniciar, podría agregar, bastante bueno). Algunas pulsaciones de teclas más tarde, tuve dos interfaces de red en funcionamiento y ambas obtuvieron direcciones IP de DHCP.

Pero luego surgió el problema: los administradores de red podían ver (en el conmutador) la entrada ARP para ambas interfaces, pero solo la primera interfaz de red que presenté respondería a pings o cualquier tipo de tráfico TCP o UDP.

Después de mucho cavar y hurgar, esto es lo que se me ocurrió. Parece funcionar, pero también parece ser mucho trabajo para algo que parece que debería ser simple. ¿Alguna idea alternativa por ahí?


Paso 1: habilite el filtrado ARP en todas las interfaces:

# sysctl -w net.ipv4.conf.all.arp_filter=1
# echo "net.ipv4.conf.all.arp_filter = 1" >> /etc/sysctl.conf

Desde el archivo networking / ip-sysctl.txt en los documentos del kernel de Linux:

arp_filter - BOOLEAN
    1 - Allows you to have multiple network interfaces on the same
    subnet, and have the ARPs for each interface be answered
    based on whether or not the kernel would route a packet from
    the ARP'd IP out that interface (therefore you must use source
    based routing for this to work). In other words it allows control
    of which cards (usually 1) will respond to an arp request.

    0 - (default) The kernel can respond to arp requests with addresses
    from other interfaces. This may seem wrong but it usually makes
    sense, because it increases the chance of successful communication.
    IP addresses are owned by the complete host on Linux, not by
    particular interfaces. Only for more complex setups like load-
    balancing, does this behaviour cause problems.

    arp_filter for the interface will be enabled if at least one of
    conf/{all,interface}/arp_filter is set to TRUE,
    it will be disabled otherwise

Paso 2: Implemente el enrutamiento basado en la fuente

Básicamente, solo seguí las instrucciones de http://lartc.org/howto/lartc.rpdb.multiple-links.html , aunque esa página se escribió con un objetivo diferente en mente (tratar con dos ISP).

Suponga que la subred es 10.0.0.0/24, la puerta de enlace es 10.0.0.1, la dirección IP para eth0 es 10.0.0.100 y la dirección IP para eth1 es 10.0.0.101.

Defina dos nuevas tablas de enrutamiento denominadas eth0 y eth1 en / etc / iproute2 / rt_tables:

... top of file omitted ...
1    eth0
2    eth1

Defina las rutas para estas dos tablas:

# ip route add default via 10.0.0.1 table eth0
# ip route add default via 10.0.0.1 table eth1
# ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
# ip route add 10.0.0.0/24 dev eth1 src 10.0.0.101 table eth1

Defina las reglas para cuándo usar las nuevas tablas de enrutamiento:

# ip rule add from 10.0.0.100 table eth0
# ip rule add from 10.0.0.101 table eth1

DHCP ya se ocupó de la tabla de enrutamiento principal (y ni siquiera está claro que sea estrictamente necesario en este caso), pero básicamente equivale a esto:

# ip route add default via 10.0.0.1 dev eth0
# ip route add 130.127.48.0/23 dev eth0 src 10.0.0.100
# ip route add 130.127.48.0/23 dev eth1 src 10.0.0.101

¡Y voilá! Todo parece funcionar bien. Enviar pings a ambas direcciones IP funciona bien. Enviar pings desde este sistema a otros sistemas y forzar el ping para usar una interfaz específica funciona bien ( ping -I eth0 10.0.0.1, ping -I eth1 10.0.0.1). Y lo más importante, todo el tráfico TCP y UDP hacia / desde cualquiera de las direcciones IP funciona como se esperaba.


Nuevamente, mi pregunta es: ¿hay una mejor manera de hacer esto? Esto parece mucho trabajo para un problema aparentemente simple.


Actualización: la solución anterior terminó siendo incompleta. Las cosas funcionaban bien si el tráfico permanecía en la misma subred, pero las comunicaciones a otras subredes que usan la segunda interfaz no funcionarían correctamente. En lugar de cavar un hoyo más grande, terminé hablando con los administradores de la red y conseguí que permitieran múltiples direcciones IP para la única interfaz y usé alias de IP (por ejemplo, eth0 y eth0: 0).


La distinción clave para recordar es que la IP no pertenece a la interfaz, sino a la máquina. Por lo tanto, es correcto enviar cualquiera de las interfaces para cualquier IP en esta configuración, por lo tanto, requiere algunos trucos para no hacerlo.
MikeyB

Creo que el enrutamiento de origen no es necesario en este caso porque el filtrado de arp debería aplicarse solo cuando el conmutador está enviando a una interfaz / tiene que encontrarlo entre sus puertos. Podría estar equivocado, pero cuando la máquina envía datos hacia el conmutador, la IP en el campo de origen (encabezado IP) no está marcada, solo el arp envía el paquete.
AndreasM

MikeyB es correcto, el enrutamiento de origen es la única forma. La máquina puede elegir cualquier interfaz de salida que desee enviar tráfico, siempre que esté en la misma subred. No importa si la IP no se encuentra realmente en esa interfaz o no.
Patrick

2
AndreasM: Los paquetes entrantes no son el problema, son los paquetes salientes los que son el problema. Sin el enrutamiento de origen, todos los paquetes salientes utilizarán la ruta predeterminada, que está vinculada a una interfaz u otra. Aunque los paquetes salientes tendrán la dirección IP de origen correcta, los filtros en el conmutador no les permitirán salir ya que esa dirección IP no pertenece a la dirección MAC de esa interfaz. Para el conmutador, solo parece que un cliente está tratando de falsificar la IP de otro cliente. (Estos son interruptores inteligentes de capa 3).
Scott Duckworth, el

Los alias de IP son obsoletos y un truco, no reflejan la realidad, sin mencionar que eliminar el primario eliminará todos los alias. Use ipfrom iproute2para agregar más de una dirección a la misma interfaz.
pilona

Respuestas:


8

Sí, la mejor manera es crear un caso de negocio adecuado y hacer que relajen las reglas de los conmutadores para que pueda tener varias IP en una NIC.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.