Troubleshooting

SSH nao conecta apos mudanca de porta

Solucao rapida

Se voce acabou de rodar implant ssh-port <porta> e ainda nao confirmou, aguarde: o watchdog volta a porta anterior em 5 minutos.

Se a nova porta funciona, confirme para cancelar a reversao:

implant ssh-port --confirm-change

Se tem acesso por outro meio (console do provedor, outra sessao):

# Opcao 1: Rollback para o ultimo snapshot
implant ssh-rollback --latest --yes

# Opcao 2: Reverter so a porta para 22
implant reset --ssh-port --yes

# Opcao 3: Reset total (volta tudo para defaults seguros)
implant emergency-reset --force

Solucao manual

Verificar:

ss -tlnp | grep sshd
implant firewall status

Solucao:

implant firewall allow --port 22
implant firewall allow --port 2222

# Ou via UFW diretamente
sudo ufw allow 22/tcp
sudo ufw allow 2222/tcp

SSH trancado apos hardening

Causa: MaxAuthTries, PerSourcePenalties, fail2ban, rate-limit ou um ban no ipset bloqueando o acesso.

Solucao (via console do provedor):

# Ver se o seu IP esta banido, e onde
implant ban test <SEU_IP>
implant unban <SEU_IP>

# Rollback SSH
implant ssh-rollback --latest --yes

# Reverter so o hardening do SSH
implant reset --ssh-hardening --yes

# Ultimo recurso
implant emergency-reset --force

Para evitar a repeticao, coloque o IP na whitelist (fail2ban, UFW, PerSourcePenaltyExemptList e rate-limit de uma vez):

implant ssh-key --whitelist-ip <SEU_IP>

SSH restrito por lockdown nao volta

Uma restricao feita com ssh-service disable (ou lockdown create) volta sozinha quando o TTL vence sem heartbeat. Para recuperar na hora, com acesso local (exige TTY):

sudo implant ssh-service status
sudo implant ssh-service emergency-restore

Veja Lockdown / Deadman.

Preciso desligar rapidamente as protecoes opt-in

Se suspeitar que rate-limit, sysctl, limites ou outra feature opt-in esta causando o problema, desligue tudo temporariamente com TTL (volta sozinho ao vencer):

implant emergency-mode enable --duration 3600   # TTL em segundos (max 6h)
implant emergency-mode status
implant emergency-mode disable     # restaura agora

Veja emergency-mode.

Comando recusa o dry-run

Sintoma: implant <comando> nao tem modo --dry-run: nada foi feito (rode sem --dry-run para executar de verdade).

Causa: desde a v2.59.0, subcomando que muda o host e nao sabe simular recusa o --dry-run global em vez de executar. Antes o flag era aceito e ignorado: o "teste" rodava de verdade (geo-block apply --dry-run, por exemplo, aplicava o allowlist).

Recusam com --dry-run:

Comando Excecoes (simulam ou so leem)
geo-block service install / uninstall / start / stop service status, service logs
auto-ban allow / unallow / offenses-clear —
auto-ban service ... service status, service logs
firewall-restore install / uninstall / confirm / arm / fallback status, ensure
capture prune, capture service ... service status, service logs
audit apply / revert, audit service ... service status, service logs

Nada e alterado na recusa. Solucao: rode sem --dry-run para executar de verdade, ou use um comando que simula. Passaram a simular de fato na v2.59.0: geo-block apply/update/revert/add-country/remove-country, firewall allow/deny/block-ip/unblock-ip/rate-limit/enable/disable, fail2ban use-ipset-action e firewall-restore ensure; auto-ban scan passou a aceitar o --dry-run global.

Docker nao inicia

Verificar:

systemctl status docker
journalctl -u docker -n 50

Causa comum: o dockerd recusa o daemon.json com JSON invalido ou com chave que ele nao conhece (erro de digitacao, opcao de outra versao do Docker) e nao sobe. O docker-limits apply/revert preserva as chaves que voce escreveu e reinicia o Docker quando altera o arquivo, entao uma chave invalida pre-existente derruba o Docker nesse reinicio.

Validar o arquivo (versoes do Docker com --validate):

sudo dockerd --validate --config-file /etc/docker/daemon.json

Corrija a chave apontada e inicie o Docker (sudo systemctl start docker). O Implant nao sobrescreve um daemon.json com JSON invalido, e desde a 2.55.1 tambem nao grava nem reinicia o Docker se o dockerd --validate recusar o resultado: apply e revert param com o motivo dado pelo dockerd.

Reverter as chaves gravadas pelo Implant no daemon.json (cada chave volta ao valor anterior; o Docker e reiniciado se o arquivo mudar):

implant docker-limits revert

Veja docker-limits.

logrotate: "duplicate log entry"

Sintoma: logrotate (ou o logrotate.service) acusa duplicate log entry for /var/log/syslog (ou kern.log, auth.log...).

Causa: ate a 2.54.0, o logrotate apply guardava o backup da config do rsyslog em /etc/logrotate.d/rsyslog.backup.implant. O logrotate le todo arquivo desse diretorio como configuracao, entao o backup virava uma segunda config para os mesmos arquivos.

Solucao: atualize para a 2.55.0 ou posterior e rode o apply, que move o backup para /var/lib/implant/backups/logrotate/:

implant self-update
implant logrotate apply
logrotate -d /etc/logrotate.conf 2>&1 | grep -i duplicate   # nao deve mostrar nada

O check --auto-fix faz a mesma migracao. Veja logrotate.

IP legitimo bloqueado

Diagnosticar (ipset, fail2ban e UFW numa visao so):

implant ban test <IP>
implant ban list

Desbanir (remove dos tres mecanismos e encerra o cooldown do auto-ban):

implant unban <IP>

Evitar novo bloqueio:

implant ssh-key --whitelist-ip <IP>

`check` mostra Fail em "Boot-survival do firewall"

Causa: a unit implant-firewall-restore nao esta instalada, ou e de uma versao antiga cuja ordenacao impedia a execucao no boot. Sem ela, um reboot deixa os ipsets do Implant vazios e o firewall sobe sem blocklist nem rate-limit.

Solucao: rode implant rate-limit reconcile (v2.58.0+), que instala a unit com guarda; o agente de controle remoto confirma sozinho. Sem o agente, a instalacao automatica e desfeita em 10 minutos e o reconcile passa a so apontar; nesse caso, instale a mao e confirme:

implant rate-limit reconcile
implant firewall-restore status               # guard.auto_install_reverted indica que foi desfeita
implant firewall-restore install --confirm-timeout 10 --boot-guard
implant firewall-restore confirm              # depois de conferir que o acesso continua ok

Causa (v2.59.0+): a unit esta ok, mas as regras nao voltam no boot. A mensagem do check diz o que falta: netfilter-persistent ou iptables-persistent nao instalado, servico netfilter-persistent desabilitado ou /etc/iptables/rules.v4 ausente/vazio. O caso mais comum e a instalacao do pacote ufw, que remove o iptables-persistent e o netfilter-persistent no apt (conflito de pacotes): os ipsets voltam, as regras que os usam nao, e o servidor sobe sem blocklist nem rate-limit.

Solucao (v2.61.0+): atualize o implant (implant self-update). A unit nova reaplica as regras do implant no boot sem o netfilter-persistent, e o self-update troca a unit antiga sozinho. Confira:

implant firewall-restore status -o json       # rules_mechanism: implant-firewall-restore; up_to_date: true
sudo implant firewall-restore boot-rules --dry-run
implant check --modules hardening

Em versoes anteriores nao ha correcao automatica: reinstalar o iptables-persistent remove o UFW pelo mesmo conflito.

Causa (v2.61.0+): a reaplicacao deste boot falhou (firewall-restore status com boot_rules_failed). O boot seguiu aberto para o componente que falhou (fail-open); o passo esta em /var/lib/implant/firewall-restore/boot-rules.json.

Solucao: refaca o componente (implant rate-limit reconcile, implant feed-block apply ou implant geo-block apply). O passo vira recovered e o check deixa de reprovar.

Enquanto as regras nao voltam por nenhum mecanismo, o ban responde persisted: false com o motivo em warnings, e o rate-limit (apply, revert, reconcile, status) avisa no stderr e traz rules_persist_warning no JSON: as regras valem ate o proximo reboot.

Veja firewall-restore.

`check` mostra Fail em "Cobertura DOCKER-USER"

Causa: o rate-limit esta aplicado, mas a chain DOCKER-USER nao tem o gancho da blocklist (instalacoes antigas). IPs banidos continuam chegando aos containers.

Solucao:

implant rate-limit reconcile

`check` mostra Fail no access log do Traefik

Causa: arquivos de log ou logrotate legiveis por outros usuarios, ou config que grava a query string (que pode conter credenciais) no log.

Solucao:

implant traefik-accesslog --fix-perms     # so permissoes, sem reiniciar o Traefik
implant fix --auto                        # tambem grava a config da query, se o Traefik aceitar

Versoes do Traefik que nao suportam o descarte da query aparecem como Fail pedindo a atualizacao do proprio Traefik.

Arquivos sensiveis acessiveis pelo Traefik (`/.env`, `/.git`)

implant traefik-edge              # audita (somente leitura)
implant traefik-edge --configure  # escreve a guarda (403 no ingresso)

Veja traefik-edge.

VPN WireGuard no ar, mas sem conexao apos reboot

Causa: em versoes anteriores, a regra de firewall da porta UDP era so de runtime.

Solucao: atualize o Implant e rode novamente o init com --adopt para gravar o drop-in que reabre a porta a cada subida:

implant self-update
implant wireguard init --adopt
implant wireguard status

install claude-code: "Claude CLI nao encontrado no PATH"

Causa: O instalador nativo coloca o claude em ~/.local/bin/, que pode nao estar no PATH.

Solucao:

# Adicionar ao PATH
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# Ou criar symlink
sudo ln -sf ~/.local/bin/claude /usr/local/bin/claude

Instalacao de pacotes travou (apt lock)

Causa: Outro processo apt ou dpkg esta ativo, ou unattended-upgrades travou o lock.

O que o Implant faz automaticamente:

  1. Para o servico unattended-upgrades antes de instalar
  2. Suspende o needrestart durante a instalacao
  3. Mata processos apt/dpkg com mais de 30 minutos
  4. Timeout de 120 segundos por operacao

Solucao manual (se persistir):

# Verificar processos travados
ps aux | grep -E 'apt|dpkg'

# Encerrar o processo travado
sudo kill <PID>

# Reconfigurar pacotes pendentes
sudo dpkg --configure -a

# Tentar novamente
implant check --auto-fix

Pin verification failed (TLS)

Causa: o certificado do host de download foi trocado e o hash SPKI nao corresponde mais ao pin embutido no binario. Pode ser rotacao legitima de certificado ou interceptacao (MITM).

Solucao: reinstale pelo init.sh, que verifica a assinatura minisign do binario de forma independente do pin:

curl -sL https://implant.ccs.systems/init.sh | sudo bash

Se voce aponta o Implant para infraestrutura propria com [[tls_pins]] no config.toml, atualize o pin do seu host.

Assinatura ausente ou invalida

No init.sh: assinatura ausente (HTTP 404) ou invalida aborta a instalacao sem gravar nada. Tente novamente mais tarde; se persistir, nao instale o binario.

No self-update: .minisig invalida sempre aborta. Com --url para um host sem pin embutido, .minisig valida e obrigatoria.

404 Not Found no self-update

Causa: nao ha binario publicado para a arquitetura detectada, ou a URL configurada em [endpoints] esta errada.

Verificar:

ARCH=$(uname -m)
curl -sI "https://implant.ccs.systems/${ARCH}/implant"
grep -A3 '^\[endpoints\]' /etc/protocolo-implant/config.toml 2>/dev/null

Logs de Debug

# Modo verbose
implant check --verbose

# Modo debug completo
RUST_LOG=debug implant check

# Saida estruturada para analise
implant check -o json