Arquivos históricos do BR-Linux.org apresenta:

Linux in Brazil (Controle de banda com CBQ )

Controle de Banda com CBQ - (Class Based Queueing)

Por Fabrizio Flores (fabrizio.flores@vant.com.br)

1.0 - Introdução:

Há algum tempo venho notando a falta de documentação, principalmente em Português, que aborde a configuração básica de controle de banda numa Linux Box.

Este artigo pretende demonstrar alguns conceitos sobre o controle de banda e uma configuração básica do CBQ.

Obs: A distribuição usada foi um Slackware 8.0 Kernel 2.4.7

1.1 - Considerações iniciais:

A grande vantagem do CBQ sobre outros, (traffic Shaper ), é permitir o controle não só do tráfego de downstream ( trafego de entrada ), bem como o upstream ( trafego de saída ). Isto é muito importante principalmente hoje onde temos conexões DSL ( Digital Subscriber Line ), sendo instaladas Comumente em prédios e compartilhada entre vários computadores. Note que com raras exceções, uma das características da tecnologia DSL é ter uma diferença entre as taxas de transferência para o trafego que entra e o trafego que sai da sua máquina. Comumente o trafego de entrada é superior já que o fluxo de dados tende a ser maior no sentido servidor-cliente. Já no caso do trafego de saída, ele tende a ser apenas texto. Portanto no caso de prédios ou locais onde temos vários computadores compartilhando o mesmo link é recomendável limitar também o tráfego de saída, agora, suponhamos que numa destas máquinas seja instalado um serviço ftp, facilmente ele poderia ocupar todo o upstream e fatalmente acabaria por comprometer o uso da rede pelas outras estações ! O CBQ também possibilita controlar o trafego sobre um determinado ip e não somente por interface como o traffic shaper faz.

O CBQ apresenta outros recursos, alguns que valem citar:

  • controle sobre a banda excedente
  • possibilidade de criação e utilização de classes.
  • junto ao firewall: para proteção contra Ataques D.O.S. ( Denial-Of-Service ) *

    * não tratado neste artigo.

    1.2 - Arquivos Necessários:

    Antes de iniciarmos a configuração de nossa Box, alguns arquivos que serão necessários:

  • cbq.ini ( ftp.equinox.gu.net/pub/linux/cbq/ )
  • kernel-2.4.7 (http://www.kernel.org/pub/linux/kernel/v2.4/linux-2.4.7.tar.gz ) ou (ftp://ftp.inr.ac.ru/ip-routing/ )
  • iproute2 (ftp://ftp.linuxmafia.org/pub/Slackware-8/robert/iproute2-2.4.7 ) ou ( www.linuxmafia.org ) existe um search para os pacotes do slackware ( ..tgz )

    2.0 - Instalando o Cbq.ini, Iproute2 e Configurando seu Kernel:

    Crie um diretório onde serão colocados os arquivos de configuração para o CBQ, geralmente dentro do /etc. Aqui eu criei o diretório /etc/cbq.

    Edite o script cbq.ini e procure pela linha: CBQ_PATH="/etc/sysconfig/cbq" substitua o que esta dentro das aspas pelo caminho completo até o diretório que você acabou de criar. Ex: CBQ_PATH="/etc/cbq". Salve e faça uma copia do arquivo para o diretório /sbin. Caso queira você poderá renomear o arquivo apenas para "cbq", o que irá facilitar na hora de digitar algum comando : )

    Lembre-se de verificar as permissões para o script que você acabou de copiar , ele deve ser executável.

    Verifique se sua distribuição já não possui o pacote iproute2 previamente instalado.

    Caso sua distribuição seja o Slackware, é provável que não esteja instalado. Para instalar o pacote no Slackware 8, apenas digite installpkg iproute2-2.4.7.tgz. Feito isto digite apenas ip ... deve aparecer algo na tela tipo:

    # 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] }
    
    Caso você use outra distribuição e esta não venha com o iproute2 instalado, procure pelos pacotes do iproute2 ou obtenha os fontes no ftp do projeto: ( ftp://ftp.inr.ac.ru/ip-routing/ ), no caso de optar pelos fontes, lembre-se de ler o README antes de compilar !

    2.1 - Configurando o Kernel

    No exemplo abaixo, foram colocadas apenas as opções referentes ao QOS / CBQ e NETFILTER / IPTABLES, estas são as opções que geralmente eu utilizo. Você provavelmente terá que adicionar mais alguma coisa, mas isto fica a seu critério.

    [*]Prompt for development and/or incomplete code/drivers
    (*) Packet socket
    [*] Kernel/User netlink socket
    [*] Routing messages
    [*] Network packet filtering (replaces ipchains)
    [*] Socket Filtering
    (*)Unix domain sockets
    [*] UCP/IP networking
    [*] IP: multicasting
    [*] IP: advanced router
    [*] IP: policy routing (NEW)
    [*] IP: use netfilter MARK value as routing key (NEW)
    [*] IP: equal cost multipath (NEW)
    [*] IP: use TOS value as routing key (NEW)
    [*] IP: verbose route monitoring (NEW)
    [*] IP: large routing tables (NEW)
    [*] IP: TCP syncookie support (disabled per default)
    IP: Netfilter Configuration  ---)
     (*) Connection tracking (required for masq/NAT)
     (*) FTP protocol support
     (*) IP tables support (required for filtering/masq/NAT)
     (*) limit match support
     (*) MAC address match support
     (*) netfilter MARK match support
     (*) Multiple port match support
     (*) TOS match support
     (*) tcpmss match support
     (*) Connection state match support
     (*) Packet filtering
     (*) REJECT target support
     (*) Full NAT
     (*) MASQUERADE target support
     (*) REDIRECT target support
     (*) Packet mangling
     (*) TOS target support
     (*) MARK target support
    ---
    QoS and/or fair queueing  ---)
    [*] QoS and/or fair queueing
     (M) CBQ packet scheduler (NEW)
     (M) CSZ packet scheduler (NEW)
     (M) The simplest PRIO pseudoscheduler (NEW)
     (M) RED queue (NEW)
     (M) SFQ queue (NEW)
     (M) TEQL queue (NEW)
     (M) TBF queue (NEW)
     (M) GRED queue (NEW)
     (M) Diffserv field marker (NEW)
     (M) Ingress Qdisc (NEW)
     [*] QoS support (NEW)
     [*] Rate estimator (NEW)
     [*] Packet classifier API (NEW)
     (M) TC index classifier (NEW)
     (M) Routing table based classifier (NEW)
     (M) Firewall based classifier (NEW)
     (M) U32 classifier (NEW)
     (M) Special RSVP classifier (NEW)
     (M) Special RSVP classifier for IPv6 (NEW)
     [*] Traffic policing (needed for in/egress) (NEW)
    

    Compile, instale o novo kernel e reinicie seu sistema !

    3.0 - Configurando o CBQ:

    O CBQ trabalha com arquivos de configuração encontrados no diretório definido pela variável $CBQ_PATH, sendo que cada arquivo contém uma regra

    O arquivo de configuração deve obedecer o formato pré-definido: cbq-(clsid).(nome)

    onde: (clsid) é um número hexadecimal de dois-bytes na escala ( 0002-FFFF ), que forma uma classe ID de CBQ e (nome) é o nome do shaper - ( pode ser qualquer texto )

    Em casos em que temos poucos arquivos de configuração, você pode definir o (clsid) como a velocidade do shaper Ex. 64k, cbq-0064.backbone-cliente; 512k, cbq-0512.backbone-cliente

    Cada arquivo de configuração deve conter os parâmetros(obrigatórios) :

    DEVICE=(int-nome),(banda),(peso)
    RATE=(velocidade)
    WEITH=(peso/10)
    PRIO=(prioridade)
    RULE=(ip ou rede a ser controlada)
    

    Parâmetro DEVICE ( obrigatório )

    DEVICE=(int-nome),(banda),(peso) ex: DEVICE=eth0,10Mbit,1Mbit

    (int-nome) é o nome da interface a ser controlada ex: eth0, eth1, lo, ppp0, wvlan0

    (banda) é a velocidade do dispositivo. ex: ethernet 10Mbit ou 100Mbit

    (peso) é um parâmetro de ajuste que deve ser proporcional a (banda). Como regra teremos que: (peso) = (banda) / 10

    Quando houver mais classes não mesma interface, só é necessário especificar o parâmetro (banda) e (peso) uma única vez, conseqüentemente em outros arquivos você poderá ter somente o DEVICE=(nome)

    Parâmetro RATE ( obrigatório )

    RATE=(velocidade) ex: RATE=5Mbit

    Banda alocada para a classe - limitando a velocidade do shaper. podemos usar: Kbit, Mbit ou bps, Kbps, Mbps como sufixos.

    Parâmetro WEIGHT ( obrigatório )

    WEIGHT=(peso/10) ex: WEIGHT=500Kbit

    parâmetro de ajuste que deve ser proporcional a (banda). Como regra teremos que: (peso) = (banda) / 10

    parâmetro PRIO ( obrigatório )

    PRIO=(1-8) ex: PRIO=5

    Prioridade do tráfego para a classe. Quanto mais elevado o número, menor a prioridade. A prioridade 5 é um valor excelente.

    parâmetro RULE

    RULE=[[saddr[/prefix]][:port],][daddr[/prefix]][:port]

    Os parâmetros acima fazem que o filtro u32 controlem o tráfego para cada uma das classes. Você pode usar múltiplos compôs de regras por arquivo de configuração.

    Exemplos:

    RULE=10.1.1.0/24:80

    controla o tráfego de rede que passa através da porta 80 na rede 10.1.1.0

    RULE=10.2.2.5

    controla o tráfego de rede que passa através de qualquer porta ou do host 10.2.2.5

    RULE=:25,10.2.2.128/26:5000

    controla o trafego vindo de qualquer origem, com destino entre a porta 50 a porta 5000 na rede 10.2.2.128

    RULE=10.5.5.5:80,

    controla o tráfego vindo da porta 80 do host 10.5.5.5

    Uma virgula "," colocada após qualquer uma destas regras irá controlar o trafego de saída da rede (upstream). Tome cuidado para adicionar a "," na interface de rede correta.

    parâmetro TIME

    Este parâmetro limita o acesso em horários predeterminados

    TIME=(hora inicial)-(hora final);(velocidade)/(velocidade/10)

    ex. TIME=18:00-06:00;256Kbit/25Kbit

    Outros parâmetros

    BOUNDED=yes/no

    se definido como "yes" o shaper será mantido mesmo que haja banda excedente

    ISOLATED=yes/no

    se definido como "yes" a banda excedente não será compartilhada

    4.0 - Exemplos de arquivos de configuração:

    Observe o exemplo abaixo:

    DEVICE=eth0,10Mbit,1Mbit
    RATE=128Kbit
    WEIGHT=10Kbit
    PRIO=5
    RULE=192.128.1.0/24
    

    Esta configuração diz, que o tráfego na interface eth0 de 10Mbit através da rede 192.168.1.0 será processado com a prioridade 5 e uma taxa de shapping de 128kbit. Note que desta forma somente o tráfego de saída (upstream) está sendo controlado.

    Para controlar o tráfego nos dois sentidos, devemos configurar o CBQ para ambas interfaces.

    Observe o exemplo:

                        +--------------+            192.168.1.1
     BACKBONE -----eth0-|  linux box   |-eth1------*-[cliente]
                        +--------------+
    

    Imagine que você deseja controlar o tráfego que vem do backbone para o cliente a 28Kbit e o trafego que vai do cliente para o backbone a 128Kbit. Você terá que criar dois arquivos de configuração, um para a eth0 e outro para a eth1:

    cbq-0028.backbone-client
    ------------------------------------------------
    DEVICE=eth1,10Mbit,1Mbit
    RATE=28Kbit
    WEIGHT=2Kbit
    PRIO=5
    RULE=192.168.1.0/24
    ------------------------------------------------
    
    cbq-0128.client-backbone
    ------------------------------------------------
    DEVICE=eth0,10Mbit,1Mbit
    RATE=128Kbit
    WEIGHT=10Kbit
    PRIO=5
    RULE=200.1.1.1,
    -------------------------------------------------------------------------
    

    5.0 - Testando:

    No prompt de comando, digite:

    cbq
    

    Uma pequena lista de comandos irá aparecer na tela:

    cbq
    Usage:  cbq {start|stop|restart|timecheck|list|stats}
    

    Digitando cbq start, os arquivos de configuração serão carregados, neste momento sua rede já deve estar sofrendo a ação do shaper.

    Para testar, basta mudar os parâmetros de configuração e digitar: cbq restart, isto forçara a reinicialização do cbq e as novas configurações serão lidas. Coloque velocidades da ordem de 1kbit, e você verá como fica realmente lento ( hahahahahah ), mas falando sério isto irá demonstrar que o cbq realmente está atuando :)

    Teste os demais comandos do cbq, como cbq list e cbq stats.

  • Outra dica importante: para que o cbq seja carregado toda vez que a sua linux Box for inicializada, coloque o comando /sbin/cbq start no seu rc.local

    6.0 - Finalizando

    6.1 NAT: (Network Address Translation):

    Nossa configuração já esta praticamente concluída, apenas devo lembrar que as estações ainda não poderão navegar na internet. Esta faltando uma coisinha chamada NAT. Não pretendo explicar neste artigo o que é, ou dar qualquer detalhamento sobre o assunto, contudo colocarei um exemplo de script que você deverá: ler, entender, e se achar que deve, rodar em seu rc.local. ( este script não foi feito por mim , peço desculpas ao autor, mas não lembro onde encontrei este exemplo)

    echo "1" > /proc/sys/net/ipv4/ip_forward
    /sbin/modprobe iptable_nat
    /sbin/modprobe ip_conntrack
    /sbin/modprobe ip_conntrack_ftp
    /sbin/modprobe ip_tables
    /sbin/modprobe ipt_unclean
    /sbin/modprobe ipt_limit
    /sbin/modprobe ipt_LOG
    /sbin/modprobe ipt_REJECT
    /usr/sbin/iptables -F
    /usr/sbin/iptables -t nat -F
    /usr/sbin/iptables -P FORWARD DROP
    /usr/sbin/iptables -A INPUT -i lo -j ACCEPT
    /usr/sbin/iptables -A OUTPUT -o lo -j ACCEPT
    /usr/sbin/iptables -A FORWARD -s 192.168.1.0/24 -d 0/0 -j ACCEPT
    /usr/sbin/iptables -A FORWARD -s 0/0 -d 192.168.1.0/24 -mstate \
                       --state ESTABLISHED,RELATED -j ACCEPT
    /usr/sbin/iptables -t nat -A POSTROUTING -s 192.168.1.0/24 \
                       -d 0/0 -j MASQUERADE
    

    Obs: troque o ip 192.168.1.0 para o ip de sua rede interna

    Para maiores informações procure no www.google.com por: NAT, IPTABLES, NETFILTER, MASQUERADE

    6.2 - DHCPD:

    Para deixar a solução completa, provavelmente seria interessante você rodar um dhc server, para facilitar sua vida e de seus clientes. Então resolvi colocar também um exemplo de dhcpd.conf.

    Para instalar: em sua linux Box, no diretório /etc, crie um arquivo chamado dhcpd.conf e cole o exemplo abaixo. Você deve editar o arquivo e substituir os ips como indicado abaixo.

    #-----------------------------------------------
    default-lease-time 43200;
    max-lease-time 43200;
    option domain-name "nome-de-seu-servidor";
    option domain-name-servers 192.168.1.1;
    subnet 192.168.1.0 netmask 255.255.255.0 {
            range 192.168.1.50      192.168.1.250;
            option routers          192.168.1.1;
            option subnet-mask      255.255.255.0;
            #option netbios-name-servers 192.168.1.1;
            #option netbios-node-type 2;
    #-----------------------------------------------
    

    onde:

    default-lease-time 43200;
    max-lease-time 43200;
    option domain-name "nome-de-seu-servidor";
    option domain-name-servers ip-do-seu-servidor-de-nomes;
    subnet 192.168.1.0 netmask 255.255.255.0 {
            range 192.168.1.50      192.168.1.250;
            option routers          192.168.1.1;
            option subnet-mask      255.255.255.0;
            #option netbios-name-servers 192.168.1.1;
            #option netbios-node-type 2;
    

    substitua o ip 192.168.1.0 pelo ip de sua rede interna !

    Feito isto, coloque o seguinte comando em seu rc.local:

    /usr/sbin/dhcpd (interface)

    onde: (interface) é a interface de rede em que você deseja rodar o dhcp server.

    para maiores informações e outros detalhes, no prompt, digite man dhcpd

    Obs: ( Ip dinâmico )

    Em casos onde temos o ip da interface de entrada sendo fornecido via dhcp, teremos que fazer com que o ip dentro do arquivo de configurção do cbq também seja alterado da mesma forma.

    Para tanto criei um pequeno script usando os comando ifconfig e cut que deve resolver. Sei que a solução ficou muito "bonita", mas funciona : ). Caso alguém tenha alguma idéia melhor .... meu e-mail esta no final deste artigo !

    Coloque estas linhas dentro de seu rc.local. Lembre-se de alterar o caminho e o nome em cada linha para corresponder ao path e o nome de seu arquivo de configuração do cbq. Verifique também o nome da interface de rede.

    No meu caso ficou assim:

    #!/bin/sh
    ip=`ifconfig eth0 | cut -dF -f1 | cut -d: -f2 | cut -dB -f1 -s`
    echo "DEVICE=eth0,10Mbit,1Mbit" > /etc/cbq/cbq-64.backbone-client
    echo "RATE=256Kbit" >> /etc/cbq/ cbq-64.backbone-client
    echo "WEIGHT=25Kbit" >> /etc/cbq/ cbq-64.backbone-client
    echo "PRIO=5" >> /etc/cbq/ cbq-64.backbone-client
    echo "RULE=$ip," >> /etc/cbq/ cbq-64.backbone-client
    /sbin/cbq start
    

    NOTA1:

  • O autor deste artigo não possui nenhuma responsabilidade sobre qualquer problema ou danos que venham a ocorrer em seu computador ou sistema em função das informações contidas aqui.
  • O RISCO é inteiramente SEU.
  • As informações contidas neste artigo são baseadas em experiência própria e documentação coletada na rede ( os links estão em "referencias" ).
  • Note que nenhum aspecto de segurança foi abordado neste artigo, é seu o DEVER de zelar pela segurança de seu sistema!

    NOTA2

  • Qualquer correção ou contribuição que você queira fazer, mande um e-mail para: fabrizio.flores@vant.com.br ou admin@arquivologia.ufsm.br. Sua contribuição será publicado e seu nome citado.

    Referencias:

    IPROUTE2 Utility Suite Howto: [ http://www.linuxgrill.com/iproute2.doc.html ]

    Linux 2.4 Advanced Routing HOWTO: [ http://www.linuxhq.com/ldp/howto/Adv-Routing-HOWTO-11.html ]

    Bandwidth Limiting Howto: [ http://www.linuxdoc.org/HOWTO/Bandwidth-Limiting-HOWTO/index.html ]

    UnderLinux.com.br: [ http://www.underlinux.com.br/sections.php?op=viewarticle&artid=86 ]

    cbq.ini e cbq.ini howto: [ ftp.equinox.gu.net/pub/linux/cbq/cbq.ini ]


    Autor: Fabrizio Flores (fabrizio.flores@vant.com.br)


    O Arquivo Histórico do BR-Linux.org mantém no ar (sem alteração, exceto quanto à formatação) notícias, artigos e outros textos publicados originalmente no site na segunda metade da década de 1990 e na primeira década do século XXI, que contam parte considerável a história do Linux e do Open Source no Brasil. Exceto quando indicado em contrário, a autoria dos textos é de Augusto Campos, e os termos de uso podem ser consultados na capa do BR-Linux.org. Considerando seu caráter histórico, é provável que boa parte dos links estejam quebrados, e que as informações deste texto estejam desatualizadas.