Limitando Taxa a único host ou máscara de rede :: Admirável Mundo Novo




Muito Bem Vindo

Prezado Leitor, a proposta desse Blog é compartilhar conhecimento com as pessoas que trabalham com Linux, Asterisk, OpenSER, e com tecnologia de voz sobre a rede IP em geral, através de tutoriais, dicas, howto, notícias entre outros assuntos.

Atente para termo de uso do conteúdo do blog no rodapé da página.

quarta-feira, 21 de janeiro de 2009

Limitando Taxa a único host ou máscara de rede




15.9. Limitando Taxa a único host ou máscara de rede

Embora isso seja descrito em detalhes em outros lugares estupendamente e em nossas manpages, essa questão foi muito perguntada e felizmente existe uma resposta simples que não precisa da compreensão total de controle de tráfego.

Esse script de três linhas dá a pista:

tc qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth 10mbit

tc class add dev $DEV parent 1: classid 1:1 cbq rate 512kbit \
allot 1500 prio 5 bounded isolated

tc filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip dst 195.96.96.97 flowid 1:1

A primeira linha instala uma fila baseada em classe em sua interface, e ela diz ao kernel que cálculos, ele supõe que seja uma interface 10mbit. Se você tiver esse problema, nenhum dano real acontecerá. Mas se certifique que esteja fazendo tudo o mais preciso possível.

A segunda linha cria uma classe 512kbit com alguns padrões razoáveis. Para detalhes, veja as manpages CBQ e o Capítulo 9.

A última linha diz qual tráfego deve seguir para a classe shape-ada. O Tráfego que não bateu com essa regra NÃO será shape-ado. Para implementar match´s mais complicados (sub-redes, portas origem, portas destino), veja a Seção 9.6.2.

Se você alterou qualquer coisa e deseja recarregar o script, execute ‘tc qdisc del dev $DEV root’ para limpar sua configuração existente.

O script pode ser melhorado ainda mais adicionando uma linha opcional ao comando ‘tc qdisc add dev $DEV parent 1:1 sfq perturb 10’. Veja a seção 9.2.3 para detalhes a respeito do que disso faz.


15.10. Exemplo de uma solução full nat com QoS

Eu sou o Pedro Larroy . Aqui Eu estarei descrevendo uma instalação comum onde nós temos muitos usuários em uma rede privada conectada a Internet através de um roteador Linux com um endereço IP público que está fazendo NAT. Eu uso essa instalação QoS para permitir a acesso a Internet aos 198 usuários em um dormitório universitário, no qual Eu vivo e da qual eu sou o Administrador da rede. Os usuários daqui fazem uso pesado de programas peer-to-peer, de modo que o controle de tráfego é uma necessidade. Eu espero que isso sirva como um exemplo prático para todos os leitores do LARTC interessados.

Antes de tudo, Eu faço uma abordagem prática com configuração passo a passo, e no final Eu explico como fazer que o processo suba automaticamente no bootime. A rede para a qual esse exemplo se aplica é uma rede LAN privada conectada a Internet através de um roteador Linux que possui um endereço IP público. Estendê-lo a vários endereços IP públicos deve ser muito fácil, um punhado de regras iptables deve ser adicionado. A fim de fazer que as coisas funcionem como nós precisamos:


Versão do kernel Linux 2.4.18 ou superior instalado

Se você usar o 2.4.18, você precisará aplicar patch HTB disponível aqui.



iproute

Também assegure que o binário "tc" esteja com o HTB pronto, um binário pré-compilado é distribuído com o HTB.



iptables



15.10.1. Comecemos otimizando aquela banda escassa

Primeiro nós instalamos algumas qdiscs nas quais classificaremos o tráfego. Nós criamos uma qdisc HTB com 6 classes com prioridade ascendente. Depois temos classes que sempre obterão taxa alocada, mas podemos usar a largura de banda não usada que outras classes não precisarão. Chama novamente essas classes com prioridade mais alta (ou seja, com um número prio mais baixo) que pegarão o excesso de largura de banda alocada inicialmente. Nossa conexão é ADSL com 2Mbits/s de downstream e 300kbits de upstream. Eu uso 240kbit/s como taxa ceil apenas porque é a elevada. Eu posso defini-lo antes que latência comece a crescer, devido ao preenchimento de buffer em qualquer que seja o lugar entre nós e os hosts remotos. Esse parâmetro deve ser ajustado experimentalmente, aumentando e baixando-o enquanto observa a latência entre alguns hosts próximos.

Ajuste o CEIL a 75% de sua banda de upstream limite agora, e onde Eu uso eth0, você deve usar a interface que possui um endereço da Internet pública. Para começar nosso exemplo execute os seguintes passos no shell como root:

CEIL=240
tc qdisc add dev eth0 root handle 1: htb default 15
tc class add dev eth0 parent 1: classid 1:1 htb rate ${CEIL}kbit ceil ${CEIL}kbit
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 80kbit ceil 80kbit prio 0
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 80kbit ceil ${CEIL}kbit prio 1
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 20kbit ceil ${CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:13 htb rate 20kbit ceil ${CEIL}kbit prio 2
tc class add dev eth0 parent 1:1 classid 1:14 htb rate 10kbit ceil ${CEIL}kbit prio 3
tc class add dev eth0 parent 1:1 classid 1:15 htb rate 30kbit ceil ${CEIL}kbit prio 3
tc qdisc add dev eth0 parent 1:12 handle 120: sfq perturb 10
tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10
tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10
tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10


Nós apenas criamos uma árvore HTB com um nível de profundidade. Algo parecido com isso:


+---------+
| root 1: |
+---------+
|
+---------------------------------------+
| class 1:1 |
+---------------------------------------+
| | | | | |
+----+ +----+ +----+ +----+ +----+ +----+
|1:10| |1:11| |1:12| |1:13| |1:14| |1:15|
+----+ +----+ +----+ +----+ +----+ +----+



classid 1:10 htb rate 80kbit ceil 80kbit prio 0


Essa é a classe de prioridade mais elevada. Os pacotes nessa classe terão o atraso mais baixo e pegariam o excesso de largura de banda inicial assim é uma boa idéia limitar a taxa ceil para essa classe. Nós enviaremos através dessa classe os seguintes pacotes que se beneficia do baixo atraso como o tráfego interativo: ssh, telnet, dns, quake3, irc, e pacotes com o flag SYN.


classid 1:11 htb rate 80kbit ceil ${CEIL}kbit prio 1


Aqui nós temos a primeira classe na qual podemos começar a colocar tráfego pesado. Em meu exemplo Eu tenho tráfego do servidor web local e requisições por paginas web: porta 80 de origem, e porta 80 de destino respectivamente.


classid 1:12 htb rate 20kbit ceil ${CEIL}kbit prio 2


Nessa classe Eu colocarei o tráfego com o bit TOS marcado como máximo throughput e o resto do tráfego que segue de processos locais no roteador para a Internet. Assim as classes seguintes somente terão o tráfego que é “roteado através” da caixa.


classid 1:13 htb rate 20kbit ceil ${CEIL}kbit prio 2


Essa classe é para o tráfego de outras máquinas NATeadas que precisam de prioridade alta para seus tráfegos pesados.


classid 1:14 htb rate 10kbit ceil ${CEIL}kbit prio 3


Aqui segue o tráfego de email (SMTP, pop3, ...) e pacotes com o bit TOS definido para custo mínimo.


classid 1:15 htb rate 30kbit ceil ${CEIL}kbit prio 3


E finalmente aqui nós temos tráfego pesado das máquinas NATeadas atrás do roteador. Tudo de kazaa, de edonkey, e outros seguirão por aqui, a fim de não interferir com outros serviços.


15.10.2. Classificação de pacotes

Nós criamos a instalação da qdisc, mas nenhuma classificação de pacote foi feita, assim agora todos os pacotes saintes são enviados pela classe 1:15 (porque usamos: tc qdisc add dev eth0 root handle 1: htb default 15). Agora precisamos diz quais pacotes seguirão por esse lugar. Essa é a parte mais importante.

Agora nós definimos os filtros assim nós podemos classificar os pacotes com o iptables. Eu realmente prefiro fazer isso com o iptables, porque eles são mais flexíveis e você tem contagem de pacote para cada regra. Também com a flecha RETURN os pacotes não precisarão atravessar todas as regras. Nós executaremos os seguintes comandos:


tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 1 fw classid 1:10
tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid 1:11
tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid 1:12
tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw classid 1:13
tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 5 fw classid 1:14
tc filter add dev eth0 parent 1:0 protocol ip prio 6 handle 6 fw classid 1:15


Nós apenas dissemos ao kernel que os pacotes que tenham um valor específico FWMARK (handle x fw) entram na classe especificada (classid x:x). Seguindo você verá como marcar pacotes com o iptables.

Primeiro você precisa entender como os pacotes atravessam os filtros com o iptables:


+------------+ +---------+ +-------------+
Packet -| PREROUTING |--- routing-----| FORWARD |-------+-------| POSTROUTING |- Packets
input +------------+ decision +-¬-------+ | +-------------+ out
| |
+-------+ +--------+
| INPUT |---- Local process -| OUTPUT |
+-------+ +--------+


Eu assumi que criou todas as suas tabelas e com o policiamento padrão ACCEPT (-P ACCEPT) se você não tiver batido com o iptables ainda, deve ser OK por padrão. Nossas redes privadas são de uma classe B com endereço 172.17.0.0/16 e o endereço IP público é 212.170.21.172.

Prosseguindo nós instruiremos o kernel para realmente executar NAT, assim os clientes na rede privada podem começar a falar com o mundo externo.


echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s 172.17.0.0/255.255.0.0 -o eth0 -j SNAT \
--to-source 212.170.21.172


Agora verificaremos que os pacotes estão fluindo através de 1:15.


tc -s class show dev eth0


Você pode começar marcando pacotes adicionando regras à chain PREROUTING na tabela mangle.


iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 0x1
iptables -t mangle -A PREROUTING -p icmp -j RETURN


Agora você deve ser capaz de ver contagem de pacote aumentando quando fazendo ping de máquinas dentro da rede privada para algum site na Internet. Verifique a contagem de pacote aumentando em 1:10:


tc -s class show dev eth0


Nós temos feito um -j RETURN assim os pacotes não atravessam todas as regras. Pacotes icmp não casarão com outras regras abaixo de RETURN. Tenha isso em mente. Agora podemos começar adicionar mais regras, vamos fazer a manipulação do TOS:


iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j MARK --set-mark 0x1
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Delay -j RETURN
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j MARK --set-mark 0x5
iptables -t mangle -A PREROUTING -m tos --tos Minimize-Cost -j RETURN
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j MARK --set-mark 0x6
iptables -t mangle -A PREROUTING -m tos --tos Maximize-Throughput -j RETURN


Agora prioriza pacotes SSH:

iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j MARK --set-mark 0x1
iptables -t mangle -A PREROUTING -p tcp -m tcp --sport 22 -j RETURN


Uma idéia boa é priorizar pacotes que começam conexões TCP, aquelas com flag SYN definido:

iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j MARK --set-mark 0x1
iptables -t mangle -I PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -j RETURN


E assim por diante. Quando tivermos adicionado regras a PREROUTING na tabela mangle, nós concluímos a tabela PREROUTING com:

iptables -t mangle -A PREROUTING -j MARK --set-mark 0x6


Assim o tráfego não marcado anteriormente entra na classe 1:15. De fato esse último passo é desnecessário já que a classe padrão era 1:15, mas Eu os marcarei a fim de ficar consistente com todas a instalação, e além do mais é útil ver o contador nessa regra.

Será um idéia boa fazer o mesmo na regra OUTPUT, assim repita aqueles comandos com -A OUTPUT em vez de PREROUTING. Execute o comando egrep (s/PREROUTING/OUTPUT/). Então o tráfego gerado localmente (no roteador Linux) será também classificado. Eu finalizo a chain OUTPUT com -j MARK --set-mark 0x3 de sorte que o tráfego local tenha prioridade mais alta.


15.10.3. Melhorando nossa instalação

Agora temos toda nossa instalação funcionando. Gaste tempo analisando os gráficos, e assistindo onde sua banda é consumida e como você deseja-a. Fazer isso por muitas horas, Eu finalmente conseguir que a conexão Internet funcionasse realmente bem. Do contrário, timeouts contínuos e allotment próximo à zero de banda para conexões TCP criada recentemente ocorrerão.

Se você descobrir que algumas classes ficam cheias na maioria das vezes, seria uma idéia boa anexar uma outra disciplina de enfileiramento a elas de modo que o compartilhamento de banda fique mais justo:

tc qdisc add dev eth0 parent 1:13 handle 130: sfq perturb 10
tc qdisc add dev eth0 parent 1:14 handle 140: sfq perturb 10
tc qdisc add dev eth0 parent 1:15 handle 150: sfq perturb 10


15.10.4. Fazendo tudo subir no boot

Isso pode ser feito de várias maneiras obviamente. Na minha, Eu tenho um script shell em /etc/init.d/packetfilter que aceita [start | stop | stop-tables | start-tables | reload-tables] que configura as qdiscs e que carrega os módulos necessários do kernel, assim ele se comporta muito parecido como um daemon. O mesmo script carrega as regras iptables de /etc/network/iptables-rules que podem ser salvas com o script iptables-save e podem ser recuperadas com iptables-restore.










Autores Originais dos textos:

Bert Hubert (Netherlabs BV)
bert.hubert@netherlabs.nl

Thomas Graf (Autor de Seção)
tgraf@suug.ch

Gregory Maxwell (Autor de Seção)
greg@linuxpower.cx

Remco van Mook (Autor de Seção)
remco@virtu.nl

Martijn van Oosterhout (Autor de Seção)
kleptog@cupid.suninternet.com

Paul B Schroeder (Autor de Seção)
paulsch@us.ibm.com

Jasper Spaans (Autor de Seção)
jasper@spaans.ds9a.nl

Pedro Larroy (Autor de Seção)
piotr@member.fsf.org







Nenhum comentário:




Creative Commons License
Admirável Mundo Novo: Tudo Sobre Asterisk, OpenSER, Linux e Tecnologias de Voz sobre IP
by Cléviton Mendes de Araújo is licensed under a Creative Commons Atribuição 2.5 Brasil License.