Balanceamento de Carga

Este tuto foi feito em cima da distribuição Debian 5, com dois links de mesma velocidade.
Neste exemplo teremos 3 interface [eth0 192.168.1.100 e eth1 192.168.2.100 as duas internet] [eth2 192.168.3.1 rede local]

Primeiramente instalamos o pacote iproute 2
# aptitude update
# aptitude install iproute

Após configure as tabelas:

# vim /etc/iproute2/rt_tables
Adicione essas duas linhas no final do arquivo:

200 uplink1
201 uplink2

Vamos configurar nossa interface onde em eth0 192.168.1.1 / eth1 192.168.2.1 são os gateways
# vim /etc/network/interfaces

# LOCALHOST
auto lo
iface lo inet loopback

# LINK 1

auto eth0
iface eth0 inet static
        address 192.168.1.100
        netmask 255.255.255.0

        post-up ip route add 192.168.1.1/32 dev eth1 src 192.168.1.100 table uplink1
        post-up ip route add default via 192.168.1.1 table uplink1
        post-up ip rule add from 192.168.1.100 table uplink1
        post-down ip rule del from 192.168.1.100 table uplink1

# LINK 2

auto eth1
iface eth1 inet static
        address 192.168.2.100
        netmask 255.255.255.0

        post-up ip route add 192.168.2.1/32 dev eth1 src 192.168.2.210 table uplink2
        post-up ip route add default via 192.168.2.1 table uplink2
        post-up ip rule add from 192.168.2.210 table uplink2
        post-down ip rule del from 192.168.2.210 table uplink2

# REDE CLIENTE
auto eth2
iface eth2 inet static
        address 192.168.3.1
        netmask 255.255.255.0

Reinicie o serviço:
# /etc/init.d/networking restart

Agora vamos criar um firewall, criaremos as rotas.

#! /bin/sh

# Ativa forward
echo "1" > /proc/sys/net/ipv4/ip_forward

# Limpa regras
/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t nat -F
/sbin/iptables -X -t nat
/sbin/iptables -F -t mangle
/sbin/iptables -X -t mangle

# Carrega modulos
/sbin/modprobe iptable_nat
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_REJECT
/sbin/modprobe ipt_MASQUERADE

#Libera navegacao nas interfaces
/sbin/iptables -t nat -A POSTROUTING -s 192.168.30/24 -o eth0 -j MASQUERADE
/sbin/iptables -t nat -A POSTROUTING -s 192.168.30/24 -o eth1 -j MASQUERADE

# Configurações Proxy
# /sbin/iptables -t nat -A PREROUTING -i eth2 -p tcp --dport 80 -j REDIRECT --to-port 3128
# /sbin/iptables -A PREROUTING -t mangle -s 192.168.3.0/24 -d 0/0 -j MARK --set-mark 3
# /sbin/iptables -t mangle -A OUTPUT -p TCP -d ! 192.168.3.0/24 --dport 80 -m owner --uid-owner 23 -j MARK --set-mark 3

# Faz com que o servico dns faca consultas pelo outro link
/sbin/iptables -t mangle -A OUTPUT -p UDP --dport 53 -m owner --uid-owner 25 -j MARK --set-mark 2

# Deleta rotas
route del default

# Load balance
ip route add default scope global nexthop via 192.168.1.1 dev eth0 weight 1 nexthop via 192.168.2.1 dev eth1 weight 1

# Limpa cache
ip route flush cached

Use o comando “ip route show table main” para ver como ficou…
# ip route show table main

192.168.1.1/24 dev eth0 proto kernel scope link src 192.168.1.100
192.168.2.1/24 dev eth1 proto kernel scope link src 192.168.2.100
192.168.3.1/24 dev eth2 proto kernel scope link src 192.168.3.1
default
nexthop via 192.168.1.100 dev eth0 weight 1
nexthop via 192.168.2.100 dev eth1 weight 1

Adicione no cron o comando para limpar o cache dos dns a cada 10 min
# vim /etc/crontab
00-59/10 * * * * root ip route flush cached

Aqui fiz o siguinte script para verificar se algum dos link cai, assim refazendo a rota e deixadondo para o que estiver online.

# vim /root/uplink.sh

#! /bin/sh
# - - - - - - - - - - - - - - - #
# Script por Rudimar Remontti   #
# www.remontti.com.br           #
# - - - - - - - - - - - - - - - #
echo -e '\e[33;1mVerificando Links: \e[m'

