Para nosso sistema de redundância funcionar, devemos ter uma rota
de caminhos múltiplos no sistema e tabelas de roteamento separadas
que gerenciarão o tráfego e o enviarão para a interface apropriada
no tempo apropriado.
Nosso trabalho inicia-se com as configurações de variáveis, que
tornarão a vida um pouco mais fácil. Mas, antes, o sha-bang!
#!/bin/bash
echo "Configurando Variáveis..."
# Localização do comando iptables
IPTABLES=/sbin/iptables
# Localização do comando ip
IP=/sbin/ip
# Interface Externa 1 - Virtua
NET_EXT_INT0=eth0
# IP Virtua
NET_EXT_IP0=201.1.1.102
# Default Gateway Virtua
NET_EXT_GW0=201.1.1.1
# Interface interna
NET_INT_INT1=eth1
# IP interno
NET_INT_IP1=192.168.0.1
# Subnet interna
NET_INT_SUB1=24
# Rede interna
NET_INT_NET1=192.168.0.0
# Interface externa 2 - Speedy
NET_EXT_INT2=eth2
# IP Speedy
NET_EXT_IP2=200.100.90.80
# Default Gateway Speedy
NET_EXT_GW2=200.100.90.1
Os endereços IP das interfaces eth0 e eth2 não são os
endereços reais. Vamos agora limpar eventuais tabelas existentes:
echo "Limpando as tabelas..."
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -F -t mangle
$IPTABLES -X -t nat
$IPTABLES -X -t mangle
$IPTABLES -X
Agora podemos iniciar a configuração de nossas regras iptables
e iproute2. Vamos criar duas chaves para cada uma das
interfaces externas. Uma irá administrar pacotes vindos para
nosso sistema e outra administrará pacotes indo para o sistema
que serão transformados (NATed) ou redirecionados (forwarded). A
primeira tabela para a primeira interface residirá na tabela mangle:
echo "Configurando tabela Mangle para eth0..."
$IPTABLES -t mangle -N ETH0
$IPTABLES -t mangle -F ETH0
$IPTABLES -t mangle -A ETH0 -p tcp -j LOG -log-prefix MANGLE_TCP_ETH0
$IPTABLES -t mangle -A ETH0 -p icmp -j LOG -log-prefix MANGLE_ICMP_ETH0
$IPTABLES -t mangle -A ETH0 -j MARK --set-mark 1
Estes comandos simplesmente criarão uma chave na tabela Mangle,
chamada ETH0. Os terceiro e quarto comandos destinam-se a
depuração do sistema e podem ser removidos quando tudo estiver
funcionando corretamente. Eles simplesmente registram (log)
todos os pacotes tcp e icmp que passam pela chave. A última
linha coloca uma marca de 1 em todos os pacotes vindos através
da chave. Isso é feito porque queremos identificar pacotes para
depois roteá-los corretamente para a interface. Repetimos os
comandos para a segunda interface:
echo "Configurando tabela Mangle para eth2..."
$IPTABLES -t mangle -N ETH2
$IPTABLES -t mangle -F ETH2
$IPTABLES -t mangle -A ETH0 -p tcp -j LOG -log-prefix MANGLE_TCP_ETH2
$IPTABLES -t mangle -A ETH0 -p icmp -j LOG -log-prefix MANGLE_ICMP_ETH2
$IPTABLES -t mangle -A ETH2 -j MARK --set-mark 2
Agora temos nossas duas chaves customizadas para a tabela
mangle prontas. Configuraremos agora as regras correspondentes
que permitirão que os pacotes possuam os endereços corretos de
suas interfaces:
echo "Configurando tabela Nat para eth0..."
$IPTABLES -t nat -N SPOOF_ETH0
$IPTABLES -t nat -F SPOOF_ETH0
$IPTABLES -t nat -A SPOOF_ETH0 -j LOG -log-prefix SPOOF_ETH0
$IPTABLES -t nat -A SPOOF_ETH0 -j SNAT --to ${NET_EXT_IP0}
Isso cuidará do roteamento para nós. De novo, a terceira linha
serve apenas para depuração. A última linha é a que realmente
cuida do processamento. Ela certifica-se que o endereço IP de
nossa primeira interface externa é anexado a todo o tráfego que
será roteado através dele. Faremos o mesmo para a segunda interface.
echo "Configurando tabela Nat para eth2..."
$IPTABLES -t nat -N SPOOF_ETH2
$IPTABLES -t nat -F SPOOF_ETH2
$IPTABLES -t nat -A SPOOF_ETH2 -j LOG -log-prefix SPOOF_ETH2
$IPTABLES -t nat -A SPOOF_ETH2 -j SNAT --to ${NET_EXT_IP2}
Pessoalmente, eu gosto de adicionar a seguinte linha para
certificar-me que hosts de nossa rede interna consigam
acessar o gateway com o comando ping, para testes:
echo "Permitindo ping local..."
$IPTABLES -A INPUT -p icmp -s ${NET_INT_NET1}/${NET_INT_SUB1} -d \
${NET_INT_IP1} -j ACCEPT
Agora precisamos certificar-nos de que os pacotes vindos para
o sistema realmente alcancem as chaves criadas para eles. Isto
é feito criando-se as tabelas correspondentes com iproute2 e
regras para acomodá-las.
echo "Configurando regras de Mangle para eth0..."
$IP ru add from ${NET_EXT_IP0} lookup 1
$IP ro add table 10 default via ${NET_EXT_GW0} dev ${NET_EXT_INT0}
$IP ru add fwmark 1 table 10
$IP ro fl ca
O primeiro comando iproute2 adiciona uma regra dizendo para nosso
IP de interface 1 (Virtua) faça suas procuras através da marca 1,
anteriormente adicionada ao pacote tcp/ip. O segundo comando
adiciona uma tabela, 10, que tem como gateway padrão o gateway
especificado nas configurações do script. Então ele fez todos os
pacotes receberem uma marca 1. Finalmente ele limpa a tabela de
roteamento para termos um início limpo. Fazemos o mesmo com a
segunda interface:
echo "Configurando regras de Mangle para eth2..."
$IP ru add from ${NET_EXT_IP2} lookup 2
$IP ro add table 20 default via ${NET_EXT_GW2} dev ${NET_EXT_INT2}
$IP ru add fwmark 2 table 20
$IP ro fl ca
Agora devemos ter certeza de que as traduções de endereçamento (NAT)
estejam nos lugares corretos:
echo "Configurando regras de spoofing..."
$IPTABLES -t nat -A POSTROUTING -o ${NET_EXT_INT2} -j SPOOF_ETH2
$IPTABLES -t nat -A POSTROUTING -o ${NET_EXT_INT0} -j SPOOF_ETH0
Isso garante que pacotes de saída tenham seu endereço ip externo
correto. Agora nos certificaremos de que a máquina tenha o seu
gateway padrão, que neste caso, é uma rota de caminhos múltiplos:
echo "Adicionando rota default..."
$IP ro add default equalize nexthop via ${NET_EXT_GW2} dev \
${NET_EXT_INT2} weight 1 nexthop via ${NET_EXT_GW0} dev \
${NET_EXT_INT0} weight 1
Isso não faz nada além de dar à máquina a habilidade de sair
usando uma das duas rotas de caminho múltiplo com pesos iguais,
isto é, com probabilidades iguais. A última coisa que devemos
fazer é ter certeza de que a máquina faz o redirecionamento de
pacotes corretamente e também desabilitarmos o filtro de
pacotes reversos, para que os pacotes possam entrar livremente
em ambas as interfaces:
echo "Desabilitando filtro de caminho reverso..."
echo 0 > /proc/sys/net/ipv4/conf/eth2/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
echo "Habilitando redirecionamento de pacotes..."
echo 1 > /proc/sys/net/ipv4/ip_forward