De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Altemir Braz Dantas Junior
Data de Publicação: 10 de outubro de 2011
Sempre fiz balanceamento de links com ip fixo usando iproute2 + iptables, até que um cliente que tinha 3 links de internet com ip dinamico, ai pensei "puts vai zoar as rotas do balanceamento toda hora que trocar o gateway, vou ter que criar varios scripts para ficar monitorando e trocar a rota, vamos googlear".
O google é meu pastor e nada me faltará. rsrsrsr
Achei o que queria e vou apresentar-lo meu salvador dhclient-script, disponível a partir da versão 3 do dhclient.
Verifiquei que através dele eu poderia pegar informações importantes como as do exemplo abaixo
OBS: Nao mencionarei regras de iptables (INPUT, OUTPUT, FORWARD , MASQUERADE e etc) aqui, somente a criacao das rotas
reason='RENEW' interface='eth1' medium='' alias_ip_address='' new_ip_address='189.xxx.xxx.xxx' new_subnet_mask='255.255.240.0' new_domain_name='' new_domain_search='' new_domain_name_servers='8.8.8.8 4.2.2.2' new_routers='189.xxx.xxx.1' new_static_routes='' old_ip_address='189.yyy.yyy.yyy' old_subnet_mask='255.255.240.0' old_domain_name='spo.virtua.com.br' old_domain_search='' old_domain_name_servers='8.8.8.8 4.2.2.2' old_routers='189.yyy.yyy.1' old_static_routes=''
E o melhor ele me retorna como variaveis para eu usar no meu shell script na hora de cada ação
O dhclient-script usa o Bourne Shell.
Para voces entenderem melhor leiam o man.
Ambiente
Como uso debian vou mostrar como fiz nesta distribuição.
Instalando pacotes necessários
apt-get install dhclient3 ipcalc iproute2
Primeiramente vou criar as tabelas no iproute2
echo "201 link1" >> /etc/iproute2/rt_tables echo "202 link2" >> /etc/iproute2/rt_tables echo "203 link3" >> /etc/iproute2/rt_tables
Agora cria minhas functions
mkdir /etc/scripts vi /etc/scripts/function.sh
Contendo o seguinte
# recebe a interface da rede e retorna o nome da tabela cadastrada
pega_tabela(){
DEV=$1
case $DEV in
eth1)
TABELA="link1"
return 1
break
;;
eth2)
TABELA="link2"
return 1
break
;;
eth3)
TABELA="link3"
return 1
break
;;
esac
}
# recebe a interface da rede e retorna o numero da marcacao para poder usar rotas pela marcacao feita pelo iptables
pega_marca(){
DEV=$1
case $DEV in
eth1)
MARK="1"
return 1
break
;;
eth2)
MARK="2"
return 1
break
;;
eth3)
MARK="3"
return 1
break
;;
esac
}
# recebe a interface da rede e retorna o peso para fazer o balanceamento
pega_peso(){
DEV=$1
case $DEV in
eth1)
PESO="6"
return 1
break
;;
eth2)
PESO="3"
return 1
break
;;
eth3)
PESO="1"
return 1
break
;;
esac
}
# recebe a tabela e retorna o ip do gateway da mesma
pega_gateway(){
TABELA=$1
GATEWAY=$(ip route show table $TABELA | grep default | awk -F' ' '{ print $3 }')
}
# recebe a tabela e deleta todas as rotas da mesma
del_rotas(){
/sbin/ip route flush table $1
}
# recebe a tabela e deleta todas as regras da mesma
del_regras(){
ip rule show | grep $1 | cut -d : -f2 | while read RULES; do ip rule del $RULES ; done
}
# recebe a tabela,ip,marca e cria regras de roteamento para aquela tabela
add_regras(){
TABELA=$1
IP=$2
MARK=$3
ip rule add fwmark $MARK table $TABELA
ip rule add from $IP table $TABELA
}
# recebe a tabela,ip,interface,ip da rede e o ip do gateway para criar as rotas para aquela tabela
add_rotas(){
TABELA=$1
IP=$2
DEV=$3
REDE=$4
GW=$5
/sbin/ip route add $REDE dev $DEV src $IP table $TABELA
/sbin/ip route add default via $GW dev $DEV table $TABELA
}
# deleta todas as rotas padrao
del_rotas_padrao(){
# deletando as rotas default
# deleta a rota criada pelo dhcp
/sbin/ip route del default
# deleta a rota do balanceamento
/sbin/ip route del default
}
# recebe interface,ip do gateway e peso para criar as regras de balanceamento
add_rota_balanceamento(){
DEVNEW=$1
GWNEW=$2
PESONEW=$3
case $DEVNEW in
eth1)
pega_tabela eth2
pega_peso eth2
pega_gateway $TABELA
TABELA2=$TABELA
PESO2=$PESO
GW2=$GATEWAY
DEV2=eth2
pega_tabela eth3
pega_peso eth3
pega_gateway $TABELA
TABELA3=$TABELA
PESO3=$PESO
GW3=$GATEWAY
DEV3=eth3
;;
eth2)
pega_tabela eth1
pega_peso eth1
pega_gateway $TABELA
TABELA2=$TABELA
PESO2=$PESO
GW2=$GATEWAY
DEV2=eth1
pega_tabela eth3
pega_peso eth3
pega_gateway $TABELA
TABELA3=$TABELA
PESO3=$PESO
GW3=$GATEWAY
DEV3=eth3
;;
eth3)
pega_tabela eth1
pega_peso eth1
pega_gateway $TABELA
TABELA2=$TABELA
PESO2=$PESO
GW2=$GATEWAY
DEV2=eth1
pega_tabela eth2
pega_peso eth2
pega_gateway $TABELA
TABELA3=$TABELA
PESO3=$PESO
GW3=$GATEWAY
DEV3=eth2
;;
esac
if [ "$GWNEW" == "0" ]; then
if [ "$GW2" != "" -a $GW3 != "" ]; then
/sbin/ip route add default nexthop via $GW2 dev $DEV2 weight $PESO2 nexthop via $GW3 dev $DEV3 weight $PESO3
else
if [ "$GW2" != "" ]; then
/sbin/ip route add default via $GW2
else
/sbin/ip route add default via $GW3
fi
fi
else
if [ "$GW2" != "" -a $GW3 != "" ]; then
/sbin/ip route add default nexthop via $GWNEW dev $DEVNEW weight $PESONEW nexthop via $GW2 dev $DEV2 weight $PESO2 nexthop via $GW3 dev $DEV3 weight $PESO3
else
if [ "$GW2" != "" ]; then
/sbin/ip route add default nexthop via $GWNEW dev $DEVNEW weight $PESONEW nexthop via $GW2 dev $DEV2 weight $PESO2
else
if [ "$GW3" != "" ]; then
/sbin/ip route add default nexthop via $GWNEW dev $DEVNEW weight $PESONEW nexthop via $GW3 dev $DEV3 weight $PESO3
else
/sbin/ip route add default via $GWNEW
fi
fi
fi
fi
return 1;
}
Criado o arquivo das functions agora vou criar os scripts para o dhclient-script
Dentro do diretorio /etc/dhcp/ existem dois diretorios o dhclient-enter-hooks.d/ e o dhclient-exit-hooks.d/ e o arquivo dhclient.conf
No arquivo dhclient.conf procure a linha comentada
#prepend domain-name-servers
Descomente e coloque os seguintes DNS publicos
prepend domain-name-servers 8.8.8.8 4.2.2.2;
Assim toda vez que o servidor dhcp nos atribuir seus servidores DNS ele vai adicionar esses 2 antes do dele.
Em relação aos diretorios antes dele, fazer alteracoes em nosso /etc/resolve.conf o dhclient script vai checar se há scripts primeiramente dentro de dhclient-enter-hooks.d/ usando o "." (ponto).
Quem usa Bourne Shell (bash) sabe que é como um include no diretorio. Depois de executar ele faz a mesma operacao no diretorio dhclient-exit-hooks.d/
Para mais informações
man dhclient-script
Criei então o seguinte script dentro do diretorio dhclient-enter-hooks.d/:
vi /etc/dhcp/dhclient-enter-hooks.d/rotas_avancadas
Contendo
# da um include na minha function
. /etc/scripts/function.sh
# ok = 0 -> link fora - deleta rotas para esse link
# ok = 1 -> link ok e novo ip - altera rotas desse link
# ok = 2 -> link ok e o ip nao mudou portanto nao faca nada
# setei ok = 2 para nao fazer nada
ok=2
if [ "$reason" == "REBOOT" -o "$reason" == "RENEW" -o "$reason" == "BOUND" -o "$reason" == "REBIND" ]; then
# Se o novo ip for igual a nada setar ok = 0
if [ "$new_ip_address" == "" ]; then
ok=0
fi
# Se o novo ip tem o inicio igual 192 quer dizer que o dhcp me deu ip porem esta sem internet entao seta ok = 0
inicioip=$(echo $new_ip_address | cut -d "." -f 1)
if [ "$inicioip" == "192" ]; then
ok=0
fi
# se o ok continua igua a 2 é porque ele passou dos itens acima
if [ "$ok" == "2" ];then
# se o ip diferente do antigo seto o ok=1
if [ "$new_ip_address" != "$old_ip_address" ];then
ok=1;
fi
fi
fi
# Se aontecer uma das acoes abaixo é que o servidor dhcp falhou entao seto o ok=0
if [ "$reason" == "FAIL" -o "$reason" == "TIMEOUT" -o "$reason" == "EXPIRE" ]; then
ok=0;
fi
Depois disso criei o seguinte script
vi /etc/dhcp/dhclient-exit-hooks.d/rotas_avancadas
Contendo
# ja tenho os meus ok definidos no script anterior e minha functions incluidas tambem ai faco minhas acoes
if [ "$ok" == "1" ]; then
# pego minhas variaveis
pega_tabela $interface
pega_marca $interface
pega_peso $interface
# calcula o ip da rede
ipcalcule=$(echo "$new_ip_address/$new_subnet_mask")
my_new_network=$(ipcalc -n $ipcalcule | grep Network | cut -b 12-32)
# deleta regra antiga e cria regras novas
del_regras $TABELA
add_regras $TABELA $new_ip_address $MARK
#deleta rotas antigas e cria novas
del_rotas $TABELA
add_rotas $TABELA $new_ip_address $interface $my_new_network $new_routers
del_rotas_padrao
add_rota_balanceamento $interface $new_routers $PESO
fi
if [ "$ok" == "0" ]; then
pega_tabela $interface
del_rotas $TABELA
del_regras $TABELA
del_rotas_padrao
add_rota_balanceamento $interface 0 0
fi
Agora é só executar
dhclient -v eth1 dhclient -v eth2 dhclient -v eth3
Olhar como ficou as rotas
ip route show ip route show table link1 ip route show table link2 ip route show table link3
Para ver como ficaram as regras:
ip rule show
Para testar com o ip route get para ver qual a rota que ele usaria para sair para um determinado destino:
ip route get 8.8.8.8 ip route get 4.2.2.2 ip route get 174.120.154.93
E fazer seus testes
Altemir Braz Dantas Junior (jocajuni) http://acessa.me/@joca, http://acessa.me - crie seu atendimento online gratuito
Colaboração: Fátima Conti
![]() |
Visto em http://visualoop.tumblr.com/post/9430080645/linux-market-shares