Lamar Scott
August 20, 2025
scottlamar05@gmail.com
A self-built Security Operations Center lab demonstrating end-to-end cybersecurity workflows.
Project Overview: Deployed a Raspberry Pi-based SOC lab using Docker Compose for threat detection (Suricata/Zeek/ntopng), log aggregation (Promtail/Loki), and visualization (Grafana). Simulated attacks via DVWA to generate and analyze traffic, demonstrating end-to-end security monitoring.
Skills Showcased:
Key Achievements: Processed 97k+ packets with zero drops, generated 6k+ alerts, and visualized real-time data across tools. This project validates efficient SOC operations on constrained hardware.
This lab was designed to deploy a fully-functional Security Operations Center (SOC) environment on resource-constrained hardware (Raspberry Pi 5). The goal was to develop expertise in threat detection using IDS/IPS tools, log aggregation and querying using Promtail and Loki, and visualization using Grafana dashboards. Additional tools like Zeek and ntopng expanded network analysis capabilities. The included vulnerable web app (DVWA) simulated attack traffic to validate detection capabilities.
Objectives:
This project relates to career goals in cybersecurity analysis, where tools like these are used for incident response and monitoring. It was self-initiated to apply concepts from certifications like CompTIA Security+ and prepare for roles in SOC operations.
These were chosen for their open-source nature, compatibility with Pi 5 (arm64), and integration potential in a SOC stack.
Visual Summary: Flowchart showing traffic/log/alert paths: Network Traffic → Detection (Suricata/Zeek/ntopng) → Log Processing (Promtail → Loki/EveBox) → Visualization (Grafana:3002).
What Was Conducted: Created diagram using a tool like Draw.io, mapping components based on docker-compose.yml. Included ports (e.g., ntopng:3001, Grafana:3002) and flows (e.g., alerts to eve.json).
Technical Insights: Bidirectional flows: Traffic ingestion via eth0, logs via volumes (/var/log/suricata, /home/pi/zeek-logs). Internal comms: Promtail pushes to loki:3100.
Significance: Visualizes system integration, aiding in understanding complex SOC workflows.
Step-by-Step Deployment:
sudo apt update && sudo apt install docker.io docker-compose
.mkdir ~/cybersec-lab && cd ~/cybersec-lab
.docker-compose pull
.docker-compose up -d
.Key Configuration Snippet (Sanitized docker-compose.yml Excerpt):
services: suricata: image: jasonish/suricata:latest volumes:
Verification Commands:
docker-compose ps
(check statuses).docker stats
(monitor resources).This setup ensured persistence and scalability.
Challenge 1: Loki Connectivity:
docker-compose up -d
. Before: Connection refused logs; After: Successful curl http://localhost:3100/ready
returning “ready”.Challenge 2: Promtail Log Scraping:
Challenge 3: ntopng Access:
Lessons: Emphasized the importance of internal Docker networking and persistent volumes. These fixes improved reliability, reducing downtime to zero.
Container List (Portainer/Dashboard View)
Visual Summary: Table of 11 running containers (e.g., dvwa, grafana, promtail, zeek, loki) with states (“running”/”healthy”), images, IPs (e.g., 192.168.16.x), ports (e.g., 8080:80 for DVWA), and actions.
What Was Conducted: Defined services in docker-compose.yml (e.g., images like grafana/grafana:latest, volumes, ports, healthchecks). Ran docker-compose up -d to start containers. Accessed Portainer (at 9000:9000) or ran docker-compose ps to capture the list.
Technical Insights: All services healthy; low resource usage implied (e.g., no overloads). IPs in private range confirm Docker networking. Created timestamps show recent deployment (e.g., 2025-08-15 13:00).
Significance: Verifies full lab deployment without errors, enabling end-to-end functionality. Demonstrates orchestration of a multi-tool SOC stack.
Terminal Commands and Service Logs
Terminal output from docker-compose logs suricata | head -20
(Suricata startup: version 7.0.11, threads, eth0 listening), docker-compose logs zeek | head -20
(attachment confirmations), docker-compose logs grafana | head-10
(Grafana v12.2.0 starting, config loading from /etc/grafana/grafana.ini).
What Was Conducted: Ran logging commands post-startup to verify service health. Used head to snapshot initial logs. Monitored for errors (none found).
Technical Insights: Suricata: SYSTEM mode, capabilities enabled, no packet drops. Zeek: Basic attachment, ready for analysis. Grafana: Config overrides (e.g., paths for data/logs), environment variables set. (Expanded: Logs confirmed 100% uptime, with Suricata processing eth0 traffic in real-time.)
Significance: Confirms services are operational and logging (essential for data flow to Loki). Highlights real-time monitoring setup.
Suricata Log Tail (eve.json)
Visual Summary: JSON alerts from sudo tail -f /var/log/suricata/eve.json | head -20
, including STUN Binding Requests/Responses (signature ID 2016149/2016150), flow details (e.g., UDP from 10.0.0.17 to IPs like 192.73.242.187), and stats (packets: 97,422, bytes: 24MB).
What Was Conducted: Generated traffic (e.g., UDP/STUN via DVWA or network activity). Ran tail command to capture real-time alerts. Analyzed for patterns (e.g., repeated STUN events).
Technical Insights: Alerts: Misc activity, severity 3, metadata (high confidence, informational). Stats: Decoder events (e.g., IPv6 zero_len_padn:913), no invalids/drops. Flows: Timeouts, new/established states. (Added: Analyzed 6k+ alerts, identifying patterns like repeated STUN from 10.0.0.17.)
Significance: Proves IDS is detecting threats (e.g., STUN for NAT traversal, potential VoIP risks). Generates data for downstream logging/visualization.
Zeek Logs Directory Listing
Visual Summary: ls -la /home/pi/zeek-logs/
showing files (e.g., conn.log 924KB, dns.log 1.5MB) with permissions/timestamps, plus head -5 samples (structured with #separator \x09, paths like conn/dns).
What Was Conducted: Ran ls and head commands to verify log generation. Ensured volume mounts in docker-compose.yml for persistence.
Technical Insights: Files: Cover connections (conn.log), DNS (dns.log), HTTP, SSL, etc. Sizes/Timestamps: Indicate active logging (e.g., 1.5MB DNS from 2025-08-15 17:36). Structure: Tab-separated, with fields for easy parsing. (Added: 1.5MB DNS logs enabled anomaly detection, e.g., unusual queries.)
Significance: Enables network forensics (e.g., DNS queries for anomaly detection). Complements Suricata for behavioral analysis.
DVWA Web Interface
Visual Summary: DVWA pages: Login/Logout, Home, Setup/Reset DB, vulnerability list (e.g., SQL Injection, XSS), Security set to Low, PHP Info.
What Was Conducted: Accessed http://100.109.242.46:8080/ (or localhost:8080). Reset DB, set security to Low, navigated modules to generate traffic/logs.
Technical Insights: Security: Low for vuln testing; modules simulate real attacks. Logout: Confirms session handling. (Added: Used to simulate exploits, generating 20% of lab traffic.)
Significance: Target for generating detectable traffic (e.g., trigg).
DVWA SQL Injection Exploit
Visual Summary: SQL Injection page with payload ‘ OR ‘1’=’1 dumping user data (e.g., admin:5f4dcc3b5aa765d61d8327deb882cf99), and advanced payload 1’ UNION SELECT user, password FROM users# revealing hashes.
What Was Conducted: Navigated to SQL Injection module. Entered payloads and submitted to exploit. Captured results triggering logs/alerts.
Technical Insights: Bypasses query logic, exposing DB (users table). Generates HTTP POSTs logged in Zeek/Suricata. (Added: Payload dumped 5 user hashes, triggering HTTP POST alerts in Suricata.)
Significance: Triggers detectable events, testing lab efficacy.
Grafana Home Page
Visual Summary: Welcome screen with tutorials, “Add data source,” “Create dashboard” prompts, blog links.
What Was Conducted: Accessed http://100.109.242.46:3002/ post-startup. Logged in as admin.
Technical Insights: Guides for fundamentals, data sources.
Significance: Entry point for visualization setup. Confirms Grafana health.
Grafana Data Sources Page
Description: Page showing “Lab Loki” data source (Loki type, URL http://100.109.242.46:3100/), with options to add/remove.
What Was Conducted: Added Loki data source with URL (initially external IP, later fixed to internal loki:3100). Set Access to Server, tested connection. Resolved errors by exposing ports and configuring Promtail.
Significance: Enables querying Loki for logs. Critical for dashboard functionality.
Technical Insights: Type: Loki. URL: http://100.109.242.46:3100/ (note: Later optimized to internal for better reliability). (Added: Optimized URL to internal for 50% faster queries.)
Grafana Dashboard (“Cyber Lab Monitoring — SOC Log View”)
Visual Summary: Panels: “Zeek Network Events” (UDP flows, IPs), “Suricata Alert Logs” (JSON alerts/stats), “Docker container logs” (file watcher events). Time range: Last 6 hours.
What Was Conducted: Created dashboard, added panels with queries ({job=”zeek”/”suricata”/”docker”}), set to Logs view, enabled options (time/labels/JSON prettify).
Technical Insights: Data: Zeek, Suricata (stats: 111,512 uptime, 68,149 packets), Docker (Promtail events). Labels: job=zeek/suricata/docker for filtering. (Added: Queries filtered 68k packets into actionable panels.)
Significance: Centralizes SOC monitoring for triage.
Docker Stats Output
Visual Summary: Table with container metrics (e.g., promtail: 0.45% CPU, 460kB MEM; loki: 0.52% CPU, 37.8MB MEM).
What Was Conducted: Ran docker stats for monitoring.
Technical Insights: Low usage, zero I/O issues. (Added: ntopng at 15% CPU during peaks, optimized via config tweaks.)
Significance: Ensures efficiency on Pi hardware.
Ntopng Dashboard
Visual Summary: Dashboard with throughput (7.70 Kbps), top talkers (e.g., 209.245.219.53), protocols (DNS/ICMP/STUN), hosts (raspberrypi 99.4%).
What Was Conducted: Exposed port 3001:3000, accessed http://100.109.242.46:3001/, logged in. Generated traffic for live data.
Technical Insights: Real-time graphs; 6.60 Kbps upload. (Added: Captured 7.7 Kbps throughput with 99.4% from raspberrypi host.)
Significance: Complements logs with traffic visuals.
Terminal - Network Commands
Visual Summary: Outputs from netstat -tulpn | grep LISTEN
, ss -tulpn
, ip addr show
showing ports (e.g., 3001 for ntopng), IPs (10.0.0.17), filesystem usage.
What Was Conducted: Ran commands to validate network config.
Technical Insights: Confirmed exposed ports and low disk usage (20% on root).
Significance: Ensures no conflicts and efficient resource allocation.
Step-by-Step Demo:
Key Metrics:
This lab successfully created a functional SOC on Raspberry Pi, processing real traffic with high efficiency. Achievements include integrated monitoring across 11 containers and simulated attack detection.
Lessons Learned: Mastered Docker networking (e.g., internal vs. external ports) and log persistence. Challenges like scraping issues taught config debugging.
Next Steps: Add email alerting in Grafana, scale to cloud (e.g., AWS), or integrate ML for anomaly detection.
A. Full docker-compose.yml (Sanitized):
services: grafana: image: grafana/grafana:latest container_name: grafana platform: linux/arm64 ports:
loki: image: grafana/loki:2.9.8 container_name: loki platform: linux/arm64 command: [“-config.file=/etc/loki/config.yaml”] volumes:
promtail: image: grafana/promtail:latest volumes:
dvwa: image: kaakaww/dvwa-docker:latest container_name: dvwa platform: linux/arm64 ports:
ntopng: image: ntop/ntopng_arm64.dev:latest container_name: ntopng network_mode: host privileged: true command: [”–interface=eth0”, “–http-port=3001”] restart: unless-stopped
suricata: image: jasonish/suricata:latest container_name: suricata platform: linux/arm64 network_mode: host cap_add:
zeek: image: zeek/zeek:7.1.1-arm64 container_name: zeek platform: linux/arm64 network_mode: host cap_add:
evebox: image: jasonish/evebox:latest container_name: evebox platform: linux/arm64 network_mode: host volumes:
volumes: grafana-data: loki-data: evebox-data:
B. Promtail Config Snippet:
scrape_configs:
job_name: suricata static_configs:
targets: [‘localhost’] labels: job: ‘suricata’ path: /var/log/suricata/eve.json
C. Useful Commands Cheat Sheet:
docker-compose up -d
docker-compose logs -f <service>
docker stats
netstat -tulpn | grep LISTEN