Skip to main content
Version: 2.1.0 (latest)

Mata Elang Defense Center

Architecture​

┌──────────────────────────────────────────────────────────────────┐
│ Sensor Host (one or more) │
│ │
│ ┌──────────┐ alerts (JSON) ┌──────────────┐ │
│ │ Snort3 │ ───────────────▶ │ snort-parser │ │
│ │ (NIDS) │ │ (gRPC client)│ │
│ └──────────┘ └──────┬───────┘ │
└────────────────────────────────────────│─────────────────────────┘
│ gRPC / mTLS (port 50051)
┌────────────────────────────────────────│───────────────────────────┐
│ Defense Center Host ▼ │
│ ┌─────────────┐ │
│ │ sensor-api │ │
│ │ (gRPC srvr) │ │
│ └──────┬──────┘ │
│ │ Kafka topic: sensor_events │
│ ┌──────▼──────┐ │
│ │ broker │ (Kafka / KRaft) │
│ └──────┬──────┘ │
│ ┌──────────────┤ │
│ consume │ │ consume │
│ ┌──────────────▼──┐ ┌──────▼───────────────────┐ │
│ │ event-stream- │ │ opensearch-logstash │ │
│ │ aggr │ │ (GeoIP + enrichment) │ │
│ └──────┬──────────┘ └─────────────┬────────────┘ │
│ │ topic: snort_alerts │ │
│ ┌──────▼──────────┐ ┌──────▼──────────┐ │
│ │ (back to broker)│ │ opensearch │ │
│ └─────────────────┘ └──────┬──────────┘ │
│ │ │
│ ┌──────▼──────────┐ │
│ │ opensearch- │ │
│ │ dashboards │ │
│ └─────────────────┘ │
└────────────────────────────────────────────────────────────────────┘

Event Flow​

StageFromToProtocol
Packet captureNetwork interfaceSnort3libpcap
Alert forwardingsnort-parsersensor-apigRPC over mTLS
Raw event ingestionsensor-apiKafka sensor_eventsKafka / SSL
Aggregationevent-stream-aggrKafka snort_alertsKafka / SSL
Storage & enrichmentLogstashOpenSearchHTTPS
VisualizationOpenSearch DashboardsBrowserHTTP (port 5601)

Components​

ServiceImagePortDescription
sensor-apighcr.io/mata-elang-stable/sensor-snort-service50051gRPC server — receives Snort alerts from sensors
brokerconfluentinc/cp-kafka:8.2.09092, 19093Kafka broker in KRaft mode with full mTLS
schema-registryconfluentinc/cp-schema-registry:8.2.08081Avro schema registry over HTTPS
kafka-uiprovectuslabs/kafka-ui9021Web UI for Kafka monitoring
event-stream-aggrghcr.io/mata-elang-stable/event-stream-aggr—Aggregates and transforms sensor events
opensearch-node1opensearchproject/opensearch:39200Single-node OpenSearch with TLS
opensearch-dashboardsopensearchproject/opensearch-dashboards:35601Dashboard and visualization UI
opensearch-logstashopensearchproject/logstash-oss-with-opensearch-output-plugin:8.9.0—Kafka → OpenSearch pipeline with GeoIP enrichment
opensearch-initcurlimages/curl—One-shot init: loads index templates and dashboards

Prerequisites​

✅ Ubuntu 24.04 LTS installed and updated:

sudo apt update && sudo apt -y upgrade

✅ Docker Engine 24.x or later and Docker Compose v2.x or later installed.

🔑 Follow the Docker Official Documentation for your Linux distribution.

⚠️ NOTE: Verify your Docker version with:

docker -v && docker compose version

✅ openssl and keytool (OpenJDK) for TLS certificate generation:

sudo apt install openssl default-jre-headless

✅ TLS certificates already generated. All services communicate over mutual TLS (mTLS). You must complete the Certificate Generation guide before proceeding.

