Arquitetura desacoplada do Imunify email: engenharia reversa de thresholds e monitoramento de quarentena
Voltar para blog

Arquitetura desacoplada do Imunify email: engenharia reversa de thresholds e monitoramento de quarentena

17/10/2026 · 5 min · Cibersegurança

Em servidores cPanel e CloudLinux com Imunify Email (IE), a documentação oficial muitas vezes descreve comandos legados ou abstrai o que os binários realmente fazem no sistema operacional. Um problema frequente ocorre ao tentar ajustar os limites de score de spam: mensagens com pontuações elevadas (acima de 0.80) continuam caindo diretamente na caixa de entrada do usuário com o status No Action, em vez de serem retidas na quarentena.

Ao tentar seguir os tutoriais habituais para alterar essas regras, o administrador frequentemente esbarra em comandos inexistentes e caminhos de configuração diferentes dos manuais.

Neste artigo, vamos analisar a estrutura de microsserviços do Imunify Email, investigar as pistas deixadas pelo runtime do Go via chamadas de sistema, entender os gatilhos que forçam o sistema a ignorar spams e implementar um script de monitoramento para evitar que quotas esgotadas desativem a proteção.


1. Por que os comandos tradicionais falham no ie-CLI#

Muitos artigos e fóruns antigos recomendam o comando ie-cli config show --global para inspecionar ou alterar os limites de retenção. Em instalações modernas, no entanto, o terminal retorna um erro imediato:

[root@server ~]# ie-cli config show
Error: unknown command "config" for "ie-cli"

Pistas do runtime do go nas chamadas de sistema#

Ao monitorar a execução do binário com strace para descobrir quais arquivos de configuração estavam sendo abertos, um detalhe chamou a atenção:

[root@server ~]# strace -e openat ie-cli filter-settings 2>&1 | grep -v "ENOENT"
openat(AT_FDCWD, "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", O_RDONLY) = 3
--- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=1907699, si_uid=0} ---
{
    "allow_windows_executable_attachments": true
}
+++ exited with 0 +++

A interceptação do sinal SIGURG enviado via SI_TKILL confirma que o ie-cli e seus daemons são compilados em Go (Golang). Desde o Go 1.14, o runtime utiliza SIGURG de forma assíncrona para gerenciar a preempção das goroutines e a concorrência de processos. Além disso, a leitura de /sys/kernel/mm/transparent_hugepage mostra o gerenciador de memória interno da linguagem ajustando blocos dinâmicos.

A árvore de processos em microsserviços#

Em vez de um daemon monolítico, o Imunify Email opera com três componentes independentes organizados sob o diretório /etc/imunifyemail/ (sem hífen no nome da pasta):

ps aux | grep -E "ie-|rspamd"

O comando revela os seguintes processos ativos:

_imunify+    2962  0.0  0.0  /usr/bin/ie-dec-node run --config /etc/imunifyemail/dec-node.yaml --env-file /etc/imunifyemail/dec-node.env
_imunify+    2965  0.0  0.0  /usr/bin/ie-quarantine run --config /etc/imunifyemail/quarantine.yaml --env-file /etc/imunifyemail/quarantine.env
_rspamd      4116  0.0  0.0  rspamd: controller process (/var/lib/rspamd/rspamd-ctl.sock mode=0660 group=_imunify)

Cada processo tem uma função específica no pipeline:

  1. ie-dec-node: nó de decisão. Funciona como intermediário de processamento assíncrono. Ele recebe a pontuação do motor de análise e decide o destino da mensagem.
  2. ie-quarantine: gestor do armazenamento de quarentena. Controla o banco de dados de índice e os diretórios Maildir de retenção.
  3. rspamd: motor heurístico. Roda em paralelo e conversa com o ecossistema do Imunify através de sockets UNIX pertencentes ao grupo _imunify.

2. Estrutura do dec-node.yaml e fluxo de decisão#

O arquivo /etc/imunifyemail/dec-node.yaml define parâmetros operacionais e limites de disco:

server:
  address:    :11339
  insecure:   false
  readTimeout: 10s
  writeTimeout: 10s
  socketAddress: /var/run/imunifyemail/dec-node.sock

logger:
  level: info
  outputPaths:
    - stdout

cleaner:
  rootDir: /var/imunifyemail/dec-node/storage/data
  hardQuotaGb: 1
  softQuotaGb: 0.9
  interval: 500s

saver:
  rootDir: /var/imunifyemail/dec-node/storage/data
  indexFileName: /var/imunifyemail/dec-node/storage/index.db

O caminho percorrido pela mensagem#

Quando o MTA (Exim) recebe uma mensagem, o fluxo segue esta sequência técnica:

[Exim MTA]
    │  (Repassa payload via transporte de filtro)
    ▼
[Rspamd] ──(Calcula score com base em regras e filtros bayesianos)
    │
    ▼  Envia símbolos e pontuação pelo socket /var/run/imunifyemail/dec-node.sock
[ie-dec-node] ──(Consulta index.db e variáveis de ambiente)
    │
    ├─ Se Score >= Limite ──> Grava no storage da quarentena e atualiza index.db
    │                          ▲
    │                          │ (Gerenciado pelo ie-quarantine)
    └─ Se Score < Limite  ───> Devolve "No Action" para o Exim entregar na caixa postal

Como o ie-cli filter-settings expõe apenas configurações booleanas básicas (como o bloqueio de anexos executáveis do Windows), os limites de pontuação não residem em arquivos de configuração comuns. Eles são administrados pelo arquivo de variáveis de ambiente carregado pelo processo (/etc/imunifyemail/dec-node.env) e pelo banco de dados SQLite embarcado (/var/imunifyemail/dec-node/storage/index.db).


3. Por que mensagens com score alto recebem o veredito "no action"?#

Quando mensagens claramente identificadas como spam não são retidas, vale investigar três causas principais no terminal.

1. Descompasso de escalas entre o Rspamd e o Imunify#

O Rspamd nativo utiliza uma escala aberta de pontuação (com valores que frequentemente variam entre 5.0 e 15.0 para mensagens suspeitas). O Imunify Email aplica uma normalização estatística para converter esse resultado em uma probabilidade decimal entre 0.00 e 1.00.

Para verificar se regras brutas do Rspamd não estão interferindo na ação repassada:

rspamadm configdump actions

Se as diretivas de ação do Rspamd estiverem desalinhadas com o nó de decisão, o resultado entregue no socket /var/run/imunifyemail/dec-node.sock pode não acionar a regra esperada.

2. Esgotamento de quotas do cleaner (comportamento fail open)#

No arquivo dec-node.yaml, o bloco cleaner estabelece limites rígidos de armazenamento: hardQuotaGb: 1 e softQuotaGb: 0.9. Se o volume global da quarentena ou o espaço reservado para uma conta individual atingir essa barreira, o Imunify Email adota uma postura de segurança passiva (Fail Open).

Em vez de bloquear o recebimento ou sobrecarregar o disco, o daemon passa a devolver No Action para as novas mensagens, evitando a corrupção do banco de dados SQLite.

Para auditar o espaço em uso por conta:

ie-cli accounts list

Se a coluna UsedBytes estiver encostando em LimitBytes, a retenção automática foi temporariamente desativada pelo próprio sistema para proteger a integridade do disco.

3. Exceções e regras de liberação prévia#

E-mails recebidos sem cabeçalhos RFC elementares (como mensagens internas de alertas locais sem Message-ID ou sem data) ou remetentes inseridos em regras locais de liberação são ignorados pelo filtro.

Para inspecionar as tabelas de bypass no banco SQLite local:

sqlite3 /var/imunifyemail/dec-node/storage/index.db "SELECT * FROM settings WHERE key LIKE '%whitelist%' OR key LIKE '%bypass%';"

4. Comandos práticos e rotina de automação#

Com o ambiente mapeado, podemos ajustar os limites e criar uma rotina de monitoramento para prevenir o estouro de espaço.

Ajustando capacidades globais da quarentena#

Para consultar os limites padrões atualmente aplicados às caixas postais:

ie-cli quarantine-defaults list

Caso você precise ampliar a capacidade de armazenamento da quarentena por conta (por exemplo, subindo para 200 MB por caixa) para evitar o comportamento de Fail Open:

ie-cli quarantine-defaults set --storage-capacity 200

Script para monitorar o consumo da quarentena#

Para não depender de checagens manuais, podemos usar um script simples em Bash que consulta o ie-cli accounts list, calcula a porcentagem de uso de cada conta e registra alertas no Syslog quando a ocupação ultrapassa 80%.

Salve o script em /usr/local/bin/ie_quarantine_monitor.sh:

#!/bin/bash
# Monitoramento de espaco da quarentena do Imunify Email

ALERT_PERCENT=80
LOG_DIR="/var/log/imunifyemail"
LOG_FILE="${LOG_DIR}/quarantine_monitor.log"
BINARY="/usr/bin/ie-cli"

if [ ! -d "$LOG_DIR" ]; then
    mkdir -p "$LOG_DIR"
    chmod 750 "$LOG_DIR"
fi

if [ ! -x "$BINARY" ]; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [ERRO] Binario ie-cli nao encontrado ou sem permissao." >> "$LOG_FILE"
    exit 1
fi

$BINARY accounts list | grep -E '^[a-zA-Z0-9]' | while read -r NAME USED LIMIT RELEASE FILT; do
    if [[ "$USED" =~ ^[0-9]+$ ]] && [[ "$LIMIT" =~ ^[0-9]+$ ]] && [ "$LIMIT" -gt 0 ]; then
        PERCENT=$(( USED * 100 / LIMIT ))

        if [ "$PERCENT" -ge "$ALERT_PERCENT" ]; then
            TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
            ALERT_MSG="[ALERTA_QUOTA] Conta: ${NAME} com ${PERCENT}% de ocupacao (${USED} de ${LIMIT} bytes) na quarentena."

            echo "[${TIMESTAMP}] ${ALERT_MSG}" >> "$LOG_FILE"
            logger -p mail.warn -t IMUNIFY_EMAIL_MONITOR "${ALERT_MSG}"
        fi
    fi
done

exit 0

Torne o script executável e configure uma tarefa no Cron para executá-lo a cada 10 minutos:

chmod +x /usr/local/bin/ie_quarantine_monitor.sh
echo "*/10 * * * * root /bin/bash /usr/local/bin/ie_quarantine_monitor.sh >/dev/null 2>&1" > /etc/cron.d/imunify-quarantine-monitor
systemctl restart crond

Acompanhando os daemons em tempo real#

Para validar o processamento de novas mensagens e verificar se os vereditos de quarentena estão sendo aplicados:

# Monitora as decisoes tomadas pelo dec-node
journalctl -u ie-dec-node -f --since "1 hour ago" | grep -iE "score|action|quarantine"

# Monitora as operacoes de escrita do servico de quarentena
journalctl -u ie-quarantine -f --since "1 hour ago"

Rotina preventiva e monitoramento contínuo da quarentena#

Conhecer a separação entre o nó de decisão (ie-dec-node), o gerenciador de arquivos (ie-quarantine) e o motor estatístico (rspamd) evita perder tempo procurando arquivos de texto plano inexistentes em versões recentes do Imunify Email.

Ao manter o serviço em operação contínua:

  1. Acompanhe a ocupação de disco das caixas: lembre-se de que o sistema deixa de quarentenar quando atinge o teto da conta ou os limites definidos em dec-node.yaml.
  2. Utilize o journalctl para depuração rápida: em vez de buscar logs tradicionais em /var/log, os eventos em tempo real estão centralizados nas unidades do Systemd dos daemons.
  3. Mantenha alertas automatizados via Syslog: ao registrar avisos de quota diretamente no registrador do sistema, você consegue capturar contas com acúmulo excessivo antes que os filtros passem a ignorar spams legítimos.

Este artigo foi útil?

Deixe uma reação rápida para apoiar o conteúdo:

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.

0 comentários