Roteamento em Linux com 2 links de internet



Introdução

Como primeiro artigo sobre Linux, vou abordar um pouco sobre roteamento de pacotes usando iproute e iptables.
Imagine um cenário onde há um servidor que compartilha a internet para a rede interna, atuando como gateway, e por algum motivo foi contratado mais um link de internet. Ou então há 2 ou mais servidores proxy e se deseja definir para qual deles cada IP da rede interna deve seguir caminho. Outro cenário seria separar a parte de navegação dos demais serviços (msn, emule, e-mail…), cada uma usando um link diferente. Nesse artigo vou demonstrar que o Linux proporciona maneiras simples e eficientes de implementar esse tipo de roteamento. As distribuições utilizadas foram ubuntu server 5.04 e 5.10 e debian lenny.

Funcionamento

No exemplo em questão, o servidor que vou configurar é um gateway compartilhando a internet para vários clientes. O iptables realiza uma marcação para todos os pacotes oriundos de cada IP cliente e o iproute determina para qual link os pacotes deverão ser encaminhados de acordo com a marcação feita. Vou usar a marcação 1 para pacotes via link1, marcação 2 para pacotes à serem encaminhados para o link2 e a rota principal do próprio gateway será pelo link1.

Instalação

O iptables e iproute são pacotes presentes em quase todas as distribuições. Na maioria o iptables é instalado por padrão. Nesse caso, vou instalar apenas o iproute, via apt-get, que é o gerenciador de pacotes padrão das distribuições debian e ubuntu.
sudo apt-get install iproute2

Criando a tabela de roteamento

Vou criar 2 tabelas chamadas link1 e link2, adicionando duas linhas no final do arquivo /etc/iproute2/rt_tables, ficando assim:

root@gateway# cat /etc/iproute2/rt_tables
255 local
254 main
253 default
0 unspec
250 link1
251 link2
Agora vou criar o script rotas, dentro do diretório /etc/init.d/, que utiliza o iproute para definir as rotas.

root@gateway# vim /etc/init.d/rotas
conteúdo do script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/bin/bash
 
# DEFINICAO DOS GATEWAYS (IPs FICTICIOS)
GW_LINK1=189.12.34.1
GW_LINK2=200.56.78.1
 
# PLACAS DE REDE
ETH_LINK1=eth1
ETH_LINK2=eth2
 
function start() {
  # Limpa o cache de rotas
  ip route flush cache
  # Pacotes com marcacao 1 vao para o link1
  ip rule add fwmark 1 prio 20 table link1
  # Pacotes com marcacao 2 vao para o link2
  ip rule add fwmark 2 prio 20 table link2
  # Associa a rota do link1 a interface de rede e tabela correspondentes
  ip route add default via $GW_LINK1 dev $ETH_LINK1 table link1
  # Associa a rota do link1 a interface de rede e tabela correspondentes
  ip route add default via $GW_LINK2 dev $ETH_LINK2 table link2
  # Adiciona a rota padrao ao link1
  route add default gw $GW_LINK1
  echo "Tabela de roteamento criada."
}
 
function stop() {
  # Limpa o cache
  ip route flush cache
  # Deleta as regras de acordo com as marcacoes
  ip rule del fwmark 2
  ip rule del fwmark 3
  # Deleta a rota padrao
  route del default
  echo "Limpeza da tabela de roteamento concluida."
}
 
case $1 in
  'start') start; exit ;;
  'stop') stop; exit ;;
  'restart') stop; start; exit ;;
  *) start; exit ;;
esac
Reparem que o que o script rotas faz é dizer que pacotes marcados como 1 (fwmark 1) fazem parte da tabela link1 e marcados como 2 (fwmark 2) da tabela link2. Em seguida cria uma regra dizendo que os pacotes da tabela link1 seguem pelo gateway e interface de rede correspondentes. O mesmo para a tabela link2.
O próximo passo é fazer a marcação dos pacotes.

Marcando os pacotes com iptables

Esse script de firewall é apenas para demonstrar como fazer a marcação de pacotes. As regras devem ser incorporadas à um firewall melhor configurado e mais seguro.
O iptables na verdade é um software que age como frontend para manipulação do firewall do Linux, chamado de netfilter. Esse por sua vez possui uma tabela chamada mangle que é onde ficam armazenadas as regras de marcação de pacotes e outra chamada nat, que contém as regras de NAT.
Assim como antes, vou colocar o script dentro do diretório /etc/init.d

root@gateway# vim /etc/init.d/firewall
E dentro do script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/bash
 
# modprobe eh usado para carregar modulos do kernel
MOD=$(which modprobe)
 
# iptables
IPT=$(which iptables)
 
# Interfaces de rede
I_LINK1="eth1"
I_LINK2="eth2"
I_LAN="eth0"
 
function stop() {
  # Limpa a tabela mangle
  $IPT -t mangle -F
  $IPT -t mangle -X
 
  echo "Firewall parado."
}
 
function start() {
  # Carrega o modulo do kernel
  $MOD ip_tables
 
  # Limpa as regras anteriores
  stop;
 
  # Habilita redirecionamento de IP
  echo 1 > /proc/sys/net/ipv4/ip_forward
 
  # Clientes para o link1
  $IPT -t mangle -A PREROUTING -s 192.168.0.2 -i $I_LAN -j MARK --set-mark 1
  $IPT -t mangle -A PREROUTING -s 192.168.0.4 -i $I_LAN -j MARK --set-mark 1
 
  # Clientes para o link2
  $IPT -t mangle -A PREROUTING -s 192.168.0.3 -i $I_LAN -j MARK --set-mark 2
  $IPT -t mangle -A PREROUTING -s 192.168.0.5 -i $I_LAN -j MARK --set-mark 2
  $IPT -t mangle -A PREROUTING -s 192.168.0.6 -i $I_LAN -j MARK --set-mark 2
 
  # Apenas a navegacao vai para o link2. E-mail, msn e outros vao para o link1 que é a rota padrao.
  $IPT -t mangle -A PREROUTING -s 192.168.0.7 -i $I_LAN -p tcp --dport 80 -j MARK --set-mark 2
  $IPT -t mangle -A PREROUTING -s 192.168.0.7 -i $I_LAN -p tcp --dport ! 80 -j MARK --set-mark 1
 
  echo "Firewall iniciado."
}
 
case $1 in
  'start') start; exit ;;
  'stop') stop; exit ;;
  *) start; exit ;;
esac
Por fim, vou colocar os dois scripts para carregarem durante a inicialização do sistema. Há muitas maneiras de fazer isso, então vou fazer da mais preguiçosa possível porque isso varia de acordo com o administrador e distribuição utilizada:

root@gateway#: chmod +x /etc/init.d/rotas
root@gateway#: chmod +x /etc/init.d/firewall
root@gateway#: ln -s /etc/init.d/rotas /etc/rcS.d/S79rotas
root@gateway#: ln -s /etc/init.d/firewall /etc/rcS.d/S80firewall

Conclusão

Apenas com esses 2 scripts não será possível compartilhar a internet. Porém o objetivo aqui é mostrar uma breve abordagem de como fazer roteamento no Linux. Artigos, dicas e scripts para compartilhar internet existem aos milhares na internet. Com uma rápida pesquisa no google e implementando o que foi descrito aqui, é possível criar um servidor de internet em Linux muito mais estável e eficiente do que um rodando Windows.
fonte: http://blog.gustavohenrique.net/
Close Menu