A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Informática Numaboa - Linux

Roteamento em redes Linux

Qui

12

Abr

2007


22:39

(10 votos, média 4.80 de 5) 


Nível avançado A maioria das distribuições Linux usam os veneráveis comandos arp, ifconfig e route. Apesar de excelentes, estas ferramentas apresentam alguns comportamentos inesperados no Linux 2.2 (ou superior) - portanto, apesar de soar meio herético, esqueça-as.

A partir da versão 2.2 o Linux possui um novo subsistema de rede totalmente redesenhado. Seu novo código de roteamento, filtragem e classificação possui muito mais recursos que os oferecidos por muitos roteadores dedicados, firewalls e modeladores de tráfego disponíveis no mercado. Difícil de acreditar? Então conheça o novo iproute2 e tire a cisma smile

Aviso aos navegantes

Existem alguns pré-requisitos para poder acompanhar este tutorial. Os mais importantes são: você precisa ter uma noção clara do que é uma rede Linux, de como funciona o sistema de comunicação TCP/IP e do que são endereços de rede. Tudo isto está em outro tutorial - Redes Linux.

O iproute2

O Linux possui um sofisticado sistema para provisionar largura de banda chamado Traffic Control. Este sistema permite vários métodos de classificação, priorização, compartilhamento e limitação tanto do tráfego de entrada, quanto do de saída. Para testar as capacidades do iproute2, certifique-se de que o pacote 'iproute' está instalado usando o comando ip descrito a seguir. Se a máquina responder, está tudo em riba; senão, baixe a última versão do iproute e instale-a antes de prosseguir.

Explorando a configuração do seu iproute

Curioso para saber quais são os links da sua máquina? Use o comando atencao ip link list do iproute:

$ ip link list
1: lo:  mtu 3924 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0:  mtu 1400 qdisc pfifo_fast qlen 100
    link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff
3: eth1:  mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff
3764: ppp0:  mtu 1492 qdisc pfifo_fast qlen 10
    link/ppp

Se a sua máquina respondeu a este comando, sua máquina está com o iproute2 instalado e funcionando. O resultado deve ser algo parecido com o mostrado acima porque depende do número de placas Ethernet e do tipo dos links instalados. As principais informações fornecidas são:

O primeiro link mostrado é o da interface loopback. O tamanho MTU (Maximum Transfer Unit) é de 3924 octetos e foi configurado para não entrar na fila (noqueue) - o que faz sentido, já que a interface loopback é "imaginária". A seguir são listadas duas placas Ethernet, suas respectivas MTUs e seus endereços MAC. Finalmente aparece a interface ppp0.

Observe a ausência de endereços IP. O iproute desvincula o conceito de "links" e "endereços IP". O motivo é que, com o IP aliasing, a entidade endereço IP se tornou secundária. Mas isto não quer dizer que não seja possível descobrir estes endereços - basta listá-los com a ajuda do comando atencao ip address show:

$ ip address show
1: lo:  mtu 3924 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0:  mtu 1400 qdisc pfifo_fast qlen 100
    link/ether 48:54:e8:2a:47:16 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/8 brd 10.255.255.255 scope global eth0
3: eth1:  mtu 1500 qdisc pfifo_fast qlen 100
    link/ether 00:e0:4c:39:24:78 brd ff:ff:ff:ff:ff:ff
3764: ppp0:  mtu 1492 qdisc pfifo_fast qlen 10
    link/ppp
    inet 212.64.94.251 peer 212.64.94.1/32 scope global ppp0

Taí! Esta listagem mostra todos os endereços relacionados às placas. Examinando com mais cuidado a interface eth0 verificamos que ela está vinculada ao endereço inet 10.0.0.1/8. A designação inet refere-se à Internet (IPv4) e o "/8" é a máscara que determina o endereço da rede. A máscara também é indicada por 10.255.255.255, informando que esta rede comporta endereços IP de 10.0.0.0 até 10.255.255.255.

Com ppp0 a coisa se repete. Seu endereço é 212.64.94.251, sem máscara de sub-rede. Isto significa de que se trata de uma conexão ponto-a-ponto e que cada endereço, com exceção de 212.64.94.251, é remoto. Além disto, este registro indica que do outro lado do link há também apenas um endereço, o 212.64.94.1 - a máscara "/32" exclui sub-redes.

Só mais um comentário: "qdisk" significa Queueing Discipline (Disciplina de Fila). Este assunto será visto adiante.

De acordo com os exemplos, agora sabemos como encontrar endereços 10.x.x.x e que a máquina pode alcançar o endereço 212.64.94.1. Mas como esta máquina alcança a Internet? É através da conexão ppp0, que desemboca no endereço 212.64.94.1 e, ao que tudo indica, este nó é o responsável pelo trânsito de dados entre a máquina e o mundo exterior. É só dar uma olhada nas rotas...

