README.md 3.17 KB
Newer Older
Trishna Saeharaseelan's avatar
Trishna Saeharaseelan committed
1 2
# Communications Backbone

3 4 5 6 7 8 9 10 11 12 13 14 15 16
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`.

17 18 19 20 21 22 23 24 25
### 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.

26 27 28 29 30 31 32 33 34 35 36
### Testing 

Current coverage: 

- API: yes 
- Pika RabbitMQ implementation: no

```
pytest
```

37 38 39 40 41 42 43 44 45 46 47
### 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 
48

49 50
In a virtual environment

51
```
52
pip install -r requirements-dev.txt  
53 54 55 56 57 58 59 60 61
```

#### RabbitMQ 

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

#### API 

```
62
python api.py 
63 64 65 66 67
```

#### Event bus 

``` 
68
python soar_bus.py
69 70
```

71 72 73 74 75 76 77 78 79 80 81 82 83
### 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` 

84 85 86 87
#### Send / Receive directly 

```
# Send a message 
88
python client_send.py noc-c2-outbox 'soar.noc.slocum.something' from noc-c2
89 90 91 92
```

```
# Receive messages  
93
python client_read.py noc-sfmc-inbox
94 95 96 97 98 99 100 101 102 103 104
```

#### 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]`