Manual de Configuração Advance Routing Linux para "Bisonhos"
Colaboração: Diego Bianchetti
Data de Publicação: 30 de Julho de 2003
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
- Porque escrevi esse documento ?
- Ambiente utilizado
- Teoria para a solução do meu problema
- Configurando o Kernel
- Instalando o iproute2
- Uso básico do iproute2
- Solução do Problema de Roteamento
- 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 -.