Resolvi sozinho. Parece haver muito pouca informação sobre as coisas de rede que você pode fazer com o Linux, então eu decidi documentar e explicar minha solução em detalhes. Esta é minha configuração final:
- 3 NICs: eth0 (fio), wlan0 (wifi embutido, fraco), wlan1 (wifi usb adaptador, sinal mais strong que wlan0)
- Todos eles em uma única sub-rede cada um deles com seu próprio endereço IP.
- eth0 deve ser usado para tráfego de entrada e saída por padrão.
- Se eth0 falhar, então wlan1 deve ser usado.
- Se wlan1 falhar, wlan0 deve ser usado.
Primeiro passo :
Crie uma nova tabela de rotas para cada interface em /etc/iproute2/rt_tables
. Vamos chamá-los de rt1, rt2 e rt3
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep
1 rt1
2 rt2
3 rt3
Segunda etapa : configuração de rede em /etc/network/interfaces
. Esta é a parte principal e vou tentar explicar o máximo que puder:
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
Se você digitar ip rule show
, verá o seguinte:
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
Isso nos diz que o tráfego de entrada ou saída do endereço IP "192.168.178.99" usará a tabela de rotas rt1. Por enquanto, tudo bem. Mas o tráfego que é gerado localmente (por exemplo, você quer fazer ping ou ssh da máquina para outro lugar) precisa de tratamento especial (veja a grande cotação na pergunta).
As primeiras quatro linhas post-up em /etc/network/interfaces
são diretas e explicações podem ser encontradas na internet, a quinta e última linha post-up é aquela que faz a mágica acontecer:
post-up ip r add default via 192.168.178.1 metric 100 dev eth0
Observe como não especificamos uma tabela de rotas para essa linha de post-up. Se você não especificar uma tabela de rotas, as informações serão salvas na tabela main
route que vimos em ip rule show
. Essa linha de post-up coloca uma rota padrão na tabela de rotas "principal" usada para tráfego gerado localmente que não é uma resposta ao tráfego de entrada. (Por exemplo, um MTA no seu servidor tentando enviar um e-mail.)
As três interfaces colocam uma rota padrão na tabela de rotas principal, embora com métricas diferentes. Vamos dar uma olhada na tabela main
route com 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 a tabela de rotas principal tem três rotas padrão, embora com métricas diferentes. A prioridade mais alta é eth0, depois wlan1 e wlan0, porque números menores indicam uma prioridade mais alta. Como eth0
tem a menor métrica, essa é a rota padrão que será usada enquanto o eth0
estiver ativo. Se eth0
cair, o tráfego de saída mudará para wlan1
.
Com essa configuração, podemos digitar ping 8.8.8.8
em um terminal e ifdown eth0
em outro. ping
ainda deve funcionar porque, como ifdown eth0
removerá a rota padrão relacionada a eth0
, o tráfego de saída mudará para wlan1
.
As linhas post-down certificam-se de que as tabelas de rotas relacionadas sejam excluídas do banco de dados de políticas de roteamento ( ip rule show
) quando a interface cair, a fim de manter tudo em ordem.
O problema que resta é que quando você puxa o plugue de eth0
a rota padrão para eth0
ainda está lá e o tráfego de saída falha. Precisamos de algo para monitorar nossas interfaces e executar ifdown eth0
se houver um problema com a interface (ou seja, falha na placa de rede ou alguém puxando o plugue).
Última etapa : insira ifplugd
. Esse é um daemon que assiste interfaces e executa ifup/ifdown
se você puxar o plugue ou se houver problema com a conexão wifi /etc/default/ifplugd
:
INTERFACES="eth0 wlan0 wlan1"
HOTPLUG_INTERFACES=""
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"
Agora você pode obter o plugue em eth0
, o tráfego de saída mudará para wlan1
e, se você colocar o plugue novamente, o tráfego de saída voltará para eth0
. Seu servidor permanecerá online enquanto qualquer uma das três interfaces funcionar. Para conectar-se ao seu servidor, você pode usar o endereço IP da eth0 e, se isso falhar, o endereço IP de wlan1 ou wlan0.