implant feed-block
Baixa listas públicas de redes hostis (padrão: Spamhaus DROP, v4 e v6),
valida, filtra e carrega o resultado em ipsets dedicados, julgados na INPUT
(serviços do host) e na DOCKER-USER (portas publicadas pelo Docker). Um
systemd-timer semanal mantém a lista atualizada. Opt-in (v2.60.0+).
Uso
implant feed-block <SUBCOMANDO> [OPTIONS]sudo implant feed-block apply # baixa, valida, filtra e aplica
sudo implant feed-block apply --dry-run # plano a partir do cache; nada muda
implant feed-block status
sudo implant feed-block update # o que o timer roda
sudo implant feed-block service install # timer semanal (systemd)
sudo implant feed-block revert # tira os ganchos e esvazia os setsSubcomandos
| Subcomando | Descrição |
|---|---|
apply [--force] |
Baixa os feeds, valida, filtra e popula IMPLANT_FEED_BLOCK / IMPLANT_FEED_BLOCK6; instala as chains IMPLANT_FEED_IN (INPUT) e IMPLANT_FEED_FWD (DOCKER-USER) |
update [--force] |
Baixa de novo e repopula, só se o feed estiver aplicado (é o que o timer roda). Falha mantém o conteúdo anterior |
revert |
Remove os ganchos da INPUT e da DOCKER-USER e esvazia os sets. Cache e config são preservados |
status |
Aplicado, entradas por set, ganchos, último download, stale, last_error, timer |
service install / uninstall |
Cria (e habilita) ou remove o timer e o service |
service status |
Estado do timer |
service logs [--lines N] |
journalctl do service (execuções do update); padrão 50 linhas |
--force em apply/update: baixa mesmo que o último download bom tenha
menos de 1 h (ver Termos de uso).
Todos aceitam --output json; em falha, a saída JSON é o envelope de erro
(success: false, error.code, error.message) e o exit é diferente de 0
(v2.60.1+). --quiet suprime a saída human (para timers e scripts).
Configuração
Seção [feed_block] do config.toml (padrão
/etc/protocolo-implant/config.toml). Sem a seção, valem os padrões:
[feed_block]
urls = [
"https://www.spamhaus.org/drop/drop_v4.json",
"https://www.spamhaus.org/drop/drop_v6.json",
]
max_entries = 100000 # teto (v4 + v6) depois do filtro; máx. 262144
min_prefix_v4 = 8 # entrada mais ampla que isto é descartada
min_prefix_v6 = 16
fetch_timeout_seconds = 30- Formatos aceitos: NDJSON do Spamhaus (com uma linha de metadata que traz
a contagem de registros) e texto simples, um IP/CIDR por linha, com
comentário depois de
;ou#. - Só
https://: a lista decide bloqueio, então não pode vir por um canal adulterável.
Onde bloqueia
Os ganchos do implant seguem uma precedência única na INPUT e na
DOCKER-USER:
WL (whitelist) > BL (blocklist/ban) > FEED (feed-block) > GEO (geo-block) > RL (rate-limit)- Depois do BL: o ban do operador é o julgamento mais específico, e é o contador dele que o auto-ban lê.
- Antes do GEO: o feed é uma lista curta de redes sabidamente hostis; o DROP fica contado como "feed", não diluído no país.
- Entre DROPs a ordem não muda o veredito, só quem conta o pacote. O que importa é a whitelist antes de todos.
A posição é calculada sobre a listagem da chain, então qualquer ordem de
apply entre as features dá a mesma chain.
Corpo das chains IMPLANT_FEED_IN e IMPLANT_FEED_FWD:
RETURNemESTABLISHED,RELATED;RETURNnos prefixos locais/privados;RETURNparaIMPLANT_RL_WHITELIST[6]eIMPLANT_AB_ALLOW[6](a whitelist vale mesmo sem o rate-limit aplicado);DROPpara quem está no set.
O set v6 (IMPLANT_FEED_BLOCK6) só ganha gancho se o feed tiver entradas v6.
Antes de mexer, o apply tira um snapshot do iptables
(ver iptables). Os sets são salvos em /etc/iptables/ipsets
e voltam no boot pela unit de firewall-restore; as
regras, pelo netfilter-persistent ou, sem ele (v2.61.0+), pela reaplicação
da própria unit, que refaz os ganchos sobre os sets restaurados. Sem nenhum
mecanismo, o apply avisa em warnings.
Proteções
Feed ruim não esvazia o set
O conteúdo novo é recusado inteiro — nunca truncado, nunca parcial; uma URL ruim recusa todas — quando há:
- download falho ou HTTP de erro;
- resposta acima de 32 MB;
- feed vazio ou truncado (a contagem da metadata não bate);
- mais de 10% de linhas inválidas;
- mais entradas que
max_entries; - nenhuma entrada restante depois do filtro.
Nesses casos o set fica com o conteúdo anterior. A recusa fica registrada em
last_error (no status), no evento feed_kept_previous de
/var/lib/implant/feed-block-events.jsonl e no kept_previous do JSON. No
primeiro apply (sem conteúdo anterior), é erro e nada muda.
Swap atômico
A troca do conteúdo é feita por ipset swap: não há instante em que o set
fique vazio. O último conteúdo bom fica em cache em
/var/lib/implant/feed-block/.
Anti-tranca
Sai do feed (e aparece em filtered_out, com o motivo) toda entrada que
cobre:
- o IP da sessão SSH atual;
- o IP das sessões SSH dos últimos
apply(o timer roda sem sessão e continua protegendo-os); - os
security.trusted_ipsdo config; - qualquer entrada da whitelist do rate-limit ou da allowlist do auto-ban;
- faixa privada, loopback ou link-local.
Também sai a entrada mais ampla que min_prefix_v4 / min_prefix_v6.
Limites
max_entries(padrão 100000, máximo 262144) conta v4 + v6 depois do filtro; acima dele, o feed é recusado.- Resposta HTTP limitada a 32 MB;
fetch_timeout_secondspor download.
Intervalo mínimo de 1 h
Sem --force, o feed não é baixado de novo se o último download bom tem
menos de 1 h: o apply usa o cache e o update não faz nada.
Simular (`--dry-run`)
Vale em apply, update, revert e service install/uninstall: não baixa,
não grava cache, state nem evento, não toca ipset, regra ou unit.
apply/updatemostram o plano (contagens, entradas filtradas, aviso de recusa) a partir do cache do último download bom;revertlista os comandos que rodaria.
Timer semanal
service install cria protocolo-implant-feed-block.timer: semanal,
Persistent=true (execução perdida roda no próximo boot), atraso aleatório
de até 6 h. Ele roda implant feed-block --quiet update, que só age se o
feed estiver aplicado e, em falha, não mexe no host.
O status marca stale quando não há download bom há 14 dias.
`revert`
Tira os ganchos da INPUT e da DOCKER-USER e esvazia os sets
IMPLANT_FEED_BLOCK / IMPLANT_FEED_BLOCK6 — eles continuam existindo,
vazios, e não são destruídos. Cache e config ficam; o próximo apply volta a
popular os sets.
Com o resto do implant
ban test: `implant ban test` mostrafeed,feed_entry(a entrada do feed que cobre o IP) efeed_enforced, eblockedpassa a contar o feed.unbannão tira do feed: o IP voltaria no próximo update. Ounbanrespondein_feed/feed_entrye avisa que a saída é a whitelist, que vale acima do feed:sudo implant rate-limit whitelist-ip --ip 203.0.113.10threat-status:
iptables_drops.feed_block(DROPs daIMPLANT_FEED_IN, somados eminput_total) ehardening_state.feed_block_applied/feed_block_entries.emergency-mode:
feed-blocké uma feature opt-in. Sai porrevert(chainsIMPLANT_FEED_*removidas, sets esvaziados) e volta porapply, que reusa o cache do último download bom se o download falhar.
Termos de uso do Spamhaus DROP
Os feeds padrão são do Spamhaus. Confira a versão vigente dos termos em
https://www.spamhaus.org/drop/terms/. Em resumo:
- Uso para a própria rede: o DROP é fornecido sem custo para filtrar tráfego no próprio firewall/roteador.
- Sem redistribuição: o conteúdo é protegido por direito autoral e de base de dados, e os termos não concedem licença sobre ele. Não repasse a lista (nem cópia, nem espelho, nem a terceiros) e não use o nome "Spamhaus" em material comercial ou promocional.
- Manter atualizado: alocações mudam, e uma lista velha bloqueia rede que
já trocou de dono. O timer semanal e o
staledostatusexistem por isso.
O implant baixa direto da fonte em cada servidor e guarda só o cache local de uso próprio. O intervalo mínimo de 1 h entre downloads segue a etiqueta com o provedor. Uso fora disso (por exemplo, um serviço que repassa a lista) exige acordo com o Spamhaus.
Saída JSON
Envelope 1.0, comandos:
feed-block.apply/feed-block.update:applied,changed,dry_run,source(nova|anterior),fetched,urls,entries_v4,entries_v6,filtered_out_total,filtered_out(até 50 itens{entrada, motivo}),kept_previous,skipped,warnings;feed-block.revert;feed-block.status:entries_v4/entries_v6(lidos do ipset),hook_input,hook_docker_user,last_fetch_ok,stale,last_error,timer,warnings;feed-block.service.*.
Exemplos
# Ativar: aplicar e instalar o timer semanal
sudo implant feed-block apply
sudo implant feed-block service install
# Conferir
implant feed-block status
sudo implant ban test 198.51.100.20 # está no feed? bloqueado de fato?
# Isentar um IP que o feed cobre
sudo implant rate-limit whitelist-ip --ip 198.51.100.20
# Forçar um download novo (respeite o intervalo do provedor)
sudo implant feed-block update --force
# Desligar
sudo implant feed-block service uninstall
sudo implant feed-block revertVeja também
- geo-block — bloqueio por país, logo abaixo do feed na precedência
- ban / unban — ban manual no ipset central
- rate-limit — whitelist que isenta do feed
- firewall-restore — sets de volta no boot
- emergency-mode