¿Puede una máquina Linux multitarjeta implementar un verdadero modelo Strong ES?
Caso de uso específico
Tengo un sistema con cinco interfaces diferentes, cada una conectada a la misma subred, por lo tanto, la misma puerta de enlace a Internet.
- Me gustaría escuchar en cada interfaz por separado en el mismo puerto, y asegurarme de que los paquetes siempre salgan por la misma interfaz en la que entraron, y asegurarme de que los paquetes que intentan entrar en la interfaz "incorrecta" se descarten.
- Me gustaría poder vincularme a cada interfaz y realizar conexiones salientes a destinos de Internet que siempre se originen desde la misma IP de origen a la que me conecté. Por ejemplo,
curl --interface interface_ip http://ipecho.net/plain
siempre debe mostrar la misma dirección IP a la que me conecté con
--interface
. - Las rutas estáticas pueden ser problemáticas debido al uso de DHCP en una de estas interfaces.
RFC 1122
De RFC 1122 – Requisitos para hosts de Internet – Capas de comunicación, Sección 3.3.4.2 – Requisitos de alojamiento múltiple:
Los implementadores de host de Internet han utilizado dos
modelos conceptuales diferentes para multihoming, que se resumen brevemente
en la siguiente discusión. Este documento no
se pronuncia sobre qué modelo se prefiere; cada uno parece tener un
lugar. Esta ambivalencia se refleja en que los temas (A)
y (B) son opcionales.
-
Modelo ES fuerte
- El modelo Strong ES (Sistema final, es decir, host)
enfatiza la distinción host/gateway (ES/IS),
y, por lo tanto, sustituiría MUST por MAY en
problemas (A ) y (B) anteriores. Tiende a modelar un
host multitarjeta como un conjunto de hosts lógicos dentro
del mismo host físico.Con respecto a (A), los defensores del modelo Strong ES
señalan que los mecanismos automáticos de enrutamiento de Internet
no podían enrutar un datagrama a una
interfaz física que no se correspondía con el
dirección de destino.Bajo el modelo Strong ES, el cálculo de ruta
para un datagrama saliente es el mapeo:route(src IP addr, dest IP addr, TOS) -> gateway
Aquí, la dirección de origen se incluye como un parámetro
para seleccionar una puerta de enlace que sea directamente
accesible en la interfaz física correspondiente.
Tenga en cuenta que este modelo requiere lógicamente que, en
general, haya al menos una puerta de enlace predeterminada, y
preferiblemente múltiples valores predeterminados, para cada fuente de IP
dirección.
Modelo ES débil
- Este punto de vista resta importancia a la distinción ES/IS, y
por lo tanto, sustituiría NO DEBE por MAYO en
los temas (A) y (B). Este modelo puede ser el más
natural para hosts que interceptan protocolos de enrutamiento de puerta de enlace
y es necesario para hosts que tienen
funcionalidad de puerta de enlace integrada.
El modelo ES débil puede hacer que el mecanismo de redirección
falle. Si se envía un datagrama a través de una interfaz física
que no corresponde a la
dirección de destino, la puerta de enlace de primer salto
no se dará cuenta de cuándo debe enviar una redirección. Por
por otro lado, si el host tiene funcionalidad de puerta de enlace integrada
, entonces tiene información de enrutamiento
sin escuchar redireccionamientos.
En el modelo Weak ES, el cálculo de ruta para un
datagrama saliente es el mapeo:
route(dest IP addr, TOS) -> gateway, interface
Linux es un modelo ES débil por defecto, mientras que FreeBSD y otras variedades de Unix actúan como sistemas ES fuertes. ¿Hay alguna forma de hacer que se comporte más como un sistema Strong ES?
Qué sysctl
¿O sería necesario configurar la configuración en tiempo de compilación para que se comporte como un Strong ES de forma predeterminada, sin agregar reglas de enrutamiento específicas para cualquier nueva interfaz que agregue? Sé que podemos hacer un filtrado estricto de ruta de origen a través de net.ipv4.conf.default.rp_filter = 1
, pero parece que hay mucho más que eso. ¿Cómo puedo hacer el enrutamiento basado en la fuente de forma predeterminada?
Respuesta aceptada:
Solo agregar reglas de firewall no será suficiente para este. Desea que el sistema enrute el tráfico como si fueran dos sistemas independientes que simplemente comparten el mismo hardware y procesos:eso es lo que efectivamente es el modelo Strong ES.
Relacionado:Linux:¿la página de manual solo se encuentra después de ejecutarse con root?Cuando apunte a Strong ES Model en Linux, primero necesitará esta configuración de sysctl:
net.ipv4.conf.all.arp_filter=1
net.ipv4.conf.all.arp_ignore=1 # or even 2
net.ipv4.conf.all.arp_announce=2
Esta configuración hará que ARP se comporte según corresponda con el modelo Strong ES, es decir, cuando se reciba una solicitud de ARP, solo responderá la interfaz con la dirección solicitada exacta, y solo si el tráfico a la dirección de origen se enviaría de hecho a través de esa dirección específica. interfaz.
Luego, dado que tiene cinco interfaces que desea que se comporten de manera diferente en términos de enrutamiento, deberá configurar cinco tablas de enrutamiento personalizadas. Puede usar números para identificarlos, pero generalmente es más claro especificar nombres para ellos. Por lo tanto, elija números para cada uno de ellos entre 1 y 252, y algunos nombres adecuados. (Los números 0, 253, 254 y 255 están reservados).
Por ejemplo, elijamos 100 =rtable0, 101 =rtable1, 102 =rtable2, 103 =rtable3 y 104 =rtable4. Agregue estos números y nombres al final de /etc/iproute2/rt_tables
archivo:
# ...default stuff above...
100 rtable0
101 rtable1
102 rtable2
103 rtable3
104 rtable4
Luego, complete cada tabla de enrutamiento personalizada con un conjunto mínimo de entradas de ruta apropiadas para cada interfaz. (Estoy reemplazando los valores reales con nombres de variables de entorno con un nombre descriptivo).
ip route add $ETH0_NET dev eth0 proto static src $ETH0_IP table rtable0
ip route add default via $ETH0_GW dev eth0 proto static src $ETH0_IP table rtable0
ip route add $ETH1_NET dev eth1 proto static src $ETH1_IP table rtable1
ip route add default via $ETH1_GW dev eth1 proto static src $ETH1_IP table rtable1
# ... and so on, for all 5 interfaces
Finalmente, agregue reglas de enrutamiento avanzadas que verifiquen la dirección de origen de cada paquete y elija la tabla de enrutamiento que se utilizará en consecuencia:
ip rule add from $ETH0_IP table rtable0
ip rule add from $ETH1_IP table rtable1
#...
Para que toda esta configuración sea persistente durante los reinicios, es posible que deba escribir secuencias de comandos de inicio personalizadas (o posiblemente ifup-pre
o ifup-post
scripts) para adaptarse a las convenciones de su distribución de Linux.
Para un seguro adicional, puede agregar reglas de iptables por interfaz para descartar silenciosamente cualquier paquete entrante que pueda recibirse en la interfaz incorrecta. Si todo está bien, el conteo de paquetes para estos debe permanecer en cero:si comienzan a aumentar, es posible que haya pasado por alto algo en la configuración.
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth0 ! -d $ETH0_IP -j DROP
iptables -A INPUT -m addrtype --dst-type UNICAST -i eth1 ! -d $ETH1_IP -j DROP
# ... and so on for each interface
Advertencia: asegúrese de tener algún tipo de acceso de consola local o remoto al sistema al establecer esta configuración. Es muy probable que esta configuración estropee por completo su acceso a la red mientras está a medio hacer.
Si bien sería posible configurar N interfaces con solo (N-1) tablas de enrutamiento personalizadas, mi preferencia personal es mover toda la configuración de enrutamiento a tablas personalizadas cuando se usa el enrutamiento avanzado. Tener route -n
o ip route show
aparecer esencialmente vacío mientras el sistema claramente tiene conexiones de red será una gran pista de que algo muy especial está sucediendo. Sin embargo, cuando configuré un sistema como este, también configuré un aviso permanente en /etc/motd
sobre el enrutamiento avanzado que está en vigor y las ubicaciones de los scripts reales que lo configuran.