Skip to content

Afonso017/unified-system

Repository files navigation

Sistema unificado de microsserviços seguros em Java com Spring e Docker Compose

Unified System é um projeto de microsserviços distribuídos em Java, construído com Spring e orquestrado com Docker Compose. O sistema implementa um gateway de API centralizado, descoberta de serviços (DNS e Diretório), balanceamento de carga, um serviço de distribuição de chaves e um anel P2P.

O foco principal do projeto é aplicar segurança em todos os canais de comunicação, garantindo confidencialidade, integridade e autenticidade para cada interação entre os serviços.

Arquitetura

O sistema é "headless" (sem interface web) e se comunica inteiramente sobre TCP. A arquitetura é definida por dois conceitos principais: um modelo de segurança de duas camadas e um sistema de descoberta de serviços duplo.

1. Modelo de Segurança

Toda a comunicação na rede é criptografada e autenticada. Nenhum serviço confia em outro por padrão. Isso é alcançado usando o módulo common-crypto.

  • Algoritmos:

    • Cifragem: AES-128 (AES/CBC/PKCS5Padding).
    • Autenticidade: HMAC-SHA256.
    • Integridade: CRC32 (para verificação de checksum contra corrupção).
    • Transporte: O payload (EncryptedPayload) é serializado para JSON e depois codificado em Base64.
  • Gerenciamento de Chaves (Duas Camadas):

    1. Chaves de Bootstrap (Pré-Compartilhadas - PSK):
      • Uso: Para serviços de infraestrutura (DNS, Service Directory, P2P).
      • Como: Um par de chaves (AES e HMAC) é gerado uma vez e compartilhado com todos os serviços por variáveis de ambiente (via arquivo .env). Isso resolve o problema de como encontrar o serviço de chaves de forma segura.
    2. Chaves Dinâmicas (Key Distribution Service):
      • Uso: Para serviços de negócio, como o calculator-service.
      • Como: O key-distribution-service gera e armazena chaves sob demanda. O api-gateway e o calculator-service buscam dinamicamente essas chaves no KDS para poderem se comunicar.

2. Descoberta de Serviços (DNS e Diretório)

O sistema utiliza dois serviços de registro para diferentes propósitos:

  • mini-dns-service:

    • Funciona como um DNS real, mapeando um nome de serviço único para um endereço (ex: api-gateway -> api-gateway:8080).
    • É o serviço de bootstrap que permite que todos os outros serviços se encontrem.
    • Também inclui um TcpPushService (na porta 8085) que notifica clientes conectados (ouvintes) sobre novos registros em tempo real.
  • service-directory:

    • Funciona como um diretório de microsserviços para balanceamento de carga no lado do cliente.
    • Ele permite que múltiplas instâncias de um serviço (calculator-1 e calculator-2) sejam registradas sob o mesmo nome (calculator).

Estrutura dos Módulos

O projeto é dividido nos seguintes módulos Maven:

Módulo Descrição
common-crypto Biblioteca central. Contém CryptoUtil (primitivas de AES, HMAC) e Bootstrap (lógica de empacotamento/desempacotamento seguro). Não é um serviço Spring.
mini-dns-service Serviço de DNS seguro. Escuta na porta 8081 para registrar e resolver nomes e na 8085 para transmitir atualizações. Usa chaves Bootstrap.
service-directory Serviço de Diretório seguro para balanceamento de carga. Escuta na porta 8082 para registrar, deletar e descobrir serviços. Usa chaves Bootstrap.
key-distribution-service Serviço de Distribuição de Chaves. Escuta na porta 8083. Seu protocolo (GET_KEYS) é inseguro (texto puro), pois ele é a fonte da verdade e é acessado após o DNS seguro.
api-gateway O ponto único de entrada do sistema. Escuta na porta 8080. É o componente mais complexo, responsável por:
1. Descriptografar requisições do cliente (com chaves Bootstrap).
2. Rotear comandos (DNS, CALCULATE, FIND).
3. Fazer balanceamento de carga no lado do cliente (Round Robin).
4. Criptografar respostas para o cliente (com chaves Bootstrap).
calculator-service Serviço de negócio que realiza cálculos. Duas instâncias (calculator-1, calculator-2) são executadas. Ele se registra tanto no mini-dns (com seu nome único) quanto no service-directory (com o nome "calculator").
p2p-node Implementa um nó em um anel P2P (Overlay). Seis instâncias (P0 a P5) são executadas. Cada nó escuta em sua porta (9000-9005). Ele processa comandos FIND, respondendo se for o dono do arquivo ou encaminhando para seu sucessor.
client Um aplicativo de console Spring para interagir com o api-gateway (Modo 1) ou escutar o mini-dns (Modo 2).

Como Executar

O projeto é totalmente orquestrado pelo Docker Compose.

1. Pré-requisitos

  • Java 21
  • Maven
  • Docker e Docker Compose
  • Linux (opcional, os comandos de exportação de variáveis de ambiente podem variar em outros sistemas operacionais)

2. Gerar Chaves de Bootstrap

Este sistema requer um conjunto de chaves (AES e HMAC) pré-compartilhadas para proteger a infraestrutura de DNS.

Rode a classe KeyGenerator uma vez para gerar as chaves (exemplo):

print da execução do key generator

Depois copie as chaves geradas (DNS_AES_KEY e DNS_HMAC_KEY) para o próximo passo.

3. Criar Arquivo .env

Na raiz do projeto (unified-system/), crie um arquivo chamado .env e cole as chaves geradas.
O Docker e o Spring usarão essas variáveis de ambiente para configurar os serviços e injetar as chaves.

4. Construir o Projeto

Use o Maven para construir todos os módulos e instalá-los no seu repositório local.

  mvn clean install

5. Iniciar os Servidores

Use o Docker Compose para construir e iniciar todos os 12 contêineres de serviço.

  docker compose up --build

Graças ao depends_on e às verificações @Order no Spring, os serviços iniciarão na ordem correta para resolver as dependências de inicialização (race conditions).

6. Executar o Cliente

Para testar o sistema, você pode executar duas instâncias do cliente.

Terminal 1 (ouvinte de DNS):

  # Carregue as chaves de bootstrap no seu terminal
  export $(grep -v '^#' .env | xargs)

  # Execute o JAR do cliente (depois que o maven compilar as classes)
  java -jar client/target/client-1.0-SNAPSHOT.jar

No prompt, selecione o modo 2. O terminal ficará escutando passivamente por atualizações do DNS na porta 8085.

Terminal 2 (cliente interativo):

  # Carregue as chaves (necessário para esta nova sessão)
  export $(grep -v '^#' .env | xargs)

  # Execute o JAR do cliente
  java -jar client/target/client-1.0-SNAPSHOT.jar

No prompt, selecione o modo 1. O terminal estará pronto para enviar comandos.

Protocolo de Comandos do Cliente

O api-gateway aceita os seguintes comandos (em texto puro, o cliente cuida da criptografia):

1. Cálculo (Roteado para calculator-service)

Testa o balanceamento de carga e as chaves dinâmicas.

CALCULATE operação n1 n2

Onde operação pode ser SUM, SUB, MUL ou DIV.
n1 e n2 são números, inteiros ou ponto-flutuantes.

Exemplo: CALCULATE SUM 100 50

2. DNS (Roteado para mini-dns-service)

Testa o registro de DNS e o serviço de push.

DNS REGISTER nome-serviço endereço

Onde nome-serviço é um nome único (ex: servidor1) e endereço é um endereço TCP (ex: 192.168.10.2), ou host:porta (ex: servidor1:8080).

DNS RESOLVE nome-serviço

O serviço retornará o endereço registrado.

3. P2P (Roteado para o Anel P2P via p0)

Testa o roteamento em anel.

FIND arquivoX

Onde arquivoX é o nome do arquivo a ser localizado (ex. arquivo25).
O comando é enviado para o nó P0, que roteia pela rede P2P.
Se o arquivo for encontrado, o nó retornará o endereço do nó que o possui, caso contrário, retornará "NOT_FOUND".

É possível visualizar os logs dos serviços no terminal onde o Docker Compose foi executado para acompanhar o processamento dos comandos.
Se quiser visualizar as mensagens criptografadas entre os serviços, descomente as linhas com System.out.println na classe Bootstrap.

Teste de segurança (cliente malicioso)

Para simular um cliente malicioso, você pode modificar as chaves AES e/ou HMAC no terminal para valores incorretos:

  • Abra um novo terminal.
  • Exporte alguma chave alterando o valor real:
  export DNS_AES_KEY="chave_aes"
  export DNS_HMAC_KEY="chave_hmac"
  • Execute o cliente e depois selecione o modo 1 (interativo):
  java -jar client/target/client-1.0-SNAPSHOT.jar

Envie qualquer comando, o api-gateway tentará processá-lo, mas a verificação falhará e a mensagem será descartada e o cliente exibirá um erro de criptografia.

About

Sistema de microsserviços distribuídos em Java/Spring, orquestrado com Docker Compose, focado na segurança entre os canais de comunicação com criptografia simétrica e hashing.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors