Manual de Configuração Advance Routing Linux para "Bisonhos"
  ============================================================

Colaboração: Diego Bianchetti 
http://www.solis.coop.br

Escrito em 05/07/2003 por Diego Bianchetti - diego@solis.org.br
Este documento está sob a licença FDL

NOTA: Esse pequeno tutorial se destina a bisonhos que como eu sempre esquecem de como se instala softwares que tem que ser instalados só de vez em quando e tem preguiça de ficar lendo o README, o INSTALL e pesquisar no www.google.com.br toda vez que tem que fazê-lo.

	Resumo
	======

1. Porque escrevi esse documento ?
2. Ambiente utilizado
3. Teoria para a solução do meu problema
4. Configurando o Kernel
5. Instalando o iproute2
6. Uso básico do iproute2
7. Solução do Problema de Roteamento
8. Agradecimentos

	Porque escrevi esse documento ?
	===============================

Esse documento surgiu quando eu tive a necessidade de configurar um
roteador que tinha dois links diferentes de acceso a internet, onde o
tráfego de entrada e saída de cada link não podia interferir no outro,
ou seja, tudo que entrava por um link não podia sair pelo outro, e eu
só tinha uma placa de rede pra fazer isso. Como todos documentos que eu
encontrei na internet solucionavam esse problema utilizando duas placas
de rede e o meu chefe disse que duvidava que eu era macho pra resolver
esse problema só com uma, depois que consegui escrevi esse tutorial.

	Ambiente utilizado
	==================

A configuração desse router foi feita em um GNU/Linux Slackware 9.0,
kernel 2.4.21 com os pacotes de iptables e iproute2, seguindo vou
descrever a configuração do kernel e instalação do iproute2.

Como a ilustração em caracter a seguir mostra, eu possuia dois links de
acesso a internet por dois provedores diferentes, tudo que era originário
de um provedor deveria voltar para o mesmo sem interferir no tráfego
do outro, o Linux Router possuia apenas uma placa de rede com dois ips,
um para cada provedor, sendo que um deles era alias de interface.

                                                                         ________
                                                  +------------+        /
                                                  |            |       |
                                         +--------+ Provider 1 +-------
          __             Linux Router    |        |            |     /
      ___/  \_         +------+-------+  |        +------------+    |
    _/        \__      |              |  |                         /
   /             \     |    eth0      |  |                        |
  | Local network -----+              |--|                        |
  Internet
   \_           __/    |    eth0:0    |  |                        |
     \__     __/       |              |  |                         \
        \___/          +------+-------+  |        +------------+    |
                                         |        |            |     \
                                         +--------+ Provider 2 +-------
                                                  |            |       |
                                                  +------------+
                                                  \________

	Teoria para a solução do meu problema
	=====================================

Na teoria, como eu só tinha uma placa de rede eu teria que criar duas
tabelas de roteamento distintas no kernel e adicionar regras pra que ele
controlasse o tráfego de cada uma separadamente. Até aí tudo bonito... mas
agora vamos botar a mão na massa!

	Configurando o Kernel
	=====================

Suponho que o cara que esta implementando essa solução saiba o básico de
uma compilação de kernel. Então partindo do pre-suposto que haja o source
do kernel na máquina, não esqueça o kernel deve ser da séria 2.4.x, no
devido diretório e que vcs esteja dentro dele digite "make menuconfig",
como root.


  Code maturity level options  ---> 


Esta opção deve ser marcada, pois como o Kernel(Linux) está sempre em
desenvolvimento e talvez exitam drivers novos que ainda estão em faze
experimental:

       [*] Prompt for development and/or incomplete code/drivers



  Networking options  --->


Para poder utilizar a ferramenta iptables, ou comandos dessa ferramentas,
devemos habilitar as seguintes opções:

           [*] Network packet filtering (replaces ipchains)        
           [*]   Network packet filtering debugging                
           [*] Socket Filtering                                    

As seguinte opções correspondem ao roteamento avançado e devem estar ativas:

           [*] TCP/IP networking                                   
           [*]   IP: multicasting                                  
           [*]   IP: advanced router                               
           [*]     IP: policy routing                              
           [*]       IP: use netfilter MARK value as routing key   
           [*]       IP: fast network address translation          
           [*]     IP: equal cost multipath                        
           [*]     IP: use TOS value as routing key                
           [*]     IP: verbose route monitoring                    
           [*]     IP: large routing tables

Ao submenu "Netfilter Configuration" pertence as opções que definem quais
serão as funções com que o iptables ira trabalhar, isso fica a critério
da necessidade de cada administrador.


       IP: Netfilter Configuration  --->                     


Após isso, é só salvar as opções e seguir os passos abaixo:

  # make dep
  # make clean
  # make bzImage
  # make modules
  # make install
  # make modules_install

	Instalando o iproute2
	=====================

O Slackware 9.0 possui no cd extra o pacote tgz do iproute2, então é
só utilizar o comanda installpkg e pronto, o iproute2 está instalado na
sua máquina! Se voce não possui o cd extra do slackware tb pode baixar
o pacote tgz do site www.slackware.com.

Agora, se voce está utilizando outra distribuição que não possui o pacote
do iproute2 pré-compilando para ela a solução é baixar o source do site
official do projeto, ftp://ftp.inr.ac.ru/ip-routing/, compilar e instalar.

	Uso básico do iproute2
	======================

A base do pacote iproute2 é a ferramenta ip. Ela traz toda a
funcionalidade existente nos comandos arp, ifconfig e route. O modo de
operação desta ferramenta baseia-se na passagem de comandos com argumentos
apropriados para um dos seguintes objetos:

   +. link: interfaces físicas existentes no sistema;
   +. addr: endereços lógicos atribuídos as interfaces físicas do
   sistema nas diversas famílias distintas de protocolos de rede, como
   por exemplo inet (IPv4) e inet6 (IPv6);

   +. route: tabela de roteamento do sistema;
   +. maddr: endereços lógicos de multicast existentes no sistema;
   +. mroute: tabela de roteamento multicast do sistema;
   +. tunnel: configuração de túneis de protocolo do sistema;
   +. neigh: tabela ARP do sistema;
   +. rule: permite definir regras como rejeição de pacotes, uso de NAT
   e classificar o tráfego em tabelas com tratamento diferenciado para
   o uso por outros comandos do ip com o uso do argumento table;
   +. monitor: permite monitoramento dos demais objetos. 

A sintaxe básica da ferramenta ip é: ip OBJETO { COMANDO | help }. Onde
OBJETO é um dos objetos acima descritos e COMANDO é a ação correspondente
em cada objeto, com a respectiva passagem de argumentos. Adicionalmente,
pode ser repassada a especificação da família de protocolo sobre a qual
se atuará, de acordo com a sintaxe especificada pela chamada da ferramenta
ip sem parâmetros.

Exemplificando alguns usos comuns da ferramenta ip, o comando show
ou list pode ser aplicado nos diversos objetos manejados pelo ip para
verificar a configuração do sistema.

É possível desativar e ativar a interface de rede eth0, utilizando os
comandos abaixo:

  # ip link set eth0 down (desativa);
  # ip link set dummy0 up (ativa). 

Para verificar os endereços de rede configurados, podemos utilizar:


  # ip addr list


Para configurar o endereço xxx.xxx.xxx.x com a sub-máscara 255.255.255.0
(correspondendo ao prefixo 24) a interface de rede eth0, podemos usar:


  # ip addr add xxx.xxx.xxx.x/24 dev eth0. 


Para remover o endereço, basta usar o comando del:


  # ip addr del xxx.xxx.xxx.x/24 dev eth0. 


De modo análogo, podemos verificar a tabela de rotas:


  # ip route list


E, ainda, adicionar ou remover uma rota da tabela:


  #ip route add default via xxx.xxx.xxx.xx



  #ip route del default via xxx.xxx.xxx.xx


	Solução do Problema de Roteamento
	=================================

Muito bem, agora que sabemos o que é necessário no kernel, como é feita
a instalação e temos noções do uso básico do iproute2. Qual o próximo
passo? Se voce respondeu, voltar ao problema acertou!

Minha estrutura se apresentava da seguinte maneira:

      * Roteador do PROVIDER1: xxx.xxx.xxx.36
      * Roteador do PROVIDER2: yyy.yyy.yyy.65
      * Roteador Linux:
         o PROVIDER1 (interface eth0): xxx.xxx.xxx.34 Netmask 255.255.255.224
         o PROVIDER2 (interface eth0:0): yyy.yyy.yyy.109 Netmask 255.255.255.192

SEM ESQUECER que todo o tráfego  proviniente de um provedor não pode
interferir no tráfego do outro. A rota padrão deve ser o PROVIDER1.

