Roteamento HTTP
Para o funcionamento do sistema, é necessário que haja um servidor configurado. No caso, o servidor escolhido foi o Spark, que permite configurar rotas rapidamente. Porém, os agentes podem ser acoplados a qualquer tipo de servidor que forneça roteamento HTTP.
Como é feito o acoplamento entre servidor e agente
Na classe RequestRouter
, localizada no pacote core
, existem alguns atributos e métodos cruciais para a integração com os agentes do sistema:
MonitorGateway monitor
: permite que as requisições possam ser enviadas ao monitor por meio de uma interface.blockedIps
: guarda os IPs bloqueados previamente pelo sistema.ExecutorService executor
: permite fixar o número de threads, limitando a concorrência e tornando o servidor mais estável.- Método
public static void registerMonitor(MonitorGateway m)
: permite registrar um agente monitorm
aoMonitorGateway
. Esse método é chamado nosetup
doMonitorAgent
. - Método
public static void blockIp(String ip)
: adiciona o IP bloqueado aoblockedIps
. Esse método é chamado peloMitigatorAgent
.
Como configurar rotas no sistema
A configuração das rotas se torna uma tarefa muito fácil quando usamos o Spark. Precisamos apenas configurar o tipo do método HTTP (GET
, POST
, DELETE
, PUT
) e a rota que deseja criar. Dentro da rota, é crucial que haja o seguinte bloco de código:
post("/", (req, res) -> {
String ip = req.ip();
if (blockedIps.contains(ip)) {
res.status(403);
return "Blocked"; // Ou outro retorno, pode ser uma página HTML
}
if (monitor != null) {
final String ipCopy = ip;
executor.submit(() -> {
try {
monitor.receiveRequest(ipCopy);
} catch (Exception e) {
System.err.println("[ROUTER] Erro ao enviar IP ao monitor: " + e.getMessage());
}
});
}
// Insira a lógica do endpoint aqui
});
Com isso, podemos acoplar o sistema a qualquer rota HTTP de um servidor.
Fluxo de Dados e Armazenamento
O sistema utiliza duas principais estruturas para armazenamento e gerenciamento de dados:
1. Node
(pacote core
)
A classe Node
atua como um ponto de coleta e armazenamento de requisições por IP. Ela mantém um ConcurrentHashMap<String, List<RequestRecord>>
chamado ipRequests
, que armazena listas de requisições (RequestRecord
) associadas a cada IP. Essa estrutura permite que os agentes monitorem e analisem o comportamento de cada IP individualmente.
2. DataStore
(pacote core
)
A classe DataStore
serve como um repositório centralizado para os dados coletados pelos agentes. Ela também utiliza um ConcurrentHashMap<String, List<RequestRecord>>
para armazenar as requisições, permitindo uma visão geral do tráfego na rede. Além disso, o DataStore
fornece métodos para acessar e manipular esses dados, facilitando a análise e a geração de relatórios.
3. LogStore
(pacote core
)
A classe LogStore
é responsável por armazenar os logs gerados pelos agentes. Ela utiliza uma lista sincronizada para armazenar mensagens de log, permitindo que o sistema mantenha um histórico das ações e eventos ocorridos durante a execução.
4. RequestRecord
(pacote core
)
A classe RequestRecord
representa uma requisição individual feita por um IP. Ela armazena informações como o IP de origem e o timestamp da requisição, permitindo que os agentes analisem padrões de comportamento e detectem possíveis ataques.
Integração com a API de Monitoramento
A classe MonitoringAPI
, localizada no pacote infra
, fornece endpoints HTTP para acessar os dados armazenados no sistema. Ela permite que usuários e administradores consultem informações como:
- Lista de IPs bloqueados.
- Requisições feitas por cada IP.
- Logs gerados pelos agentes.
Esses endpoints são úteis para monitorar o estado atual da rede e tomar decisões informadas sobre ações de mitigação.