Quando você diz a um aplicativo para usar um endereço IP específico, o aplicativo é usando o endereço IP , não a interface. Alguns aplicativos permitem usar uma interface específica, mas esse é um comportamento separado ( SO_BINDTODEVICE ).
Como o aplicativo é vinculado a um endereço IP, e não a uma interface, o kernel está livre para usar qualquer interface que desejar. Para determinar qual interface usar, ele usa as tabelas de roteamento (sim, existem várias).
Se você quiser apenas uma maneira rápida de determinar qual interface / rota o tráfego levará, use ip route get 1.2.3.99 from 1.2.3.4
, que produzirá algo como:
# ip route get 1.2.3.99 from 1.2.3.4
local 1.2.3.99 from 1.2.3.4 dev lo
cache <local>
Isso mostra que o kernel enviará o tráfego pela interface lo
.
Para percorrer o porquê, vamos começar com o comando ip rule
:
# ip rule
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
Isso mostra todas as tabelas de roteamento que o kernel vai usar para encontrar a rota para o tráfego. Começa com o topo e pára no primeiro jogo. O from all
significa que a regra corresponde a qualquer endereço de origem. Então, vai consultar a tabela local
primeiro. Podemos então olhar para dentro desta tabela:
# ip route show table local
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 1.2.3.0 dev eth0 proto kernel scope link src 1.2.3.4
local 1.2.3.4 dev eth0 proto kernel scope host src 1.2.3.4
broadcast 1.2.3.255 dev eth0 proto kernel scope link src 1.2.3.4
local 1.2.3.99 dev eth1 proto kernel scope host src 1.2.3.99
(o seu provavelmente será diferente)
A partir disso, verificamos se alguma das rotas corresponde ao endereço de destino (1.2.3.99), observando se o destino corresponde ao segundo campo. Na saída acima, a última coincide. Nesta linha, o primeiro campo é local
, que de acordo com man ip-route
significa:
local - the destinations are assigned to this host. The packets are looped back and delivered locally.
Isso significa que o tráfego fluirá pela interface lo
.
Quanto a como usar a interface A
/ B
, você tem duas opções:
1) O aplicativo precisaria fornecer um argumento onde você pode especificar a interface. Há uma dúzia de sabores de netcat, mas a versão em meus sistemas não tem essa opção. socat
faz isso (eu pessoalmente recomendo socat
over netcat por causa do pesadelo de inconsistência & portabilidade que é netcat. Também é muito mais poderoso).
2) Crie uma rota que não seja local
e corresponda antes do local
one:
ip route add local 1.2.3.99 dev B table main
ip route del local 1.2.3.99 dev B table local
ip route add 1.2.3.99 dev B table local
Nessas regras, as duas primeiras regras movem a rota local
para a tabela main
. A adição da rota à tabela main
deve vir primeiro, pois o host precisa ter uma rota local
em algum lugar para o kernel aceitar tráfego para esse endereço. Ter a rota em 2 tabelas está OK. Depois disso, adicionamos uma nova rota à tabela local
, que não possui a designação local
, o que resultará em tráfego que não ultrapasse a interface lo
.