Installing the Defense Center​

Download Installation Media​

▶️ Clone Mata Elang v2 Defense Center from GitHub.

git clone https://github.com/mata-elang-stable/example-docker-deployment.git
cd example-docker-deployment

▶️ Navigate to the Defense Center directory and verify the structure.

cd defense_center && tree --dirsfirst -L 1

🔑 Expected directory structure:

.
├── conf
├── files
├── scripts
├── templates
├── compose.opencti-connector.yml
├── compose.reporting.yml
├── compose.yml
└── readme.md

5 directories, 4 files

Environment Configuration​

▶️ Create a .env file by copying the provided example:

cp .env.example .env

▶️ Edit .env with your values:

nano .env

🔑 The .env file reference:

# ─── Sensor API (gRPC Server) ─────────────────────────────────────────
MES_SERVER_HOST=0.0.0.0
MES_SERVER_PORT=50051
MES_SERVER_KAFKA_BROKERS=broker:19094
MES_SERVER_KAFKA_TOPIC=sensor_events
MES_SERVER_SCHEMA_REGISTRY_URL=https://schema-registry:8081
MES_SERVER_SECURITY_PROTOCOL=SSL
MES_SERVER_MAX_MESSAGE_SIZE=1024

# gRPC server TLS
MES_SERVER_SECURE=true
MES_SERVER_CERTIFICATE=/app/server.crt
MES_SERVER_KEY=/app/server.key

# Kafka mTLS (client certificate)
MES_SERVER_PATH_TO_CA=/app/ca.pem
MES_SERVER_PATH_TO_CLIENT_KEYSTORE=/app/sensor-client.p12
MES_SERVER_CLIENT_KEYSTORE_PASSWORD=SecurePassword@123 # must match ssl.password in config.toml

# ─── OpenSearch ────────────────────────────────────────────────────────
# Minimum 8 characters: uppercase, lowercase, digit, and special character
OPENSEARCH_INITIAL_ADMIN_PASSWORD=SecurePassword@123

# ─── SSL / Kafka Keystores ────────────────────────────────────────────
# Must match ssl.password in config.toml
SSL_PASSWORD=SecurePassword@123

# ─── File Ownership ───────────────────────────────────────────────────
# Set to your host user's UID/GID to avoid permission issues on volumes
HOST_UID=1000
HOST_GID=1000

# ─── Add-on: OpenCTI (optional) ──────────────────────────────────────
# OPENCTI_URL=http://opencti:8080
# OPENCTI_API_KEY=your-opencti-api-key

⚠️ NOTE: SSL_PASSWORD, MES_SERVER_CLIENT_KEYSTORE_PASSWORD, and ssl.password in config.toml must all be the same value.

Installing Defense Center​

▶️ Pull the container images:

docker compose pull

▶️ Start all services:

docker compose up -d

Wait approximately 60–90 seconds for OpenSearch and Kafka to be ready. The opensearch-init container will automatically load index templates and import the pre-built dashboard.

▶️ Check that all containers are running:

docker compose ps

🔑 You should see output similar to:

NAME IMAGE SERVICE STATUS
mataelang-broker-1 confluentinc/cp-kafka:8.2.0 broker Up
mataelang-event-stream-aggr-1 ghcr.io/mata-elang-stable/event-stream-aggr event-stream-aggr Up
mataelang-kafka-ui-1 provectuslabs/kafka-ui kafka-ui Up
mataelang-opensearch-dashboards-1 opensearchproject/opensearch-dashboards:3 opensearch-dashboards Up
mataelang-opensearch-init-1 curlimages/curl opensearch-init Up
mataelang-opensearch-logstash-1 opensearchproject/logstash-oss-with-opensearch-output-plugin:8.9.0 opensearch-logstash Up
mataelang-opensearch-node1-1 opensearchproject/opensearch:3 opensearch-node1 Up
mataelang-schema-registry-1 confluentinc/cp-schema-registry:8.2.0 schema-registry Up
mataelang-sensor-api-1 ghcr.io/mata-elang-stable/sensor-snort-service sensor-api Up

▶️ Watch the init progress and confirm dashboards are imported:

docker compose logs -f opensearch-init
docker compose logs -f opensearch-logstash

Web Interfaces​

After the Defense Center is running, the following UIs are available:

InterfaceURLDefault Credentials
OpenSearch Dashboardshttp://localhost:5601admin / value of OPENSEARCH_INITIAL_ADMIN_PASSWORD
Kafka UIhttp://localhost:9021None (unauthenticated)
Reporting (add-on)http://localhost:8085See Reporting Add-on

🔑 OpenSearch Dashboards ships with a pre-imported dashboard for Mata Elang sensor events. Navigate to Dashboards in the left sidebar to find it.

image

Add-ons​

Add-ons connect to the main mataelang_default Docker network and extend the core platform. The Defense Center must be running before starting any add-on.

Reporting Add-on​

Generates Daily, Monthly, Quarterly, and Yearly PDF reports from sensor event data. Includes an IP geolocation lookup service powered by MaxMind GeoLite2 databases.

Prerequisites​

Download the free GeoLite2 databases from MaxMind (free account required) and place them in defense_center/files/:

cp /path/to/GeoLite2-City.mmdb defense_center/files/GeoLite2-City.mmdb
cp /path/to/GeoLite2-ASN.mmdb defense_center/files/GeoLite2-ASN.mmdb

Deploy​

cd defense_center
docker compose -f compose.reporting.yml up -d

Access the reporting dashboard at http://localhost:8085.

Reporting Stack Services​

ServiceDescription
report-command-serviceConsumes Kafka sensor_events and posts to the report API
report-apiLaravel PHP application — report generation engine
report-api-webNginx — serves the report web UI on port 8085
iplookup-apiREST API for GeoLite2 IP lookups (city + ASN)
postgresqlPostgreSQL 17 — stores report data and sessions
redisValkey (Redis-compatible) — session and queue backend
chromiumHeadless Chromium — renders PDF reports

OpenCTI Integration Add-on​

Correlates Mata Elang sensor events with threat intelligence data from an OpenCTI instance.

Prerequisites​

Deploy an OpenCTI instance separately, then configure the connection in defense_center/.env:

OPENCTI_URL=http://your-opencti-host:8080
OPENCTI_API_KEY=your-opencti-api-token

Deploy​

cd defense_center
docker compose -f compose.opencti-connector.yml up -d

OpenCTI Stack Services​

ServiceDescription
opencti-connector-aggregatorConsumes sensor_events from Kafka and publishes to opencti_events
opencti-connector-parserReads opencti_events and pushes indicators to OpenCTI

Troubleshooting​

Certificates not found at startup​

Ensure ./generate.sh completed successfully and ssl_certs/ is populated before running docker compose up -d. The Defense Center mounts certificates from ../ssl_certs/ relative to its directory.

OpenSearch fails to start​

OpenSearch requires a strong initial admin password (uppercase, lowercase, digit, and special character):

OPENSEARCH_INITIAL_ADMIN_PASSWORD=MyStr0ng!Pass

Check logs:

docker compose logs opensearch-node1

Logstash cannot connect to Kafka​

Kafka uses mTLS — verify that the JKS truststore and keystore files exist and that SSL_PASSWORD in .env matches the password used during certificate generation:

ls -la ssl_certs/truststore/
ls -la ssl_certs/logstash/
docker compose logs opensearch-logstash

Regenerate expired or incorrect certificates​

./generate.sh --force
cd defense_center && docker compose restart

View real-time logs for any service​

docker compose logs -f <service-name>
# e.g.:
docker compose logs -f opensearch-logstash
docker compose logs -f event-stream-aggr
docker compose logs -f sensor-api