# - - - - - - - - - - - #
# Configuracoes         #
# - - - - - - - - - - - #
GTW_1=192.168.1.1
ITF_1=eth0
GTW_2=192.168.2.1
ITF_2=eth1
RT_BRT_1=200.176.3.142 # Ip do terra.com.br ele ira pingar p/ verificar se responde
RT_BRT_2=200.176.3.142 # Ip do terra.com.br...
# - - - - - - - - - - - #

echo
echo -e "\e[30;1mLink 1: $GTW_1\e[m"
echo -e "\e[30;1mLink 2: $GTW_2\e[m"
echo 

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
PING_1=`ping $RT_BRT_1 -I $ITF_1 -c 1 |grep packets |cut -c 24`
PING_2=`ping $RT_BRT_2 -I $ITF_2 -c 1 |grep packets |cut -c 24`
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

UP=`echo "($PING_1 + $PING_2)" | bc`
if [ $UP = 2 ]; then 

        route del default
        ip route add default scope global nexthop via $GTW_1 dev $ITF_1 weight 1 nexthop via $GTW_2 dev $ITF_2 weight 1
        ip route flush cached

        echo -n 'Link 1 e Link 2  Status:     '
        echo -e '\e[32;1m[ ON ] \e[m'
        echo

elif [ $UP = 0 ]; then

        route del default
        ip route add default scope global nexthop via $GTW_1 dev $ITF_1 weight 1 nexthop via $GTW_2 dev $ITF_2 weight 1
        ip route flush cached

        echo
        echo -n Link 1:
        echo -e '\e[32;1m  [  OKAY  ] \e[m'
        echo -n Link 2:
        echo -e '\e[32;1m  [  OKAY  ] \e[m'
        echo

elif [ $UP = 1 ]; then
        echo
        if [ $PING_1 = 1 ]; then
                echo -n Link 1:
                echo -e '\e[32;1m  [  OKAY  ] \e[m'
        else
                route del default
                ip route add default scope global nexthop via $GTW_2 dev $ITF_2 weight 1
                ip route flush cached
                data=`date`
                echo "$data -> Link 1 OFF" >> /root/links.log
                echo -n Link 1:
                echo -e '\e[31;1m  [  OFF   ] \e[m'
        fi
        if [ $PING_2 = 1 ]; then
                echo -n Link 2:
                echo -e '\e[32;1m  [  OKAY  ] \e[m'
        else
                route del default
                ip route add default scope global nexthop via $GTW_1 dev $ITF_1 weight 1
                ip route flush cached
                data=`date`
                echo "$data -> Link 2 OFF" >> /root/links.log
                echo -n Link 2:
                echo -e '\e[31;1m  [  OFF   ] \e[m'

        fi
        echo
        if [ $PING_1 = 0 ]; then
                echo -e '\e[30;1mRotas reconfigurada, gatway através do Link 2.\e[m'
                ROTE=`ip route show |grep default |cut -c 9-100`
                echo -e "\e[30;1m$ROTE\e[m"

        elif [ $PING_2 = 0 ]; then
                echo -e '\e[30;1mRotas reconfigurada, gatway através do Link 1.\e[m'
                ROTE=`ip route show |grep default |cut -c 9-100`
                echo -e "\e[30;1m$ROTE\e[m"
        fi
else
        echo ERRO!
fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
echo
ip route show |grep nexthop
echo

# chmod 755 /root/uplink.sh

Adicionamos ao cron (5min)
# vim /etc/crontab
00-59/5 * * * * root /root/uplink.sh

Carregue seu firewall na inicialização do sistema, utilize o iptraf para ver o trafego saindo pelas duas interfaces.
Se vc tem dois link com cargas diferente altere o weight.

Abraço

Rudimar Remontti

Trabalho atualmente como Gerente de Redes em um Provedor de Internet no Rio Grande do Sul.

Você pode gostar...

3 Resultados

  1. Fabio Florezi disse:

    Tenho um link Speedy de 2mb e outro link via rádio de 3mb, como fica o weight?

  2. BRuno disse:

    E ae cara Parabéns por mais um artigo incrivel e muito util mais deu erro pra mim de sintaxe na linha do (echo “$data -> Link 1 OFF” >> /root/links.log)

    ele da esse erro ( syntax error near unexpected token `&’)

    mais de resto esta tudo ok deixei comentado ate achar a solução.
    flw.

  3. João Bosco disse:

    Eita tutorial porreta, tudo simplese claro com agua cristalina, esta funcionando… agora vamos ver como fazemos as liberações por um link amarrando os ips validos só pelo outro para não ficar caindo os ip validos quando muda o link… se alguem tiver uma dica eu ja agradeço antecipadamente…

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *