search

TC (Traffic Control): moldando tráfego de rede com QoS avançado e Queuing Disciplines

TC (Traffic Control): moldando tráfego de rede com QoS avançado e Queuing Disciplines

O TC (Traffic Control) é uma das ferramentas mais poderosas do ecossistema Linux para moldar tráfego de rede e aplicar políticas de Qualidade de Serviço (QoS). Na prática, ele permite controlar como os pacotes saem (egress) — e, com técnicas auxiliares, também como “entram” (ingress) — de uma interface, definindo prioridades, limites de banda, latência e tratamento de congestionamento.

Em ambientes modernos (home office, roteadores Linux, servidores, Kubernetes nodes, links dedicados, VPNs), o problema raramente é “não ter banda”; é disputar banda e latência entre fluxos: videoconferência contra backups, VoIP contra downloads, API contra replicação, jogos contra atualizações. O TC resolve isso com um conjunto de componentes: qdiscs, classes, filters e actions, além de algoritmos específicos para filas.

Este guia explica os conceitos e mostra um caminho passo a passo para aplicar QoS avançado.


O que é “moldar” tráfego de rede e por que isso importa

Quando um link satura, os pacotes começam a disputar o envio. Se a fila estiver mal dimensionada, ocorre o chamado bufferbloat: muita fila acumulada, causando latência alta e jitter mesmo em links com boa banda. Em serviços sensíveis (voz, vídeo, transações), isso degrada a experiência.

O TC atua principalmente no egress (saída), porque é ali que o kernel tem controle real sobre quando enviar. As capacidades típicas incluem:

  • Shaping (moldagem): limitar a taxa de envio para um teto definido (por exemplo, 90 Mbps em um link de 100 Mbps), reduzindo congestionamento no equipamento do provedor e melhorando latência.
  • Scheduling (escalonamento): dar prioridade e reservar banda para classes de tráfego (por exemplo, garantir 10 Mbps para VoIP e limitar backups).
  • AQM (Active Queue Management): controlar crescimento de filas para reduzir latência (ex.: fq_codel, cake).
  • Policing: descartar/marcar pacotes acima de um limite (menos suave que shaping).

Arquitetura do TC: qdiscs, classes, filters e actions

O TC organiza o controle de tráfego em camadas lógicas:

Tc (Traffic Control)

1) Qdisc (Queuing Discipline)

É a “disciplina de fila” anexada a uma interface. Pode ser:

  • Classful (com classes internas): ex. HTB, HFSC, CBQ.
  • Classless (fila única com algoritmo): ex. fq_codel, pfifo_fast, tbf.

Você pode combinar: por exemplo, uma qdisc HTB como raiz (classful) e, dentro das classes, qdiscs como fq_codel para qualidade de latência.

2) Classes

Em qdiscs classful, as classes definem “compartimentos” de banda e prioridade. No HTB, você define:

  • rate: banda garantida.
  • ceil: teto máximo que a classe pode atingir quando há sobra.

3) Filters

Regras que classificam pacotes em classes. Podem usar:

  • ip (endereços, portas, protocolo),
  • fw (marca de firewall do iptables/nftables),
  • flower (classificador moderno e flexível).

4) Actions

Ações associadas a filtros, como mark, police, mirred (redirecionar), entre outras.


Diagnóstico inicial: antes de mexer no TC

Para trabalhar com tráfego de rede de forma controlada, comece medindo e mapeando:

  1. Capacidade real do link (download e upload) sob condições reais.
  2. Latência sob carga (teste “ping while downloading/uploading”).
  3. Quais fluxos importam (VoIP, VPN, RDP/SSH, games, APIs, streaming).

Ferramentas úteis:

  • ip -s link (estatísticas de interface)
  • ss -ti (estado e métricas TCP)
  • tc -s qdisc show dev eth0 (filas e drops)
  • iperf3 (testes controlados)
  • ping e mtr (latência/jitter e rotas)

Um princípio comum de QoS doméstico/SMB é aplicar shaping para um pouco abaixo do contratado (por exemplo, 90–95%), evitando que o buffer do equipamento do provedor vire o gargalo.


Passo a passo: QoS avançado com HTB + fq_codel (exemplo prático)

A seguir, um exemplo didático para interface eth0, limitando a saída total em 90 Mbps e separando classes para tráfego interativo e tráfego pesado.

1) Limpar configurações anteriores

sudo tc qdisc del dev eth0 root 2>/dev/null

Verifique o estado:

tc qdisc show dev eth0

2) Criar qdisc raiz HTB

sudo tc qdisc add dev eth0 root handle 1: htb default 30
  • handle 1: define um identificador.
  • default 30 envia o que não for classificado para a classe 1:30.
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 90mbit ceil 90mbit

Essa classe é o “link” total modelado. A partir dela, criamos classes filhas.

4) Criar classes por perfil de tráfego

Exemplo de três classes:

  • Interativo (baixa latência): 10 Mbps garantidos, pode subir até 90 Mbps se sobrar.
  • Normal: 30 Mbps garantidos.
  • Bulk (downloads/backups): 5 Mbps garantidos, pode subir, mas terá menor prioridade.
sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10mbit ceil 90mbit prio 0
sudo tc class add dev eth0 parent 1:1 classid 1:20 htb rate 30mbit ceil 90mbit prio 1
sudo tc class add dev eth0 parent 1:1 classid 1:30 htb rate 5mbit  ceil 90mbit prio 2

No HTB, prio influencia a preferência em disputas (menor é mais prioritário).

5) Adicionar qdiscs de baixa latência dentro das classes

Agora, anexamos fq_codel em cada classe para combater bufferbloat e melhorar latência:

sudo tc qdisc add dev eth0 parent 1:10 handle 10: fq_codel
sudo tc qdisc add dev eth0 parent 1:20 handle 20: fq_codel
sudo tc qdisc add dev eth0 parent 1:30 handle 30: fq_codel

Por que isso importa: mesmo com classes bem definidas, uma fila FIFO simples pode gerar latência alta sob carga. O fq_codel combina fair queuing (equidade por fluxo) com controle ativo de fila.

6) Classificar pacotes (filters): três abordagens comuns

Você pode classificar por portas, por IPs, ou por marcação via firewall. A forma mais robusta hoje costuma ser marcar no nftables/iptables e usar o TC para ler a marca, porque a política fica centralizada e mais expressiva.

Abordagem A: por portas (exemplo simples com u32)

Suponha que tráfego SSH (22) e VoIP SIP (5060) vá para classe interativa:

sudo tc filter add dev eth0 protocol ip parent 1: prio 1 u32 \
  match ip dport 22 0xffff flowid 1:10

sudo tc filter add dev eth0 protocol ip parent 1: prio 1 u32 \
  match ip dport 5060 0xffff flowid 1:10

Limitação: classificar por porta é útil, mas nem sempre suficiente (TLS, QUIC, apps dinâmicos).

Abordagem B: classificador flower (mais moderno)

Exemplo conceitual (varia por kernel e necessidades):

sudo tc filter add dev eth0 parent 1: protocol ip prio 10 flower ip_proto tcp dst_port 22 \
  flowid 1:10

Abordagem C: marca via firewall (recomendado para cenários reais)

  1. No firewall, marque pacotes (exemplo com iptables; com nftables a lógica é similar):
sudo iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 10
sudo iptables -t mangle -A OUTPUT -p udp --dport 5060 -j MARK --set-mark 10
sudo iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark 20
  1. No TC, direcione marcas para classes (classificador fw):
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 handle 10 fw flowid 1:10
sudo tc filter add dev eth0 parent 1: protocol ip prio 2 handle 20 fw flowid 1:20

O que não casar cai na default 30 (bulk).


Ingress: por que é diferente e como lidar

O TC tem controle nativo melhor no egress. Para “controlar download” (ingress), há estratégias:

  • IFB (Intermediate Functional Block): redireciona tráfego de entrada para uma interface virtual e aplica shaping como se fosse egress.
  • Policing no ingress: descarta acima do limite (pode ser agressivo para TCP).
  • Soluções como CAKE em roteadores, que simplificam parte da configuração.

Para casos avançados (principalmente em gateway), o IFB é o caminho mais comum. Ele exige mais passos (criar IFB, anexar ingress qdisc, redirecionar com mirred) e deve ser testado cuidadosamente para não introduzir drops desnecessários.


Verificação e observabilidade: como saber se o QoS está funcionando

Após aplicar regras, valide com:

tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0 parent 1:

O que observar:

  • Aumento de contadores em classes esperadas (bytes/packets).
  • Drops controlados (idealmente baixos; alguns drops em AQM podem ocorrer para manter latência).
  • Latência sob carga: rode ping para um destino estável enquanto executa iperf3 ou downloads.

Um teste prático:

  1. Inicie upload pesado (por exemplo, iperf3 -c servidor -R dependendo do cenário).
  2. Em paralelo, faça SSH/RDP/VoIP.
  3. Compare jitter e responsividade com e sem TC.

Boas práticas e riscos de segurança/estabilidade

Como ferramenta de Cyber Segurança e confiabilidade, o TC tem impacto direto em disponibilidade e desempenho:

  • Evite “policing” agressivo para tráfego TCP em links com perda variável: pode degradar throughput e gerar retransmissões.
  • Documente e versiona a configuração (scripts, systemd units). Mudanças manuais são difíceis de auditar.
  • Cuidado com classificações frágeis (somente por porta). Tráfego moderno usa HTTPS/QUIC e multiplexação.
  • Monitore: QoS mal calibrado pode criar gargalos artificiais e mascarar incidentes (por exemplo, saturação por exfiltração pode ser “suavizada”).
  • Integre com observabilidade: NetFlow/sFlow, logs de firewall, métricas de interface e alertas por saturação.

Construindo uma base sólida

O TC é uma base sólida para moldar tráfego de rede no Linux, oferecendo desde limitações simples até QoS avançado com classes, filtros e algoritmos de fila que reduzem latência. Uma configuração típica e eficaz combina:

  • Shaping no egress (geralmente abaixo da taxa do link),
  • qdisc classful (HTB) para separar perfis de tráfego,
  • AQM/fair queuing (fq_codel) dentro das classes,
  • classificação robusta, preferencialmente via marcação no firewall.

Com medições antes/depois e validação por contadores e latência sob carga, você transforma um link “rápido, porém instável” em um link “previsível”, que é exatamente o objetivo do QoS em ambientes reais.

Tags: Cursos
Compartilhar este artigo: