Redundância de links - Mon + Shell Script

Este script foi desenvolvido, de maneira simples, para sanar a necessidade de realizar redundância com dois links de Internet.

[ Hits: 13.644 ]

Por: Bruno Rodrigues Leite Correia em 03/12/2012


Instalando o Mon



Para melhor funcionamento do script desenvolvido, optei por fazer a chamada deste script a partir do Mon, que é uma ferramenta muito utilizada para fins de monitoramento de disponibilidade.

Utilizando distribuições baseadas em Debian, execute o seguinte comando:

# aptitude install mon

O Debian deve, automaticamente, executar o Mon nas próximas reinicializações.

Edite o arquivo /etc/mon/mon.cf e deixe-o da seguinte maneira:

# Definições globais
serverbind = localhost
trapbind = localhost
cfbasedir = /etc/mon
alertdir = /usr/lib/mon/alert.d
mondir = /usr/lib/mon/mon.d
maxprocs = 20
histlength = 100
randstart = 30s
logdir = /var/log/mon
dtlogfile = /var/log/mon/downtime.log
dtlogging = yes
monerrfile = /var/log/mon/error

# Definição do hostgroup de nome "localnode"
# contendo o host local (localhost)

hostgroup localnode localhost

# Monitorar hostgroup de nome "localnode"
watch localnode
   # Serviços  a  serem  checados
   service  availability
      description  Checagem de disponibilidade dos links Internet
      interval  5s
      monitor   availability.monitor
      period    wd  {Mon-Sun}

O script irá atuar testando os links para tomar ações de remoção e adição de rotas conforme disponibilidade dos links.

Abaixo, as possibilidades e ações que o script irá tomar:
  1. Link 1 OK | Link2 OK → Verifica as rotas e mantém como rota padrão a rota apontada na variável: $pref_gw
  2. Link1 Down | Link 2 Ok → Verifica as rotas e mantém como rota padrão a rota apontada na variável: $iface_eth2_gw
  3. Link1 OK | Link2 Down → O script não toma ações. Para este caso, mantenho um servidor Zabbix que monitora os links e informa as falhas do secundário mesmo que não seja a rota padrão.

Segue o script na página seguinte.

    Próxima página

Páginas do artigo
   1. Instalando o Mon
   2. O script
Outros artigos deste autor

Elastix - Instalando, criando ramais e SIP Trunk Vono

Consumo de link com Cacti

Leitura recomendada

Ajustando a hora do micro com extrema precisão

Linux com boot no Pendrive, com todas as facilidades: Smart-USB_Key-Mania, PLOP Boot Manager e outros métodos

Incrementando seus scripts com dialog

Criando uma ISO bootável do OpenBSD

KDialog com Shell Script - Conversão de slides JPG para projetores com suporte a miniaturas de imagens

  
Comentários
[1] Comentário enviado por danniel-lara em 03/12/2012 - 09:54h

Parabéns pelo artigo

[2] Comentário enviado por correiabrux em 03/12/2012 - 11:52h

Obrigado pelo incentivo Daniel.

Abraço.

[3] Comentário enviado por ragen em 03/12/2012 - 16:05h

Bruno,

Como você faria no caso de um link com ppp0? Por exemplo um link de ADSL sem ip fixo, por via de regra, a cada nova autenticação o GW da interface ppp0 pode variar.

Tem uma idéia de qual seria uma boa saída para este problema?

Abs

[4] Comentário enviado por correiabrux em 03/12/2012 - 17:15h

Olá Ragen.

Tenho uma sugestão para o seu caso sim.
Estou considerando que as suas configurações para conexão ppp estejam ok.

Nas distribuições baseadas em Debian, quando um ip é atribuído por DHCP, existe um arquivo que armazena os ips atribuídos, além de rotas, DNS e etc...

O aruiqvo é o dhclient.leases e fica em /var/lib/dhcp/

/var/lib/dhcp/dhclient.leases

Desse arquivo você pode coletar os dados para as variáveis do script de redundância.

Por exemplo:

# Gateway do link da interface eth2
iface_eth2_gw=`/bin/cat /var/lib/dhcp/dhclient.leases | /bin/grep route | /usr/bin/tail -n1 | /usr/bin/awk {'print $3'}| /usr/bin/cut -d ";" -f 1`

# Endereco IP da interface eth2
iface_eth2_ip=`/bin/cat /var/lib/dhcp/dhclient.leases | /bin/grep fixed-address | /usr/bin/tail -n1 | /usr/bin/awk {'print $2'} | /usr/bin/cut -d ";" -f 1`

Note que utilizei `(crase)`, pois assim o script entenderá o resultado do comando cat, que está filtrando somente o ip e rota utilizando awk e cut.

Como não tenho um ambiente parecido aqui pra testes, não posso afirmar com certeza se somente essas intervenções no script resolveriam o seu problema.

Espero ter ajudado, abraço !

[5] Comentário enviado por ragen em 03/12/2012 - 20:19h

Olá Bruno,

Ajudou muito! No meu ambiente o dhclient.leases não armazena ip e rota, mas usando um "ifconfig" em tenho o ip e gw da interface ppp0 - o script que irei montar deriva-se do seu raciocínio. Não tinha pensado nesta possibilidade de usar este script inline (com crases).

Cara muito obrigado mesmo pela idéia, simples e tenho quase certeza que resolverá meu problema!

Abs

[6] Comentário enviado por correiabrux em 03/12/2012 - 20:23h

Maravilha Ragen, boa sorte aí, qualquer coisa entra em contato de novo.

Abraço.

[7] Comentário enviado por canovato em 05/12/2012 - 12:22h

Bruno,

Utilizo o linux a pouco tempo, gostei do seu artigo, mas quero tirar umas dúvidas antes de tentar utilizá-lo. Por isso peço a sua ajuda.

1. No arquivo /etc/network/interfaces você disse para adicionar as linhas abaixo. Mas isso é antes ou depois de configurar a rede eth0, eth1 e eth2,

post-up route add -host 8.8.8.8 gw 189.10.11.12 dev eth1
post-up route add -host 8.8.4.4 gw 201.10.11.12 dev eth2

No meu caso quero trabalhar com a rede assim:

eth0 - rede interna
eth1 - link 1
eth2 - link 2


2. Como fica o arquivo do firewall?
Hoje quando tenho problemas eu faço a troca manual de link, o que é totalmente trabalhoso e errado, por isso seu artigo seria ideal para eu utilizar aqui.

O que eu tenho de fazer no firewall para ele entender que pode haver a troca de link, assim como o mascaramento entender isso também?

O meu firewall está + ou - como descrito abaixo, sendo que ele só trata da rede interna com um link ativo.


#!/bin/sh

# Variaveis
# -------------------------------------------------------
iptables=/sbin/iptables
IF_INTERNA=eth0
IF_EXTERNA=eth1

# Ativa moulos
# -------------------------------------------------------
/sbin/modprobe iptable_nat
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ipt_LOG
/sbin/modprobe ipt_REJECT
/sbin/modprobe ipt_MASQUERADE

# Ativa roteamento no kernel
# -------------------------------------------------------
echo "1" > /proc/sys/net/ipv4/ip_forward

# Zera regras
# -------------------------------------------------------
$iptables -F
$iptables -X
$iptables -F -t nat
$iptables -X -t nat
$iptables -F -t mangle
$iptables -X -t mangle

# Determina a politica padrao
# -------------------------------------------------------
$iptables -P INPUT DROP
$iptables -P OUTPUT DROP
$iptables -P FORWARD DROP

#################################
#várias regras abaixo disso

# Ativa mascaramento de saida
# -------------------------------------------------------
$iptables -A POSTROUTING -t nat -o $IF_EXTERNA -j MASQUERADE

# Proxy transparente
# -------------------------------------------------------
$iptables -t nat -A PREROUTING -i $IF_INTERNA -p tcp --dport 80 -j REDIRECT --to-port 3128
$iptables -t nat -A PREROUTING -i $IF_INTERNA -p tcp --dport 8080 -j REDIRECT --to-port 3128


Pode me ajudar?

[8] Comentário enviado por correiabrux em 05/12/2012 - 12:57h

Olá Carlos, tudo bem ?
Vi no seu perfil que é do Rio de Janeiro, estive aí recentemente a trabalho, lugar maravilhoso!!

Bom, vamos ao que interessa...
.
Sobre as rotas em /etc/network/interfaces, acredito que possa colocar as rotas no rodapé do arquivo, após as configurações de ip e gateway de cada interface. Mas costumo configurar da seguinte maneira, somente por questão de organização:

auto eth1
iface eth1 inet static
address 189.10.11.13
netmask 255.255.255.252
gateway 189.10.11.12
post-up route add -host 8.8.8.8 gw 189.10.11.12 dev eth1

auto eth2
iface eth2 inet static
address 201.10.11.13
netmask 255.255.255.252
gateway 201.10.11.12
post-up route add -host 8.8.4.4 gw 201.10.11.12 dev eth2

Sobre o script de firewall, eu faria alterações nas regras que fazem referência as interfaces de internet, como no exemplo abaixo:

## Antiga regra de mascaramento de saída
## $iptables -A POSTROUTING -t nat -o $IF_EXTERNA -j MASQUERADE

## Nova regra de mascaramento de saída
$iptables -A POSTROUTING -s $REDE_INTERNA -t nat -j MASQUERADE

Dessa maneira o mascaramento será feito considerando somente a rota padrão atual atribuída pelo script, independente da interface que detém a default route no momento.

Espero ter ajudado, abraço !

[9] Comentário enviado por thaleseduardo em 29/12/2012 - 18:05h

Beleza correiabrux, muito bom o artigo parabens. Mas gostaria de deixar uma "correçãozinha" na checagem se ambos os links estao disponiveis.

Do jeito que tá se o link 1 cair o link 2 assume. ok!!!
Caso o link 2 tambem caia ficando: link 1 off e link 2 off.

Quando o link 1 "voltar", não vai ser ativado pelo script por causa da checagem:
"if /usr/bin/fping -q $host_eth1 && /usr/bin/fping -q $host_eth2; then "

Então fiz umas alteração e que deram certo. Olha só como ficou:

if /usr/bin/fping -q $host_eth1 ; then

if [ $deflt_gw = $pref_gw ]; then
echo " Primario Ativo "
if /usr/bin/fping -q $host_eth2 ; then
echo " Secundario OK"
echo " LINKS OK "
else
echo " Secudario Down "
fi
else
link_iface_eth1
fi

else
if /usr/bin/fping -q $host_eth2 ; then

if [ $deflt_gw = $iface_eth2_gw ]; then
echo " Secundario Ativo "
echo " Primario Down "
else
link_iface_eth2
fi
else
echo " Primario Down "
echo " Secudario Down "
fi
fi

Depois testa. valeu

[10] Comentário enviado por correiabrux em 29/12/2012 - 18:18h

Legal Thales, obrigado!

[11] Comentário enviado por phomix em 25/02/2013 - 21:40h

olá amigos.

Trabalho com linux a algum tempo, mas sei tenho um conhecimento limitado.

Não consegui fazer funcionar o Script no MON, por isso o adaptei e inseri no crontab para executar a cada minuto, ai ta funcionando blz.

Segue o script.

#!/bin/bash

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export PATH

# Host a ser pingado pela eth0
host_eth0="8.8.8.8"
# Host a ser pingado pela eth1
host_eth1="8.8.4.4"
# Gateway preferido
pref_gw="192.168.0.254"
# Gateway padrao atual
deflt_gw=$(/sbin/route -n | grep ^0.0.0.0 | awk '{print $2}' | /usr/bin/head -n1)
# Gateway do link da inetrface eth0
iface_eth0_gw="192.168.0.254"
# Gateway do link da interface eth1
iface_eth1_gw="192.168.1.254"
# Interface do link/gateway preferido
iface_pref_gw="eth0"
# Endereco de e-mail de administrador
admin="[email protected]"
# Data atual
date=$(date +%d-%m-%Y)
# Hora atual
time=$(date +%H:%M:%S)
# Endereco IP da interface eth0
iface_eth0_ip="192.168.0.253"
# Endereco IP da interface eth1
iface_eth1_ip="192.168.1.253"

# Funcao para trocar para o link da interface eth1
link_iface_eth0() {

/sbin/route del default gw $iface_eth1_gw
/sbin/route add default gw $iface_eth0_gw dev eth0
/sbin/route del -host $host_eth0 gw $iface_eth0_gw dev eth0 || true
/sbin/route del -host $host_eth1 gw $iface_eth1_gw dev eth1 || true
/sbin/route add -host $host_eth0 gw $iface_eth0_gw dev eth0
/sbin/route add -host $host_eth1 gw $iface_eth1_gw dev eth1
/usr/sbin/squid3 -k reconfigure
for mail in $admin ; do
echo "Link prim�rio da interface eth0 ativado" | /usr/bin/mail -s "[Empresa] Link Internet prim�rio da int$done
}

# Funcao para trocar para o link da interface eth0
link_iface_eth1() {

/sbin/route del default gw $iface_eth0_gw
/sbin/route add default gw $iface_eth1_gw dev eth1
/sbin/route del -host $host_eth0 gw $iface_eth0_gw dev eth0 || true
/sbin/route del -host $host_eth1 gw $iface_eth1_gw dev eth1 || true
/sbin/route add -host $host_eth0 gw $iface_eth0_gw dev eth0
/sbin/route add -host $host_eth1 gw $iface_eth1_gw dev eth1
/usr/sbin/squid -k reconfigure
for mail in $admin ; do
echo "Link secund�rio da interface eth1 ativado" | /usr/bin/mail -s "[Empresa] Link Internet secund�rio da $done

}

# Checa se ambos os links estao disponiveis ...
if (/bin/ping -I eth0 -c1 $host_eth0 && /bin/ping -I eth1 -c1 $host_eth1); then

if [ $deflt_gw = $pref_gw ] ; then
echo "Links OK!!"
else
link_iface_eth0
echo "PREFERENCIAL UP, VOLTANDO LINK PRIMARIO"
echo "PREFERENCIAL UP,VOLTANDO LINK PRIMARIO" >> /var/log/reduntante.log
date >> /var/log/reduntante.log
a $fi

else
if [ $deflt_gw = $iface_eth1_gw ] ; then
echo "USANDO LINK SECUNDARIO, PRIMARIO DOWN"
else
if (/bin/ping -I eth1 -c1 $host_eth1) ; then
link_iface_eth1
echo "LINK PRIMARIO DOWN, ATIVANDO SECUNDARIO"
echo "LINK PRIMARIO DOWN, ATIVANDO SECUNDARIO" >> /var/log/reduntante.log
date >> /var/log/reduntante.log
else
echo "UTILIZANDO LINK PRIMARIO, SECUNDARIO DOWN"
echo "UTILIZANDO LINK PRIMARIO, SECUNDARIO DOWN" >> /var/log/reduntante.log
date >> /var/log/reduntante.log
fi
fi
fi


Caso tenham alguma informação de como fazer funcionar no MON aguardo resposta, e caso alguem veja uma forma de melhorar o scrip sugestoes são bem vindas.


Abraços.

[12] Comentário enviado por phomix em 25/02/2013 - 21:42h

A detalhe, nao sei porque o Fping nao estava conseguindo pingar os endereços, por isso troquei pelo ping...


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts