Drag
0

Building a Cloud-Agnostic Log Routing Lab with Cribl Stream: Dynamic Unified Forwarding from Splunk and Elastic to Any Cloud or Local SIEM Destination

Portfolio Thumbnail

Overview

This project is a cloud-agnostic log routing lab demonstrating how Security Operations Center (SOC) teams can centralize and control telemetry pipelines using Cribl Stream. It simulates a real-world enterprise environment where logs are ingested from any SIEM platform — including Splunk and Elastic — and dynamically filtered, enriched, and routed to any other SIEM or modern destination such as Splunk Cloud, Elastic Cloud, and New Relic. The lab showcases flexible, bi-directional routing capabilities, allowing seamless log forwarding between local and cloud SIEMs, optimizing log volume, reducing data ingestion costs, and maintaining visibility across hybrid or multi-cloud infrastructures. By highlighting structured routing, transformation logic, and observability integrations, this project demonstrates practical skills in building scalable, efficient, and threat-ready logging architectures tailored to modern security operations.

Objectives

  1. + Provide a hands-on, interactive lab environment to simulate real-world log routing and data pipeline design using Cribl Stream.
  2. + Demonstrate how logs from any SIEM platform — including Splunk and Elastic — can be dynamically routed, filtered, and enriched before being forwarded to multiple destinations such as Splunk Cloud, Elastic Cloud, New Relic, or any other SIEM.
  3. + Teach SOC analysts how to optimize data ingestion, reduce license costs, and maintain visibility across hybrid or multi-cloud environments.
  4. + Showcase practical use cases for log reduction, threat-relevant enrichment, and pipeline efficiency within security operations workflows.
  5. + Develop a self-contained, vendor-neutral lab that reflects enterprise-grade log management challenges and solutions relevant to modern SOC teams.
  6. + Highlight flexible, bi-directional log forwarding capabilities enabling seamless integration and communication between diverse SIEM systems, both local and cloud-based.

Architecture & Setup

  • Windows 11 Host — Simulated endpoint generating security logs using native Windows Event Logs and Sysmon.
  • Elastic Agent — Installed on the Windows host to forward logs from Sysmon and Windows Event Logs to Elasticsearch.
  • Splunk Universal Forwarder — Collects and forwards Windows logs from the host into a local Splunk instance.
  • Cribl Stream — Deployed in a Docker container, receiving logs from Splunk and Elastic, transforming them, and routing them to various destinations.
  • Elastic Cloud & Splunk Cloud — External SIEM platforms used to demonstrate multi-destination log delivery.
  • New Relic — Additional observability platform targeted for log forwarding to test third-party integrations.
  • Docker — Used to containerize and run Cribl Stream for rapid deployment and isolation.

Steps to Set Up Log Routing with Cribl Stream

  1. Install Elastic Agent on Windows Host: Configure it to collect logs from Sysmon and Windows Event Logs and forward to your Elastic Stack.
  2. Set up Splunk Universal Forwarder: Forward Windows logs to a local Splunk Enterprise instance.
  3. Deploy Cribl Stream via Docker:
    docker run -d --name cribl -p 9000:9000 -p 10080:10080 \
      -v /cribl:/opt/cribl cribl/cribl:latest
  4. Configure Cribl Inputs: Set up data sources to receive logs from both Splunk and Elastic (via TCP or HTTP).
  5. Create Pipelines: Add filtering, parsing, enrichment, or transformation logic using Cribl's visual editor.
  6. Configure Destinations: Define outputs to Splunk Cloud, Elastic Cloud, and New Relic using the appropriate credentials and endpoint settings.
  7. Verify and Monitor: Use Cribl’s dashboards and logging tools to monitor flow and troubleshoot issues.

Comprehensive Installation Guide: Docker, Splunk, Elastic Stack & Cribl

Step 1: Install Docker

Docker enables containerization, allowing you to run complex applications like Splunk and Elastic Stack in isolated, reproducible environments. This simplifies deployment, scaling, and maintenance.

For production environments, ensure Docker is installed following best security practices such as limiting root access and enabling TLS for Docker API.

# On Ubuntu/Debian
sudo apt update
sudo apt install -y docker.io docker-compose
sudo systemctl start docker
sudo systemctl enable docker

# Verify Docker installation
docker --version
docker-compose --version

# On Windows or macOS
# Download Docker Desktop from https://www.docker.com/get-started

Step 2: Install Splunk Enterprise with Docker Compose

Splunk Enterprise is a powerful platform for searching, monitoring, and analyzing machine-generated data via a web-style interface. Running Splunk inside Docker containers provides flexibility and isolation, making deployments cleaner and easier to manage.

Security tip: Always set a strong, complex password for the admin account, and consider integrating Splunk with LDAP or SSO for enterprise authentication.

version: '2.4'

volumes:
  opt-splunk-etc: {}
  opt-splunk-var: {}

services:
  splunkenterprise:
    container_name: splunk
    hostname: splunkenterprise
    image: splunk/splunk:latest
    mem_limit: 2G
    environment:
      - SPLUNK_START_ARGS=--accept-license
      - SPLUNK_ENABLE_LISTEN=9997
      - SPLUNK_ADD=tcp 1514
      - SPLUNK_PASSWORD=your_password
    volumes:
      - opt-splunk-etc:/opt/splunk/etc
      - opt-splunk-var:/opt/splunk/var
    ports:
      - "8000:8000"
      - "9997:9997"
      - "8088:8088"
      - "1514:1514"
      - "8089:8089"

Step 3: Explanation for Splunk Docker Compose Setup

  • Persistent Volumes: Volumes opt-splunk-etc and opt-splunk-var persist Splunk configurations and indexed data outside the container lifecycle.
  • Memory Limit: Restricting memory to 2GB ensures stable container operation without overwhelming host resources.
  • Port Exposure: Common ports exposed allow web UI access, receiving data from forwarders, HTTP event collection, and syslog ingestion.
  • Environment Variables: Accepts license and configures admin password to allow automated startup without manual intervention.

This reflects a professional approach to containerized enterprise software deployment, essential for infrastructure and security roles.

Step 4: Install Elastic Stack Using the Elastic Container Repo

Elastic Stack (Elasticsearch, Kibana, Beats, Logstash) is an open-source suite for centralized logging, analytics, and visualization. This containerized setup includes security best practices like TLS encryption, password management, and health checks.

To simplify installation, clone the GitHub repository below which contains the Docker Compose files, certificate generation logic, and setup scripts:

git clone https://github.com/mohamdhajji/elastic-secure-docker.git
cd elastic-secure-docker
cp .env.example .env # then set your passwords and stack version
./install.sh

The setup service handles automated certificate creation and secure password setup for the elastic and kibana_system users before starting the main services.

services:
  setup:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: ecp-elasticsearch-security-setup
    volumes:
      - certs:/usr/share/elasticsearch/config/certs:z
    user: "0"
    command: >
      bash -c '
        if [ x${ELASTIC_PASSWORD} == x ]; then
          echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
          exit 1;
        elif [ x${KIBANA_PASSWORD} == x ]; then
          echo "Set the KIBANA_PASSWORD environment variable in the .env file";
          exit 1;
        fi;
        if [ ! -f certs/ca.zip ]; then
          echo "Creating CA";
          bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
          unzip config/certs/ca.zip -d config/certs;
        fi;
        if [ ! -f certs/certs.zip ]; then
          echo "Creating certs";
          echo -ne           "instances:\n"          "  - name: elasticsearch\n"          "    dns:\n"          "      - ecp-elasticsearch\n"          "      - localhost\n"          "    ip:\n"          "      - 127.0.0.1\n"          "  - name: kibana\n"          "    dns:\n"          "      - ecp-kibana\n"          "      - localhost\n"          "    ip:\n"          "      - 127.0.0.1\n"          "  - name: fleet-server\n"          "    dns:\n"          "      - ecp-fleet-server\n"          "      - localhost\n"          "    ip:\n"          "      - 127.0.0.1\n"          > config/certs/instances.yml;
          bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
          unzip config/certs/certs.zip -d config/certs;
          cat config/certs/elasticsearch/elasticsearch.crt config/certs/ca/ca.crt > config/certs/elasticsearch/elasticsearch.chain.pem
        fi;
        echo "Setting file permissions"
        chown -R root:root config/certs;
        find . -type d -exec chmod 750 {} \;;
        find . -type f -exec chmod 640 {} \;;
        echo "Waiting for Elasticsearch availability";
        until curl -s --cacert config/certs/ca/ca.crt https://ecp-elasticsearch:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
        echo "Setting kibana_system password";
        until curl -s -X POST --cacert config/certs/ca/ca.crt -u elastic:${ELASTIC_PASSWORD} -H "Content-Type: application/json" https://ecp-elasticsearch:9200/_security/user/kibana_system/_password -d "{\"password\":\"\KIBANA_PASSWORD\"}" | grep -q "^{}"; do sleep 10; done;
        echo "All done!";
      '
    healthcheck:
      test: ["CMD-SHELL", "[ -f config/certs/elasticsearch/elasticsearch.crt ]"]
      interval: 1s
      timeout: 5s
      retries: 120

  elasticsearch:
    depends_on:
      setup:
        condition: service_healthy
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    container_name: ecp-elasticsearch
    volumes:
      - certs:/usr/share/elasticsearch/config/certs
      - esdata01:/usr/share/elasticsearch/data
    ports:
      - ${ES_PORT}:9200
    restart: always
    environment:
      - node.name=ecp-elasticsearch
      - cluster.name=${CLUSTER_NAME}
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - bootstrap.memory_lock=true
      - discovery.type=single-node
      - xpack.security.enabled=true
      - xpack.security.http.ssl.enabled=true
      - xpack.security.http.ssl.key=certs/elasticsearch/elasticsearch.key
      - xpack.security.http.ssl.certificate=certs/elasticsearch/elasticsearch.chain.pem
      - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.http.ssl.verification_mode=certificate
      - xpack.security.http.ssl.client_authentication=optional
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.key=certs/elasticsearch/elasticsearch.key
      - xpack.security.transport.ssl.certificate=certs/elasticsearch/elasticsearch.crt
      - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.client_authentication=required

volumes:
  certs:
  esdata01:

Step 5: Install Cribl Stream with Docker Compose

Cribl Stream allows for routing, shaping, and reducing log data before forwarding it to systems like Splunk or Elastic. This helps optimize data ingestion and reduces costs by filtering unnecessary data early.

Using Docker Compose for Cribl provides ease of management and ensures a consistent environment across deployments.

Proficiency in log pipeline optimization and data reduction techniques is a strong asset for security monitoring and big data roles.

version: '3'

services:
  cribl:
    container_name: cribl
    image: cribl/cribl:latest
    ports:
      - "9000:9000"
    volumes:
      - cribl-data:/opt/cribl/var
      - ./cribl.conf:/opt/cribl/conf/cribl.conf
    environment:
      - CRIBL_LICENSE=your_license_key

volumes:
  cribl-data:

Cribl Stream: The Enterprise-Grade Observability Pipeline Platform

Cribl Stream is a powerful and vendor-neutral telemetry pipeline solution designed to empower Security Operations Centers (SOCs), DevOps, and IT teams with real-time control, enrichment, and routing of log and event data, before it reaches your SIEM, analytics, or observability platforms.

Real-time Log Processing

Ingest and transform millions of log events per second on the fly, enabling filtering, parsing, sampling, and enrichment to reduce noise and optimize storage costs.

Dynamic Multi-Destination Routing

Simultaneously route enriched and filtered telemetry streams to multiple destinations — including Splunk Enterprise & Cloud, Elastic Cloud (Fleet-managed), New Relic, and more.

Cloud-Native & Vendor Neutral

Designed for hybrid and multi-cloud architectures with support for containerized deployments, Kubernetes, and a wide range of observability integrations — with zero vendor lock-in.

Why Cribl Stream Is Essential for Modern SOCs

  • Cost Efficiency: Significantly reduce SIEM license and storage costs with pre-ingest filtering, sampling, and route control.
  • Enhanced Data Quality: Enrich raw telemetry with contextual metadata like threat intel, user identity, geo-location, and more — enabling faster and more accurate threat detection.
  • Operational Agility: Centralized pipeline control simplifies complex data routing across hybrid cloud and on-premise environments, avoiding vendor lock-in.
  • Enterprise Scalability: Proven at scale, Cribl reliably processes millions of events per second in large distributed environments.
  • Security & Compliance: Supports encrypted data transport (TLS), granular access control, and audit logging to meet stringent security requirements.

Sending Logs from Splunk to Cribl Stream: Configuration & Flow

This section explains how to forward logs from a Splunk Enterprise instance to Cribl Stream for advanced log routing, filtering, and enrichment. This integration allows Security Operations Centers (SOCs) and IT teams to leverage Cribl’s powerful log pipeline capabilities while preserving existing Splunk infrastructure investments.

Configure Splunk Forwarder to Send Data to Cribl Stream

Use the Splunk Universal Forwarder (recommended for most deployments) or Heavy Forwarder to forward data to Cribl Stream. Configure the forwarder to send data via a TCP or HTTP endpoint where Cribl Stream listens.

# outputs.conf on Splunk Forwarder
[tcpout:cribl_stream]
server = cribl_host_ip:9000

[tcpout-server://cribl_host_ip:9000]
disabled = false

Example: TCP output configuration targeting Cribl Stream on port 9000

Setup Input in Cribl Stream to Receive Splunk Logs

In Cribl Stream’s web UI, create a new input source to accept data from Splunk. Common input types include:

  • TCP Input: Listens on a TCP port for Splunk forwarder traffic.
  • HTTP Event Collector (HEC): Receives logs via HTTP, compatible with Splunk’s HEC.

Configure source parsing and metadata tagging to ensure logs are correctly structured and enriched for downstream analysis.

Pro Tip: Leverage Cribl’s pre-built Splunk sourcetypes parsers for enhanced compatibility and ease of use.

Validate Forwarding & Monitor Log Flow

After configuration, validate that logs are arriving correctly in Cribl Stream by using the Live Tail and Dashboard views. These tools help you:

  • Inspect incoming events in real-time
  • Verify accurate parsing and field extraction
  • Monitor pipeline health and processing latency

Once validated, logs can be enriched, filtered, or routed simultaneously to multiple destinations such as Splunk Cloud, Elastic, or New Relic — all configurable through Cribl’s pipeline.

Configuration Screenshots & Examples

Splunk outputs.conf configuration example
Splunk outputs.conf: Configuring TCP output to Cribl
Cribl Stream input configuration
Cribl Stream Input Setup for Splunk Logs

Forwarding Logs from Elastic Agent to Cribl Stream: Configuration & Best Practices

This section explains how to configure the Elastic Agent to send logs to Cribl Stream using the Outputs feature in Fleet. Integrating Elastic Agent with Cribl enables centralized log processing, flexible routing, and reduces dependency on a single destination — optimizing observability and SOC workflows.

Integration Steps

Configure Elastic Agent Output to Point to Cribl Stream

If you are using Fleet Server, configure the output from the Fleet UI → Agent Policies → Settings → Outputs. Set the output to use TCP or HTTP(s) and direct logs to Cribl Stream’s input endpoint.

Example: TCP output configuration that sends logs to Cribl on port 9000:

outputs:
  default:
    type: tcp
    hosts: ["cribl_host_ip:9000"]
    ssl.enabled: false  # set true if Cribl has TLS configured
📁 Managed via: Fleet → Agent Policies

Note: This output is applied to all agents enrolled under the selected policy.

Create Cribl Input to Receive Elastic Agent Logs

In Cribl Stream, create an input that accepts logs from Elastic Agent. Options include:

  • TCP Input: Listen on a raw TCP port (e.g., 9000) for incoming agent logs.
  • HTTP Input: Use if your Elastic Agent output is configured for HTTP(s).

Ensure the input pipeline includes the right parsing and enrichment functions to normalize Elastic Agent logs.

Note: Verify network routes and firewall rules allow agents to reach Cribl inputs.

Validate Data Flow & Monitor Logs in Cribl Stream

Use Cribl’s Live Tail, dashboards, and metrics to confirm logs are arriving as expected. Check for dropped events, parsing errors, or enrichment failures in the pipeline.

Logs can now be routed from Cribl to multiple destinations like Elasticsearch, Splunk, S3, or Kafka — optimizing your SIEM and observability costs.
This enables flexible pipelines and reduces vendor lock-in.

Configuration Screenshots & Examples

Elastic Agent Outputs Configuration Example
Elastic Agent outputs.yml: Forwarding to Cribl TCP input
Cribl Stream Input Configuration for Elastic Agent
Cribl Input: Listening for Elastic Agent Logs (TCP 9000)

Routing Logs from Cribl Stream to Splunk, Elastic, and New Relic: Output Configuration

After receiving and processing logs from various sources, Cribl Stream enables flexible and vendor-neutral forwarding to multiple destinations, optimizing data ingestion, cost, and visibility. This section details how to configure Cribl’s outputs for Splunk, Elastic, and New Relic.

Configure Cribl Stream Output to Splunk (HTTP Event Collector)

Use Splunk’s HTTP Event Collector (HEC) to forward logs from Cribl Stream. Obtain the HEC token and URL from your Splunk instance, then configure a new output in Cribl:

Output Type: Splunk HEC
HEC Endpoint: https://splunk-cloud-instance:8088/services/collector
Token: <your-splunk-hec-token>
Format: JSON
TLS/SSL: Enabled (Recommended)
Compression: Enabled (Optional)

Ensure your Splunk HEC endpoint is accessible from Cribl and the token has correct permissions.

⚠️ Ensure Cribl has network-level access to the Splunk HEC port and the token has the `ingest` capability.

Configure Cribl Stream Output to Elastic Stack (Elasticsearch)

To send logs to Elastic Stack, configure an Elasticsearch output in Cribl:

Output Type: Elasticsearch
Hosts: ["https://elastic-cloud-instance:9200"]
Index: custom-index-name
Authentication: Basic (Username & Password) or API Key
TLS/SSL: Enabled (Mandatory)

Verify your Elasticsearch cluster allows writes from Cribl’s IP and credentials are correct.

Configure Cribl Stream Output to New Relic Logs

For New Relic, configure a custom HTTP output using New Relic’s Logs API endpoint:

Output Type: HTTP
Endpoint: https://log-api.newrelic.com/log/v1
Headers:
  - Api-Key: <your-new-relic-license-key>
Content-Type: application/json
Method: POST
TLS/SSL: Enabled

Make sure to comply with New Relic’s data format and rate limits for optimal ingestion.

Output Configuration Screenshots & Examples

Cribl Stream Output Configuration to Splunk
Cribl Stream: Splunk HEC Output Setup
Cribl Stream Output Configuration to Elastic
Cribl Stream: Elasticsearch Output Setup
Cribl Stream Output Configuration to New Relic
Cribl Stream: New Relic HTTP Output Setup

Work with me

I would love to hear more about your project