#server-performance

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

12 min de leitura - 5 de junho de 2026

hero section cover

Controlar a largura de banda, priorizar o tráfego e moldar o tráfego de entrada e saída no Linux com o tc. Configurações funcionais de HTB, IFB, DSCP e fq_codel para servidores reais.

Controlo de Tráfego no 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 aborda os conceitos fundamentais, uma configuração funcional do HTB, o shaping de entrada com IFB, a priorização baseada em DSCP e como depurar o sistema quando algo falhar.


 

Como funciona o tc

Cada tc configuração é composta por quatro componentes:

  • qdisc (disciplina de enfileiramento). O agendador associado a uma interface de rede. É ele que determina como os pacotes são colocados na fila e retirados da mesma.
  • Classe. Uma subdivisão dentro de um qdisc com classes. Pense nela como uma faixa de rodagem com o seu próprio limite de velocidade.
  • Filtro. Inspeciona os cabeçalhos dos pacotes (endereços IP, portas, marcas) e atribui cada pacote a uma classe.
  • Ação. O que acontece a um pacote quando este corresponde a um critério: encaminhar, descartar, redirecionar.

Estes elementos 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 colocados na fila de um qdisc folha para transmissão.

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

Saída vs. entrada

A direção é importante. O kernel pode armazenar em buffer e atrasar os pacotes de saída, o que permite uma verdadeira regulação do tráfego. Os pacotes de entrada já atravessaram a rede quando os vemos, pelo que só é possível controlá-los (descartá-los acima de um limiar) a menos que os redirecionemos primeiro para um dispositivo IFB.

FuncionalidadeSaídaEntrada
DireçãoSaídaEntrada
RegulaçãoNativoRequer IFB
Controlo de tráfegoCompatívelCompatível
Utilização típicaQoS, partilha de largura de banda, regulação de tráfegoLimitaçã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 garantir uma largura de banda mínima por serviço, com a capacidade de utilizar a capacidade não utilizada de outras classes.
  • TBF (Token Bucket Filter). Sem classes. Utilize-o quando precisar apenas de limitar toda uma interface a uma única taxa.
  • fq_codel (Fair Queuing Controlled Delay). Combina a equidade por fluxo com a gestão ativa de filas para eliminar o «bufferbloat». Tem sido o qdisc predefinido na maioria das distribuições Linux desde o systemd 217 e vem predefinido 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. Necessitará de direitos de root ou do sudo.

Verifique primeiro o nome correto da interface. Indicar o nome errado da interface é a razão mais comum para uma configuração não ter qualquer efeito:

ip link show

Verifique o que já se encontra na interface, incluindo os contadores em tempo real:

tc -s qdisc show dev eth0

Limpe qualquer qdisc de 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 o TSO e o GSO, agrupa os pacotes de forma a interferir com o shaping. Desative-os na interface sujeita a shaping:

sudo ethtool -K eth0 tso off gso off

Defina fq_codel como qdisc predefinido a nível do sistema para novas interfaces:

sysctl -w net.core.default_qdisc=fq_codel

Para servidores com elevado tráfego, 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 um equipamento remoto via SSH: abra uma segunda sessão e tenha tc qdisc del dev eth0 root pronto para colar. Uma regra de filtragem incorreta pode bloquear o acesso instantaneamente.

Regulação do 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 é redirecionada para quem precisar, por ordem de prioridade. Aqui está uma configuração funcional de três níveis 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 a taxa 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 prioridade na largura de banda não utilizada:

# 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 que envolva estado, marque no iptables e faça corresponder a 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

Regulação do 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 do 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. Aplica a tua árvore HTB a ela exatamente como farias 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

Priorização do 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 terem de procurar portas em todo o conjunto de regras. Ao fazer a correspondência do 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 do DSCP dos 2 bits do ECN.

Um mapeamento predefinido 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 estes atingirem os seus tc filtros:

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

Em seguida, compare a etiqueta 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 contadores. Pacotes perdidos significam que a fila está saturada; valores acima do limite significam que atingiu o teto da classe e que 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 em JSON, se estiver a canalizar os dados 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 ativadoConfirme 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 contra-medida e verifique o número 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
Latência elevada no tráfego prioritárioSem qdisc «leaf» ou burst demasiado 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 assim que um utilizador inicia uma transferência de grandes dimensões. Se precisar de largura de banda bruta e da liberdade para a moldar como quiser, dê uma vista de olhos aos servidores dedicados da FDC.

Blogue

Em destaque esta semana

Mais artigos
Tutorial do iperf3: Testar a velocidade da rede no Linux e no Windows
#bandwidth#server-performance

Tutorial do iperf3: Testar a velocidade da rede no Linux e no Windows

Instale o iperf3, execute testes de largura de banda e ajuste os buffers TCP para obter resultados precisos no Linux e no Windows. Abrange testes UDP, bidirecionais e de 10 GbE+.

10 min de leitura - 7 de maio de 2026

#server-performance

Perfis otimizados para a otimização da carga de trabalho de servidores Linux

16 min de leitura - 9 de junho de 2026

Mais artigos