implant firewall-restore

Gerencia a unit systemd implant-firewall-restore.service (v2.25.0+), que devolve os ipsets do implant (IMPLANT_*: blocklist, whitelist, geo-block, rate-limit) no boot, antes do netfilter-persistent, do iptables e do Docker.

Sem ela, os sets sobem vazios após um reboot e o iptables-restore das regras que usam -m set falha: o firewall sobe sem blocklist nem rate-limit, sem aviso. A unit lê o arquivo /etc/iptables/ipsets, que o implant atualiza a cada mudança nos sets.

Desde a v2.58.0 o rate-limit reconcile instala a unit sozinho, com a mesma guarda do install manual recomendado (--confirm-timeout 10 --boot-guard). rate-limit apply e check --auto-fix continuam só apontando a falta. O install manual (abaixo) segue disponível.

Desde a v2.59.0 o self-update também cuida disso: depois de trocar o binário, roda firewall-restore ensure com o binário novo (ver `ensure` e self-update).

Desde a v2.61.0, quando as regras não voltam pelo netfilter-persistent (caso típico: host com UFW), a unit reaplica as regras do implant depois de restaurar os sets — ver Regras no boot sem netfilter-persistent.

Instalação automática pelo `reconcile` (v2.58.0+)

Depois de refazer o rate-limit, o reconcile olha a unit. Se ela falta, é a antiga (≤ 2.50.0, que não rodava no boot) ou está desabilitada, instala como firewall-restore install --confirm-timeout 10 --boot-guard (mantém o --boot-timeout já configurado). Quem confirma é o agente de controle remoto, sozinho, assim que fala com o console de gerenciamento depois do install; sem confirmação em 10 minutos, a guarda desfaz (fail-open).

  • Sem laço: se a instalação automática foi desfeita por falta de confirmação (prazo vencido ou reboot com ela pendente), o reconcile não tenta de novo — só aponta (boot_restore_advice). O bloqueio fica em guard.auto_install_reverted no status e some com uma instalação confirmada ou com um install manual sem guarda bem-sucedido.
  • Com uma instalação já pendente de confirmação, o reconcile não instala de novo. Sem rate-limit gerenciado, não mexe na unit.
  • --dry-run só mostra o plano.
  • No JSON do reconcile: boot_unit_action (installed_pending_confirm, already_ok, pending_confirm, skipped_previous_revert, planned, install_failed, not_managed), boot_unit_installed (se este reconcile instalou), boot_unit_plan e boot_unit_install.

Regras no boot sem netfilter-persistent (v2.61.0+)

Instalar o pacote ufw remove o iptables-persistent e o netfilter-persistent no apt (conflito de pacotes). Até a 2.60, os sets voltavam no reboot, mas as regras que os leem não: o servidor subia sem blocklist nem rate-limit. Agora a unit, depois do ipset restore, roda implant firewall-restore boot-rules, que reaplica a partir dos states:

  • rate-limit: pelo mesmo caminho do rate-limit reconcile (sets, whitelist do state, regras e ganchos na INPUT e na DOCKER-USER). Não volta se o state está suspenso (revert --keep-state, emergency-mode) ou no schema antigo;
  • feed-block: os ganchos sobre os sets restaurados, por família com entradas. Nada é baixado no boot;
  • geo-block: os ganchos no modo do state. Família cujo set não voltou (ou voltou vazio) fica sem gancho — em allowlist, gancho sobre set vazio derrubaria toda conexão nova de IP público.
Situação O que acontece no boot
netfilter-persistent + plugin do iptables-persistent, serviço habilitado e rules.v4 gravado ele carrega as regras; a unit não reaplica (uma fonte só)
sem ele (UFW), ou presente sem carregar nada (desabilitado, sem plugin, sem rules.v4) a unit reaplica a partir dos states
  • Ordem com o UFW: a unit roda After=ufw.service (com MANAGE_BUILTINS=yes o UFW esvazia a tabela filter inteira ao subir). Os ganchos do implant entram na posição calculada — whitelist > blocklist > feed-block > geo-block > rate-limit, antes de qualquer regra que não seja do implant —, ou seja, acima das chains do UFW. O resultado sai em hooks_after_ufw (mesmo critério do achado ufw.order.* do `firewall audit`).
  • Docker: a unit roda antes do Docker. Com o Docker instalado, ela cria a DOCKER-USER vazia para os ganchos entrarem; o Docker aceita a chain pronta e não a esvazia.
  • Fail-open: erro num componente não para os outros nem o boot. O comando sai 0 (a unit o chama com ExecStart=-, teto de 120 s), grava o resultado em /var/lib/implant/firewall-restore/boot-rules.json e registra o evento boot_rules_failed na guarda. Se o ipset restore falhar, a unit para antes da reaplicação: sem sets, sem regras — aberto.
  • Guarda de boot: roda depois da reaplicação; o fallback dela esvazia os sets de bloqueio que esses ganchos leem.
  • Só o implant volta. DROP/REJECT cru e policy DROP própria da INPUT não têm quem os traga sem o netfilter-persistent: o firewall audit avisa (persistence.rules em warn). Use o UFW ou `implant ban`.
  • Componente refeito depois do boot: se a reaplicação de um componente falhou no boot e ele foi refeito depois (rate-limit reconcile, feed-block apply, geo-block apply), o passo vira recovered e o implant check deixa de reprovar por ele.

A unit da 2.51–2.60 não tem a reaplicação: status mostra up_to_date: false, e o `self-update` a troca pelo caminho de sempre (ensure → rate-limit reconcile, com a guarda).

Uso

implant firewall-restore <subcomando> [OPTIONS]

Subcomandos

`install`

Instala e habilita a unit e roda o restore uma vez para validar.

Flag Descrição
--confirm-timeout <MIN> Instalação com confirmação: sem firewall-restore confirm em N minutos (2–360), desfaz — a unit e os sets IMPLANT_* voltam ao que eram. Sem a flag, instala sem guarda
--boot-guard Instala também a guarda de boot (ver abaixo)
--boot-timeout <MIN> Minutos para confirmar cada boot (2–360). Padrão 10

Por que confirmar

Se o arquivo de sets tiver algo errado — o IP de quem administra numa blocklist, por exemplo — o host pode subir fechado para o próprio operador. As duas guardas usam o mesmo dead-man do lockdown: o desfazer fica agendado e só é cancelado pela confirmação.

  • Confirmação da instalação (--confirm-timeout N): antes de aplicar, o implant guarda uma cópia dos sets. Sem confirm no prazo, a unit e os sets IMPLANT_* voltam ao estado anterior.
  • Guarda de boot (--boot-guard): instala uma segunda unit, implant-firewall-restore-guard.service, que a cada boot arma uma confirmação com prazo de --boot-timeout minutos. Sem confirm no prazo, o implant libera apenas as entradas do implant nos sets IMPLANT_* de bloqueio (blocklist e geo-block). Whitelist, allow do auto-ban, regras de iptables, UFW e sets que não são do implant não são tocados. Antes, guarda uma cópia do arquivo de sets e registra um evento com o que foi liberado, por origem (ban, auto_ban, geo_block, sem_registro).

Forma recomendada:

sudo implant firewall-restore install --confirm-timeout 10 --boot-guard
# … conferir que o acesso continua de pé …
sudo implant firewall-restore confirm

`ensure`

(v2.59.0+) Roda o rate-limit reconcile só quando ele instalaria a unit; em qualquer outro caso não faz nada. É o passo que o `self-update` executa com o binário novo, e é idempotente e seguro à mão.

sudo implant firewall-restore ensure            # reconcilia só se a unit precisar
sudo implant firewall-restore ensure --dry-run  # mostra o que faria

O reconcile roda quando todas as condições valem:

  • rate-limit gerenciado (há state), ativo (não suspenso) e no schema 2.0;
  • unit faltando, antiga (≤ 2.50.0) ou desabilitada;
  • nenhuma instalação aguardando confirmação;
  • nenhuma reversão anterior da instalação automática.

Assim o rate-limit não é reaplicado a cada atualização: com a unit em dia, o ensure só responde already_ok. Com --dry-run, devolve planned sem alterar nada.

JSON (firewall-restore.ensure):

Campo Significado
reconciled o ensure rodou o rate-limit reconcile
boot_unit_action o do reconcile quando rodou; senão, o motivo de não rodar (os valores da tabela acima, mais suspended e unsupported_schema)
boot_unit_plan o plano de instalação (em --dry-run)
boot_restore_advice orientação quando a unit continua faltando
reconcile o relatório do reconcile, quando rodou

Valores exclusivos do ensure:

  • suspended — o rate-limit está suspenso (revert --keep-state ou emergency-mode); o ensure não o reaplica.
  • unsupported_schema — state do rate-limit anterior ao schema 2.0 (ver rate-limit migrate-to-ipset).

`confirm`

Confirma a instalação e/ou o boot pendente (desarma a reversão) e devolve os eventos ainda não repassados (ex.: um fallback de boot que já aconteceu). Pode ser rodado à mão pelo operador ou por um console de gerenciamento remoto, depois de confirmar que o caminho até o servidor está de pé. Enquanto há algo pendente, existe o marcador /run/implant/firewall-restore.pending.

`status`

Somente leitura: estado da unit (installed, up_to_date, enabled, active), resumo do arquivo /etc/iptables/ipsets (sets e número de entradas) e o estado da guarda (guard: guarda de boot ligada, prazo, instalação aguardando confirmação, último evento).

up_to_date: false indica uma unit antiga: até a 2.50.0 ela não rodava no boot (ciclo de ordenação no systemd); da 2.51 à 2.60 não reaplica as regras. Corrija com implant firewall-restore install (ou deixe o self-update trocar).

Desde a v2.61.0, também:

Campo Significado
rules_mechanism netfilter-persistent, implant-firewall-restore ou null (nenhum: as regras não voltam no boot)
boot_rules último resultado do boot-rules (ver acima)
boot_rules_failed a reaplicação deste boot teve passo falho ainda não refeito

`boot-rules`

(v2.61.0+) O passo que a unit roda no boot, depois do ipset restore. À mão, serve para ver o que ela faria agora:

sudo implant firewall-restore boot-rules --dry-run

JSON (firewall-restore.boot-rules):

Campo Significado
decision reapply ou skip_netfilter_persistent
mechanism mecanismo de regras detectado
docker_user_precreated a DOCKER-USER foi criada antes do Docker
steps[] name (docker_user, rate_limit, feed_block, geo_block), status (reapplied, skipped, failed, recovered) e detail
hooks_after_ufw ganchos do implant que ficaram depois das chains do UFW (vazio = ordem certa)
ok nenhum passo falho
boot_id boot a que o resultado se refere

`uninstall`

Remove a unit e a guarda de boot. Os ipsets em memória não são tocados; só o restore no próximo boot deixa de existir.

`arm` / `fallback` (uso interno)

Chamados pelas próprias units e pelo agendamento do lockdown, não pelo operador:

  • arm --boot — roda na implant-firewall-restore-guard.service e arma a confirmação do boot.
  • fallback --boot — prazo do boot vencido: libera as entradas do implant nos sets de bloqueio.
  • fallback --install --nonce <ID> — prazo da instalação vencido: desfaz a instalação identificada.

Flags globais relevantes

Flag Descrição
--dry-run Só status e ensure simulam. Os demais subcomandos (install, uninstall, confirm, arm, fallback) recusam o --dry-run sem fazer nada (v2.59.0+)
-o, --output json|yaml Envelope estruturado (firewall-restore.install, .uninstall, .status, .ensure, .confirm, .arm, .fallback)

Exemplos

# Instalação simples, sem guarda
sudo implant firewall-restore install

# Instalação com confirmação em 15 min e guarda de boot de 10 min
sudo implant firewall-restore install --confirm-timeout 15 --boot-guard

# Guarda de boot com prazo maior
sudo implant firewall-restore install --boot-guard --boot-timeout 30

# Confirmar (instalação ou boot)
sudo implant firewall-restore confirm

# Garantir a unit (o mesmo passo que o self-update roda)
sudo implant firewall-restore ensure

# Estado
sudo implant firewall-restore status -o json

# Remover
sudo implant firewall-restore uninstall

Notas

  • Com a guarda de boot ligada, todo boot precisa ser confirmado. Sem confirmação no prazo, os bans do implant (manuais, do auto-ban e do geo-block) saem dos sets; o evento devolvido pelo confirm diz quantos saíram de cada origem.
  • O ban responde persisted: false quando a unit não está instalada ou está desatualizada — e, desde a v2.59.0, também quando as regras não voltam no boot. Desde a v2.61.0 a reaplicação pela unit conta como mecanismo (ver ban).
  • O implant check reprova o item "Boot-survival do firewall" sem a unit e aponta o comando de instalação com guarda; reprova também quando as regras não voltam por nenhum mecanismo, ou quando a reaplicação deste boot falhou e o componente não foi refeito (ver hardening).

Veja também