Roteamento avançado com Linux

Started by Skayler, 19 de August , 2006, 11:14:25 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Skayler

Roteamento avançado com Linux

Allan Edgard Silva Freitas http://www.6bone.rnp.br/ . As opções referentes ao mesmo são:

<*> The IPv6 Protocol
  • enable EUI-64 token format

Para utilizar a ferramenta iptables, ou comandos da ferramenta ip sobre o objeto rule, possibilitando recursos com NAT e Proxy Transparent, devemos habilitar as opções:

  • Network packet filtering (replaces ipchains)
  • Network packet filtering debugging
  • Socket Filtering

E, ainda, devemos ativar as opções existentes no subitem "IP: Netfilter Configuration -->", dentre as quais o suporte a iptables.

Para o suporte ao estabelecimento de túneis de protocolo, ative:

<*> IP: tunneling
<*> IP: GRE tunnels over IP

Um recurso bastante interessante de rede (com algumas melhorias com o IPv6), o Multicast, é uma opção a se observar:

  • IP: multicasting
  • IP: multicasting routing

Opções avançadas de roteamento, incluindo NAT, devem estar ativas para os nossos propósitos:

  • 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

Para, então, compilar o Kernel, salva-se a configuração e segue-se os seguintes passos:

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

Para instalar o pacote iproute, deve-se fazer o download do mesmo no endereço ftp://ftp.inr.ac.ru/ip-routing/iproute2-current.tar.gz . Este link simbólico aponta para a última versão estável disponível para download. A versão do iproute2, indicada pelo arquivo iproute2-current.tar.gz, que foi utilizada neste artigo, foi a do arquivo iproute2-2.4.7-now-ss010824. tar.gz . Após obter o pacote, deve-se executar os seguintes passos:

# cp iproute2-current.tar.gz /usr/src/
# cd /usr/src
# tar -zxpvf iproute2-current.tar.gz
# cd iproute2
# make

Caso você obtenha algum erro na tempo de compilação, deve-se analisar o arquivo-fonte indicado. A depender do contexto do ambiente de instalação, podem ocorrer problemas de compilação referentes ao suporte a algumas tecnologias, protocolos e tipos de interfaces, os quais não devem estar diretamente relacionados ao nosso ambiente, indicados no arquivo ll_types.c sob o diretório lib. Caso ocorra mensagem de erro referente a este arquivo, edite o arquivo e comente as linhas indicadas pelo comando make, colocando "//" no início das mesmas e recompile. Após a compilação, instale as ferramentas ip e tc manualmente:

# cp ip/ip /sbin
# cp tc/tc /sbin

E, ainda, os arquivos de configuração necessários para essas ferramentas:

# mkdir /etc/iproute2
# cp /etc/iproute2/* /etc/iproute2

O ambiente estará pronto para o uso após o reinício do sistema para a carga do Kernel recompilado.

^
3. 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:

   1. link: interfaces físicas existentes no sistema;
   2. 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);
   3. route: tabela de roteamento do sistema;
   4. maddr: endereços lógicos de multicast existentes no sistema;
   5. mroute: tabela de roteamento multicast do sistema;
   6. tunnel: configuração de túneis de protocolo do sistema;
   7. neigh: tabela ARP do sistema;
   8. 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;
   9. 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.

# ip

Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }

where OBJECT := { link | addr | route | rule | neigh | tunnel |

maddr | mroute | monitor }

