Como usar tc para simular latência e perda de pacotes em testes

1. Introdução ao tc (Traffic Control) e seu papel em testes de rede

O tc (Traffic Control) é uma ferramenta do subsistema de rede do Linux que permite controlar o fluxo de tráfego em interfaces de rede. Ele faz parte do pacote iproute2 e oferece recursos avançados para simular condições adversas de rede, como latência, perda de pacotes, duplicação e corrupção de dados.

Em cenários de teste, o tc é amplamente utilizado para validar a resiliência de aplicações, testar timeouts de conexão e observar o comportamento de protocolos como TCP sob condições adversas. Diferentemente de condições reais de rede, que são imprevisíveis, o tc permite criar cenários controlados e reproduzíveis.

2. Instalação e verificação do ambiente

Antes de começar, verifique se o iproute2 está instalado e se o módulo sch_netem (Network Emulator) está disponível:

# Verificar instalação do iproute2
tc -V

# Verificar módulo netem
modprobe sch_netem
lsmod | grep sch_netem

Comandos básicos de consulta:

# Listar disciplinas de fila (qdisc) ativas
tc qdisc show

# Listar classes configuradas
tc class show

Atenção: O tc requer privilégios de root. Para testes seguros, use interfaces virtuais com ip link add dummy0 type dummy ou namespaces de rede.

3. Simulação de latência (delay) com netem

A sintaxe básica para adicionar latência em uma interface:

# Adicionar 100ms de latência na interface eth0
tc qdisc add dev eth0 root netem delay 100ms

Para simular variação na latência (jitter):

# 100ms base com variação de 20ms (distribuição normal)
tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal

Correlação de atraso para simular rajadas:

# 100ms base, 20ms de variação, 25% de correlação
tc qdisc add dev eth0 root netem delay 100ms 20ms 25%

4. Simulação de perda de pacotes (loss)

Comando básico para perda aleatória:

# Perder 5% dos pacotes
tc qdisc add dev eth0 root netem loss 5%

Para simular perda correlacionada (modelo Gilbert-Elliott):

# Perda de 5% com probabilidade de 25% de continuar perdendo
tc qdisc add dev eth0 root netem loss 5% 25%

Dica importante: Evite taxas de perda acima de 50% em testes, pois podem causar desconexões completas e dificultar a análise.

5. Combinação de latência, perda e outros parâmetros

É possível combinar múltiplos efeitos em um único comando:

# Latência de 50ms, perda de 2%, duplicação de 1% e corrupção de 0.5%
tc qdisc add dev eth0 root netem delay 50ms loss 2% duplicate 1% corrupt 0.5%

Simulação de pacotes fora de ordem (reorder):

# 100ms de latência, 25% dos pacotes reordenados com 50% de correlação
tc qdisc add dev eth0 root netem delay 100ms reorder 25% 50%

Para limitar banda simultaneamente, use tbf (Token Bucket Filter) em conjunto:

# Primeiro: limitar banda a 1Mbps
tc qdisc add dev eth0 root handle 1: tbf rate 1mbit burst 32kbit latency 400ms

# Depois: adicionar netem sob o handle
tc qdisc add dev eth0 parent 1:1 netem delay 100ms loss 5%

6. Gerenciamento de regras: remoção, troca e visualização

Removendo todas as regras de uma interface:

tc qdisc del dev eth0 root

Substituindo parâmetros sem remover o qdisc:

# Alterar perda de 5% para 10%
tc qdisc change dev eth0 root netem loss 10%

Monitoramento em tempo real com estatísticas detalhadas:

tc -s qdisc show dev eth0

Exemplo de saída:

qdisc netem 8001: root refcnt 2 limit 1000 delay 100.0ms
 Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
 backlog 0b 0p requeues 0

7. Exemplos práticos de testes com aplicações reais

Testando timeout de conexão SSH com latência de 500ms

# Terminal 1: Aplicar latência
tc qdisc add dev eth0 root netem delay 500ms

# Terminal 2: Tentar conexão SSH (deve demorar ~500ms para estabelecer)
time ssh usuario@servidor "echo conectado"

# Remover após teste
tc qdisc del dev eth0 root

Simulando perda de 10% para validar retransmissão TCP

# Aplicar perda de 10%
tc qdisc add dev eth0 root netem loss 10%

# Testar download com curl (observe o tempo e possíveis retransmissões)
curl -o /dev/null -w "Tempo total: %{time_total}s\n" http://exemplo.com/arquivo-grande

# Verificar estatísticas de perda
tc -s qdisc show dev eth0

Script de shell para alternar entre perfis de rede

#!/bin/bash
# Perfis de rede: normal, lento, instavel

perfil=$1
interface=${2:-eth0}

case $perfil in
    normal)
        tc qdisc del dev $interface root 2>/dev/null
        echo "Perfil normal aplicado em $interface"
        ;;
    lento)
        tc qdisc replace dev $interface root netem delay 300ms 50ms
        echo "Perfil lento (300ms ±50ms) aplicado em $interface"
        ;;
    instavel)
        tc qdisc replace dev $interface root netem delay 100ms 20ms loss 5% 25%
        echo "Perfil instável aplicado em $interface"
        ;;
    *)
        echo "Uso: $0 {normal|lento|instavel} [interface]"
        exit 1
        ;;
esac

8. Boas práticas e limitações

Uso de namespaces de rede para isolar tráfego de teste:

# Criar namespace de teste
ip netns add teste_netem
ip link add veth0 type veth peer name veth1
ip link set veth1 netns teste_netem

# Configurar IPs e aplicar netem no namespace
ip netns exec teste_netem tc qdisc add dev veth1 root netem delay 100ms

Limitações importantes:

  • O tc afeta todo o tráfego da interface, não apenas aplicações específicas
  • Em produção, nunca aplique regras sem planejamento e monitoramento
  • O netem não simula congestionamento real; para isso, combine com tbf ou htb

Alternativas e complementos:

  • iptables com módulo statistic para filtrar pacotes específicos
  • mausezahn para gerar tráfego personalizado
  • tcpdump para capturar e analisar pacotes durante os testes

Referências