PROJECTAdvanced

Network Traffic Analysis with Zeek and Suricata

Deploy a network monitoring stack combining Zeek for protocol analysis and Suricata for intrusion detection, with ELK integration for visualization and...

Dylan H.

Security Engineer

February 3, 2026
6 min read
6-8 hours
Network Traffic Analysis with Zeek and Suricata

Tools & Technologies

ZeekSuricataElasticsearchKibanaDocker

Introduction

Understanding what's happening on your network is fundamental to security. This project deploys two complementary tools — Zeek for deep protocol analysis and metadata extraction, and Suricata for signature-based intrusion detection — feeding into an ELK stack for visualization and hunting.

What You'll Build

  • Zeek network analyzer generating rich connection logs
  • Suricata IDS with ET Open and custom rulesets
  • Elasticsearch + Kibana for log storage and visualization
  • Pre-built dashboards for security monitoring
  • Automated alerting on suspicious activity
  • Pcap replay capability for training and testing

Who This Is For

  • SOC analysts building detection capabilities
  • Network engineers adding security visibility
  • Security engineers deploying IDS/NSM
  • Homelab enthusiasts learning network forensics

Time to complete: 6-8 hours


Prerequisites

Hardware Requirements

ComponentMinimumRecommended
RAM8 GB16 GB
CPU4 cores8 cores
Storage100 GB500 GB SSD
NetworkMonitoring port/tapSPAN port or network TAP

Software Requirements

  • Ubuntu 22.04 LTS (or similar)
  • Docker and Docker Compose
  • Network interface in promiscuous mode

Architecture Overview

                    Network Traffic
                         │
                    ┌────▼────┐
                    │ Network │
                    │  TAP /  │
                    │  SPAN   │
                    └────┬────┘
                         │
              ┌──────────┴──────────┐
              │                     │
         ┌────▼────┐          ┌────▼────┐
         │  Zeek   │          │Suricata │
         │Protocol │          │  IDS    │
         │Analysis │          │Signatures│
         └────┬────┘          └────┬────┘
              │                     │
              │  JSON Logs          │  EVE JSON
              │                     │
         ┌────▼─────────────────────▼────┐
         │        Filebeat               │
         │     (Log Shipper)             │
         └──────────┬────────────────────┘
                    │
              ┌─────▼─────┐
              │Elasticsearch│
              │  (Storage)  │
              └─────┬──────┘
                    │
              ┌─────▼─────┐
              │  Kibana    │
              │(Dashboards)│
              └────────────┘

Part 1: Deploy ELK Stack

Docker Compose Configuration

# docker-compose.yml
version: '3.8'
 
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
    volumes:
      - es-data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - monitoring
 
  kibana:
    image: docker.elastic.co/kibana/kibana:8.12.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    networks:
      - monitoring
 
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.12.0
    container_name: filebeat
    user: root
    volumes:
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/log/zeek:/var/log/zeek:ro
      - /var/log/suricata:/var/log/suricata:ro
    depends_on:
      - elasticsearch
    networks:
      - monitoring
 
volumes:
  es-data:
 
networks:
  monitoring:
    driver: bridge

Filebeat Configuration

# filebeat.yml
filebeat.inputs:
  # Zeek logs
  - type: log
    enabled: true
    paths:
      - /var/log/zeek/current/*.log
    json.keys_under_root: true
    json.add_error_key: true
    fields:
      source: zeek
    fields_under_root: true
 
  # Suricata EVE JSON
  - type: log
    enabled: true
    paths:
      - /var/log/suricata/eve.json
    json.keys_under_root: true
    json.add_error_key: true
    fields:
      source: suricata
    fields_under_root: true
 
output.elasticsearch:
  hosts: ["elasticsearch:9200"]
  indices:
    - index: "zeek-%{+yyyy.MM.dd}"
      when.equals:
        source: zeek
    - index: "suricata-%{+yyyy.MM.dd}"
      when.equals:
        source: suricata
 
setup.kibana:
  host: "kibana:5601"
# Start the stack
docker compose up -d
 
# Verify Elasticsearch is running
curl -s http://localhost:9200/_cluster/health | jq

Part 2: Install and Configure Zeek

Install Zeek

# Add Zeek repository
echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' | \
    sudo tee /etc/apt/sources.list.d/zeek.list
wget -qO - https://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/Release.key | \
    sudo apt-key add -
 
sudo apt update && sudo apt install -y zeek
 
# Add Zeek to PATH
echo 'export PATH=/opt/zeek/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Configure Zeek

# Edit node configuration
sudo nano /opt/zeek/etc/node.cfg
# /opt/zeek/etc/node.cfg
[zeek]
type=standalone
host=localhost
interface=eth0    # Change to your monitoring interface
# Configure JSON output for ELK integration
sudo nano /opt/zeek/share/zeek/site/local.zeek

Add to local.zeek:

# JSON logging for ELK integration
@load policy/tuning/json-logs

# Additional protocol analyzers
@load policy/protocols/ssl/validate-certs
@load policy/protocols/ssl/log-hostcerts-only
@load policy/protocols/http/detect-sqli
@load policy/protocols/dns/detect-external-names
@load policy/frameworks/notice/community-id

# File extraction
@load policy/frameworks/files/hash-all-files

# Detect traceroute
@load policy/misc/detect-traceroute

Start Zeek

# Deploy Zeek
sudo zeekctl deploy
 
# Check status
sudo zeekctl status
 
# Verify logs are being generated
ls -la /opt/zeek/logs/current/

Key Zeek Log Files

Log FileContents
conn.logAll network connections (source of truth)
dns.logDNS queries and responses
http.logHTTP requests and responses
ssl.logTLS/SSL handshakes and certificates
files.logFiles transferred over network
notice.logZeek-generated alerts
weird.logUnusual protocol behavior
x509.logCertificate details
smtp.logEmail transactions
ssh.logSSH connections

Part 3: Install and Configure Suricata

Install Suricata

sudo apt install -y software-properties-common
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update && sudo apt install -y suricata

Configure Suricata

sudo nano /etc/suricata/suricata.yaml

Key settings to modify:

# Network variables
vars:
  address-groups:
    HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
    EXTERNAL_NET: "!$HOME_NET"
 
# Interface configuration
af-packet:
  - interface: eth0  # Your monitoring interface
    cluster-id: 99
    defrag: yes
 
# EVE JSON output (for ELK)
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: /var/log/suricata/eve.json
      types:
        - alert
        - http
        - dns
        - tls
        - files
        - flow
        - stats

Update Rule Sets

# Update Emerging Threats Open rules
sudo suricata-update
 
# Enable additional rule sources
sudo suricata-update enable-source et/open
sudo suricata-update enable-source oisf/trafficid
 
# Update and restart
sudo suricata-update
sudo systemctl restart suricata

Start Suricata

# Start Suricata
sudo systemctl enable suricata
sudo systemctl start suricata
 
# Verify it's running
sudo systemctl status suricata
 
# Check for alerts
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'

Part 4: Testing the Stack

Replay Pcap Files

# Download sample pcap files for testing
wget https://www.malware-traffic-analysis.net/training-exercises.html
# Or use Zeek's sample pcaps
 
# Replay through Zeek
zeek -r sample.pcap local
 
# Replay through Suricata
suricata -r sample.pcap -l /var/log/suricata/
 
# Test with EICAR (safe malware test)
curl -o /dev/null http://www.eicar.org/download/eicar.com

Verify Data in Kibana

  1. Open Kibana at http://localhost:5601
  2. Create index patterns: zeek-* and suricata-*
  3. Verify data appears in Discover

Part 5: Threat Hunting Queries

Kibana KQL Examples

# Find DNS queries to suspicious TLDs
source: zeek AND type: "dns" AND query: (*.tk OR *.ml OR *.ga OR *.cf)

# Find large data transfers (potential exfiltration)
source: zeek AND type: "conn" AND orig_bytes: > 100000000

# Find Suricata alerts by severity
source: suricata AND event_type: "alert" AND alert.severity: 1

# Find beaconing behavior (regular interval connections)
source: zeek AND type: "conn" AND id.resp_p: (443 OR 80)

# Find connections to known-bad ports
source: zeek AND type: "conn" AND id.resp_p: (4444 OR 1337 OR 31337 OR 8888)

Security Considerations

  • Run Zeek and Suricata on a dedicated monitoring interface (not the management interface)
  • Use a network TAP for production deployments (SPAN ports can drop packets under load)
  • Encrypt Elasticsearch communications in production
  • Restrict Kibana access to authorized security personnel
  • Ensure adequate storage — network logs grow fast (plan 5-20 GB/day depending on traffic)

References