Agregando links (Load Balance) no Linux.

Como recentemente adquiri a internet via cabo (Ajato), resolvi buscar informações a respeito de como integrar a nova internet ao meu antigo Speedy, para efetivar um powerup na conexão!! E segue aqui o resultado da minha experiência… 😎

Como a conexão Ajato é via dhcp, utilizei uma placa de rede exclusiva para ela (pois não funcionaria o dhcp com a alias de um ip fixo em uma mesma interface de rede).

Essa é uma versão resumida da documentação que você pode encontrar em:
http://www.ssi.bg/~ja/

É preciso aplicar um patch e recompilar o kernel (de preferência a última versão, é possível utilizar o kernel 2.4 ou 2.6), além de adicionar os seguintes módulos, se já não estiverem adicionados:

Networking support
     Networking Options
          [x] TCP/IP Networking
          [x] IP: advanced router
          [x] IP: equal cost multipath
          [x] IP: Policy routing
          [x] Network packet filtering framework (netfilter)
                    IP: Netfilter Configuration
                         [x] Full NAT

Obs: Eu habilitei o suporte a NAT pois vou utilizar meu linux compartilhando as conexões agregadas. Para utilizar somente os dois links no linux, o NAT não é necessário, podendo-se suprimir as opções de NAT no kernel, as regras de NAT no script que segue abaixo.

Essas opções foram referentes ao kernel 2.6.19 e posteriores.
No kernel 2.4 precisa-se descobrir, mas basta saber que é preciso ativar:
[+] IP: advanced router
[+] IP: equal cost multipath

O patch referente à versão do seu kernel é encontrado em:
http://www.ssi.bg/~ja/#routes
Depois de aplicar o patch (patch -p1 < filename.diff) no kernel, compilar,  instalar e possivelmente reiniciar o linux, podemos prosseguir na próxima etapa.

Para simplificar a tarefa de configurar o roteamento, podemos utilizar o script a seguir. Modifique-o de acordo com o seu sistema.

#!/bin/bash

# Rede Interna
IFI=eth0           # Interface de rede
IPI=192.168.0.1    # IP da rede
NWI=192.168.0.0    # Endereco da rede
NMI=24             # Bit de netmask da rede
BRDI=192.168.0.255 # Broadcast da rede

# Interface Externa #1
IFE1=eth1           # Interface de rede
IPE1=201.20.193.50  # IP da rede
GWE1=201.20.192.1   # Gateway da rede
NWE1=201.20.193.0   # Endereco da rede
NME1=21             # Bit de netmask da rede
BRD1=201.20.199.255 # Broadcast da rede

# Interface Externa #2
IFE2=eth2            # Interface de rede
IPE2=200.206.217.169 # IP de rede
GWE2=200.206.217.129 # Gateway da rede
NWE2=200.206.217.128 # Endereco da rede
NME2=26              # Bit de netmask da rede
BRD2=200.206.217.191 # Broadcast da rede

##### Fim das configuracoes #####

# Regras de NAT
iptables -t nat -A POSTROUTING -o ${IFE1} -s ${NWI}/${NMI} -j SNAT to ${IPE1}
iptables -t nat -A POSTROUTING -o ${IFE2} -s ${NWI}/${NMI} -j SNAT to ${IPE2}

# Roteamento
ip rule add prio 50 table main
ip route del default table main
ip rule add prio 222 table 222
ip route add default table 222 proto static \
   nexthop via ${GWE1} dev ${IFE1} weight 1 \
   nexthop via ${GWE2} dev ${IFE2} weight 1
ip rule add prio 201 from ${NWE1}/${NME1} table 201
ip route add default via ${GWE1} dev ${IFE1} src ${IPE1} proto static table 201
ip route append prohibit default table 201 metric 1 proto static
ip rule add prio 202 from ${NWE2}/${NME2} table 202
ip route add default via ${GWE2} dev ${IFE2} src ${IPE2} proto static table 202
ip route append prohibit default table 202 metric 1 proto static
ip route flush cache

Depois de executar o script, o servidor já estará roteando pelas duas interfaces e compartilhando as conexões com a sua rede local! 😀

Podemos agregar mais de dois links com apenas algumas adições extras no script, que também pode ser definido para inicializar junto com o sistema.

Caso o IP seja dinâmico e o linux utilizar o dhcpcd para as requisições dhcp, é possível modificar o script para pegar as informações necessárias direto dos arquivos atualizados do dhcpd, como indicado a seguir:

# Interface Externa #1

IFE1=eth1   # Interface de rede
IPE1=`grep IPADDR /etc/dhcpc/dhcpcd-${IFE1}.info | awk -F= '{ print $2 }'`
GWE1=`grep GATEWAY /etc/dhcpc/dhcpcd-${IFE1}.info | awk -F= '{ print $2 }'`
NWE1=`grep NETWORK /etc/dhcpc/dhcpcd-${IFE1}.info | awk -F= '{ print $2 }'`
BRD1=`grep BROADCAST /etc/dhcpc/dhcpcd-${IFE1}.info | awk -F= '{ print $2 }'`
SNM1=`grep NETMASK /etc/dhcpc/dhcpcd-${IFE1}.info | awk -F= '{ print $2 }'`
NME1="`echo "$SNM1" | awk '{ split($0,array,"."); print "obase=2;" array[1] }' | bc`"
NME1="$NME1`echo "$SNM1" | awk '{ split($0,array,"."); print "obase=2;" array[2] }' | bc`"
NME1="$NME1`echo "$SNM1" | awk '{ split($0,array,"."); print "obase=2;" array[3] }' | bc`"
NME1="$NME1`echo "$SNM1" | awk '{ split($0,array,"."); print "obase=2;" array[4] }' | bc`"
NME1="`echo $NME1 | sed 's/1/1\n/g' | grep "1" | wc -l`"

4 ideias sobre “Agregando links (Load Balance) no Linux.

  1. Olá Eduardo, muito bom o artigo, parabens!
    Uma dúvida, para Debian 6.05 será preciso recompilar o kernel também ou já esta nativo?
    Existe alguma maneira de verificar antes?

    Obrigado!

    • Olá Thiago! Obrigado pelo cumprimento!

      Como o patch citado no artigo não faz parte dos kernels antigos será preciso recompilá-lo, e nesse caso já pode-se aproveitar e verificar se as opções necessárias também estarão presentes no novo kernel.

      Acredito que talvez os novos kernels já possuam código similar que facilitem o agregamento dos links.

      Abraços e boa sorte!

  2. Caro Eduardo,
    Realmente para novos Kernels não precisa fazer nada, apenas criar os roteamentos!

    O que acontece se um dos links cair ? o iproute sabe que o link está fora e para de encaminhar pacotes por ele? Se ele está fazendo 50/50, significa que vc tera perda de pacotes quando um link cair, correto ?

    Abraços!

    • Boas novas então!

      Tecnicamente o linux tenta enviar o pacote por uma interface e se falhar tenta pela outra.. não deve ter grande perda de pacotes mas sim algum atraso quando um link cair..

      Abraços!

Escreva seu comentário: