Implementação de delay pool com Squid

De Eriberto Wiki
Ir para navegação Ir para pesquisar
A versão imprimível não é mais suportada e pode ter erros de renderização. Atualize os favoritos do seu navegador e use a função de impressão padrão do navegador.

by (C) João Eriberto Mota Filho <eriberto (a) eriberto pro br>

Artigo criado em: 10 de novembro de 2011.

Última atualização: veja o rodapé desta página.

Tiny URL ou bit.ly: http://bit.ly/delay_pool



Este artigo foi escrito com base em um Debian Squeeze 6.0.3, utilizando Squid 2.7. O Squid mais atual (3.1) possui diversas features a mais, inclusive na área de delay pool. No entanto, este artigo já resolve um dos maiores problemas dos administradores de rede: o controle de downloads.



O que é delay pool?

Delay Pool ou Delay Pools, como alguns chamam, é um recurso do Squid que permite limitar o tráfego HTTP de usuários ou até de redes inteiras. Ele é essencial para que tenhamos condições justas para todos os que navegam em sites a partir de uma rede.

O grande objetivo deste artigo será a limitação da velocidade de download por usuário, apesar de que serão citadas outras variantes de controle.

Para a implementação dos recursos aqui citados, o Squid deverá estar previamente configurado e funcionando normalmente como proxy na rede.

O delay pool somente cuida do tráfego HTTP. É muito importante que todo o resto do tráfego seja controlado. Para isso, consulte o artigo Controle de tráfego com TC, HTB e Iptables. Lembre-se: HTB e delay pool são indispensáveis em QUALQUER rede!



Unidades de medida

As unidades básicas de medida na informática são:

  • b: bit. Representa a menor informação possível.
  • B: byte. Um conjunto de 8 bits.

Em telecomunicações, as unidades de medida possuem base decimal. Isso quer dizer que o multiplicador/divisor é sempre 1000 e não 1024, como estamos acostumados. Assim, 1 KB/s (kilobyte por segundo) corresponde a 1000 B/s (bytes por segundo). Ainda, 1 Mb/s (megabit por segundo) corresponde a 1000 Kb/s (kilobits por segundo) que, por sua vez, é igual a 125 KB/s (kilobytes por segundo). Este último cálculo se deu da seguinte forma:

1 Mb/s = 1000 Kb/s
1000 Kb/s ÷ 8 = 125 KB/s
O delay pool trabalha com B e B/s.



ACLs, buckets, classes, pools e rajadas

Veremos alguns termos básicos utilizados no Squid e, particularmente, no delay pool.

ACLs

As ACLs (Active Control Lists) servem para definirmos regras no Squid. Elas criam um escopo referente a uma determinada situação. Exemplo:

acl minharede src 192.168.1.0/24

A ACL anterior foi denominada minharede e refere-se a tudo que seja originado (src = source) na rede 192.168.1.0/24.

O delay pool atua sobre tráfegos que estejam liberados no Squid. Ou seja: o tráfego tem que estar em condições de ocorrer sem problemas. Um comando para liberar o tráfego através Squid para rede citada seria:

http_access allow minharede

É possível bloquear alguns tipos de tráfego com http_access deny. Exemplo:

acl proibidos url_regex -i \.(orkut|facebook)\.com
http_access deny proibidos

No caso anterior, foi utilizado um sistema de expressão regular (veja mais sobre o assunto logo adiante) para dizer que todas os sites com domínio .orkut.com e .facebook.com, em letras maiúsculas ou minúsculas (opção -i), deverão ser bloqueados. Se a relação de sites proibidos for longa, há como colocar cada um em uma linha dentro de um arquivo. A referência ao arquivo poderá ser feita pela ACL da seguinte forma:

acl proibidos url_regex -i "/etc/squid/proibidos.txt"
Evite utilizar muitos bloqueios como, por exemplo, um milhão de sites de pornografia. Isso vai exigir que você tenha uma máquina hiperpoderosa para comparar cada URL solicitada por um usuário da rede com cada linha de bloqueio. Acredite: a cada dia, milhões de sites são criados e não há como bloquear tudo o que existe ou existirá daqui a 10 minutos.

É muito importante ressaltar que o acl sempre trabalha com OR lógico e que http_access usa AND lógico. Observe:

acl rede1 src 10.0.0.0/8
acl rede2 src 192.168.1.0/24
acl proibidos url_regex -i \.(orkut|facebook)\.com
http_access deny rede1 proibidos

No caso anterior, foram criadas três ACLs e uma regra. Nessa regra houve um AND que utilizou duas ACLs: rede1 AND proibidos. Isso quer dizer que a tudo o que for rede1 e proibidos será bloqueado. Um exemplo: a máquina 192.168.1.12 tentando acessar http://www.orkut.com.

Mas imagine se a linha http_access deny fosse assim:

http_access deny rede1 rede2 proibidos

Nesse caso, estaríamos dizendo que tudo o que fosse rede1 e rede2 e proibidos seria bloqueado. Mas isso é impossível, pois um IP de origem não pode pertencer, ao mesmo tempo, às redes 10.0.0.0/8 e 192.168.1.0/24. Em outras palavras, a regra nunca teria efeito algum.

Observe que todas as regras do tipo http_access criadas por você deverão ser colocadas logo após a sentença # INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS, existente dentro do arquivo de configuração do Squid. Isso porque a última regra sempre deverá ser http_access deny all. Isso garantirá que tudo o que não for habilitado pelo administrador de rede será bloqueado por default.

Utilizamos aqui a sentença url_regex na ACL. Essa sentença serve para buscar ocorrências em toda a URL. Há também urlpath_regex, que busca somente depois do domínio. Em outras palavras, utilizando urlpath_regex em:

http://eriberto.pro.br/site/wp-content/uploads/2011/11/737-800.jpg

será analisada somente a parte

site/wp-content/uploads/2011/11/737-800.jpg.

Para saber sobre todas as possibilidades de ACLs no Squid 2.7, consulte o site http://www.visolve.com/squid/squid27/accesscontrols.php. Para o Squid 3.0, veja http://www.visolve.com/squid/squid30/accesscontrols.php.

Buckets

Buckets ou baldes são fruto da famosa teoria de tráfego por baldes e bastões (tokens). Partimos do princípio de que temos balde(s) cheio(s) de bastões. Cada pacote de rede necessita apanhar um bastão para ter o seu tráfego liberado.

No Squid, cada bastão (token) tem o tamanho de 1 byte.

Há várias formas de utilizar os baldes. Exemplo: você tem um balde onde cabem 30 KB e que leva 1 segundo para esvaziar. Os downloads serão feitos com base nesse balde. Em outras palavras, a cada 1 segundo só poderemos encher o balde com 30 KB de dados (que representam os bastões). Isso será responsável pela limitação de velocidade.

É interessante citar que diversos sistemas de controle de tráfego modernos utilizam a teoria dos baldes. Um exemplo clássico é o delay pool. Outro é a disciplina HTB (Hierarchy Token Bucket), muito conhecida.

Classes

O delay pool do Squid 2.7 possui três classes. São elas:

  • Classe 1: realiza o controle de toda a rede. Para isso, utiliza apenas um balde. Em outras palavras, em um link de 10 Mb/s, caso seja configurada uma classe 1 de 7 Mb/s, a soma de todas as conexões HTTP não poderão ultrapassar a 7 Mb/s. Com isso, 3 Mb/s ficarão livres para outras atividades e protocolos.

  • Classe 2: há dois baldes. O primeiro limita a rede como um todo, exatamente como faz a classe 1. O segundo balde limita os endereços IP individualmente, considerando apenas o último octeto. Essa pode ser a classe a ser utilizada quando buscamos a limitação de usuários individualmente. Mas observe que há uma armadilha: dependendo das regras e da situação de rede, IPs como 172.20.10.5 e 172.20.11.5 serão englobados pelo mesmo balde, uma vez que os dois possuem 5 como último octeto. Então, haverá a divisão da velocidade de um único balde por dois tráfegos diferentes. Há duas soluções para o problema: fazer regras muito específicas ou utilizar a classe 3 (melhor opção por ser mais fácil).

  • Classe 3: há três baldes. O primeiro balde limita tudo. O segundo atua no terceiro octeto somente e pode ser utilizado como um delimitador de uma subrede inteira. O terceiro balde atua nos dois últimos octetos (isso mesmo! no terceiro octeto novamente e no quarto). Essa classe é perfeita para limitar usuários individualmente.
No Squid 3.x há ainda as classes 4 e 5, que atuam também sobre o login de usuários autenticados e tags.



Pools e rajadas

As pools (uniões) são o resultado da agregação de uma ou mais ACLs com uma regra de tráfego. As regras determinarão a velocidade a qual cada situação de rede será submetida.

Cada pool, dependendo da classe, utiliza um ou mais pares de números. O primeiro desses números é o restore rate e o segundo é o maximum size. O maximum size representa o tamanho do balde a ser utilizado e o restore rate é a velocidade com a qual ele é reabastecido com bastões. Assim, observe a pool a seguir:

delay_parameters 1 -1/-1 25000/90000
delay_access 1 allow rede_usuarios

O -1 significa livre. Então, -1/-1 quer dizer um balde de tamanho ilimitado, sendo preenchido com bastões, instantanea e constantemente. Já 25000/90000 significa que temos um balde onde cabem 90.000 bastões. Como cada bastão no Squid equivale a 1 byte, temos um balde de 90.000 bytes, que é igual a 90 KB. Ainda, cada balde será reabastecido com 25.000 bastões por segundo, que correspondem a 25.000 bytes por segundo. Com isso, teremos um efeito denominado rajada.

Especificamente, o balde em questão iniciará com a velocidade de 90 KB/s e irá decaindo até chegar a 25 KB/s. Isso serve para que o sistema livre-se rapidamente de arquivos menores em download. No entanto, esse tipo de procedimento pode ser prejudicial à rede. Assim, é aconselhável, para a maioria dos casos, não permitir rajadas. Então, a não ser que haja motivos para não fazer dessa forma, use os mesmos valores para restore rate e maximum size. Exemplo: 25000/25000. Isso será o suficiente para que não ocorram rajadas.

A ordem das regras

A ordem das regras (ACLs) interfere diretamente no funcionamento do Squid. A primeira regra que englobar uma determinada situação será aplicada e as demais ignoradas.

Considere um exemplo hipotético de regras:

1) Todos podem acessar qualquer JPG sem restrição.
2) Cada usuário terá a sua velocidade de download restrita a 1 Mb/s entre 08:00h e 10:00h.
3) Cada usuário terá a sua velocidade de download restrita a 3 Mb/s.

Agora, imagine a seguinte situação: um usuário fará o download de uma figura JPG de 10 MB de tamanho e, em paralelo, de um arquivo .exe também com 10 MB. Imagine ainda que são 08:45h. Com as regras anteriores, o arquivo JPG será baixado na maior velocidade possível, enquanto o arquivo .exe estará limitado a 1 Mb/s. Se fossem 11:00h, o JPG seria novamente baixado na maior velocidade possível e o .exe a 3 Mb/s.

O raciocínio para o arquivo .exe, caso seja baixado às 09:00h, será o seguinte:

  • Regra 1: O .exe é um JPG? Não. Então, vamos para a próxima regra.
  • Regra 2: Está para ocorrer um download e a hora está entre 08:00h e 10:00h? Sim. Então, aplica-se a regra e não serão lidas as próximas. Será feito o download a 1 Mb/s.

Agora, observe as regras:

1) Cada usuário terá a sua velocidade de download restrita a 3 Mb/s.
2) Todos podem acessar qualquer JPG sem restrição.
3) Cada usuário terá a sua velocidade de download restrita a 1 Mb/s entre 08:00h e 10:00h.

Observe que houve uma inversão na ordem. A antiga regra 3 agora é a primeira. Então, considere que são 09:00h e que faremos um download de um JPG. O raciocínio será o seguinte:

  • Regra 1: Está para ocorrer um download? Sim. Então, aplica-se a regra e não serão lidas as próximas. Será feito o download a 3 Mb/s.
Em resumo, as regras mais restritivas deverão aparecer primeiro e as mais amplas no fim.



Exemplo simples de configuração

Considere uma ACL previamente existente em um Squid já configurado:

acl rede_usuarios src 192.168.10.0/24

Vamos implementar apenas uma pool, classe 2, para que possamos controlar o tráfego de cada IP individualmente. Não haverá um controle para a rede como um todo.

delay_pools 1
delay_class 1 2

Então, apenas reforçando, a primeira linha definiu que haverá apenas uma pool e a segunda diz que a pool 1 será classe 2.

A velocidade de cada usuário será de 200 Kb/s (kbits por segundo), que correspondem a 25000 B/s (bytes por segundo). O cálculo foi: 200 / 8 * 1000. Então, o resultado final será:

delay_parameters 1 -1/-1 25000/25000
delay_access 1 allow rede_usuarios

A primeira linha disse que a pool 1 não sofrerá controle global de rede (-1 significa livre). Diz ainda que cada usuário terá a sua velocidade de download reduzida para 25000 B/s (= 25 KB/s), sem direito a rajadas (o primeiro 25000 representa o regime de reabastecimento do balde, enquanto o segundo é o tamanho total de tal balde).

A segunda linha diz que a pool 1 será aplicada a quem for englobado pela ACL rede_usuarios.

Note que o objetivo foi controlar downloads individualmente. Isso só foi possível com a classe 2, que considera apenas o último octeto, porque estamos em uma rede com máscara classe C. Então, só teremos variação no último octeto. No entanto, para downloads individuais, o ideal é sempre trabalhar com a classe 3 do delay pool, que considera os dois últimos octetos.



Recursos especiais para as ACLs

O uso de expressões regulares

O Squid permite o uso de expressões regulares. Isso quer dizer que podemos utilizar caracteres com significados especiais para referenciarmos situações. Caracteres colocados entre colchetes, por exemplo, permitirão a criação de uma lista de elementos possíveis. Assim, test[ae] pode ser interpretado como testa e teste. O símbolo de interrogação refere-se à existência opcional do caractere anterior. Assim, [js]?html? representa, de uma só vez, htm, html, jhtm, jhtml, shtm e shtml. Da mesma forma, jpg e jpeg poderiam ser trocados por jpe?g.

Um resumo sobre a função desses caracteres especiais, conhecidos como metacaracteres, pode ser encontrado em http://aurelio.net/regex/guia/metacaracteres.html#2.

Agora, veja a seguinte ACL:

acl exclusao urlpath_regex -i \.([js]?html?|jpe?g|php|png|txt)$

Esta ACL define exclusao como sendo tudo que tiver um ponto, seguido de htm ou html ou jhtm ou jhtml ou shtm ou shtml ou jpg ou jpeg ou php ou png ou txt no fim da linha (simbolizado pelo caractere cifrão). A opção -i serve para fazer o Squid ignorar a caixa do caractere (case insensitive). Ou seja: -i jpg casa com jpg, JPG, jpG, JpG etc. Ainda, urlpath_regex faz a busca somente depois do nome do domínio na URL, como já foi explicado anteriormente.

Possibilidades nas ACLs

Há diversas possibilidades em ACLs. Com time, por exemplo, podemos definir dias e horários. Veja:

acl turno1 time MTWHF 07:00-13:00
acl turno2 time MTWHF 13:00-19:00

Nas ACLs anteriores, M, T, W, H e F representam os dias da semana de segunda a sexta-feira.

Como já foi dito anteriormente, para saber sobre todas as possibilidades de ACLs no Squid, consulte:

O arquivo de configuração do Squid também é um ótimo local para aprender sobre as ACLs. O arquivo é rico em comentários e termina sendo um manual para administradores.



Um exemplo um pouco mais sofisticado

Considere as seguintes ACLs:

acl rede_usuarios src 172.20.0.0/16
acl rede_gerentes src 172.21.0.0/16
acl exclusao url_regex -i \.(aspx?|css|jsp?|[js]?html?|rss|php|xml|txt|gif|jpe?g|png)$
acl expediente time MTWHF 6:30-19:00
Para facilitar, coloque todas as configurações de delay pool, incluindo as ACLs, no fim do arquivo /etc/squid/squid.conf. Caso você já tenha definido a rede anteriormente (rede_usuarios, rede_gerentes etc), não será necessário fazê-lo novamente.

As duas primeiras ACLs definem redes. Utilizando expressões regulares, a terceira ACL define exclusao como sendo algumas extensões que não causam problema de tráfego na rede. Essas extensões deverão aparecer no fim das URLs (o caractere cifrão indica isso). A quarta linha define expediente como sendo os dias de segunda a sexta-feira, das 06:30h às 19:00h.

Declararemos que haverá 4 pools e que cada uma utilizará a classe 3.

delay_pools 4
delay_class 1 3
delay_class 2 3
delay_class 3 3
delay_class 4 3

A partir deste momento, consideraremos um link de 10 Mb/s para 50 usuários. Considere ainda que há quatro agrupamentos de usuários, como, por exemplo, 172.20.1.0/24, 172.20.2.0/24, 172.20.3.0/24 e 172.20.4.0/24.

Daremos uma boa liberdade de tráfego para as extensões citadas na ACL exclusao. No entanto, é necessário ter um limite individual e um de subrede. O individual evitará que ocorra algum incidente, como um usuário baixando uma imagem ISO de CD com o nome de cd_musica.txt, por exemplo. O limite de subrede serve para fazer com que uma subrede não estrapole o sistema, prejudicando as outras. Exemplo:

delay_parameters 1 -1/-1 250000/250000 75000/75000
delay_access 1 allow exclusao

Ou seja: cada usuário pode acessar as citadas extensões a 600 Kb/s (75 KB/s). Cada subrede estará limitada a 2 Mb/s (250 KB/s).

A seguir, estabeleceremos os limites dos usuários durante o expediente como sendo 400 Kb/s (= 50 KB/s). O limite de cada subrede será 2 Mb/s.

delay_parameters 2 -1/-1 250000/250000 50000/50000
delay_access 2 allow rede_usuarios expediente

Definição dos limites dos gerentes de rede somente durante o expediente (600 Kb/s = 75 KB/s), com subrede a 3 Mb/s (375 MB/s):

delay_parameters 3 -1/-1 375000/375000 75000/75000
delay_access 3 allow rede_gerentes expediente

Por fim, definiremos a velocidade dos usuários fora do expediente como 1 Mb/s, com subredes a 3 Mb/s.

delay_parameters 4 -1/-1 375000/375000 125000/125000
delay_access 4 allow rede_usuarios

Como nada foi falado para os gerentes fora do expediente, com exceção do que se encaixa na ACL exclusao, haverá velocidade plena de rede em tal período.

Considerações importantes

A partir de agora, algumas considerações relevantes para a implementação do delay pool.

Erros nas pools

Sempre reveja e teste tudo. Fazer delay pool é simples mas muitas vezes erramos detalhes e liberamos tráfegos inadequados, escrevemos números mal calculados etc. Ainda, alguns erros poderão, simplesmente, fazer o Squid ignorar todo o delay pool. Exemplo: uma pool declarada mas inexistente.

Releitura do arquivo de configuração do Squid

Após alterar alguma configuração do Squid, não é preciso reiniciá-lo. Isso leva tempo e derruba temporariamente a navegação web. A solução é forçá-lo a apenas reler as suas regras. No Debian isso poderá ser feito com o seguinte comando:

# /etc/init.d/squid reload

Mas qualquer Squid, em qualquer distribuição, poderá ler o seu arquivo de configuração assim:

# squid -k reconfigure

No entanto, se você notar anomalias, terá que reiniciar mesmo o Squid. Neste caso:

# /etc/init.d/squid restart
É importante ressaltar que se você determinar ao Squid que somente leia as novas regras, os tráfegos que já estiverem ocorrendo manterão a configuração anterior. Já um restart provocará uma queda de todas as conexões. Com isso, os novos tráfegos já respeitarão as novas regras.



O cache do Squid

o cache do Squid é importantíssimo para poupar link. Parece que o tempo passou e as configurações default não foram atualizadas. Com isso, o Squid só guarda objetos que tenham sido baixados da Internet e que tenham um tamanho relativamente pequeno. Bem, eu uso 4 GB por objeto e tenho um cache de 100 GB. Mas sugiro o valor (mínimo) de 900 MB. Com isso, o Squid já armazenaria a ISO de um CD, por exemplo.

Para configurar o tamanho máximo de cada objeto que poderá permanecer em cache para 1 GB, altere a linha maximum_object_size para:

maximum_object_size 1 GB



Ajuste tudo com paciência...

Um dos grandes segredos do afinamento do controle de tráfego é a paciência. Assim, depois de ajustar o delay pool, observe por 3 ou 4 dias o comportamento da rede. NÃO TENHA PRESSA! A calma para esperar e ver resultados é importante nesta hora.

É essencial utilizar um recurso como MRTG ou Cacti para que você possa ter gráficos que mostrem o andamento do tráfego. Escolha apenas um desses programas. Eles são fáceis de configurar e dão uma boa ideia do que possa estar acontecendo.

A figura a seguir mostra um exemplo de MRTG em funcionamento.



Veja também



Links externos



Redes sociais

  • Twitter: Para novidades sobre artigos, livros e palestras, siga-me em eribertomota.