Quando alias de IP, como o sistema operacional determina qual endereço IP será usado como fonte para conexões TCP / IP de saída?

15

Eu tenho um servidor rodando o Ubuntu Server com quatro endereços IP em um único NIC.

eth0       192.168.1.100
eth0:0     192.168.1.101
eth0:1     192.168.1.102
eth0:2     192.168.1.103

(Usando 192.168.x.x para fins de exemplo, suponha que estes sejam NAT-ed para um intervalo de endereços IP públicos)

Um de nossos clientes publica seu inventário via FTP, então fazemos login todas as noites para baixar um arquivo grande do servidor dele. Seu firewall espera que nossa conexão FTP (passiva) seja feita a partir de 192.168.1.100.

Dado que o meu servidor tem logicamente quatro endereços IP em um único adaptador, como o sistema operacional determina qual endereço IP é usado como fonte para conexões TCP / IP de saída?

Digamos que eu ssh no meu servidor em 192.168.1.101 e execute FTP interativamente. A conexão TCP / IP de saída usará 192.168.1.101 porque o sistema operacional sabe que essa é a interface na qual meu shell está conectado?

E se a tarefa de FTP for executada de forma não interativa através de uma tarefa cron onde não exista shell?

Como você provavelmente pode dizer, isso me deixa bastante confuso, então espero que minhas perguntas tenham pelo menos fez sentido.

Editar

Para esclarecer por que estou perguntando - eu não fiz nenhuma alteração na tabela de roteamento e ela realmente lista 'eth0' como o IFace para as rotas 0.0.0.0. No entanto, todas as indicações são de que ele está realmente usando eth0: 0 como a origem.

Destination    Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
0.0.0.0        192.168.1.1     0.0.0.0         UG    100    0        0 eth0

Eu posso mexer com a tabela de roteamento ou fazer com que nosso cliente mude suas regras de firewall para obter o comportamento de que preciso, mas estou tentando entender um pouco como isso funciona para saber se há um bug no SO ou apenas minha compreensão ingênua de como todas as peças se encaixam.

Obrigado

    
por Joe Holloway 26.05.2009 / 18:26

6 respostas

12

Por padrão, no Linux, se uma interface tiver vários endereços que estejam em sub-redes diferentes, o tráfego destinado às respectivas sub-redes terá o IP de origem adequado. Isto é, se eth0 tiver dois endereços 192.168.1.1/24 e 10.1.1.1/8, então o tráfego para qualquer coisa na sub-rede 10.0.0.0 terá a origem 10.1.1.1 e o tráfego para qualquer coisa na sub-rede 192.168.1.0 terá origem 192.168.1.1. Você também pode atribuir endereços de origem explicitamente neste caso usando a opção "src 1.2.3.4" para "ip route".

No seu caso, porém, todos os seus endereços estão na mesma sub-rede, então o "principal" (como revelado por "ip addr lista dev eth0") é usado como o IP de origem para o tráfego que sai naquela interface. Acho que é possível controlar os IPs de origem neste caso usando apenas "ip route", mas achei mais fácil usar o iptables para reescrever os endereços de origem para o tráfego de interesse.

Se você deseja forçar um endereço de origem específico a ser usado para destinos específicos, é possível fazer isso com uma regra SNAT:

iptables -t nat -I POSTROUTING -o eth0 -d dest-IP-or-net/mask -s primary-IP-of-eth0 -j SNAT --to-source desired-source-IP

Então, se o seu endereço IP "primário" é 192.168.100.1, mas você quer que o tráfego para 1.2.3.4 tenha uma fonte 192.168.100.2, faça o seguinte:

iptables -t nat -I POSTROUTING -o eth0 -d 1.2.3.4/0 -s 192.168.100.1 -j SNAT --to-source 192.168.100.2

Note que o "-s 192.168.100.1" é importante: impede que os endereços de origem do tráfego encaminhado sejam reescritos por esta regra.

Se você pretende implementar configurações complexas de rede no Linux, leia a documentação sobre Roteamento e Controle de Tráfego Avançado do Linux, link

    
por 23.07.2009 / 04:58
5

Eu vejo no seu exemplo que todos os ips estão muito próximos para não estarem na mesma rede

tem a certeza de que está realmente multihoming e não tem apenas 4 aliases IP?

se este for o caso, então você pode definir o ip de origem em uma rota com algo semelhante a este

/sbin/ip route show 192.168.222.0/24 dev eth0 proto kernel scope link src 192.168.222.178 169.254.0.0/16 dev eth0 scope link default via 192.168.222.1 dev eth0

sudo /sbin/ip route replace default via 192.168.222.1 src 192.168.222.178

/sbin/ip route show
192.168.222.0/24 dev eth0 proto kernel scope link src 192.168.222.178 169.254.0.0/16 dev eth0 scope link default via 192.168.222.1 dev eth0 src 192.168.222.178

veja interfaces homem sobre como torná-lo persistente entre reinicializações

    
por 26.05.2009 / 18:58
5

Ele usa qualquer gateway padrão na tabela de roteamento, a menos que haja uma rota específica informando para usar outro: route -n

EDIT: Eu li sua pergunta muito rápido, parece ...

Como você está usando o modo passivo e o cliente sempre estará iniciando a conexão, acho que o campo src ip no cabeçalho IP sempre aparecerá como qualquer IP do cliente conectado. Se fosse o modo ativo o servidor estava iniciando a conexão, acho que seria sempre o IP 'Primário'. Se os seus endereços estiverem na mesma sub-rede, o Linux fará o primeiro endereço que você adicionou 'Primário' e os outros secundários.

Eu não tenho certeza, eu iria rodar o tcpdump -n e ver o que ele vê como o src IP.

EDIT2: Ok, escrevi o texto acima do ponto de vista de que você estava executando o servidor, portanto, como você é o cliente e inicia a conexão, acho que sempre parecerá vir do endereço IP Primário, mas tente novamente e veja com o tcpdump.

    
por 26.05.2009 / 18:30
4

A menos que seu trabalho de FTP tenha uma maneira de especificar a interface a ser usada para conexões, acredito que o padrão seja a primeira interface física na sub-rede relevante (eth0, neste caso). Se você tivesse um servidor com duas NICs em diferentes sub-redes, ele descobriria qual interface usar com base na tabela de roteamento.

Como há apenas uma única interface física no sistema (eth0) e quatro virtuals / aliases (eth0: 0 até eth0: 2) na mesma sub-rede, o tráfego de saída usará o endereço IP eth0 como origem, a menos que o aplicativo é inteligente o suficiente para declarar uma interface de saída.

    
por 26.05.2009 / 19:59
4

Você pode ver qual dispositivo e endereço IP src serão usados pelo comando ip route get, como abaixo:

$ /sbin/ip route get 1.1.1.1
1.1.1.1 via 2.2.2.2 dev eth0  src 2.2.2.2 
    cache  mtu 1500 advmss 1460 hoplimit 64

Eu não tentei isso em um ambiente com alias, mas espero que isso ajude.

    
por 24.06.2009 / 20:35
1

Ao estabelecer uma conexão de saída, seu servidor procurará em sua tabela de roteamento para determinar quais de suas quatro interfaces usar; suas conexões TCP terão um IP de origem de sua interface de saída.

netstat -rn

Irá dar-lhe a saída da sua tabela de roteamento; procure por entradas específicas que correspondam ao IP do cliente ao qual você está tentando se conectar. Se não existir, você estará usando uma rota padrão (0.0.0.0, máscara 0.0.0.0). Se você tiver várias rotas padrão, a que tiver o menor custo será a usada.

    
por 26.05.2009 / 20:41