O comando atencao ip route show do iproute também pode revelar quais as rotas existentes:

$ ip route show
212.64.94.1 dev ppp0  proto kernel  scope link  src 212.64.94.251 
10.0.0.0/8 dev eth0  proto kernel  scope link  src 10.0.0.1 
127.0.0.0/8 dev lo  scope link 
default via 212.64.94.1 dev ppp0 

O resultado é auto-explicativo. As primeiras 3 linhas apenas confirmam o que o comando ip address show já mostrou; a última informa que podemos cair no mundo através do endereço 212.64.94.1, o gateway default. Um gateway é identificado pela palavra via e é para onde devem ser enviados e por onde entram os pacotes de dados.

Apenas para comparar, veja o que o "velho e bom" comando route tem para oferecer:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use
Iface
212.64.94.1     0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo
0.0.0.0         212.64.94.1     0.0.0.0         UG    0      0        0 ppp0

ARP

ARP é o Protocolo de Resolução de Endereço (Address Resolution Protocol), descrito na RFC 826. Este protocolo é usado por máquinas de rede para resolver a localização/endereço do hardware de uma outra máquina pertencente à mesma rede local. As máquinas da Internet geralmente são conhecidas pelos seus nomes que podem ser traduzidos para um endereço IP. É desta forma que uma máquina na rede tico.com.br consegue se comunicar com outra máquina que esteja na rede teco.com.br. Um endereço IP, no entanto, não informa a localização física de uma máquina - é aí que entra o ARP.

Vamos a um exemplo bem simples. Suponha que você tenha uma rede composta por várias máquinas. Uma delas é a tico, com endereço IP 10.0.0.1; a outra é a teco, com o endereço 10.0.0.2. Imagine que a tico queira enviar um ping para a teco para ver se ela está viva, só que não tem a mínima idéia de onde ela possa estar. O jeito é pedir socorro para o ARP enviando uma solicitação. Esta solicitação ARP é como se fosse um "berro" na rede do tipo "Teco (10.0.0.2), cadê ocê?". Cada uma das máquinas que compõem a rede vão ouvir o grito, mas apenas a teco (10.0.0.2) vai responder. O ARP, ouvindo a resposta, envia uma mensagem para a tico dizendo "Tico (10.0.0.1), estou aqui em 00:60:94:E9:08:12". Com esta dica, a tico consegue se comunicar com a teco até sua "memória" (o cache ARP) se esgotar, o que leva cerca de 15 minutos em sistemas Unix.

A historinha até que é legal, mas o melhor é conferir se é verdadeira. É possível ver o ARP/cache de vizinhos/tabela das suas máquinas com o comando atencao ip neigh show (a tradução de neighbour é vizinho). Usando este comando na tico (10.0.0.1) a resposta é a seguinte:

$ ip neigh show
10.0.0.2 dev eth0 lladdr 00:60:08:3f:e9:f9 REACHABLE
10.0.0.10 dev eth0 lladdr 00:06:29:21:73:c8 REACHABLE

Observação: REACHABLE significa ALCANÇÁVEL. A máquina tico (10.0.0.1) sabe onde encontrar a teco (10.0.0.2), como também sabe que o "ticotecogate" (o gateway) tem o endereço 10.0.0.10. Agora, que tal adicionar mais uma máquina no cache do ARP?

$ ping -c 1 superdotada
PING superdotada (10.0.0.3) from 10.0.0.1 : 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=0 ttl=255 time=0.9 ms

--- superdotada ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.9/0.9/0.9 ms

$ ip neigh show
10.0.0.3 dev eth0 lladdr 00:06:29:21:80:20 REACHABLE
10.0.0.2 dev eth0 lladdr 00:60:08:3f:e9:f9 REACHABLE
10.0.0.10 dev eth0 lladdr 00:06:29:21:73:c8 REACHABLE

Como resultado da tentativa de fazer contato com a superdotada, o endereço/localização do hardware da superdotada foi adicionado ao cache ARP/vizinhos. Enquanto a entrada para a superdotada não expirar (pela ausência de comunicação entre as duas), a tico sabe onde achar a superdotada e não precisa enviar uma nova solicitação para o ARP.

Da mesma forma que podemos adicionar uma "dica" no ARP, também é possível tirá-la do cache. Para suprimir a superdotada (afinal, está atrapalhando a tico e a teco smile ), use o comando atencao ip delete neigh:

$ ip neigh delete 10.0.0.3 dev eth0
$ ip neigh show
10.0.0.3 dev eth0 FAILED
10.0.0.2 dev eth0 lladdr 00:60:08:3f:e9:f9 REACHABLE
10.0.0.10 dev eth0 lladdr 00:06:29:21:73:c8 STALE

