Balanceamento de links por conteúdo

1. Balanceamento de links por conteúdo

Bruno Vescovi Nogueira
brunovescovi

(usa Debian)

Enviado em 15/10/2009 - 10:13h

Boa dia a todos.
Sou usuário do Ubuntu Desktop a uns anos, mas tive a necessidade de montar um servidor de internet em Ubuntu Server na escola onde eu trabalho e estou na fase final agora.
Nesse servidor tenho instalado o Ubuntu Server básico e acrescentei os seguintes serviços: DHCP (e usei o arquivo ethers para amarrar o IP ao MAC), SSH Server, Web Admin, Squid Proxy (em modo transparent junto com umas regrinhas de iptables para isso) e faço relatórios com o SARG.
Os serviços acima estão funcionando em produção há cerca de um mês. Tenho cerca de 40 a 50 estações cadastradas usando internet por esse servidor. Eu recebo internet através de um link de rádio e redistribuo internamente na escola via cabo e wireless. Meu servidor é um Pentium III 800 com 384 MB RAM e HD de 20 GB.
Bom, vamos ao problema!!!
A empresa que nos fornece o link de rádio só tem planos até 600Kbps. Imagine 50 pessoas acessando sites através desse link!!! Impossível.
Por isso tínhamos aqui, antes de implantarmos esse servidor, um link desse de 600Kbps para cada grupo de 6 estações. Então nos deparamos numa situação onde já tínhamos 6 links de 600Kbps cada um, separados por roteadores wireless independentes, e sem nenhum tipo de segurança ou controle de conteúdo, o que vimos ser indispensável pelo fato de que temos vários alunos acessando a rede.
A idéia do servidor é interligar toda a escola para controlar horários e conteúdos dos sites visitados, o que já estou fazendo usando o Squid.
O que não consegui fazer foi utilizar os 6 links que temos.
Depois de muito pesquisar, consegui fazer o load balance com três links ao mesmo tempo. Poderia fazer com os seis mas não tenho mais slots PCI na placa mãe. Coloquei quatro placas de rede no servidor. A eth0 é para a rede interna e a eth1, eth2 e eth3 são os três links que estou balanceando no servidor. Estou balanceando usando apenas iptables e iproute2. O script que rodo meu firewall e compartilhamento é o seguinte:

#### início do script de firewall e compartilhamento
# Reiniciando o firewall
iptables -F
iptables -Z
iptables -X
iptables -t nat -F

# Compartilha a conexão
modprobe ip_tables
modprobe iptable_nat
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth3 -j MASQUERADE

# Configura proxy transparente
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3128

# Bloqueia pings e protege contra IP spoofing e pacotes inválidos
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP
echo 1 > /proc/sys/net/ipv4/conf/default/rp_filter
iptables -A INPUT -m state --state INVALID -j DROP

# Abre para a interface de loopback e para a interface de rede local
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT

# Abre para portas específicas
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Bloqueia as demais conexões, deixando passar apenas pacotes de resposta
iptables -A INPUT -p tcp --syn -j DROP

ip route flush cache
#### fim do script de firewall e compartilhamento


O script do balanceamento é o seguinte:

#### início do script de balanceamento
#!/bin/bash

# Interface da rede local
IF0=eth0

# Interface 1
IF1=eth1
# Interface 2
IF2=eth2
# Interface 3
IF3=eth3

# IP 1
IP1=192.168.23.8
# IP 2
IP2=192.168.23.9
# IP 3
IP3=192.168.23.16

# Gateway 1
P1=192.168.23.1
# Gateway 2
P2=192.168.23.1
# Gateway 3
P3=192.168.23.1

# Rede Local
P0_NET=192.168.77.0

# Rede 1
P1_NET=192.168.23.0
# Rede 2
P2_NET=192.168.23.0
# Rede 3
P3_NET=192.168.23.0

# Apaga a rota padrão
route del default gw $P1
route del default gw $P2
route del default gw $P3

