implant traefik-ratelimit
Escreve um middleware de rate-limit por IP no file-provider do Traefik (v2.60.0+). A requisição acima do limite recebe 429 do próprio Traefik, antes de chegar ao serviço e antes de virar linha de erro no access log. O implant não roda daemon nenhum: quem limita é o Traefik. Opt-in.
Reaproveita a descoberta do traefik-edge: container do Traefik, diretório do file-provider no host e versão (2 ou 3).
Uso
implant traefik-ratelimit <SUBCOMANDO> [OPTIONS]sudo implant traefik-ratelimit apply [--dry-run] # padrão: 100/s, burst 200, period 1s, depth 0
sudo implant traefik-ratelimit apply --average 20 --burst 60 --period 1s --in-flight 30
sudo implant traefik-ratelimit apply --no-in-flight
implant traefik-ratelimit status [-o json]
implant traefik-ratelimit print [--major 2|3] [--neutral] # YAML, sem tocar em nada
sudo implant traefik-ratelimit revert [--dry-run] # remove (recusa se algum router usa)
sudo implant traefik-ratelimit revert --neutral # mantém o nome, sem limiteSubcomandos
| Subcomando | Descrição |
|---|---|
apply |
Escreve/atualiza implant-ratelimit.yml no diretório do file-provider (o Traefik recarrega sozinho). Sem flags e com state, refaz o que estava |
revert |
Remove o arquivo e o state. Recusa se algum router usa o middleware, salvo --force |
revert --neutral |
Não remove: deixa o middleware definido e sem limite (average: 0); o apply sem flags refaz o limite |
status |
Arquivo presente, atual ou divergente, neutro, parâmetros, routers que usam o middleware e avisos |
print |
Só imprime o YAML que o apply escreveria (state + flags), sem tocar em nada. --neutral imprime a versão neutra |
Parâmetros
| Flag | Padrão | Descrição |
|---|---|---|
--average <N> |
100 |
Requisições por --period, por IP de origem (média) |
--burst <N> |
200 |
Rajada acima da média. Página com muitos assets precisa de folga |
--period <DUR> |
1s |
Janela da média: <N>s, <N>m ou <N>h |
--depth <N> |
0 |
ipStrategy.depth: 0 = IP da conexão; N = N-ésimo IP do X-Forwarded-For contando da direita (ver "--depth atrás de CDN ou proxy") |
--in-flight <N> |
desligado | Também limita requisições simultâneas por IP (inFlightReq.amount) |
--no-in-flight |
Desliga o limite de simultâneas | |
--major <2|3> |
detectado | Força a versão MAJOR do Traefik (apply, print) |
--force |
apply: substitui arquivo de mesmo nome que não é do implant (fica backup). revert: remove mesmo com router usando |
Os parâmetros ficam no state, em /var/lib/implant/traefik-ratelimit.json.
Cada apply parte do state e só troca o que vier na linha de comando; apply
sem flags e sem state usa os padrões.
Arquivo e middleware
O apply grava implant-ratelimit.yml no diretório do file-provider,
definindo o middleware implant-ratelimit. A primeira linha é a marca do
implant; editar à mão não adianta, porque o implant reescreve quando o
conteúdo diverge.
# Gerado pelo Implant (implant traefik-ratelimit).
# average=100 burst=200 period=1s depth=0 in_flight=off
http:
middlewares:
implant-ratelimit:
rateLimit:
average: 100
burst: 200
period: '1s'
sourceCriterion:
ipStrategy:
depth: 0Com --in-flight N, implant-ratelimit vira uma chain de
implant-ratelimit-rate (o rateLimit) e implant-ratelimit-inflight (o
inFlightReq). Anexe sempre o nome público, implant-ratelimit.
rateLimit, inFlightReq, chain e ipStrategy.depth têm a mesma sintaxe
no Traefik 2 e no 3. O arquivo não usa ipWhiteList/ipAllowList.
File-provider de arquivo único (filename:) não é suportado: use
directory:, ou cole o bloco do print no seu arquivo.
Anexar ao router (é com o operador)
O implant não mexe em router nenhum. Para proteger um serviço, acrescente o middleware ao router dele.
Label do container (se já houver outros middlewares, separe por vírgula):
labels:
- "traefik.http.routers.app.middlewares=implant-ratelimit@file"
# com outro middleware já presente:
# - "traefik.http.routers.app.middlewares=headers-seguros@file,implant-ratelimit@file"Router de arquivo:
http:
routers:
app:
rule: Host(`app.example.com`)
service: app
middlewares: [implant-ratelimit@file]Sem nenhum router usando o middleware, o apply e o status avisam.
`--depth` atrás de CDN ou proxy
Cuidado: errar o depth custa caro nos dois sentidos.
--depth 0(padrão) limita pelo IP da conexão. Atrás de CDN ou proxy reverso, esse é o IP do CDN: todos os usuários que chegam pelo mesmo nó dividem o limite.--depth Nusa o N-ésimo IP doX-Forwarded-For, contando da direita.
Os dois erros possíveis:
- Balde único. Depth alto demais, ou depth > 0 sem
forwardedHeaders.trustedIPsno entrypoint (o Traefik descarta oX-Forwarded-Forde origem não confiável), deixa o IP vazio. Todas as requisições caem no mesmo balde e o limite vira global: 429 para todo mundo. - IP falsificável. Depth > 0 sem proxy na frente deixa o cliente escolher o próprio IP pelo cabeçalho e contornar o limite.
O apply e o status avisam quando o depth é maior que zero e nenhum
entrypoint confia em X-Forwarded-For.
Idempotência e backup
- Conteúdo e state iguais não reescrevem nada.
- Mudança grava backup do arquivo anterior em
implant-ratelimit.yml.implant-bak, no mesmo diretório. - Arquivo de mesmo nome sem a marca do implant na 1ª linha não é tocado sem
--force.
Simular (`--dry-run`)
O apply mostra o YAML que escreveria; o revert, o que removeria. Nada é
gravado, nem o state.
`revert`
Apagar um middleware que um router cita derruba esse router (o Traefik
desliga router com middleware inexistente). Por isso o revert procura quem
usa o middleware:
- labels de todos os containers, inclusive parados;
- os outros arquivos do diretório dinâmico;
- o
usedByda API do Traefik, se ela responder.
Achou uso: recusa e lista os routers. As saídas são:
- tirar a referência dos routers antes;
revert --neutral— mantém o nome comaverage: 0(sem limite) e guarda o state; umapplysem flags refaz o limite;--force— remove mesmo assim (os routers que o citam caem).
O revert completo remove o arquivo e o state, mas deixa o backup
implant-ratelimit.yml.implant-bak no diretório do file-provider. O Traefik
ignora esse arquivo (a extensão não é .yml/.toml); apague-o à mão se
quiser.
`status`
Mostra: arquivo presente; atual (igual ao que o state gera) ou divergente;
neutro; parâmetros; routers que usam o middleware; avisos (nenhum router
usando, depth sem trustedIPs).
"Quem usa" vem sempre de labels e arquivos, e também da API do Traefik
(/api/http/middlewares/implant-ratelimit@file, consultada de dentro do
container, só com api.insecure). Sem a API, middleware_api.motivo diz que
não dá para saber por ela; routers de outros providers (Consul, Kubernetes)
ficam de fora nesse caso.
Emergency-mode
traefik-ratelimit é uma feature opt-in do
emergency-mode. Sai por revert --neutral — o
middleware continua definido, sem limite, e os routers que o usam não caem —
e volta por apply sem flags, com os parâmetros guardados no state.
Limitações
- Sem isenção por IP da whitelist. O
rateLimitdo Traefik não tem isenção por IP, echainnão é condicional. Isentar exigiria duplicar cada router com um matcherClientIP(...), o que o implant não faz em router de terceiro. A whitelist do rate-limit não vale aqui: dimensione os limites para o tráfego legítimo mais pesado (monitoramento, CI) ou deixe sem o middleware os routers que esse tráfego usa. - Anexo por entrypoint não implementado (próximo passo). Anexar a todos os
routers de uma vez por
entryPoints.<ep>.http.middlewaresexige editar a config estática e recriar o Traefik. Além disso, um middleware de entrypoint que deixa de existir (file-provider que não sobe, arquivo removido) derruba todos os routers do entrypoint. Quando vier, seguirá o molde dotraefik-edge --enable-file-provider: plano com hash,--applyexplícito, backup e restart verificado.
Saída JSON
Envelope 1.0, comandos traefik.ratelimit.apply, traefik.ratelimit.revert
e traefik.ratelimit.status.
Exemplos
# Ver o YAML antes de gravar
implant traefik-ratelimit print --average 20 --burst 60
# Aplicar: 20 req/s por IP, rajada de 60, até 30 simultâneas
sudo implant traefik-ratelimit apply --average 20 --burst 60 --in-flight 30
# Atrás de um CDN que acrescenta 1 IP no X-Forwarded-For
# (exige forwardedHeaders.trustedIPs no entrypoint)
sudo implant traefik-ratelimit apply --depth 1
# Conferir quem usa e os avisos
implant traefik-ratelimit status
# Desligar o limite sem derrubar routers
sudo implant traefik-ratelimit revert --neutralVeja também
- traefik-edge — corte de arquivos sensíveis no mesmo file-provider
- traefik-accesslog
- rate-limit — rate-limit L4 por porta (iptables)
- auto-ban — detecção HTTP pelo access log