README.md 3.17 KB

Communications Backbone

Communications Backbone by C2 Team (NOC)

Data flow

  • Client A sends to client-a-outbox (or POSTs to API /send - not yet implemented)
  • Messages are forwarded from client-a-outbox to soar-publish
  • Messages are published from soar-publish with the given topic read from the message
  • Subscribers listen to for messages
  • Subscription is delivered to client-b-inbox
  • Client B reads from `client-b-inbox (or GETs from API /receive)

There is a parallel flow when a client sends to client-a-notify in which case the messages are delivered through the broadcast exchange to all clients client-x-inbox.

Auth placeholder

As a proxy for proper authentication, when you post a client a random secret is returned in the response. To send to / receive from the bus you then call the API with the client_id and secret and it checks they match. The client_id determines which queues it reads from.

Subsequent requests to the client endpoint return the client_id but not the secret.

Testing

Current coverage:

  • API: yes
  • Pika RabbitMQ implementation: no
pytest

Running via docker-compose

Using docker-compose will mean that everything is setup automatically, this includes the rabbitmq container, the backbone API, and the backbone bus. The run-compose.sh script has been provided to simplify this even further - all you have to do is set whatever env vars you need in the .env file and then run ./run-compose.sh (the defaults in .env are fine for local dev work, but ones not labelled optional will need setting in a production setting). The env vars are:

  • DATA_DIR - Where to mount the volume of the API container on your local system. This defaults to the result of pwd, which should be within the communications-backbone repo
  • SOAR_TOKEN_LIFETIME (Optional) - The number of hours until a newly created token expires
  • SOAR_TOKEN_SECRET (Optional) - A secret key used to encrypt/decrypt token data. If specified the value should be set using TokenModel.getKey()

Running manually

Setup

In a virtual environment

pip install -r requirements-dev.txt  

RabbitMQ

docker run --rm -p 5672:5672 -d --hostname rmq --name rmq rabbitmq:management

API

python api.py 

Event bus

python soar_bus.py

Usage

To use the backbone you have to create a client. The client id and name should be unique but human readable. A client secret is returned by the API and client credential grants using this client_id and secret are used to authenticate client application connections.

Create some clients

POST to http://localhost:3000/clients

Send / Receive directly

# Send a message 
python client_send.py noc-c2-outbox 'soar.noc.slocum.something' from noc-c2
# Receive messages  
python client_read.py noc-sfmc-inbox

Receive via API

As a placeholder for proper authentication you post the client_id and secret and it checks that a client with that id exists and that the secret matches before allowing the request.

This should be replaced with a proper auth layer.

GET http://localhost:5000/receive?client_id=[client_id]&secret=[secret]