Lo resolví yo mismo. Parece que hay muy poca información sobre las cosas de redes que puede hacer con Linux, por lo que he decidido documentar y explicar mi solución en detalle. Esta es mi configuración final:
- 3 NIC: eth0 (cable), wlan0 (wifi incorporado, débil), wlan1 (adaptador wifi usb, señal más fuerte que wlan0)
- Todos ellos en una única subred, cada uno con su propia dirección IP.
- eth0 se debe utilizar para el tráfico entrante y saliente de forma predeterminada.
- Si eth0 falla, entonces se debe usar wlan1.
- Si wlan1 falla, entonces se debe usar wlan0.
Primer paso : crear una nueva tabla de ruta para cada interfaz en /etc/iproute2/rt_tables
. Llamémoslos rt1, rt2 y rt3
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
1 rt1
2 rt2
3 rt3
Segundo paso : configuración de red en /etc/network/interfaces
. Esta es la parte principal y trataré de explicar todo lo que pueda:
auto eth0 wlan0
allow-hotplug wlan1
iface lo inet loopback
iface eth0 inet static
address 192.168.178.99
netmask 255.255.255.0
dns-nameserver 8.8.8.8 8.8.4.4
post-up ip route add 192.168.178.0/24 dev eth0 src 192.168.178.99 table rt1
post-up ip route add default via 192.168.178.1 dev eth0 table rt1
post-up ip rule add from 192.168.178.99/32 table rt1
post-up ip rule add to 192.168.178.99/32 table rt1
post-up ip route add default via 192.168.178.1 metric 100 dev eth0
post-down ip rule del from 0/0 to 0/0 table rt1
post-down ip rule del from 0/0 to 0/0 table rt1
iface wlan0 inet static
wpa-conf /etc/wpa_supplicant.conf
wireless-essid xyz
address 192.168.178.97
netmask 255.255.255.0
dns-nameserver 8.8.8.8 8.8.4.4
post-up ip route add 192.168.178.0/24 dev wlan0 src 192.168.178.97 table rt2
post-up ip route add default via 192.168.178.1 dev wlan0 table rt2
post-up ip rule add from 192.168.178.97/32 table rt2
post-up ip rule add to 192.168.178.97/32 table rt2
post-up ip route add default via 192.168.178.1 metric 102 dev wlan0
post-down ip rule del from 0/0 to 0/0 table rt2
post-down ip rule del from 0/0 to 0/0 table rt2
iface wlan1 inet static
wpa-conf /etc/wpa_supplicant.conf
wireless-essid xyz
address 192.168.178.98
netmask 255.255.255.0
dns-nameserver 8.8.8.8 8.8.4.4
post-up ip route add 192.168.178.0/24 dev wlan1 src 192.168.178.98 table rt3
post-up ip route add default via 192.168.178.1 dev wlan1 table rt3
post-up ip rule add from 192.168.178.98/32 table rt3
post-up ip rule add to 192.168.178.98/32 table rt3
post-up ip route add default via 192.168.178.1 metric 101 dev wlan1
post-down ip rule del from 0/0 to 0/0 table rt3
post-down ip rule del from 0/0 to 0/0 table rt3
Si escribe ip rule show
, debería ver lo siguiente:
0: from all lookup local
32756: from all to 192.168.178.98 lookup rt3
32757: from 192.168.178.98 lookup rt3
32758: from all to 192.168.178.99 lookup rt1
32759: from 192.168.178.99 lookup rt1
32762: from all to 192.168.178.97 lookup rt2
32763: from 192.168.178.97 lookup rt2
32766: from all lookup main
32767: from all lookup default
Esto nos dice que el tráfico entrante o saliente de la dirección IP "192.168.178.99" usará la tabla de ruta rt1. Hasta aquí todo bien. Pero el tráfico que se genera localmente (por ejemplo, desea hacer ping o ssh desde la máquina a otro lugar) necesita un tratamiento especial (vea la gran cita en la pregunta).
Las primeras cuatro líneas posteriores /etc/network/interfaces
son sencillas y se pueden encontrar explicaciones en Internet, la quinta y última línea posterior es la que hace que la magia suceda:
post-up ip r add default via 192.168.178.1 metric 100 dev eth0
Tenga en cuenta que no hemos especificado una tabla de ruta para esta línea posterior. Si no especifica una tabla de ruta, la información se guardará en la main
tabla de ruta que vimos en ip rule show
. Esta línea posterior coloca una ruta predeterminada en la tabla de rutas "principal" que se utiliza para el tráfico generado localmente que no es una respuesta al tráfico entrante. (Por ejemplo, un MTA en su servidor que intenta enviar un correo electrónico).
Las tres interfaces ponen una ruta predeterminada en la tabla de rutas principal, aunque con diferentes métricas. Echemos un vistazo a la main
tabla de rutas con ip route show
:
default via 192.168.178.1 dev eth0 metric 100
default via 192.168.178.1 dev wlan1 metric 101
default via 192.168.178.1 dev wlan0 metric 102
192.168.178.0/24 dev wlan0 proto kernel scope link src 192.168.178.97
192.168.178.0/24 dev eth0 proto kernel scope link src 192.168.178.99
192.168.178.0/24 dev wlan1 proto kernel scope link src 192.168.178.98
Podemos ver que la tabla de rutas principales tiene tres rutas predeterminadas, aunque con diferentes métricas. La prioridad más alta es eth0, luego wlan1 y luego wlan0 porque los números métricos más bajos indican una prioridad más alta. Dado que eth0
tiene la métrica más baja, esta es la ruta predeterminada que se utilizará mientras eth0
esté activa. Si eth0
baja, el tráfico saliente cambiará a wlan1
.
Con esta configuración podemos escribir ping 8.8.8.8
en una terminal y ifdown eth0
en otra. ping
todavía debería funcionar porque porque ifdown eth0
eliminará la ruta predeterminada relacionada con eth0
, el tráfico saliente cambiará a wlan1
.
Las líneas posteriores aseguran que las tablas de rutas relacionadas se eliminen de la base de datos de políticas de enrutamiento ( ip rule show
) cuando la interfaz deja de funcionar, para mantener todo ordenado.
El problema que queda es que cuando desconecta el enchufe de eth0
la ruta predeterminada eth0
todavía está allí y el tráfico saliente falla. Necesitamos algo para monitorear nuestras interfaces y ejecutarlas ifdown eth0
si hay un problema con la interfaz (es decir, falla de NIC o alguien que desconecta).
Último paso : entrar ifplugd
. Es un demonio que mira las interfaces y se ejecuta ifup/ifdown
si desconectas o si hay un problema con la conexión wifi /etc/default/ifplugd
:
INTERFACES="eth0 wlan0 wlan1"
HOTPLUG_INTERFACES=""
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"
Ahora puede conectar el enchufe eth0
, el tráfico saliente cambiará a wlan1
y si vuelve a enchufarlo, el tráfico saliente volverá a cambiar eth0
. Su servidor permanecerá en línea mientras funcione cualquiera de las tres interfaces. Para conectarse a su servidor, puede usar la dirección IP de eth0 y, si eso falla, la dirección IP de wlan1 o wlan0.