OPTIONS := { -V[ersion] | -s[tatistics] | -r[esolve] |

-f[amily] { inet | inet6 | ipx | dnet | link } | -o[neline]

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. Assim, caso quisermos ver as interfaces presentes no sistema, podemos utilizar o comando:

# ip link show
1: lo: mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:40:05:14:a2:47 brd ff:ff:ff:ff:ff:ff
3: eth1: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:10:5a:5c:5d:bf brd ff:ff:ff:ff:ff:ff
4: eth2: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:00:21:45:06:b2 brd ff:ff:ff:ff:ff:ff

Podemos 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 verificarmos os endereços de rede configurados, podemos utilizar:

# ip addr list
1: lo: mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
2: eth0: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:40:05:14:a2:47 brd ff:ff:ff:ff:ff:ff
inet 200.128.35.1/24 brd 200.128.35.255 scope global eth0
inet6 fe80::240:5ff:fe14:a247/10 scope link
3: eth1: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:10:5a:5c:5d:bf brd ff:ff:ff:ff:ff:ff
inet 10.1.0.1/16 brd 10.1.255.255 scope global eth1
inet6 fe80::210:5aff:fe5c:5dbf/10 scope link
4: eth2: mtu 1500 qdisc pfifo_fast qlen 100
link/ether 00:00:21:45:06:b2 brd ff:ff:ff:ff:ff:ff
inet 200.254.245.1/24 brd 200.254.245.255 scope global eth2
inet6 fe80::200:21ff:fe45:6b2/10 scope link.

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

# ip addr add 200.254.245.1/24 dev eth0.

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

# ip addr del 200.254.245.1/24 dev eth0.

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

# ip route list
200.254.245.0/24 dev eth2 proto kernel scope link src 200.254.245.1
200.128.35.0/24 dev eth0 proto kernel scope link src 200.128.35.1
10.1.0.0/16 dev eth1 proto kernel scope link src 10.1.0.1
10.0.0.0/8 via 10.1.1.10 dev eth1
127.0.0.0/8 dev lo scope link
default via 200.254.245.10 dev eth2 metric 1

E, ainda, adicionarmos ou removermos uma rota da tabela:

#ip route add default via 200.128.35.10
#ip route del default via 200.128.35.10.

O Kernel do Linux, a partir da versão 2.2, possui toda a funcionalidade de gerenciamento de largura de banda, através de controle de tráfego. Isto é feito por filtros e filas. Os filtros colocam o tráfico em filas, e nestas há o encaminhamento de quais pacotes serão enviados primeiro ou depois ou, ainda, rejeitados. A ferramenta tc também acompanha o pacote iproute2 e é dedicada ao controle de tráfego, permitindo a configuração de filas e filtros de modo a implementarmos o controle de tráfego e alguma Qualidade de Serviço. Não será abordada, neste artigo, o uso desta ferramenta.

   1.  filter: é a tabela padrão, sobre a qual podemos nos referir a três correntes de regras, ou chains: INPUT, pacotes que entram na interface; OUTPUT, pacotes que saem da interface e FORWARD, pacotes que estão sendo roteados de uma interface para outra;
   2. nat: esta tabela se refere ao uso do recurso de Network Address Translation ou NAT, na qual podemos nos referir aos chains: PREROUTING, pacotes que serão alterados antes de roteamento; OUTPUT, pacotes locais que serão alterados antes do roteamento e POSTROUTING, pacotes que serão alterados após a aplicação das regras de roteamento;
   3. mangle: usada para alterações especiais no pacote, PREROUTING, para alteração antes do roteamento e OUTPUT, pacotes locais que serão alterados antes do roteamento.

Dentre as ações que são feitas sobre os pacotes que atendem a um determinado chain em uma dada tabela, temos:

   1. ACCEPT: aceita o pacote;
   2. DROP: rejeita o pacote;
   3. MASQUERADE: atua somente sobre a tabela nat e indica que será efetuado a conversão de endereços ou NAT, conforme indicado no comando.

Podemos definir regras padrão para um determinado chain e regras mais específicas, usando:

iptables [–t TABELA] –P CHAIN AÇÃO,

onde TABELA é a tabela sobre a qual estamos atuando – caso não especificarmos, será assumida a tabela filter; CHAIN é a corrente de regras à qual o pacote está associado; e AÇÃO é a ação a ser executada.

Para adicionarmos uma regra usando iptables, procedemos da seguinte forma:

iptables [–t TABELA] –A CHAIN {OPÇÕES} –j AÇÃO,

sendo OPÇÕES é um conjunto diverso de opções que podemos especificar, como interface de origem ou de destino e TABELA, CHAIN e AÇÃO definidos como anteriormente.

De modo análogo,

iptables [–t TABELA] –D CHAIN {OPÇÕES} –j AÇÃO

permite removermos uma regra.

Para limparmos todas as regras existentes de um chain usamos:

iptables [–t TABELA] –F CHAIN.

O uso de iptables em conjunto com o pacote iproute2 permite, assim, uma configuração completa de roteamento no Linux.

^

5. Roteamento avançado com o iproute2

Estando o Kernel configurado com as opções avançadas de roteamento descritas na preparação do ambiente, pode-se fazer uso de políticas de roteamento antes não disponíveis. Uma das opções avançadas é o fato de que pode-se ter múltiplas tabelas de roteamento. Ao se efetuar o roteamento de um pacote, o Kernel deve verificar se o pacote se enquadra em uma tabela e ao roteamento correspondente a mesma, então aplicando-o. Existe um conjunto de regras para esta verificação, cada qual com sua prioridade, e o Kernel verifica se o pacote se enquadra inicialmente em uma prioridade mais baixa. O Kernel utiliza três tabelas iniciais:

   1. local: identificada no Kernel por 255, é associada com a regra de prioridade 0, possui rotas para endereços locais e de broadcast, tal regra não pode ser alterada;
   2. 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;
   3. 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.

Podemos verificar as regras existentes no sistema com o comando:

# ip rule list

0: from all lookup local

32766: from all lookup main

32767: from all lookup default

Por padrão, 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.

O Kernel trabalha exclusivamente com o identificador númerico da tabela. Podemos estabelecer novas tabelas e definir situações especiais de roteamento. Para uso da ferramenta ip, deveremos informar essas novas tabelas no arquivo /etc/iproute2/rt_tables, cujo conteúdo padrão é:

#
# reserved values
#
255 local
254 main
253 default
0 unspec

Podemos adicionar uma nova tabela editando este arquivo e definir uma regra nova com o comando ip rule add. Tal regra pode ser aplicada para pacotes que atendam a critérios específicos como, por exemplo, o endereço IP de origem. Isto permite a realização de Roteamento pela Origem, conforme será abordado no estudo de caso.

^

6. Roteamento avançado: roteamento pela origem e NAT

Conforme descrito no artigo "Roteando pela Origem com Linux", uma aplicação não convencional de roteamento é o caso em que possuímos mais de um provedor de Backbone servindo a nossa rede local e desejamos que parte dessa rede utilize um dos provedores e a outra parte utilize o outro. Explicitamente falando, por exemplo, se a instituição possui dois links de acesso a Internet, um com a RNP e outro com a Embratel, pode-se colocar um roteador com Linux com três interfaces, uma conectada ao roteador com a RNP, outra conectada ao roteador com a EMBRATEL e outro conectado a Rede Local. Com o uso do roteamento pela origem, configuramos que a subrede 1 da Rede Local terá acesso a Internet pela RNP e a subrede 2 da Rede Local terá acesso a Internet pela EMBRATEL.

O acesso, de acordo com a mesma abordagem utilizada em "Roteando pela Origem com Linux", deve ser feito utilizando-se o NAT onde, quando uma máquina da rede interna for acessar a Internet terá seus pacotes com o endereço de origem trocado pelo do roteador Linux, o qual guarda uma tabela para mapear o endereço original do pacote. Sem o NAT, poderia haver problemas no retorno do pacote, pois cada provedor de Backbone possui um bloco próprio de endereçamento IP.

Para exemplificar, usaremos o seguinte cenário:

  • Roteador da RNP: 200.128.35.10
  • Roteador da EMBRATEL: 200.254.245.10
  • Roteador Linux:
              o RNP (interface eth2): 200.128.35.1 Netmask 255.255.255.0
              o EMBRATEL (interface eth1): 200.254.245.1 Netmask 255.255.255.0
              o Rede Interna (interface eth0): 10.1.0.1 Netmast 255.255.0.0
  • Roteador Interno:
              o Interface para Subrede 1: 10.1.0.2 Netmask 255.255.0.0
              o Interface para Subrede 2: 10.2.0.2 Netmask 255.255.0.0
  • Subrede 1 (acesso via RNP): 10.1.0.0/16
  • Subrede 2 (acesso via EMBRATEL): 10.2.0.0/16

A nossa rota padrão será a da Embratel. O roteador Linux fará o NAT dos pacotes da Rede Interna para a RNP ou para EMBRATEL, de acordo com a interface de saída do pacote. Não será abordada a configuração das estações de trabalho de cada subrede, bem como dos roteadores da RNP e da EMBRATEL e do Roteador Interno, por fugir do escopo deste artigo. O primeiro passo é configurar as interfaces no Linux:

# ip addr add 10.1.0.1/16 dev eth0
# ip addr add 200.254.245.1/24 dev eth1
# ip addr add 200.128.35.1/24 dev eth2

Feito isso, deve-se adicionar uma rota para toda a Rede Interna via eth0:

#ip route add 10.0.0.0/8 via 10.1.0.2

E a rota default também deve ser incluída:

#ip route add default via 200.254.245.10

Contudo, a rede interna ainda não pode acessar a Internet, pois o NAT deve ser configurado para fazer a troca de endereços, já que os endereços desta rede interna são endereços de caráter privado (10.0.0.0/8), não sendo, portanto, roteáveis na Internet.

O uso do iptables permite definir o comportamento da passagem de pacotes entre as interfaces de rede do roteador. Inicialmente, limpamos as regras estabelecidas pelo iptables, definindo como padrão aceitar a entrada e saída de pacotes pelas interfaces, porém sem efetuar o roteamento:

#iptables -P INPUT ACCEPT
#iptables -F INPUT
#iptables -P OUTPUT ACCEPT
#iptables -F OUTPUT
#iptables -P FORWARD DROP
#iptables -F FORWARD

O roteamento só será permitido de modo que pacotes que sejam originários da rede interna alcancem a Internet, ou ainda que pacotes da Internet alcancem a rede interna caso sejam resposta a alguma solicitação da mesma. Os comandos abaixo definem o primeiro comportamento, onde –i indica a interface de entrada dos pacotes no roteador e –o, a interface de saída:

#iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
#iptables -A FORWARD -i eth0 -o eth2 -j ACCEPT

O segundo comportamento necessita de uso de uma outra restrição –m state e – – state, onde o estado do pacote indica haver uma conexão já estabelecida ou uma resposta a uma solicitação vinda da rede interna:

#iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

#iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

A filosofia empregada é proteger a rede interna de tentativas de acesso não autorizados. O próximo passo é estabelecer e configurar o NAT. Para isto, se referindo a chain POSTROUTING da tabela nat no iptables, estabelece-se que quando o pacote sair para uma das interfaces externas, ou seja acesso a Internet, será feita a ação MASQUERADE que realizará o NAT no pacote:

#iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

#iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

O roteador Linux já está ativo e realizando o NAT, permitindo a toda a rede interna acessar a Internet via Embratel. Contudo, ainda não estamos utilizando o link RNP; para usarmos tal link deveremos configurar o roteamento pela origem, fazendo o roteamento dos pacotes da subrede 2 (10.2.0.0/16) através do link RNP. Isto pode ser feito criando-se uma tabela de roteamento própria para a subrede 2, adicionando-a inicialmente ao arquivo /etc/iproute2/rt_tables, cujo conteúdo passa a ser:

#

# reserved values

#

255 local

254 main

253 default

200 subrede2

0 unspec

Adicionamos uma rota padrão nessa nova tabela de roteamento apontando para o roteador da RNP:

#ip route add default via 200.128.35.10 table subrede2

Essa tabela de rotas – subrede2 – ainda não está em uso pelo sistema, deve-se criar uma regra que indicará que a tabela só deve ser utilizada pelos pacotes que tenham endereço de origem a rede 10.2.0.0/16. Após o roteamento, o pacote será remetido para interface ligada a RNP e o sistema efetuará o NAT, substituindo o endereço do pacote pelo endereço 200.128.35.1. Caso o pacote possua outro endereço de origem não pertencente a 10.2.0.0/16, como 10.1.0.3, essa tabela nova não será usada e sim a tabela de roteamento main, a qual indicará que o mesmo será remetido para a interface ligada a EMBRATEL e o sistema efetuará o NAT, substituindo o endereço do pacote pelo endereço 200.254.245.1. A regra que refere-se ao roteamento pela origem da subrede 2 é:

#ip rule add from 10.2.0.0/16 table subrede2

Onde vemos a referência direta ao endereço de origem do pacote e ao uso da tabela de roteamento subrede2.

Então, a lista de regras de roteamento é dada por:

# ip rule list

0: from all lookup local

32765: from 10.2.0.0/16 lookup labs

32766: from all lookup main

32767: from all lookup default

Que realiza exatamente o comportamento descrito.

A solução está agora totalmente operacional. Para que o sistema funcione a contento, basta incluirmos esses comandos de configuração da rede em um arquivo de inicialização do sistema, como, no caso da distribuição Slackware, no /etc/rc.d/rc.inet1. Assim, ao reiniciarmos o sistema, ele irá automaticamente restabelecer a configuração, roteando os pacotes de acordo com o desejado.

7. Considerações finais

Uma série de outros recursos podem ser explorados com o uso do iptables e ip, sempre que o convencional não atender às nossas expectativas. Uma boa referência é o documento "Linux 2.4 Advanced Routing HOWTO", disponível a partir de http://www.linux.org/ .

Como exemplo de solução possível usando os recursos aqui abordados, vimos o uso de roteamento pela origem onde há uma necessidade de se aproveitar o recurso de dois links, separando o uso pelas subredes. Embora tal tema tenha sido tratado com extrema precisão e clareza em artigo anterior, " Roteando pela Origem com Linux ", a solução apresentada baseia-se no Kernel de série 2.0, através de aplicação de patches ao mesmo. O uso desta versão do Kernel não é desejável, pois limita os recursos disponíveis do sistema, ao mesmo tempo em que o Kernel 2.4 possui um subsistema de rede no Kernel do Linux totalmente remodelado e com claras melhorias em relação ao 2.0, o que implica que a implementação descrita no referido artigo não se aplica a sistemas baseados em versões recentes do Kernel.

Este artigo procurou apenas introduzir as ferramentas ip e iptable. Embora apenas tenha sido citado, a ferramenta tc é extremamente poderosa para a execução de ações de controle de tráfego, sugerindo-se uma análise cuidadosa dos recursos da mesma. As três ferramentas usadas em conjunto tornam o Linux um roteador altamente flexível, configurável e seguro, equiparado a um grupo seleto de soluções de roteamento.

^

Referências bibliográficas

[1] Netherlabs BV, Gregory Maxwell, Remco van Mook, Martijn van Oosterhout, Paul B Schroeder e Jasper Spaans – "Linux 2.4 Advanced Routing HOWTO". Linux Documentation Project. Setembro de 2001.  http://www.linux.org/docs/ldp/howto/Adv-Routing- HOWTO.html

[2] Alexey N. Kuznetsov - "IP Command Reference". Institute for Nuclear Research, Moscou. Abril de 1999. http://defiant.coinet.com/iproute2/ip-cref/node104.html .

[]'s


Skayler
Away

Anonymous