# 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
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
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
[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.
[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.
[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.
[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.
[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?