Páginas filhas
  • DTTALK1-117 - Definir modelo de deploy do API Mirror com Rabbit MQ para acesso externo (TKS)

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

Introdução

Este documento busca mostrar como deve ser feita a separação dos componentes cloud, para que atendam tanto a mensageria de eventos entre microsserviços, quanto subscrição de comandos. 

Tentamos esclarecer algumas das vantagens do modelo proposto.

Essas são algumas das perguntas que levantaram a necessidade desse Spike:

  • Precisaremos ter ao menos dois brokers (Acesso externo permitido e bloqueado)?
  • Sistemas externos podem se subscrever nas nossas mensagens?
  • A multitenância sempre será tratada como Virtual Hosts? Até mesmo em ambientes compartilhados?
  • APIMirror deve possuir um login único para todos os virtual hosts?

Arquitetura Proposta

Existem dois modelos a ser entendidos aqui. Um ocorre quando o cliente opta pelo ambiente exclusivo, e outro compartilhado.

Exclusivo

  • Acesso externo habilitado
  • Existe um VHOST exclusivo para o tenant, e as APIs devem conectar-se nele
  • Não trafega dados de tenant na mensagem, para evitar brechas de segurança, e por não ser um dado relevante nesse cenário
    • É uma brecha de segurança permitir que nosso cliente saiba como estamos tratando nosso ID de cliente, ou em qual ID ele está.
      • Engenharia Reversa
      • Manipulação de mensagem
    • Todas as mensagens dentro de determinado VHOST pertencem ao mesmo tenant, tornando esse dado irrelevante
  • Permite arquitetura orientada a Comandos
  • Permite microsserviços distribuídos de maneira híbrida
  • Permite subscrição de sistemas externos

draw.io Diagram
bordertrue
viewerToolbartrue
fitWindowfalse
diagramNameModeloConvivenciaCommandEventMessageBroker
simpleViewerfalse
width400
diagramWidth1005
revision10

Já tínhamos a premissa de que para a subscrição de eventos o RabbitMQ deveria estar exposto para acesso externo. Entretanto, percebemos que essa mesma também pode existir para um cenário de microsserviços, onde o cliente tenha parte destes rodando na sua infraestrutura, e parte em cloud. 

Levamos em consideração também que pode ser bastante vantajoso para o cliente subscrever suas próprias aplicações nos nossos eventos. 

As conexões externas devem ser realizadas através de AMQPS, que nada mais é do que é o protocolo AMQP através de TLS.

Informações

Essa modelagem também propõe como poderia funcionar o modelo de subscrição dos microsserviços.

A base aqui e a arquitetura de publish/subscribe, em sua maneira mais simples, sem utilizar tópicos ou roteamentos mais complexos. Se existir uma necessidade de negócio para justificar uma complexidade maior, essa deveria passar pelo nosso comitê para um entendimento mais aprofundado.

Cada Exchange representa uma informação de eventos realizados que outros sistemas podem vir a se interessar (não necessariamente de CRUD, pode ser um processo que foi realizado). Cada API tem sua fila própria, para aquele evento, e a mesma é subscrita na Exchange.

O escalonamento pode ser feito por N instâncias da mesma API lendo a mesma fila.

Compartilhado

  • Acesso externo desabilitado, é visível apenas de dentro do cluster. Ambiente mais seguro.
  • Cada API utiliza uma única conexão (compartilham o VHOST "/"), causando menor ônus ao servidor.
    • Cada conexão ao RabbitMQ custa 100kb de memória no server.
    • Pode ser maior que 100kb se TLS estiver habilitado. Nesse ambiente controlado e fechado, pode ser uma vantagem técnica não habilitar o TLS para favorecer a performance e uso de memória.
  • Trafega dados de tenant na mensagem
  • Não permite Arquitetura orientada a Comandos
  • Não permite microsserviços distribuídos de maneira híbrida. Tem que pertencer a um contrato "full cloud".
  • Não permite subscrição de sistemas externos

API Mirror

Na arquitetura proposta acima, o API Mirror só existe dentro do modelo exclusivo, e por isso somente necessita um login (O do VHOST do tenant a qual pertence).

Se existir alguma mudança, e ele precisar ter um acesso no modelo compartilhado, continua sendo ainda apenas a conexão com o VHOST default ("/").
Supondo ainda que precisasse acessar N VHOSTS, aí faria sentido ele ter um login com perfil de administrador, com acesso a todos, que muda sua senha periodicamente.

Segurança

Autenticação e Autorização 

No RabbitMQ, a autenticação é feita com base no usuário e senha de um determinado VHOST que se deseja conectar.

Ele possui dois níveis de autorização, sendo que isso é facilmente configurável através do console de administração. 

Níveis:

  1. VHost (Rejeita conexões de quem não tem a permissão de acesso)
  2. Operações em recursos: Exchanges, Queues, e outras entidades.
    1. Leitura, Escrita, Configuração

Integração com IDPs externos

É possível cadastrar os chamados "Alternative Authentication and Authorisation Backends". Isso é feito através de plugins do Rabbit.

O Plugin rabbitmq-auth-backend-http é o oficial para isso, e ele exige que o server para o qual aponta respeite o padrão especifico de autenticação do Rabbit.

Eles também possuem o plugin rabbitmq-auth-backend-oauth2 para trabalhar com IDPs no padrão Oauth 2.0. Existe uma nota informando que o mesmo ainda está em um estágio experimental, e, no momento de escrita desse documento, existem testes unitários quebrando na master.

Não encontrei plugins específicos para o formato esperado pelo RAC (OpenID).

Customizações nos comportamentos dos plugins exige conhecimento de Erlang.

Detalhes na implementação ou utilização de ambos plugins exigem um estudo/spike mais aprofundado voltado para tal.

Referências

https://www.rabbitmq.com/access-control.html

https://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html

https://www.rabbitmq.com/tutorials/tutorial-three-dotnet.html

https://www.rabbitmq.com/ssl.html

https://www.cloudamqp.com/blog/2017-12-29-part1-rabbitmq-best-practice.html

https://github.com/rabbitmq/rabbitmq-auth-backend-http

https://github.com/rabbitmq/rabbitmq-auth-backend-oauth2

Propriedades de página
Elaboração

 

Apresentação

 

Implementação

 

Issue JIRA

Jira
serverTotvs
columnskey,summary,type,created,updated,due,assignee,reporter,priority,status,resolution
serverId0c783de1-186e-383b-975c-a1acd7d76cb5
keyDTTALK1-117

Índice