implant geo-block

Bloqueia tráfego por país usando CIDRs do IPDeny populados em ipset dedicado — na INPUT (serviços do host) e na DOCKER-USER (portas publicadas pelo Docker). systemd-timer semanal para update automático.

Setup

sudo implant geo-block service install     # cria timer + service + config + ipsets
sudo implant geo-block service status      # verifica

Bloqueando países

sudo implant geo-block apply --countries CN,RU,KP    # popula ipset + ativa
sudo implant geo-block list-countries                 # mostra países + entry counts
sudo implant geo-block add-country --code IR --apply  # adiciona um país
sudo implant geo-block remove-country --code KP --apply

Simular (`--dry-run`)

Desde a v2.59.0, o --dry-run global vale em todos os subcomandos que mudam o host: apply, update, revert, add-country e remove-country simulam sem gravar config, cache, state, ipset nem regra.

sudo implant geo-block apply --countries BR --mode allowlist --dry-run   # só simula
  • No apply, roda a checagem anti-tranca e devolve as contagens a partir do cache local (dry_run: true, applied: false, avisos em warnings).
  • No revert, mostra os comandos que rodaria.
  • service install/uninstall/start/stop não sabem simular: com --dry-run recusam e não fazem nada.

Até a v2.58.0, o --dry-run não chegava ao geo-block: apply --dry-run aplicava de verdade (em allowlist, podia trancar o servidor).

Update do DB

systemd-timer roda semanalmente. Manual:

sudo implant geo-block update          # se DB > interval_days, baixa
sudo implant geo-block update --force  # força mesmo se fresh

Fonte

IPDeny (https://www.ipdeny.com/) — sem credencial:

  • v4: /ipblocks/data/countries/{iso}.zone
  • v6: /ipv6/ipaddresses/aggregated/{iso}-aggregated.zone

Cache local: /var/lib/implant/geoip/{iso}.zone + {iso}-v6.zone.

Bulk populate

ipset restore (stdin) — 8800 CIDRs em ~0.8s.

Topologia

O apply cria duas chains e as engancha seguindo a precedência única do implant — whitelist > blocklist > feed-block > geo-block > rate-limit (a posição é calculada sobre a chain real, independente da ordem em que as features foram aplicadas):

  • IMPLANT_GEO_IN (saltada da INPUT): RETURN para ESTABLISHED,RELATED, prefixos locais e whitelist; DROP por último
  • IMPLANT_GEO_FWD (saltada da DOCKER-USER): idem para tráfego encaminhado aos containers, com RETURN também para quem está em IMPLANT_RL_WHITELIST/IMPLANT_AB_ALLOW
INPUT: -j IMPLANT_RATELIMIT_WHITELIST                      (whitelist → ACCEPT)
INPUT: -m set --match-set IMPLANT_RL_BLOCKLIST src -j DROP (blocklist)
INPUT: -j IMPLANT_FEED_IN                                  (feed-block, se aplicado)
INPUT: -j IMPLANT_GEO_IN                                   (geo-block)
INPUT: -j IMPLANT_RATELIMIT                                (rate-limit)

Falha ao instalar o gancho aborta o apply (não fica meio aplicado em silêncio). O apply tira um snapshot do iptables antes de mexer (implant iptables restore --snapshot-id 1 desfaz). Instalações no formato antigo (DROP solto na INPUT) são migradas no próximo apply — inclusive o disparado pelo update semanal do timer.

Whitelist (IMPLANT_RL_WHITELIST ou IMPLANT_AB_ALLOW) bypassa geo-block. Para criar exceção: implant rate-limit whitelist-ip --ip <X> ou implant auto-ban allow --ip <X>.

Modes

geo-block suporta dois modes:

Mode Comportamento Config
blocklist (default) Bloqueia CIDRs dos block_countries --mode blocklist
allowlist Bloqueia TUDO exceto allow_countries --mode allowlist

Allowlist mode

# Só permite Brasil, Portugal, US
sudo implant geo-block apply --mode allowlist --countries BR,PT,US

# Verifica
sudo implant geo-block status   # mode: allowlist
sudo iptables -L IMPLANT_GEO_IN -n

ATENÇÃO: Allowlist mode com allow_countries vazio bloquearia todo INPUT. Implant recusa.

Anti-tranca: em allowlist, o apply recusa se o IP da sua sessão SSH atual ($SSH_CONNECTION) não estiver num país permitido nem na whitelist. Desde a v2.59.0, o --mode/--countries só é gravado no config depois que a checagem passa: allowlist recusado não fica pendente.

Update só repopula config validado (v2.59.0+): o update (e o timer semanal, que roda sem sessão SSH) não aplica allowlist que não passou pela anti-tranca. Ele só repopula se o config for blocklist ou o mesmo allowlist do último apply (ou com países a mais). Troca de blocklist para allowlist, país removido do allowlist ou config editado à mão ficam para um geo-block apply numa sessão SSH. Na recusa:

  • sets e regras ficam como estavam;
  • o state ganha update_refused, mostrado no status;
  • é registrado o evento update_refused_unvalidated_allowlist em /var/lib/implant/geo-block-events.jsonl e há aviso no journal;
  • o JSON do update traz refused.

O status mostra validated_at/validated_by do último apply feito por um operador.

Whitelist precede: IPs em IMPLANT_RL_WHITELIST ou IMPLANT_AB_ALLOW bypassam geo-block em ambos modes. Use isso para exceções (ex: monitor uptime fora do allow).

Switch entre modes

# Antes: blocklist mode com CN bloqueado
sudo implant geo-block apply --mode allowlist --countries BR
# Effect: agora SÓ permite BR, todo o resto (incluindo CN) é bloqueado

apply detecta mudança de mode + remove hook antigo (qualquer variação) antes de aplicar o novo.

Comandos

Comando Descrição
service install/uninstall Cria/remove timer + service + ipsets
service start/stop/status Ciclo de vida do timer
service logs [--lines N] journalctl wrapper
apply [--countries CN,RU] [--mode blocklist|allowlist] Popula ipset + chains IMPLANT_GEO_IN/IMPLANT_GEO_FWD. --countries persiste no config.
revert Remove os ganchos da INPUT e da DOCKER-USER (ipsets flushed; sets preservados; config preservado)
update [--force] Refetch IPDeny + repopula se aplicado (só config validado pela anti-tranca)
add-country --code CN [--apply] Adiciona ao config; --apply reaplica
remove-country --code CN [--apply] Remove do config
list-countries Países + entry counts por país
status Combinado (applied, timer, last_update, ipset sizes, stale, validated_at/validated_by, update_refused)
config show/path Imprime config / caminho

Todos com --output json para automação. apply, update, revert, add-country e remove-country aceitam --dry-run.

Config

/etc/protocolo-implant/geo-block.yml — todos os campos têm default. implant geo-block config show imprime a config efetiva.

Emergency-mode

geo-block é uma feature opt-in. emergency-mode enable desabilita junto com as demais features opt-in. ipsets preservados — deadman re-aplica.