O ip neigh show nos mostra que a tico "esqueceu" como achar a superdotada, ou seja, vai precisar de uma nova solicitação ARP para encontrá-la. Além do mais, o "ticotecogate" mudou seu estado para "STALE" (envelhecido). Isto significa que a localização mostrada ainda é válida, mas precisa ser confirmada na primeira transação que envolver esta máquina.


Regras: base de dados da política de roteamento

Quando se tem um roteador mais parrudo, que precisa atender as necessidades de muitas pessoas, entram em jogo as tabelas de roteamento da base de dados da política de roteamento. Para usar esta característica, o kernel do Linux precisa ter sido compilado com "IP: advanced router" e "IP: policy routing".

Quando o kernel precisar tomar uma decisão de roteamento, ele descobre qual tabela deve ser consultada. Como default, há três tabelas. Tanto a ferramenta "route" quanto a "ip" modificam as tabelas principal (main) e local.

$ ip rule list
0:	from all lookup local 
32766:	from all lookup main 
32767:	from all lookup default

O comando atencao ip rule list mostra a prioridade de todas as regras. De acordo com a listagem acima, todas as regras são aplicadas a todos os pacotes ("from all"). Já vimos a tabela principal quando usamos o comando ip route list (ip route ls é a mesma coisa), mas as tabelas local e default são novidade.

Se quisermos roteamentos mais sofisticados, podemos criar regras que apontam para outras tabelas que permitem modificar as regras de roteamento do sistema. Para a sintaxe correta, procure o Dicionário do iproute2 (tradução do texto de Alexey N. Kuznetsov).

Uma política de roteamento simples

Vamos a um exemplo muito comum no mundo real: dois cable modems conectados a um roteador Linux NAT ("mascarador") instalados num edifício. Os moradores do edifício pagam para usar a Internet. Imagine que um deles usa apenas o hotmail e quer pagar menos. Tudo bem para o administrador do sistema, só que o freguês vai acabar usando o low-end cable modem.

O cable modem "rápido" é conhecido como 212.64.94.251 e é um link PPP para 212.64.94.1. O cable modem "lento" é conhecido por vários endereços IP, 212.64.78.148 neste exemplo, e é um link para 195.96.98.253.

A tabela local

$ ip route list table local
broadcast 127.255.255.255 dev lo  proto kernel  scope link  src 127.0.0.1 
local 10.0.0.1 dev eth0  proto kernel  scope host  src 10.0.0.1 
broadcast 10.0.0.0 dev eth0  proto kernel  scope link  src 10.0.0.1 
local 212.64.94.251 dev ppp0  proto kernel  scope host  src 212.64.94.251 
broadcast 10.255.255.255 dev eth0  proto kernel  scope link  src 10.0.0.1 
broadcast 127.0.0.0 dev lo  proto kernel  scope link  src 127.0.0.1 
local 212.64.78.148 dev ppp2  proto kernel  scope host  src 212.64.78.148 
local 127.0.0.1 dev lo  proto kernel  scope host  src 127.0.0.1 
local 127.0.0.0/8 dev lo  proto kernel  scope host  src 127.0.0.1 

tem uma porção de coisas que precisam ser especificadas. Bem, é aqui mesmo que elas estão. Quanto à tabela default... bem, esta está vazia. Já a tabela principal mostra o seguinte:

$ ip route list table main 
195.96.98.253 dev ppp2  proto kernel  scope link  src 212.64.78.148 
212.64.94.1 dev ppp0  proto kernel  scope link  src 212.64.94.251 
10.0.0.0/8 dev eth0  proto kernel  scope link  src 10.0.0.1 
127.0.0.0/8 dev lo  scope link 
default via 212.64.94.1 dev ppp0

Agora, para atender o Marco, o morador que só usa o hotmail, vamos criar uma regra nova. Mesmo podendo trabalhar apenas com números, é muito mais fácil adicionarmos nossas tabelas ao arquivo /etc/iproute2/rt_tables.

# echo 200 Marco >> /etc/iproute2/rt_tables
# ip rule add from 10.0.0.10 table Marco
# ip rule ls
0:	from all lookup local 
32765:	from 10.0.0.10 lookup Marco
32766:	from all lookup main 
32767:	from all lookup default

Agora só falta criar a tabela do Marco e dar uma limpada no cache de rotas:

# ip route add default via 195.96.98.253 dev ppp2 table Marco
# ip route flush cache

E isto é tudo. Aproveite o exemplo e comece a brincar um pouco smile


Roteando para múltiplos uplinks/provedores

Uma configuração muito comum é a mostrada na Fig.1, na qual há dois provedores que conectam uma rede local (ou até mesmo uma única máquina) com a Internet.

Roteador

Geralmente existem dois pontos importantes nesta configuração: fracionamento de acesso e balanço de carga.

  • Fracionamento de acesso

A primeira tarefa é garantir que as respostas a pacotes vindos de um determinado provedor sejam roteadas para este mesmo provedor. Para isto vamos começar criando alguns nomes simbólicos. A primeira interface será chamada de $IF1 (if1 da figura acima) e a segunda de $IF2. O endereço IP da primeira interface será $IP1 e, o da segunda, $IP2. O endereço do gateway no Provedor 1 será $P1; o do segundo será $P2. Finalmente, $P1_NET será o nome da rede IP onde está $P1 e $P2_NET o nome da rede IP onde está $P2.

Bão... agora está na hora de criar duas tabelas de roteamento adicionais, a T1 e a T2. Estas tabelas devem ser adicionadas ao arquivo /etc/iproute2/rt_tables. Depois é só adicionar rotas nestas tabelas com o seguinte:

ip route add $P1_NET dev $IF1 src $IP1 table T1
ip route add default via $P1 table T1
ip route add $P2_NET dev $IF2 src $IP2 table T2
ip route add default via $P2 table T2

Até aqui, nada de excepcional. Criamos uma rota para o gateway e uma rota default que passa através deste gateway, mas as rotas devem ser colocadas em tabelas separadas, uma para cada provedor. Note que basta uma rota de rede porque ela permite encontrar qualquer host nesta rede, o que inclui o gateway (como especificado acima).

Depois é só caprichar na tabela de roteamento principal. Uma boa idéia é rotear coisas para o vizinho mais próximo através da interface conectada a este vizinho. Os argumentos "src" garantem que o endereço IP de saída seja selecionado.

ip route add $P1_NET dev $IF1 src $IP1
ip route add $P2_NET dev $IF2 src $IP2

Depois, vamos indicar a preferência para a rota default:

ip route add default via $P1

As regras de roteamento vêm a seguir. Estas regras determinam a tabela que deve ser usada para fazer o roteamento. Aqui é preciso indicar a interface de saída correta, de acordo com o endereço de origem. O conjunto de comandos a seguir garante que todas as respostas ao tráfego que chega através de uma determinada interface sejam despachadas pela mesma interface:

ip rule add from $IP1 table T1
ip rule add from $IP2 table T2

atencao Se $P0_NET for a rede local e $IF0 for sua interface, é aconselhável fazer as seguintes entradas adicionais:

ip route add $P0_NET     dev $IF0 table T1
ip route add $P2_NET     dev $IF2 table T1
ip route add 127.0.0.0/8 dev lo   table T1
ip route add $P0_NET     dev $IF0 table T2
ip route add $P1_NET     dev $IF1 table T2
ip route add 127.0.0.0/8 dev lo   table T2

Este exemplo é de uma configuração bem básica. Vai funcionar para todos os processos que estejam rodando no roteador, como também para a rede local se ela tiver uma máscara. Se não, então existe um espaço IP dos dois provedores ou há uma máscara para um dos provedores. Em ambos os casos é preciso adicionar regras que selecionem o provedor que fará o roteamento de saída de acordo com o endereço IP da máquina da rede local.

  • Balanceamento de carga

O segundo ponto importante é equilibrar o tráfego de saída dos dois provedores. Esta não é uma tarefa difícil se o fracionamento de acesso já estiver configurado.

Ao invés de escolher um dos provedores como rota default, podemos configurar a rota default como uma rota multi-caminho. No kernel padrão isto fará com que as rotas sejam balanceadas, isto é, sejam divididas entre os dois provedores de forma equilibrada. Continuando com o exemplo do fracionamento de acesso, a coisa fica assim:

ip route add default scope global nexthop via $P1 dev $IF1 weight 1 \
  nexthop via $P2 dev $IF2 weight 1

Isto vai dividir e equilibrar as rotas entre os dois provedores. Os parâmetros weight podem ser alterados para favorecer (ou penalizar smile ) um dos provedores.

Na prática este equilíbrio não é perfeito porque é baseado em rotas e as rotas vão para o cache. Como resultado, as rotas para os sites mais solicitados acabam passando sempre pelo mesmo provedor.

info Se você está pensando em botar o fracionamento de acesso e o balanço de carga para funcionar, talvez seja bom dar uma olhada na página de patches do Julian Anastasov's em http://www.ssi.bg/~ja/#routes. São patches ótimos que já facilitaram a vida de muita gente.


Fonte de Referência

Вадим Логофет Sberbankкупить утятницу в москвеменю никас ноутбуки i7сковорода вокблендэр лобановский александр

Informações adicionais