ip route add $P1_NET dev $IF1 src $IP1 table LINK_1
ip route add 127.0.0.0/8 dev lo table LINK_1
ip route add $P0_NET dev $IF0 table LINK_1
ip route add default via $P1 table LINK_1

ip route add $P2_NET dev $IF2 src $IP2 table LINK_2
ip route add 127.0.0.0/8 dev lo table LINK_2
ip route add $P0_NET dev $IF0 table LINK_2
ip route add default via $P2 table LINK_2

ip route add $P3_NET dev $IF3 src $IP3 table LINK_3
ip route add 127.0.0.0/8 dev lo table LINK_3
ip route add $P0_NET dev $IF0 table LINK_3
ip route add default via $P3 table LINK_3

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

ip rule add from $IP1 table LINK_1
ip rule add from $IP2 table LINK_2
ip rule add from $IP3 table LINK_3

ip route add default equalize nexthop via $P1 dev $IF1 weight 1 nexthop via $P2 dev $IF2 weight 1 nexthop via $P3 dev $IF3 weight 1

ip route flush cache
#### fim do script de balanceamento


Meu rt_tables ficou assim:


#### início do rt_tables
#
# reserved values
#
255 local
254 main
253 default
0 unspec
#
# local
#
#1 inr.ruhep

10 LINK_1
11 LINK_2
12 LINK_3
30 LINKS_UNIDOS
#### fim do rt_tables


Esse LINKS_UNIDOS é porque eu estava fazendo outros testes.
Vou colocar também meu squid.conf:


#### início do squid.conf
### ----------------------------------
### --- Configurações de estrutura ---
### ----------------------------------

# Porta do Squid com proxy transparente
http_port 3128 transparent
# Nome do proxy para a rede
visible_hostname deuteroxy
# Força o DNS do servisor
dns_nameservers 192.168.23.1
# Tamanho do cache na memória RAM
cache_mem 128 MB
# Tamanho máximo de um arquivo em cache na memória RAM
maximum_object_size_in_memory 512 KB
# Tamanho máximo de um arquivo em cache de disco
maximum_object_size 512 MB
# Tamanho mínimo de um arquivo em cache de disco
minimum_object_size 0 KB
# Porcentagem de cache em disco em baixa
cache_swap_low 90
# Porcentagem de cache em disco em alta
cache_swap_high 95
# Tamanho reservado em disco para o cache
# Número de diretórios
# Número de subdiretórios
cache_dir ufs /var/spool/squid 10000 16 256
# Local do log de acessos
cache_access_log /var/log/squid/access.log
# Local para buscar as mensagens de erro
error_directory /usr/share/squid/errors/Portuguese/
# Email para mensagens
#cache_mgr brunovescovi@bol.com.br



### -------------------------
### --- Cache obrigatório ---
### -------------------------

# Cache dos arquivos de atualização da microsoft
refresh_pattern windowsupdate.com/.*\.(cab|exe|dll|msi) 10080 100% 43200 reload-into-ims
refresh_pattern download.microsoft.com/.*\.(cab|exe|dll|msi) 10080 100% 43200 reload-into-ims
refresh_pattern www.microsoft.com/.*\.(cab|exe|dll|msi) 10080 100% 43200 reload-into-ims
refresh_pattern au.download.windowsupdate.com/.*\.(cab|exe|dll|msi) 4320 100% 43200 reload-into-ims



### -------------------------------------------
### --- Não faz cache de chamadas dinâmicas ---
### -------------------------------------------

hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin /?
no_cache deny QUERY



### -------------------------------
### --- Configuração das regras ---
### -------------------------------

# Regras padrão
acl all src 192.168.77.0/255.255.255.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl SSL_ports port 443 563 10000
acl Safe_ports port 80 21 280 443 488 563 591 777 70 210 1025-65535
acl purge method PURGE
acl CONNECT method CONNECT

# Rede local
acl redelocal src 192.168.77.0/24
# Horário de aula
acl horario_de_aula time TWHFA 08:00-12:00
# IP dos alunos
acl alunos src "/etc/squid/acl/ip_alunos"
# IP dos estagiários
acl estagiarios src "/etc/squid/acl/ip_estagiarios"
# IP das estações da informática
acl setores src "/etc/squid/acl/ip_setores"
# IP dos obreiros
acl obreiros src "/etc/squid/acl/ip_obreiros"
# URL de update microsoft
acl microsoft url_regex windowsupdate.com download.microsoft.com
# Horários para fazer atualização microsoft
acl horario_microsoft time SMTWHFA 05:00-08:00 17:00-19:00


### ------------------------------
### --- Balanceamento de links ---
### ------------------------------

#acl ROTA_LINK_2 dstdom_regex youtube.com
#tcp_outgoing_address 192.168.23.9 ROTA_LINK_2


### ----------------------------
### --- Aplicação das regras ---
### ----------------------------

# Aplicações padrão
http_access allow manager localhost
http_access deny manager
http_access allow purge localhost
http_access deny purge
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports

# Bloqueia atualização microsoft fora do horário permitido
http_access deny microsoft !horario_microsoft
# Bloqueia acesso de alunos em horário de aula
http_access deny alunos horario_de_aula

# Libera para o servidor
http_access allow localhost
# Libera para a rede local
http_access allow redelocal
# Bloqueia para todos
#http_access allow ROTA_LINK_2
http_access deny all



### -------------------------
### --- Controle de banda ---
### -------------------------

delay_pools 2

delay_class 1 2
delay_parameters 1 -1/-1 15000/15000
delay_access 1 allow alunos
delay_access 1 allow estagiarios
delay_access 1 allow setores

delay_class 2 2
delay_parameters 2 -1/-1 -1/-1
delay_access 2 allow all
#### fim do squid.conf

O balanceamento, como vocês podem ver no segundo script, está usando os três links de forma uniforme com peso 1 para cada link, mas para mim isso não funciona muito, pois minha intenção é dividir os links por "assunto". Por exemplo: Um link para navegação de páginas, outro link para downloads, outro link para orkut, MSN, etc, outro link para youtube e stream de vídeo e por aí vai. Gostaria de dedicar cada link de acordo com o conteúdo.
Imaginei que pudesse fazer isso através do squid em conjunto com a configuração de múltiplas rotas com iproute2.
Se vocês notarem, eu até tentei fazer isso pelo squid.conf com o parâmetro tcp_outgoing_address, mas sem sucesso.
Uma das coisas que penso ser obstáculo é que todos os meus links chegam na forma de endereços classe C do meu provedor.
Vou listar abaixo os dados dos três links que estou usando agora, mas os outros três que não estou usando têm característica semalhante:
- Link 1 - 192.168.23.8
- Link 2 - 192.168.23.9
- Link 3 - 192.168.23.16
O DNS e o Gateway para todos os links é o mesmo: 192.168.23.1

É isso aí então. A solução que eu procuro é poder direcionar para cada link um conteúdo específico de navegação. Se fosse por porta ou serviço seria mais fácil, mas meu uso principal aqui é navegação. Se pudesse controlar tudo pelo Squid seria mais fácil, mas estou aberto a qualquer idéia. Qualquer idéia mesmo. Mas estou limitado a esses links de 600Kbps. Quanto a isso não precisa nem perguntar pois já explorei todas as possibilidades de acesso disponíveis na minha região e não encontrei nada melhor, por incrível que pareça. Velox da OI não chega aqui pois estou a mais de 6 Km da central mais próxima (pelo menos foi essa a desculpa que ouvi!) e a única empresa que distribui internet via rádio na cidade é essa que me fornece hoje.
Depois terei que arrumar um jeito de colocar seis links num só servidor, mas isso já é outro problema.
Se eu resolver o assunto com os três links, depois é só questão de hardware para incluir quantos links eu precisar.

Desde já, muito obrigado pelo esforço só em ler esse post gigante; é que eu quis pintar o quadro da maneira mais clara.

Um grande abraço a todos.


  






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts