Balanceamento de 3 links com redundância no Linux

Como continuação do artigo anterior, neste apresento um script atualizado e modificado para uso de redundância entre 3 links de internet.

[ Hits: 66.457 ]

Por: Cristiano Landsmann em 08/06/2009


Script gwping.sh



#!/bin/bash -x

IPTABLES=/sbin/iptables

# Convencionalmente " 0 " indica sucesso neste script.

# Tempo entre verificações em segundos
SLEEPTIME=5

# Endereço IP ou nome de domínio para o ping. O roteiro baseia-se no domínio a ser pingável e sempre disponível.
TESTIP=200.98.249.120

# Ping Timeout em segundos.
TIMEOUT=3

# Interfaces externas.
EXTIF1=eth1
EXTIF2=eth2
EXTIF3=eth3

# Endereço IP de interfaces externas. Este não é o endereço do gateway.
IP1=192.168.1.10
IP2=192.168.2.10
IP3=192.168.3.10

# Gateway endereços IP. Este é o primeiro (hop) gateway, poderia ser o seu router IP endereço, se tiver sido configurado como o gateway.
GW1=192.168.1.1
GW2=192.168.2.1
GW3=192.168.3.1

# Pesos relativos de rotas. Guarde este para um baixo valor inteiro. Estou usando 1 para GVT porque é 3 vezes mais rápida.
W1=1
W2=1
W3=1

# Nome dos Provedores; utilizar os seus próprios nomes aqui.
NAME1=gvt
NAME2=brt
NAME3=net

# N º de repetições de sucesso ou fracasso antes de mudar status de conexão.
SUCCESSREPEATCOUNT=1
FAILUREREPEATCOUNT=4

## Não mudar nada abaixo desta linha.

# Última link status indica que a macro estado da ligação é determinada.
#Trata-se inicialmente em vigor estabelece encaminhamento mudança adiantado. Não alterar estes valores.
LLS1=1
LLS2=1
LLS3=1

# Última ping estado. Não alterar estes valores.
LPS1=1
LPS2=1
LPS3=1

# Ping atual estatuto. Não alterar estes valores.
CPS1=1
CPS2=1
CPS3=1

# Mudança link status indica que a ligação tem de ser mudado. Não alterar estes valores.
CLS1=1
CLS2=1
CLS3=1

# Conde de repetidos até estatuto ou para baixo estatuto. Não alterar estes valores.
COUNT1=0
COUNT2=0
COUNT3=0

