segunda-feira, 15 de março de 2010

Roteamento Avançado em Linux

Olá!

Essa é uma técnica bem simples porém muito útil quando temos dois links de Internet. Felizmente o Linux, como de costume, permite mexermos em qualquer funcionalidade dele.
Nesse caso, faremos uma alteração relacionada à tabelas de roteamento podendo direcionar tráfegos bem específicos para o link que quisermos.

A situação mais comum para usarmos essa técnica é a de uma empresa com dois Links de Internet sendo um deles o principal, ou seja,  por onde saem todos os serviços e por onde estão publicados endereços externos, etc e um outro usado apenas como redundância para acesso a Internet.

Já que o link principal normalmente é o mais usado, nosso link secundário acaba sendo subutilizado. Por experiência, posso garantir que o trafego Web (tcp/80 - http e tcp/443 - https) é um dos maiores consumidores de link. Isso é lógico, cada vez mais dependemos da Internet.

Então, nesse post fareia seguinte configuração: Tudo que for serviço sai pelo Link Principal e tudo que for tráfego Web sai pelo Link Secundário. Isso vai garantir que os dois links sejam utilizados de forma equilibrada. Lembrando que isso não é regra!! Podem ter situação que outros tráfegos possam predominar, portanto faça uma análise da sua rede antes de seguir esse post.

Mãos-a-obra
Nosso objetivo é fazer essa façanha simplesmente manipulando tabelas de roteamento do nosso Firewall.
Para isso a primeira dependência que temos é o pacote iproute2. Normalmente ele já vem instalado na maioria das distros. Senão estiver instalado? Da um jeito de instalar ué!!

Bom, começaremos editando o arquivo /etc/iproute2/rt_tables.
Esse arquivo já vem com 3 tabelas de roteamento por default como no exemplo abaixo:

$ cat /etc/iproute2/rt_tables
255     local
254     main
253     default

OBS: Quanto maior o número, maior a prioridade da tabela no sistema.

Local: Essa é uma tabela padrão criada pelo Kernel que serve para gerenciar todos os endereços locais da máquina. Ela possui todos os endereços cadastrados na interface do firewall. Não tem necessidade de mexermos nela a não ser que você seja um maníaco testador.

Comando bacana:
$ ip route show table local

Main: Essa e principal tabela do sistema. É nela que criamos rotas, adicionamos nosso default gateway, etc. Todos os comando de roteamento, por padrão, apontam para ela.

Comandos bacanas:
$ ip route show table main
$ route -n

Default: Como quase tudo que é desenvolvido, principalmente na área de redes, os desenvolvedores sempre criar algo que poderá ser utilizado no futuro caso haja a necessidade de algo que não foi previsto enquanto ele digitava o código desse treco, ou seja, essa tabela de roteamento vem vazia e não serve para nada a não ser que mandemos ela fazer algo.

Legal vamos deixar esse default bem quietinha no lugar dela e vamos criar uma nova tabela. Edite o arquivo rt_tables e adicione uma nova tabela.

Ex:
$ cat /etc/iproute2/rt_tables
255     local
254     main
253     default
100     link_sec

Por quê o número 100?
Porque acho um número fácil de digitar, decorar e também misterioso para os leigos... heheheh Na verdade você pode usar qualquer número entre 1 e 255. Mas recomendo fortemente usar algum menor que os números das tabelas default. Caso duvide pode fazer um teste. É bem divertido.

Com essa alteração criamos uma tabela nova e zerada. Nenhum tráfego vai passar por ela, pois na pior das hipóteses ele vai casar com o default gateway da tabela main. É bem isso que queremos. Continue funcionando perfeitamente e especificaremos minuciosamente o que vamos mandar para a nova tabela.
Mas antes disso, vamos criar uma rota ou gateway nessa nova tabela.

$ ip route add default via "gateway" table link_sec

Para conferir:
$ ip route show table link_sec

Beleza! Agora tudo que cair nessa tabela vai para o link secundário.

Selecionando o Tráfego
Podemos fazer isso diretamente com parâmetros do ip rule, mas eles são um pouco limitados e como sou um adorador do iptables, usarei a extensão MARK dele para fazer isso.

Como quero que todo o tráfego WEB saia pelo Link Secundário, criarei a seguinte linha do iptables:
# iptables -t mangle -A PREROUTING -j MARK --set-mark 1 -p tcp -m multiport --dports 80,443 -i "interface interna" -d ! "rede interna ou dmz"

Essa linha colocará uma marca/garimbo em cada pacote que contiver 80 ou 443 na porta de destino e não for direcionado para o servidor local. Resumindo, marcará tudo que for navegação para fora da empresa.

Pronto, temos a tabela de roteamento criada, uma rota default dela para meu link secundário e todos os pacotes marcados.

Só falta jogarmos esses pacotes para a nova tabela e automaticamente eles sairão pelo link secundário.

Direcionando o Tráfego
Como já temos os pacotes marcados pelo iptables, vamos criar uma rule para eles.

# ip rule add fwmark 1 table link_sec

Prontinho, seu link tráfego já estará direcionado para o Link Secundário.

Observações:
- Verifique se as regras de Postrouting ficaram de acordo, senão não vai conseguir navegar em função do mascaramento incorreto.
- Instale um agente/gerenciador SNMP para monitorar as interfaces. Fica bacana. O Zenoss já serve.
- Não tente mexer nas outras tabelas com o comando ip. Isso pode causar um caos mundial em servidores de produção.

Abraço!

3 comentários:

  1. APenas para confirmar, a regra de postrouting seria algo como? :
    iptables -t nat -A POSTROUTING -o $IF_LINK1 -j MASQUERADE
    iptables -t nat -A POSTROUTING -o $IF_LINK2 -j MASQUERADE

    ResponderExcluir
  2. Olá, Marcos.

    Pode ser essa regra sim.
    Alternativamente também pode especificar o endereço de mascaramento com o -j SNAT --to-source no lugar do -j MASQUERADE.

    Abraço!

    ResponderExcluir
  3. Olá Marcos estou configurando um roteamento avançado. Só que possuo 2 links sendo um com internet e outro não. Não estou conseguindo fazer. Alguma luz. Sabendo que tenho um proxy/squid e firewall na mesma máquina, possuo 3 interface de rede.

    ResponderExcluir