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:
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:
- Capacidade real do link (download e upload) sob condições reais.
- Latência sob carga (teste “ping while downloading/uploading”).
- 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)pingemtr(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 30envia o que não for classificado para a classe1:30.
3) Criar classe principal (teto do link)
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)
- 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
- 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
pingpara um destino estável enquanto executaiperf3ou downloads.
Um teste prático:
- Inicie upload pesado (por exemplo,
iperf3 -c servidor -Rdependendo do cenário). - Em paralelo, faça SSH/RDP/VoIP.
- 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.