while : ; do
        ping -W $TIMEOUT -I $IP1 -c 1 $TESTIP > /dev/null  2>&1
        RETVAL=$?

        if [ $RETVAL -ne 0 ]; then
      echo $NAME1 Down
      CPS1=1
        else
      CPS1=0
        fi

   if [ $LPS1 -ne $CPS1 ]; then
      echo `date +%x" "%X` Ping status changed for $NAME1 from $LPS1 to $CPS1
      COUNT1=1
   else
      if [ $LPS1 -ne $LLS1 ]; then
         COUNT1=`expr $COUNT1 + 1`
      fi
   fi

        if [[ $COUNT1 -ge $SUCCESSREPEATCOUNT || ($LLS1 -eq 0 && $COUNT1 -ge $FAILUREREPEATCOUNT) ]]; then
      echo `date +%x" "%X` Uptime status will be changed for $NAME1 from $LLS1
      CLS1=0
      COUNT1=0
      if [ $LLS1 -eq 1 ]; then
         LLS1=0
      else
         LLS1=1
      fi
   else
      CLS1=1
        fi

   LPS1=$CPS1

   ping -W $TIMEOUT -I $IP2 -c 1 $TESTIP > /dev/null  2>&1
          RETVAL=$?

   if [ $RETVAL -ne 0 ]; then
      echo `date +%x" "%X` $NAME2 Down
                CPS2=1
        else
                CPS2=0
        fi

        if [ $LPS2 -ne $CPS2 ]; then
      echo `date +%x" "%X` Ping status changed for $NAME2 from $LPS2 to $CPS2
                COUNT2=1
        else
                if [ $LPS2 -ne $LLS2 ]; then
                        COUNT2=`expr $COUNT2 + 1`
                fi
        fi

        if [[ $COUNT2 -ge $SUCCESSREPEATCOUNT || ($LLS2 -eq 0 && $COUNT2 -ge $FAILUREREPEATCOUNT) ]]; then
      echo `date +%x" "%X` Uptime status will be changed for $NAME2 from $LLS2
      CLS2=0
      COUNT2=0
                if [ $LLS2 -eq 1 ]; then
                        LLS2=0
                else
                        LLS2=1
                fi
   else
      CLS2=1
        fi

   LPS2=$CPS2

   ping -W $TIMEOUT -I $IP3 -c 1 $TESTIP > /dev/null  2>&1
          RETVAL=$?

   if [ $RETVAL -ne 0 ]; then
      echo `date +%x" "%X` $NAME3 Down
                CPS3=1
        else
                CPS3=0
        fi

        if [ $LPS3 -ne $CPS3 ]; then
      echo `date +%x" "%X` Ping status changed for $NAME3 from $LPS3 to $CPS3
                COUNT3=1
        else
                if [ $LPS3 -ne $LLS3 ]; then
                        COUNT3=`expr $COUNT3 + 1`
                fi
        fi

        if [[ $COUNT3 -ge $SUCCESSREPEATCOUNT || ($LLS3 -eq 0 && $COUNT3 -ge $FAILUREREPEATCOUNT) ]]; then
      echo `date +%x" "%X` Uptime status will be changed for $NAME3 from $LLS3
      CLS3=0
      COUNT3=0
                if [ $LLS3 -eq 1 ]; then
                        LLS3=0
                else
                        LLS3=1
                fi
   else
      CLS3=1
        fi

   LPS3=$CPS3


   if [[ $CLS1 -eq 0 || $CLS2 -eq 0 || $CLS3 -eq 0 ]]; then
  
      if [[ $LLS1 -eq 1 && $LLS2 -eq 0 && $LLS3 -eq 0 ]]; then
         echo `date +%x" "%X` Switching to $NAME2 #Se o link 1 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
            ip rule del fwmark 0x10 lookup gvt prio 3
         ip rule add from 192.168.3.10 table net
         ip rule add from 192.168.2.10 table brt
         ip rule add fwmark 0x30 lookup net prio 3
         ip rule add fwmark 0x20 lookup brt prio 3
         ip route replace default scope global nexthop via $GW2 dev $EXTIF2 weight $W2 nexthop via $GW3 dev $EXTIF3 weight $W3
         ip route flush cache
      #Para usar a marcação de pacotes descomente as linhas abaixo, e comente a linha acima logo após o
#último comando nexthop para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3  
         #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK --set-mark 0x30
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport --dports 110,25 -j MARK --set-mark 0x20  
         cat /etc/link/resolv.conf > /etc/resolv.conf
        
      elif [[ $LLS2 -eq 1 && $LLS1 -eq 0 && $LLS3 -eq 0 ]]; then
         echo `date +%x" "%X` Switching to $NAME1 #Se o link 2 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
           ip rule del fwmark 0x20 lookup brt prio 3
         ip rule add from 192.168.1.10 table gvt
         ip rule add from 192.168.3.10 table net
         ip rule add fwmark 0x10 lookup gvt prio 3
         ip rule add fwmark 0x30 lookup net prio 3        
         ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW3 dev $EXTIF3 weight $W3
         ip route flush cache
      #Para usar a marcação de pacotes descomente as linhas abaixo, comente a linha acima logo após o
#último comando nexthop para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK --set-mark 0x30  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp --dport 443 -j MARK --set-mark 0x10  
         cat /etc/link/resolv.conf > /etc/resolv.conf
              
      
      elif [[ $LLS1 -eq 0 && $LLS2 -eq 0 && $LLS3 -eq 1 ]]; then
         echo `date +%x" "%X` Switching to $NAME1 #Se o link 3 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
         ip rule del fwmark 0x30 lookup net prio 3
         ip rule add from 192.168.1.10 table gvt
         ip rule add from 192.168.2.10 table brt
         ip rule add fwmark 0x10 lookup gvt prio 3
         ip rule add fwmark 0x20 lookup brt prio 3
         ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW2 dev $EXTIF2 weight $W2
         ip route flush cache
      #Para usar a marcação de pacotes descomente as linhas abaixo.  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport --dports 110,25 -j MARK --set-mark 0x20  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp --dport 443 -j MARK --set-mark 0x10  
         cat /etc/link/resolv.conf > /etc/resolv.conf
        
        
      elif [[ $LLS2 -eq 0 && $LLS3 -eq 1 && $LLS1 -eq 1 ]]; then
         echo `date +%x" "%X` Switching to $NAME2#Se o link 1 e 3 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
            ip route replace default scope global via $GW2 dev $EXTIF2
         ip rule del fwmark 0x10 lookup gvt prio 3
         ip rule del fwmark 0x30 lookup net prio 3
         ip route flush cache
         cat /etc/link/resolv.conf > /etc/resolv.conf
        
      elif [[ $LLS3 -eq 0 && $LLS2 -eq 1 && $LLS1 -eq 1 ]]; then
         echo `date +%x" "%X` Switching to $NAME3#Se o link 1 e 2 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
            ip route replace default scope global via $GW3 dev $EXTIF3
         ip rule del fwmark 0x20 lookup brt prio 3
         ip rule del fwmark 0x10 lookup gvt prio 3
         ip route flush cache
         cat /etc/link/resolv.conf > /etc/resolv.conf
        
      elif [[ $LLS1 -eq 0 && $LLS2 -eq 1 && $LLS3 -eq 1 ]]; then
         echo `date +%x" "%X` Switching to $NAME1#Se o link 2 e 3 cair
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
            ip route replace default scope global via $GW1 dev $EXTIF1
         ip rule del fwmark 0x20 lookup brt prio 3
         ip rule del fwmark 0x30 lookup net prio 3
         ip route flush cache
         cat /etc/link/resolv.conf > /etc/resolv.conf
        
      elif [[ $LLS1 -eq 0 && $LLS2 -eq 0 && $LLS3 -eq 0 ]]; then
         echo `date +%x" "%X` Restoring default load balancing
         echo "Limpando todas as regras da tabela mangle ....."
         iptables -F -t mangle
         iptables -X -t mangle
         echo "Regras limpas ....."
         ip route replace default scope global nexthop via $GW1 dev $EXTIF1 weight $W1 nexthop via $GW2 dev $EXTIF2 weight $W2 nexthop via $GW3 dev $EXTIF3 weight $W3
         ip rule add from 192.168.1.10 table gvt
         ip rule add from 192.168.2.10 table brt
         ip rule add from 192.168.3.10 table net
         ip rule add fwmark 0x10 lookup gvt prio 3
         ip rule add fwmark 0x20 lookup brt prio 3
         ip rule add fwmark 0x30 lookup net prio 3
         ip route flush cache
      #Para usar a marcação de pacotes descomente as linhas abaixo, comente a linha acima logo após o último comando nexthop
#para desativar o balanceamento do 3 link ex.: #nexthop via $GW3 dev $EXTIF3 weight $W3  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.6 -j MARK --set-mark 0x30  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp -m multiport --dports 110,25 -j MARK --set-mark 0x20  
      #$IPTABLES -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 0/0 -p tcp --dport 443 -j MARK --set-mark 0x10  
         cat /etc/link/resolv.conf > /etc/resolv.conf
      fi
   fi
        sleep $SLEEPTIME
done

Página anterior    

Páginas do artigo
   1. Introdução
   2. Modificando as tabelas e rotas
   3. Script gwping.sh
Outros artigos deste autor

Balanceamento de links + redundância + acesso remoto + sites de bancos

Squid - Níveis de bloqueio para usuários

Leitura recomendada

DNS no Slackware

Exemplos práticos de tabelas de partições

GoboLinux? Que distro é essa? (Parte 3 - Instalando programas)

Debian Wheezy - Instalação e utilização em desktops

Driver ATI (proprietário) no kernel 2.6.29 e posteriores

  
Comentários
[1] Comentário enviado por gustavoisouza em 09/06/2009 - 07:50h

Primeiramente parabéns pelo artigo.
Já implementei algumas vezes balanceamento, parando nesse problema de sites de banco que interrompem a conexão quando identificam a troca do IP proveniente.
Não tive a chance de testar se poderíamos colocar, em vez do nome de todos os bancos no IPTABLES, colocar --dport 443 para sair por 1 link só resolveria esse problema.

[2] Comentário enviado por info24hs em 09/06/2009 - 08:20h

Amigo,

Veja esse exemplo abaixo, essa regra uso atualmente para me conectar com o Banrisul. Entenda a regra, tudo que vier pela interface da rede interna com origem da minha rede interna e com destino ao ip do banco usando protocolo tcp e as portas 80 e 443 são marcadas para sair pelo link 1. Coloque o ip do banco ai invés do nome para evitar resolução de nomes ou alguma falha com o dns.