Bem, conforme a teoria para resolução do problema apresentada, vamos
criar as duas tabelas de roteamento no kernel. Para isso é preciso editar
o arquivo /etc/iproute2/rt_tables. Se olharmos para o arquivo original
veremos o seguinte:

  #
  # reserved values
  #
  255     local
  254     main
  253     default
  0       unspec
  #
  # local
  #
  #1      inr.ruhep

Onde,

local: identificada no Kernel por 255, é associada com a regra de priorida
de 0, possui rotas para endereços locais e de broadcast, tal regra não
pode ser alterada;

main: identificada no Kernel por 254, é associada com a regra de
prioridade 32766, possui as demais rotas normais do sistema, sem envolver
quaisquer políticas especiais de roteamento, podendo ser alterada
livremente pelo administrador, ou até apagada;

default: identificada no Kernel por 253, é associada com a regra de prioridade 32768, por padrão está vazia, é reservada para alguma atividade de pós-processamento, se o pacote não foi selecionado por nenhuma das tabelas iniciais.

Por default, todas as regras são aplicadas a todos os pacotes de acordo
com a prioridade descrita, confrontando-se assim o pacote com cada tabela
de roteamento até que a regra atenda ao pacote a ser roteado.

Não devemos confundir tabelas de roteamento com as regras: as regras
apontam para as tabelas de roteamento, várias regras podem se referir a
uma tabela de roteamento e algumas tabelas de roteamento podem não ter
regra alguma apontando para elas. Se o administrador remove todas as
regras se referindo a uma tabela, a tabela não é usada, mas permanece
e só desaparecerá se todas as rotas contidas nela forem apagadas.

Adicionando mais duas tabelas de roteamento o arquivo ficará assim:

  #
  # reserved values
  #
  255     local
  254     main
  253     default
  0       unspec
  200     provider1
  199	provider2
  #
  # local
  #
  #1      inr.ruhep


O próximo passo é adicionar as rotas para as tabelas. É nesse instante
que informamos para tabela qual o roteador é utilizado para determinado
ip de origem, para isso usamos o comando ip com o objeto route, como na
demonstração abaixo.

  # ip route add xxx.xxx.xxx.34 via xxx.xxx.xxx.36 table provider1
  # ip route add yyy.yyy.yyy.109 via yyy.yyy.yyy.65 table provider2
                |_______________|   |______________|     |_________|
                        |                   |                 |
                 ip da interface            |                 |
                                     ip do gateway            |
                                                     tabela de roteamento

A seguir, devemos adicionar a regras as tabelas de roteamento, para
isso utilizamos o comando ip com o objeto rule. Estamos "amarrando"
a tabela à interface, informando que ela deverá rotear.

  # ip rule add from xxx.xxx.xxx.34 table provider1
  # ip rule add from yyy.yyy.yyy.109 table provider2
                    |_______________|     |_________|
                            |                  |
                     ip da interface           |
                                      tabela de roteamento

E o último passo é adicionar as rotas default para as tabelas criadas
e para o device, no nosso caso a eth0. Se essa rota não for adicionada
não será possível nem pingar para fora, mas o tráfego de fora pra dentro
será normal.

Adicionando rota default para as tabelas:

  # ip route add default via xxx.xxx.xxx.36 table provider1
  # ip route add default via yyy.yyy.yyy.65 table provider2
                            |______________|     |_________|
                                   |                  |
                              ip do gateway           |
                                             tabela de roteamento


Adicionando rota default para o device:

  # ip route add default via xxx.xxx.xxx.36
                            |______________|
                                    |
                              ip do gateway

Pronto!! Para testar podemos, "de uma máquina que está em outra rede",
pingar as duas interfaces que foram criadas e analizar o tráfego com a
ferramenta tcpdump.

	Agradecimentos
	==============

E tenho que agradecer mesmo ao pessoal que escreveu os tutorias que eu
consultei para chegar a essa solução e ao grande mestre conhecedor do
universo e seus segredos - www.google.com -.

- http://tldp.org/HOWTO/Adv-Routing-HOWTO/
- http://linux-ip.net/html/

--------------------------------------------------------------------

Perl - Guia de Consulta Rápida
http://novateceditora.com.br/guias/perl/
--------------------------------------------------------------------
As mensagens da lista Dicas-L são veiculadas diariamente
para 22085 assinantes.

       Todas as mensagens da Dicas-L ficam armazenadas em 
               http://www.Dicas-L.unicamp.br.

A redistribuição desta e outras mensagens da lista Dicas-L pode
ser feita livremente, deste que o conteúdo, inclusive esta nota, 
não sejam modificados.
---------------------------------------------------------------