você está aqui: Home  → Arquivo de Mensagens

Roteamento avançado - Linux - utilizando IPROUTE e IPTABLES - Load Balance

Colaboração: Fabricio Ferreira

Data de Publicação: 27 de Março de 2007

Certo tempo atrás, escrevi um script usando IPROUTE2 e IPTABLES que desenvolvi na ocasião, já que havia a necessidade de utilizar 2 links de Internet distintos. Desta vez, reescrevi com muito mais detalhes mostrando exatamente como funciona cada passo.

Lembrando que, este script foi desenvolvido no SLACKWARE, mas acredito que funcione em qualquer outra distribuição LINUX com Kernel 2.4.x e superiores, com algumas poucas modificações.

Quanto aos links, vamos chamá-los de LINK1 e LINK2...

Imagine que você queira que determinado protocolo use o LINK1 e outro protocolo use o LINK2.

Um exemplo fácil seria dizer que mensagens de E-mail SMTP e POP (portas 110 e 25) utilizam o LINK1, enquanto o tráfego de internet (portas 80, 21, 53, 443...) utiliza o LINK2. Isto permitiria que usuários fizessem downloads pesados sem comprometer o tráfego de mensagens, ou ainda, enviar e receber mensagens de E-mail grandes sem interferir na velocidade dos usuários que navegam na Internet.

Um outro exemplo para quem tem Vlans em suas redes seria dizer que a REDE 192.160.0.X utiliza o Link1, enquanto a REDE 192.170.0.X utiliza o LINK2.

Basicamente, o processo funciona marcando pacotes que entram e saem do FIREWALL onde o script será implementado com o Comando IPTABLES usando Mark, um artifício que faz com que o Firewall monte uma tabela dinâmica de todos os pacotes que passam por ele. Imagine que você tenha um Firewall com 4 Interfaces, assim vamos chamá-las de: ETH0, ETH1, ETH2 e ETH3, onde ETH0 está conectada à sua LAN interna, a ETH1 conectada em uma DMZ, e as interfaces ETH3 e ETH4 conectadas a 2 Links distintos.

Se um pacote entrou pela interface ETH0 e saiu pela interface ETH3, é necessário que ele retorne para o mesmo lugar de onde veio. Eis o motivo de marcar os pacotes; caso contrário, eles se utilizarão do DEFAULT GATEWAY do Firewall, que pode não ser o mesmo que você deseja.

Entendendo isto, podemos seguir adiante com nosso script.

Abaixo descrevo detalhadamente como fazer cada configuração no Script para que você tenha sucesso na implementação.

Entendam que os IP´s aqui utilizados são fictícios, bem como seus Defaut Gateways. Você deverá trocá-los pelos IP´S da sua rede conforme a necessidade!

Eis um exemplo de um script pronto em um Firewall com 3 Interfaces apenas.

A primeira - ETH0, é a interface conectada à rede interna. A Interface ETH1 é a interface ligada ao LINK1, e por último, a interface ETH2, ligada ao LINK2.

Vejamos:

  < A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>< A NAME="note" HREF="#textnote">< SUP>##
  
  # Nesta parte denominamos variáveis para as interfaces como segue.
  # Denominamos que o nome LAN seja referente à Interface ETH0 que no nosso
  # script é a da rede interna. Verifique no seu Firewall qual é a interface
  # correta.
  
  IF_LAN='eth0'
  
  #  Aqui denominamos as variáveis dos LINKS 1 e 2, e os chamamos de LINK1 e LINK2
  # É claro que você poderá chamá-los do que quiser. Exemplo: ADSL1 e ADSL2,
  # mas não esqueça de alterar as variáveis no restante do script.
  
  IF_LINK1='eth1'
  IF_LINK2='eth2'
  
  # Aqui colocamos os Gateways dos Links de Internet.
  # Geralmente, os Default Gateways dos Links são os IP´S dos roteadores de
  # Internet.
  GW_LINK1='200.70.0.1'
  GW_LINK2='200.80.0.1'
  
  # Nesta parte, utilizamos o comando IPTABLES para mascarar os IP s, ou seja,
  # fazemos um NAT (Network Address Translation) para que os pacotes que venham da
  # Interface ETH0 com IP s da rede interna, ou mesmo pacotes gerados dentro do
  # próprio Firewall, possam sair para a Internet com endereços trocados, usando
  # os IP s das interfaces ligadas aos Links de Internet.
  # O  MASQUERADE  ao final do comando faz exatamente isto.
  # Caso contrário, utilizaria ACCEPT, mas aí os pacotes sairiam para a Internet
  # com IP s da rede interna e jamais retornariam ao Firewall.
  
  iptables -t nat -A POSTROUTING -o $IF_LINK1 -j MASQUERADE
  iptables -t nat -A POSTROUTING -o $IF_LINK2 -j MASQUERADE
  
  # Aqui começamos a marcar os pacotes diferenciando-os pela porta utilizada.
  # Observe que escolhemos os pacotes com destino às portas 80 (HTTP) 443 (HTTPS)
  # 25 (SMTP) 110 (POP)
  # Todo pacote que passar pelo Firewall com estas particularidades receberão
  # uma  marca , uma espécie de carimbo. Pacotes destinados à porta 80
  # recebem  carimbo  de número 2, pacotes com destino à porta 25
  # recebem  carimbo  número 3.
  # Desta forma, podemos diferenciá-los para que mais à frente no script tenhamos
  # controle do que saiu/entrou e por onde saiu/entrou.
  
  iptables -t mangle -A PREROUTING -i $IF_LAN -p tcp --dport 80 -j MARK --set-mark 2
  
  iptables -t mangle -A PREROUTING -i $IF_LAN -p tcp --dport 443 -j MARK --set-mark 2
  
  iptables -t mangle -A PREROUTING -i $IF_LAN -p tcp --dport 25 -j MARK --set-mark 3
  
  iptables -t mangle -A PREROUTING -i $IF_LAN -p tcp --dport 110 -j MARK --set-mark 3
  
  # A diferença entre o PREROUTING e o OUTPUT é que, PREROUTING abrange os
  # pacotes que foram originados fora do FIREWALL, por exemplo Interface ETH0
  # ($IF_LAN), enquanto OUTPUT são os pacotes originados no Firewall, ou seja, na
  # própria console.
  
  iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 2
  iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 2
  iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark 3
  iptables -t mangle -A OUTPUT -p tcp --dport 110 -j MARK --set-mark 3
  
  # Aqui montamos as tabelas dinâmicas a partir das marcas (carimbos) que fizemos
  # lá em cima no nosso script.
  # Pacotes que foram marcados com 2 vão para a tabela  table 20  e os marcados
  # com 3, vão para a tabela  table 21 , com a mesma prioridade. Perceba o PRIO 20
  # após os comandos.
  
  ip rule add fwmark 2 table 20 prio 20
  ip rule add fwmark 3 table 21 prio 20
  
  # se quisermos condicionar esta marcação de outra forma, podemos utilizar o
  # comando das seguintes formas:
  
  # Este condiciona que todos os pacotes que vierem da rede 192.160.0.0 vão para
  # a tabela 20.
  # O comando está comentado. Caso queira utilizá-lo, apenas retire o sinal de "#"
  # da frente.
  
  # ip rule add from 192.160.0.0/24 table 20
  
  # Este outro condiciona os pacotes da rede 192.170.0.0 a irem para a tabela 21
  # O comando está comentado. Caso queira utilizá-lo, apenas retire o sinal de
  #  "#" da frente do comando.
  
  # ip rule add from 192.170.0.0/24 table 21
  
  # Agora sim daremos rumo aos pacotes que foram marcados e cadastrados na tabela
  # dinâmica.
  # Veja que os pacotes que foram enviados para a tabela 20 têm como DEFAULT
  # GATEWAY o LINK1. Sendo assim, os pacotes serão enviados para o LINK1 na
  # Interface ETH1 com o IP 200.70.0.1.
  # Já os pacotes da tabela 21 serão enviados para o LINK2 na Interface ETH1, com
  # o IP 200.80.0.1
  
  ip route add default via $GW_LINK1 dev $IF_LINK1 table 20
  ip route add default via $GW_LINK2 dev $IF_LINK2 table 21
  
  
  # Este último comando limpa a tabela, caso ela já tenha sido utilizada
  # anteriormente, ou apenas para termos certeza de que quando você resetar as
  # regras todas, o Firewall não guarde nenhum tipo de informação na
  # memória (cache). Daí o nome  FLUSH CACHE.
  
  ip route flush cache

Você pode utilizar parte do script, se necessário. Por exemplo, se quiser apenas rotear pacotes pela origem, utilize:

  ip rule add from 192.160.0.0/24 table 20

ou

  ip rule add from 192.160.0.0/24 table 21

Conforme o Link que deseja utilizar. Onde 192.160.0.0/24 é a origem. Neste exemplo, a rede em questão tem a máscara 255.255.255.0 (/24)

Desta forma, não há necessidade de marcar pacotes e você poderá deletar as linhas do script.

  Fabrício Ferreira   GUZZY
  Especialista em Segurança Digital
  MCP   Microsoft Certified Professional
  Linux Specialist


 

 

Veja a relação completa dos artigos de Fabricio Ferreira

Opinião dos Leitores

Pedro Ferreira
18 Mar 2014, 20:43
Muito bom, parabens!!
Rafael
05 Out 2011, 16:17
Tem como marcar por destinos?
Diego Ferraz
26 Mai 2011, 22:36
Tenho uma dúvida com isso preciso ainda habilitar o ip_forward?
Lucio
12 Nov 2010, 11:15
Mario.

Apache é aplicação, precisas pensar a nível de rede. o Apache utiliza porta 80 pois é HTTP.

Sds,

Lúcio Dalmas
Allconnection Soluções em Tecnologia.
mauricio
30 Out 2010, 13:40
ola mario e fabricio,

voces podem postar o ip route show de voces?
Alessandro
24 Ago 2010, 13:51
roteamento do dicas-l
mario
17 Jul 2010, 17:42
Caro fabricio
tenho uma dificuldade e gostaria de sua ajuda

tenho a seguinte situação:
servidor linux com 2 int de redes

eth0 192.168.1.201 gateway 192.168.1.1
eth1 192.168.1.202 gateway 192.168.1.3

gostaria que tudo que saisse pelo apache saisse pela eth1 e o restante pela eth0.

voce pode me ajudar?

obrigado
mario balielo
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script