# Marcação Banco Banrisul
iptables -I PREROUTING -t mangle -i eth0 -s 192.168.0.0/24 -d 201.55.240.10 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 0x10

Utilizo essa regra para o Banrisul e tmb tenho outras similar para acessar outros bancos...

Abraço..

[3] Comentário enviado por gustavoisouza em 09/06/2009 - 08:31h

Entendi.....

Meu intuito era reduzir o número de linhas e trabalho para pegar todos os IP`s de banco ou outros sites que usam esse tipo de restrição de segurança na unha..... Mas perfeito.

Novamente parabéns, e em breve testo por aqui.

Abç.

[4] Comentário enviado por rafaelturazzi em 10/06/2009 - 08:26h

Parabéns pelo artigo!
Apenas uma pergunta: Como você trabalha com 3 links, você usa no linux as 3 rotas (uma de cada link) ou somente a do link com maior banda? Pergunto isso para saber como devemos proceder para sar um suporte remoto, entro por qual link?
Abraços,
Rafael

[5] Comentário enviado por info24hs em 10/06/2009 - 09:36h

Rafael,

Como tu pode ter visto no esquema acima é necessário configurar as 3 rotas.. uma para cada link, a seguir o comando que irá fazer o balanceamento configura a primeira rota como padrão do sistema, ou seja a segunda rota e a terceira na respectiva ordem. Veja exemplo:

# 1º rota ip x.x.1.1, 2º rota ip x.x.2.1, 3º rota ip x.x.3.1, nesse exemplo a rota padrao será o link 1 porque ele esta na frente de todos. A primeira conexão estabelecida sempre é feita pelo link da rota padrão do sistema, no caso abaixo o 3º será o último link a ser utilizado.

ip route add default scope global nexthop via 192.168.1.1 dev eth1 weight 2 nexthop via 192.168.2.1 dev eth2 weight 1
nexthop via 192.168.3.1 dev eth3 weight 1

# Veja abaixo a regra para acesso remoto configurada e marcada para ser usado pelo link 2, lembrando que o link 1 é a minha rota padrão.

iptables -I FORWARD -p tcp --dport 4893 -j ACCEPT
iptables -t nat -I PREROUTING -i eth2 -p tcp --dport 4893 -j DNAT --to-dest 192.168.0.3
iptables -t mangle -A PREROUTING -p tcp -s 192.168.0.3 --sport 4893 -j MARK --set-mark 0x20


[6] Comentário enviado por qxada07 em 21/06/2009 - 08:26h

Cara.... Meus parabéns... Paguei um pau para este artigo.... Te garanto que muita genth irá precisar deste artigo...

Flw e continue assim!!!!!!!!!!

[7] Comentário enviado por gersonraymond em 24/07/2009 - 20:59h

Amigo dispensa comentários, pois trata -se de artigo de extrema utilidade, show de bola !!! Parabéns !!! e muito mais.

Um grande abraço.

[8] Comentário enviado por fell em 19/11/2009 - 10:04h

Uma duvida como este script faz a chacagem dos links,pois estou vendo que ele checa quando se executa o script,mas depois de carregando o script como que é feito esta checagem dos links.

[9] Comentário enviado por wellington.linux em 12/05/2010 - 16:46h

Ola, tenho uma dúvida e se o link que caiu voltar, esse script vai entender e voltar tudo ao normal?

[10] Comentário enviado por faosfbi em 16/11/2010 - 14:44h

Olá, primeiramente parabenizo pelo excelente artigo, de grande utilidade.
Apenas tenho uma dúvida.
Quando faço um teste de velocidade de uma estação de trabalho que está dentro desta infraestrutura o mesmo me retorna a velocidade de um link e não a somatória de todos os links. É assim mesmo ou o resultado teria de ser a soma de todos os links?

[11] Comentário enviado por giuseppeinfo em 28/03/2014 - 13:11h

Bom dia,

Meu script da erro no while :; do, tem alguma solução para isso.

Obrigado

[12] Comentário enviado por wagnerfs em 09/09/2014 - 18:16h

Parabéns amigo por compartilhar o conhecimento. Sucesso em tua vida.

[13] Comentário enviado por nunesdutra em 06/07/2015 - 11:37h


Bom dia Amigos!!!!

Estou com uma duvida!!!

Eu preciso do SCRIPT GWPING.SH para funcionar? Ou se eu apenas acrescentar as linhas no RC.local ja estarei em redundância???

Obrigado!!!


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts