Controlo de tráfego Linux (tc): um guia prático

12 min de leitura - 5 de junho de 2026

hero section cover
Índice
  • Controlo de Tráfego Linux (tc): um Guia Prático
  • Como funciona o tc
  • Configurar o tc num servidor Linux
  • Modelar o tráfego de saída com HTB
  • Modelar o tráfego de entrada com IFB
  • Priorizar o tráfego com DSCP
  • Monitorização e resolução de problemas
Partilhar

Controlar a largura de banda, dar prioridade ao tráfego e modelar a entrada e saída no Linux com o tc. Configuração funcional de HTB, IFB, DSCP e fq_codel para servidores reais.

Controlo de Tráfego Linux (tc): um Guia Prático

O comando tc permite-lhe controlar diretamente a forma como o seu servidor gere o tráfego de rede. Pode limitar a largura de banda por serviço, manter sessões interativas como o SSH responsivas quando ocorrem picos de transferências em massa e moldar os fluxos de saída e de entrada a partir de uma única ferramenta. Este guia abrange os conceitos fundamentais, uma configuração HTB funcional, modelagem de entrada com IFB, priorização baseada em DSCP e como depurar quando algo falhar.


 

Como funciona o tc

Cada tc configuração é composta por quatro partes móveis:

  • qdisc (disciplina de enfileiramento). O agendador associado a uma interface de rede. Decide como os pacotes são enfileirados e retirados da fila.
  • Class. Uma subdivisão dentro de um qdisc com classes. Pense nisso como uma faixa com o seu próprio limite de velocidade.
  • Filtro. Inspeciona os cabeçalhos dos pacotes (IPs, portas, marcas) e atribui cada pacote a uma classe.
  • Ação. O que acontece a um pacote quando este corresponde: encaminhar, descartar, redirecionar.

Estes formam uma árvore. Os pacotes entram no qdisc raiz, passam pelos filtros, são classificados em classes por um major:minor identificador e acabam por ser enfileirados num qdisc folha para transmissão.

Para qualquer coisa mais complexa do que a correspondência baseada em porta, marque os pacotes com iptables ou nftables na tabela mangle e, em seguida, utilize o fw filtro no tc para classificar por marca. Escala muito melhor do que encadeamento de regras u32 para cada tipo de tráfego.

Saída vs. entrada

A direção importa. O kernel pode armazenar em buffer e atrasar pacotes de saída, o que é o que permite o shaping real. Os pacotes de entrada já atravessaram a rede quando os vê, pelo que só pode controlá-los (descartar acima de um limiar) a menos que os redirecione primeiro para um dispositivo IFB.

FuncionalidadeSaídaEntrada
DireçãoSaídaEntrada
ModelagemNativoRequer IFB
ControloSuportadoSuportado
Utilização típicaQoS, partilha de largura de banda, regulaçãoLimitação de taxa, mitigação básica de DDoS

Os qdiscs que irá realmente utilizar

  • HTB (Hierarchical Token Bucket). Com classes. Utilize-o quando pretender largura de banda mínima garantida por serviço, com a capacidade de utilizar capacidade não utilizada de outras classes.
  • TBF (Token Bucket Filter). Sem classes. Use-o quando precisar apenas de limitar toda uma interface a uma única taxa.
  • fq_codel (Fair Queuing Controlled Delay). Combina equidade por fluxo com gestão ativa de filas para eliminar o bufferbloat. Tem sido o qdisc padrão na maioria das distribuições Linux desde o systemd 217 e vem como padrão no RHEL 9. Anexe-o sempre como um qdisc folha sob classes HTB; caso contrário, um único fluxo ganancioso pode monopolizar uma classe inteira.

Configurar o tc num servidor Linux

tc vem incluído no pacote iproute2. No Debian e no Ubuntu, instale-o com apt-get install iproute2. No RHEL e derivados, yum install iproute. Vai precisar de direitos de root ou sudo.

Obtenha primeiro o nome correto da interface. Nomear incorretamente a interface é a razão mais comum para uma configuração não produzir qualquer efeito:

ip link show

Verifique o que já está na interface, incluindo contadores em tempo real:

tc -s qdisc show dev eth0

Limpe qualquer qdisc raiz existente antes de aplicar uma nova configuração, para evitar RTNETLINK answers: File exists erros:

tc qdisc del dev eth0 root 2>/dev/null || true

Se estiver a atualizar uma regra existente em vez de começar do zero, utilize replace em vez de add para uma troca atómica.

O descarregamento de hardware, como TSO e GSO, agrupa pacotes de formas que interferem com o shaping. Desative-os na interface com shaping:

sudo ethtool -K eth0 tso off gso off

Defina fq_codel como o qdisc padrão em todo o sistema para novas interfaces:

sysctl -w net.core.default_qdisc=fq_codel

Para servidores ocupados, combine-o com o algoritmo de controlo de congestionamento BBR (kernel 4.9+). O BBR mantém a taxa de transferência elevada sem aumentar as filas:

sysctl -w net.ipv4.tcp_congestion_control=bbr

Um hábito de segurança se estiver a configurar uma máquina remota via SSH: abra uma segunda sessão e tenha tc qdisc del dev eth0 root pronto para colar. Uma regra de filtro incorreta pode bloquear o acesso instantaneamente.

Modelar o tráfego de saída com HTB

O HTB permite atribuir a cada serviço um mínimo garantido (rate) e um limite máximo (ceil). A largura de banda não utilizada é direcionada para quem precisar, por ordem de prioridade. Aqui está uma configuração funcional de três camadas para um uplink de 1 Gbps.

Crie o qdisc HTB raiz. O default 30 envia qualquer pacote não classificado para a classe 1:30 em vez de o deixar contornar as suas regras:

tc qdisc add dev eth0 root handle 1: htb default 30

Limite a taxa de transferência total a 900 Mbps. Defina sempre um valor ligeiramente abaixo da capacidade real da ligação; caso contrário, forma-se uma fila num router ou modem a montante que não controla:

tc class add dev eth0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit

Defina os níveis de serviço. Os prio obtêm a largura de banda não utilizada em primeiro lugar:

# High priority: web and API traffic
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1
 
# Medium priority: database replication
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 300mbit ceil 900mbit prio 2
 
# Low priority: bulk and backup traffic
tc class add dev eth0 parent 1:1 classid 1:30 htb rate 100mbit ceil 900mbit prio 3

Anexe fq_codel como qdisc de folha em cada classe para que um único fluxo não domine o seu nível:

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

Agora, classifique o tráfego. Para uma correspondência simples de portas, u32 é o mais rápido:

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

Para qualquer coisa com estado, marque no iptables e faça a correspondência da marca com fw:

iptables -t mangle -A OUTPUT -p tcp --dport 5432 -j MARK --set-mark 2
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 2 fw flowid 1:20

Modelar o tráfego de entrada com IFB

Não é possível moldar o tráfego de entrada de forma nativa, porque quando um pacote chega já utilizou a sua largura de banda. A solução alternativa consiste em redirecionar o tráfego de entrada para uma interface virtual de Bloco Funcional Intermédio (IFB), onde o kernel o trata como tráfego de saída e permite aplicar qdiscs com classes.

Carregue o módulo e ative a interface:

modprobe ifb numifbs=1
ip link set dev ifb0 up

Adicione um qdisc de entrada à interface física e redirecione tudo para ifb0:

tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all u32 \
  match u32 0 0 action mirred egress redirect dev ifb0

A partir daqui, ifb0 comporta-se como qualquer outra interface. Aplique a sua árvore HTB a ela exatamente como faria na saída:

tc qdisc add dev ifb0 root handle 1: htb default 30
tc class add dev ifb0 parent 1: classid 1:1 htb rate 900mbit ceil 900mbit
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 500mbit ceil 900mbit prio 1

Priorizar o tráfego com DSCP

O DSCP (Differentiated Services Code Point) marca os pacotes com um valor de 6 bits no byte TOS, pelo que os seus tc filtros possam classificar por etiqueta, em vez de procurarem portas em todo o conjunto de regras. Ao corresponder o DSCP em tc, desloque o valor 2 bits para a esquerda. O DSCP EF (46) passa a ser 0xb8. A máscara 0xfc isola os 6 bits DSCP dos 2 bits ECN.

Um mapeamento padrão sensato para cargas de trabalho de servidor:

Tipo de tráfegoDSCPTOS hexExemplos
InterativoEF0xb8SSH, DNS, VoIP
NegóciosAF410x88HTTP, HTTPS, APIs
Em massaCS10x20Cópias de segurança, FTP, atualizações de pacotes
Melhor esforçoCS00x00Tudo o resto

Marque os pacotes de saída no iptables antes de atingirem os seus tc filtros:

iptables -t mangle -A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp 46

Em seguida, compare a tag no tc e encaminhe-o para a classe HTB correta:

# EF (SSH, VoIP) goes to the high-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
  match ip tos 0xb8 0xfc flowid 1:10
 
# AF41 (web traffic) goes to the medium class
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 \
  match ip tos 0x88 0xfc flowid 1:20
 
# CS1 (bulk) goes to the low-priority class
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 \
  match ip tos 0x20 0xfc flowid 1:30

Monitorização e resolução de problemas

Os três comandos que irá utilizar constantemente:

tc -s qdisc show dev eth0
tc -s class show dev eth0
tc -s filter show dev eth0

Observe o dropped e overlimits . Pacotes perdidos significam que a fila está saturada; valores acima do limite significam que atingiu o limite da classe e o kernel teve de atrasar ou descartar tráfego. Para uma visualização em tempo real:

watch -n 1 'tc -s class show dev eth0'

Adicione -d para parâmetros internos (alvo, intervalo, quantum) e -j para saída JSON se estiver a canalizar para uma pilha de métricas. Combine-o com ss -tin para ver estimativas de RTT e retransmissões na camada TCP.

A maioria das falhas enquadra-se numa lista curta:

SintomaCausa provávelSolução
RTNETLINK answers: File existsqdisc raiz já configuradotc qdisc del dev eth0 root primeiro
As regras aplicam-se, mas o tráfego não é limitadoInterface errada ou TSO/GSO ainda ativadoConfirmar com ip link show, desative os offloads com ethtool -K
O filtro nunca correspondeSintaxe incorreta da porta/IP ou alinhamento da máscaraAdicione uma ação de contagem e verifique a contagem de ocorrências em tc -s filter show
Regras desaparecidas após o reinícioA configuração reside apenas na memóriaIncorpore num script e chame a partir do systemd ou de um despachante do NetworkManager
Alta latência no tráfego prioritárioSem qdisc de folha ou burst muito baixoLigar fq_codel às classes leaf, aumente burst

Se alguma vez ficar bloqueado devido a uma configuração incorreta, a redefinição é simples:

tc qdisc del dev eth0 root

tc não é possível criar largura de banda que não se tem, mas numa ligação ascendente bem provisionada isso faz a diferença entre um desempenho previsível e um servidor que entra em colapso no momento em que um utilizador inicia uma transferência de grandes dimensões. Se precisar de largura de banda bruta e da liberdade de a moldar como quiser, dê uma vista de olhos aos servidores dedicados da FDC.

Blogue

Em destaque esta semana

Mais artigos
Controlo de tráfego Linux (tc): um guia prático

Controlo de tráfego Linux (tc): um guia prático

Controlar a largura de banda, dar prioridade ao tráfego e modelar a entrada e saída no Linux com o tc. Configuração funcional de HTB, IFB, DSCP e fq_codel para servidores reais.

12 min de leitura - 5 de junho de 2026

Porque é que é importante ter um VPS potente e ilimitado

7 min de leitura - 9 de maio de 2025

Mais artigos