Skip to content

Latest commit

 

History

History
250 lines (163 loc) · 8.6 KB

C2.md

File metadata and controls

250 lines (163 loc) · 8.6 KB

E4: C2 backend server documentation

C2 back-end server, run from ./bin/c2.

Quick start

The following commands are provided for starting a local development environment for the C2 server:

# Start docker containers for required services
docker-compose up -d
# Build the binary
./scripts/build.sh
# Create configuration from provided sample
cp configs/config.yaml.example configs/config.yaml
# Generate self signed certificates
openssl req  -nodes -newkey rsa:2048 -keyout configs/c2-key.pem -x509 -sha256 -days 365 -out configs/c2-cert.pem  -subj "/CN=localhost" -extensions san -config <(echo "[req]"; echo distinguished_name=req; echo "[san]"; echo subjectAltName=IP:127.0.0.1)
# Start the C2 server
./bin/c2

# Test everything is ok from the c2cli by creating a topic:
./bin/c2cli topic create --name test

For more details, keep reading.

Initial setup

A configuration file must be created under configs/config.yaml, and a sample one is provided in configs/config.yaml.sample, which holds a good enough configuration for a local development instance.

The webserver requires certificates in order to start. In development, we can reuse the same self signed certificate for both HTTP and GRPC server, generated from the following OpenSSL command:

openssl req  -nodes -newkey rsa:2048 -keyout configs/c2-key.pem -x509 -sha256 -days 365 -out configs/c2-cert.pem  -subj "/CN=localhost" -extensions san -config <(echo "[req]"; echo distinguished_name=req; echo "[san]"; echo subjectAltName=IP:127.0.0.1)

Database setup

The C2 backend uses relational databases as its datastore. You can use sqlite3 (which is supported for testing/demos) or you can deploy fully using PostgreSQL (supported for production).

In all cases you must set

db-encryption-passphrase: somevalue

This value cannot be empty.

SQLite3

It is sufficient to set only two configuration values:

db-type: sqlite3
db-file: /path/to/e4c2.sqlite

to specify the SQLite3 file.

PostgreSQL

A pre-configured insecure / development PostgreSQL container is provided in the docker-compose, with automatic creation of user / password / schema / db and permissions, matching the default settings provided in the config.yaml.example. For a manual setup, see below.

PostgreSQL setup is a little trickier. You must install postgresql for your platform. On RedHat systems this might look like

yum install postgresql-server
postgresql-setup --initdb

The rationale and details for the postgresql database design are explained in DB.md and will not be repeated here. A working setup schema is provided in schemas/postgres/init.sql. On linux, run:

sudo su - postgres

to switch to the postgresql user and then

psql < /path/to/e4go/schemas/postgres/init.sql

to execute the script (you can optionally run the secure_public.sql too). This will create a database e4, a user e4_c2_test and a matching schema, set everything up correctly etc.

These settings can then appear in your config.yaml:

db-type: postgres
db-username: e4_c2_test
db-password: teserakte4
db-secure-connection: insecure
db-schema: e4_c2_test

You also need to configure your database server correctly for access. First, go to /var/lib/pgsql/data (this path may different for your distribution).

Note on the homebrew install The homebrew install uses trust authentication in pg_hba.conf. You do not need to make any changes to pg_hba.conf as a result - postgresql will accept any username provided it exists and any password without checking it. This is obviously not suitable for production but is fine for development environments.

If you do not want to configure SSL then things are relatively straightforward. You need to edit pg_hba.conf to configure user authentication:

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

This allows network logins using passwords over the network. You can then add

db-secure-connection: insecure

to your configuration file. Connections will be plaintext over port 5432.

If you wish to deploy SSL things are only slightly more involved. You need to obtain three files, server.crt, server.key and optionally ca.crt, which are: the certificate for the server, the private key for the server and an optional certificate authority bundle.

Place all of these in /var/lib/pgsql/data. Set their ownership to your postgres user and permissions to read only, for example

chown postgres:postgres server.key
chmod 0400 server.key

Now edit postgresql.conf, either located in this directory or possibly in /etc and configure these lines:

ssl = on
# ssl_ciphers = ... mozilla recommended cipher list ...
ssl_prefer_server_ciphers = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'ca.crt'

You can add additional ssl configuration as required (curve choices, dh parameters etc) for production environments. In your pg_hba.conf file you must now set:

# IPv4 local connections:
hostssl    all             all             127.0.0.1/32            md5
# IPv6 local connections:
hostssl    all             all             ::1/128                 md5

You will also be required to set hostssl for replication entries if deploying a server with replication (not required for development).

You can restart the server (systemctl restart postgresql) and then try

sudo su - postgres
psql -U e4_c2_test -h 127.0.0.1 -W e4
Password: (type it)

and connect to the database.

If your certificate is self signed, you can set

db-secure-connection: selfsigned

If your certificate is signed by a known certificate authority from the system store, you can instead use:

db-secure-connection: yes

You will also need to set

db-encryption-passphrase: somevalue

If you change, forget or lose this value you will lose access to any key material created in the database (all client keys and topic keys are encrypted).

Running and using C2

This assumes that the binaries have been successfully built using script/build.sh and that the binaries are in bin/.

1. Start the required services

The whole stack can be started from the docker-compose.yml using docker-compose up -d. It will start up:

  • A PostgreSQL server (even if using SQLite3 from configuration)
  • A MQTT broker
  • An ElasticSearch server and a Kibana UI server
  • A Prometheus / Jaeger / OpenCensus Agent services.

Manually run the database service

See setting up the database above. You should verify it is running with the equivalent of systemctl status postgresql and you should attempt to connect with

psql -U e4_c2_test -h 127.0.0.1 -W e4

If you can connect and the postgresql prompt is

e4=>

You are connected through the postgres-supplied client.

If you wish to run the database on boot, on Linux run

systemctl enable postgresql

Manually run an MQTT broker

For example, a local broker on macOS can be installed and run as follows:

brew install mosquitto
mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf

The broker will then run on localhost:1883 by default.

On linux (redhat systems)

yum install mosquitto
systemctl start mosquitto

You can make this run on boot with:

systemctl enable mosquitto

Backend and demo client will by default use localhost:1883.

For a list of public brokers see https://github.com/mqtt/mqtt.github.io/wiki/public_brokers.

2. Run the C2 backend

Run bin/c2, it will list for gRPC connections on port 5555 and HTTP on 8888 by default.

See configs/config.yaml for parameters.

If /var/log/e4_c2.log is writable, the C2 will output its logs there, otherwise stdout/stderr will be used.

APIs

C2 exposes a gRPC endpoint over port 5555 by default, and HTTP over 8888. The complete api definition can be found in the api.proto file. A swagger definition is also generated, and available in doc/api.swagger.json. The swagger file can be visualized with Swagger UI (a preconfigured docker container can be started with ./scripts/swagger-ui.sh, if port 8080 is available, making it easily reachable from a browser on http://localhost:8080)

Monitoring

C2 will subscribe to all the MQTT topics for which it generated a key, and will generate logs for each message received, where a log will include payload, metadata, and enriched data.

We use Docker containers for ElasticSearch, and Kibana applications, available from the docker-compose file, and configured from files in configs/.