A Homelab Project to Implementing the Elastic Stack SIEM


Part 1: Foundational Concepts - From Log Management to SIEM

This section establishes the foundational knowledge required for the project, defining the core technologies and setting clear expectations. It outlines the transition from simple log collection to creating a powerful, DIY Security Information and Event Management (SIEM) system.

1.1 The Modern Homelab as a Micro-Enterprise

A modern homelab, with its diverse collection of services—firewalls like OPNsense, hypervisors such as Proxmox VE hosting various virtual machines (VMs) and Linux containers (LXCs), and network-attached storage (NAS)—mirrors the complexity of a small enterprise network. This complexity presents a significant challenge for security visibility. Events happening on the firewall, a Windows VM, and a Linux container are isolated data points. Without a centralized system, correlating these events to identify a coordinated attack is nearly impossible. This project aims to build that centralized system, a “single pane of glass” that provides comprehensive oversight and transforms disparate log entries into a cohesive security narrative.1

1.2 Understanding SIEM: Core Principles

Security Information and Event Management (SIEM) is a foundational concept in cybersecurity operations. A SIEM system’s primary purpose is to aggregate log data from a multitude of sources across an IT infrastructure, normalize this data into a common format, and analyze it to detect security threats and anomalous behavior. The core functions of a SIEM include log aggregation, data normalization, event correlation, alerting, and reporting.2 The ultimate value of a SIEM lies in its ability to convert vast quantities of raw, often cryptic, log data into structured, actionable security intelligence that can be used for threat detection, incident response, and forensic analysis.4

1.3 The Elastic Stack as a SIEM Toolkit

The Elastic Stack, which evolved from the original “ELK Stack,” is a powerful, open-source platform for search, analysis, and visualization of data.4 It provides the essential components needed to build a custom SIEM solution.

  • Elasticsearch: At the heart of the stack, Elasticsearch is a distributed, RESTful search and analytics engine. It is a NoSQL, document-oriented database that stores data in flexible JSON format. Its core strength, built on Apache Lucene, is its proficiency in full-text search and real-time analytics, allowing it to query massive datasets with near-instantaneous results.1

  • Logstash: This component serves as the data processing pipeline. Logstash ingests data from a wide variety of sources, processes it through a series of filters, and sends it to a destination, or “stash,” like Elasticsearch. The filter stage is where the critical work of parsing unstructured log data, enriching it with additional context (like geographic information), and transforming it into a structured format occurs.1

  • Kibana: As the visualization layer, Kibana provides a web-based user interface to explore the data stored in Elasticsearch. Users can perform ad-hoc queries, create powerful visualizations like charts and maps, and assemble them into comprehensive dashboards for monitoring and analysis.1

  • Beats: These are a family of lightweight, single-purpose data shippers that are installed on endpoint systems to collect and forward data. For this project, the most relevant Beats are:

    • Filebeat: Collects and forwards log files from Linux systems.7

    • Winlogbeat: Gathers event logs from Windows systems.7

    • Auditbeat: Collects Linux audit framework data and monitors file integrity, capturing security-relevant events.7

It is critical to understand that the open-source Elastic Stack is not a SIEM out-of-the-box. Instead, it is a powerful toolkit for building a Do-It-Yourself (DIY) SIEM.2 The base installation lacks the pre-configured correlation rules, security-specific dashboards, and automated incident response workflows found in commercial SIEM products. The responsibility for building these capabilities—parsing logs, creating correlation rules for alerting, and managing long-term data archiving—falls to the user.2 This project’s value, therefore, lies not merely in installing the software, but in mastering the data engineering pipeline required to transform it into an effective security tool.

1.4 Architectural Blueprint for Your Homelab SIEM

The data flow for this homelab SIEM will follow a logical and scalable pattern, demonstrating the synergy between the Elastic Stack components.1

  1. Sources: Log and event data will be generated by the key components of the homelab: the OPNsense firewall, the Proxmox VE host, Windows VMs, Linux Containers, and the Raspberry Pi-based NAS.

  2. Collection: Data will be collected using two primary methods. OPNsense, Proxmox, and the NAS will forward their system logs via the standard syslog protocol. The Windows VMs and Linux Containers will use dedicated Beats agents (Winlogbeat and Filebeat) for more structured and reliable log shipping.

  3. Processing: A central Logstash instance will act as the ingestion and processing hub. It will receive all syslog and Beats data. Here, logs will be parsed from their native formats, normalized into a common schema, and enriched with additional data, such as GeoIP information for public IP addresses.

  4. Storage & Search: The processed, structured data will be sent from Logstash to a single-node Elasticsearch cluster for indexing and storage. This indexed data becomes immediately available for high-speed searching and analysis.

  5. Visualization & Alerting: Kibana will serve as the primary interface to the system, providing the tools to query the Elasticsearch data, build security dashboards, and configure alerting rules to proactively identify threats.

This architecture provides a robust foundation for a homelab security operations center (SOC), centralizing visibility and enabling powerful analytical capabilities.


Part 2: Deployment Strategy and Planning

Before deploying the stack, several critical decisions regarding hosting, resource allocation, and network configuration must be made. These choices will significantly impact the performance, stability, and usability of the SIEM.

2.1 Hosting the Stack: VM vs. LXC Container on Proxmox

Proxmox VE offers two primary virtualization technologies: full Virtual Machines (VMs) and lightweight Linux Containers (LXCs). While LXCs are resource-efficient and fast, a VM is the recommended platform for hosting the Elastic Stack in this context.9

  • LXC Containers are lightweight as they share the host system’s kernel, resulting in lower CPU and RAM overhead and faster startup times.9 However, this “leaky abstraction” can lead to compatibility issues and difficult-to-troubleshoot errors with complex, stateful applications like the Elastic Stack.10 Furthermore, running containerization platforms like Docker within an LXC can introduce additional layers of complexity and potential instability.11

  • Virtual Machines provide full hardware virtualization and strong kernel-level isolation. A VM behaves like a dedicated physical server, offering a stable and predictable environment that is ideal for resource-intensive Java applications like Elasticsearch and Logstash.10 This isolation protects the Proxmox host and other guests from potential issues within the SIEM environment.

The definitive recommendation is a hybrid approach: Deploy the Elastic Stack within a dedicated Linux Virtual Machine on Proxmox. Inside this VM, use Docker and Docker Compose to manage the individual stack components. This strategy combines the robust isolation of a VM with the declarative, reproducible, and easy-to-manage nature of a containerized deployment, representing a modern best practice for complex applications.13

2.2 Resource Allocation for Your SIEM VM

The Elastic Stack can be resource-intensive, but for a homelab environment, it is practical to start with a modest allocation and scale up as needed.1 Performance for Elasticsearch is less about raw CPU cores and more about sufficient RAM and fast disk I/O. The Java Virtual Machine (JVM) heap size for Elasticsearch is a critical tuning parameter; a common rule of thumb is to allocate no more than 50% of the VM’s total RAM to the heap, leaving the rest for the operating system’s filesystem cache, which is crucial for search performance.4

It is also highly recommended to disable swap space on the VM. Elasticsearch’s performance degrades severely if the OS begins swapping memory to disk, so it is preferable for the application to fail than to run in a critically slowed state.15

TiervCPUsRAMStorageNotes
Basic (Start Here)24-8 GB100 GBAllocate 2-4 GB of RAM to the Elasticsearch JVM heap. SSD storage is strongly recommended.
Recommended416 GB250 GBAllocate 8 GB of RAM to the Elasticsearch JVM heap. Ideal for moderate log volume and more complex dashboards.
Advanced832 GB500+ GBAllocate 16 GB of RAM to the Elasticsearch JVM heap. Suitable for high log volumes or advanced machine learning features.

2.3 Network and Firewall Configuration

The ELK VM requires a static IP address on the local network to ensure that log shippers and the user interface can reliably connect to it. The following firewall rules should be configured in OPNsense to allow the necessary traffic.

ServicePortProtocolSourceDestinationPurpose
Kibana UI5601TCPManagement LANELK VM IPAccessing the Kibana web interface.
Logstash Beats Input5044TCPAll Internal NetworksELK VM IPReceiving logs from Filebeat/Winlogbeat agents.
Logstash Syslog Input5140UDPAll Internal NetworksELK VM IPReceiving syslog messages from OPNsense, Proxmox, etc.

Part 3: Core Infrastructure Build-Out

This section provides the hands-on instructions for deploying the foundational SIEM infrastructure using Proxmox and Docker Compose. This method provides a declarative, version-controlled setup that is vastly superior to manual installation for its reliability and reproducibility.

3.1 Step 1: Provisioning the Proxmox VM

  1. Create the VM: In the Proxmox web UI, create a new virtual machine. Use an Ubuntu Server 22.04 LTS or Debian 12 ISO for the installation.

  2. Allocate Resources: Configure the VM’s resources according to the “Basic” tier in the table above (2 vCPUs, 8 GB RAM, 100 GB disk on SSD-backed storage).

  3. Install OS: Complete the operating system installation. During setup, create a standard user and enable the OpenSSH server for remote access.

  4. Post-Installation:

    • Log in to the new VM via SSH.

    • Configure a static IP address by editing /etc/netplan/00-installer-config.yaml (for Ubuntu) or /etc/network/interfaces (for Debian).

    • Update the system: sudo apt update && sudo apt upgrade -y.

    • Install necessary packages: sudo apt install -y curl git docker.io docker-compose-plugin.

3.2 Step 2: Deploying the Elastic Stack with Docker Compose

Using Docker Compose allows the entire stack—its configuration, networking, and data persistence—to be defined in a single file, embodying the “Infrastructure as Code” principle.13

  1. Create Project Directory: On the ELK VM, create a directory for the project: mkdir ~/elk-siem && cd ~/elk-siem.

  2. Create docker-compose.yml: Create a new file named docker-compose.yml and add the following content. This configuration defines the three core services, creates a dedicated network for them to communicate, and establishes persistent volumes to ensure data is not lost when containers are restarted.

    YAML

    version: '3.8'
    
    services:
      elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:8.11.1 # Use a specific version
        container_name: elasticsearch
        environment:
          - discovery.type=single-node
          - ES_JAVA_OPTS=-Xms4g -Xmx4g # Allocate 4GB heap RAM
          - xpack.security.enabled=false # Disable security for simplicity in homelab
          - xpack.license.self_generated.type=basic # Use the free basic license
        volumes:
          - esdata:/usr/share/elasticsearch/data
        ports:
          - "9200:9200"
        networks:
          - elastic
    
      logstash:
        image: docker.elastic.co/logstash/logstash:8.11.1
        container_name: logstash
        volumes:
          -./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
          -./logstash/pipeline:/usr/share/logstash/pipeline
        ports:
          - "5044:5044/tcp" # Beats input
          - "5140:5140/udp" # Syslog input
        depends_on:
          - elasticsearch
        networks:
          - elastic
    
      kibana:
        image: docker.elastic.co/kibana/kibana:8.11.1
        container_name: kibana
        environment:
          - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
        ports:
          - "5601:5601"
        depends_on:
          - elasticsearch
        networks:
          - elastic
    
    volumes:
      esdata:
        driver: local
    
    networks:
      elastic:
        driver: bridge
    
  3. Create Logstash Directories: Create the local directories that will be mounted into the Logstash container: mkdir -p logstash/config logstash/pipeline.

  4. Create logstash.yml: Create a basic logstash.yml file in logstash/config/ to enable configuration reloading:

    YAML

    http.host: "0.0.0.0"
    config.reload.automatic: true
    
  5. Launch the Stack: From the ~/elk-siem directory, run the command: docker compose up -d. This will download the images and start the containers in the background.

3.3 Step 3: Initial Stack Configuration and Verification

With the containers running, the final step is to verify that all components are communicating correctly.

  1. Check Container Status: Run docker ps to ensure all three containers (elasticsearch, logstash, kibana) are running.

  2. Access Kibana: Open a web browser and navigate to http://<ELK_VM_IP>:5601. The Kibana UI should load.

  3. Verify Elasticsearch Health: In the Kibana UI, go to the main menu (hamburger icon) and select Dev Tools. In the console, execute the command GET /_cluster/health. The response should show a status of “green” or “yellow,” confirming that Kibana is successfully communicating with Elasticsearch.

  4. Version Consistency: The docker-compose.yml file enforces that all components use the same version (e.g., 8.11.1), which is a critical requirement for a stable stack.5


Part 4: Data Ingestion and Parsing - The Heart of the SIEM

This section details the configuration of data shippers on each source system and the creation of Logstash pipelines to parse and structure the incoming data. The parsing of unstructured logs, particularly from the firewall, is the most crucial step in transforming raw data into a queryable security asset.

4.1 Configuring OPNsense Firewall

OPNsense firewall logs are sent via syslog as unstructured, comma-separated text. A Logstash pipeline is required to parse this text into meaningful fields.

  1. Configure OPNsense Syslog Forwarding:

    • In the OPNsense web interface, navigate to System > Settings > Logging / targets.16

    • Click the + icon to add a new target.

    • Enable the target and configure the following settings 17:

      • Transport: UDP(4)

      • Applications: Select filterlog (for firewall logs). Consider adding others like suricata if you use it.

      • Hostname: Enter the static IP of your ELK VM.

      • Port: Enter 5140.

    • Save and apply the changes.

  2. Create the Logstash Pipeline (opnsense.conf):

    • On the ELK VM, create a new file at ~/elk-siem/logstash/pipeline/01-opnsense-input.conf. The numerical prefix helps control the processing order.

    • Add the following configuration. This pipeline listens for syslog messages, uses a grok filter to parse the standard syslog header, and then a csv filter to break down the OPNsense-specific log message. Finally, it enriches the data with GeoIP information and renames fields for clarity.18

    Groovy

    input {
      syslog {
        port => 5140
        type => "opnsense-firewall"
      }
    }
    
    filter {
      if [type] == "opnsense-firewall" {
        # OPNsense filterlog format is comma-separated
        grok {
          match => { "message" => "<%{POSINT:syslog_pri}>%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{PROG:syslog_program}: %{GREEDYDATA:firewall_data}" }
        }
    
        csv {
          source => "firewall_data"
          separator => ","
          columns => ["rule_number","sub_rule_number","anchor","tracker_id","interface","reason","action","direction","ip_version","tos","ecn","ttl","id","offset","flags","protocol_id","protocol","length","source_ip","destination_ip","source_port","destination_port","data_length"]
        }
    
        # Data type conversions
        mutate {
          convert => {
            "length" => "integer"
            "source_port" => "integer"
            "destination_port" => "integer"
          }
        }
    
        # GeoIP enrichment for public IPs
        if [source_ip] {
          geoip {
            source => "source_ip"
            target => "source_geo"
          }
        }
        if [destination_ip] {
          geoip {
            source => "destination_ip"
            target => "destination_geo"
          }
        }
    
        # Rename fields for clarity
        mutate {
          rename => {
            "interface" => "[opnsense][interface]"
            "action" => "[opnsense][action]"
            "direction" => "[opnsense][direction]"
            "protocol" => "[opnsense][protocol]"
            "source_ip" => "[source][ip]"
            "destination_ip" => "[destination][ip]"
            "source_port" => "[source][port]"
            "destination_port" => "[destination][port]"
          }
        }
      }
    }
    
    output {
      elasticsearch {
        hosts => ["http://elasticsearch:9200"]
        index => "opnsense-firewall-%{+YYYY.MM.dd}"
      }
    }
    

The following table demonstrates the transformation of a raw log into a structured JSON document.

Original Field (CSV Position)Parsed Field NameExample ValueDescription
7[opnsense][action]passThe action taken by the firewall (pass, block).
8[opnsense][direction]outThe direction of the traffic (in, out).
17[opnsense][protocol]icmpThe network protocol of the traffic.
19[source][ip]1.2.3.4The source IP address of the packet.
20[destination][ip]5.6.7.8The destination IP address of the packet.
22[destination][port]443The destination port (for TCP/UDP).
N/A[source_geo][country_name]United StatesEnriched GeoIP data for the source IP.

4.2 Monitoring Windows Endpoints (Winlogbeat)

  1. Install Winlogbeat: On each Windows VM, download and run the Winlogbeat installer. Open an administrative PowerShell prompt, navigate to the installation directory (C:\Program Files\Winlogbeat), and run .\install-service-winlogbeat.ps1 to install the service.19

  2. Configure winlogbeat.yml: Edit the winlogbeat.yml configuration file. Comment out the output.elasticsearch section and configure the output.logstash section to point to the ELK VM.20 Also, specify which event logs to collect.

    YAML

    winlogbeat.event_logs:
      - name: Application
      - name: System
      - name: Security
        # Filter for specific high-value event IDs
        event_id: 4624, 4625, 4688, 4720, 1102
    
    #... other settings...
    
    # output.elasticsearch:
    #   hosts: ["localhost:9200"]
    
    output.logstash:
      hosts: ["<ELK_VM_IP>:5044"]
    
  3. Start the Service: In PowerShell, run Start-Service winlogbeat.

4.3 Monitoring Linux Systems (Filebeat)

  1. Install Filebeat: On each Linux VM or container, install Filebeat using the appropriate package manager commands.21 For Debian/Ubuntu:

    Bash

    curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.11.1-amd64.deb
    sudo dpkg -i filebeat-8.11.1-amd64.deb
    
  2. Enable System Module: The system module is pre-configured to collect common system logs like syslog and auth.log.22 Enable it with:

    Bash

    sudo filebeat modules enable system
    
  3. Configure filebeat.yml: Edit /etc/filebeat/filebeat.yml. Comment out output.elasticsearch and enable output.logstash:

    YAML

    # output.elasticsearch:
    #   hosts: ["localhost:9200"]
    
    output.logstash:
      hosts: ["<ELK_VM_IP>:5044"]
    
  4. Start the Service: sudo systemctl start filebeat.

4.4 Configuring the Beats Pipeline in Logstash

Both Winlogbeat and Filebeat send data to the same port. A single Logstash pipeline can handle both, using metadata from the Beats to route events to the correct indices.

  1. Create beats.conf: On the ELK VM, create ~/elk-siem/logstash/pipeline/10-beats-input.conf.

    Groovy

    input {
      beats {
        port => 5044
      }
    }
    
    output {
      elasticsearch {
        hosts => ["http://elasticsearch:9200"]
        # Use metadata from the Beat to create a unique index name
        index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
      }
    }
    

This configuration dynamically creates daily indices like winlogbeat-8.11.1-2023.10.27 and filebeat-8.11.1-2023.10.27, ensuring data from different sources is properly segregated.23

4.5 Monitoring the Hypervisor and NAS

Both the Proxmox VE host and the Raspberry Pi NAS run Debian-based operating systems and use rsyslog for logging. Forwarding their logs is a straightforward process.

  1. Configure rsyslog: SSH into the Proxmox host and the Raspberry Pi.

  2. Edit the rsyslog configuration file: sudo nano /etc/rsyslog.conf.

  3. Add the following line at the end of the file to forward all logs to the Logstash syslog input 24:

    *.* @<ELK_VM_IP>:5140
    
  4. Restart the rsyslog service: sudo systemctl restart rsyslog.

These logs will be processed by the same opnsense.conf pipeline created earlier. While not perfectly parsed, they will be ingested and searchable. For a production setup, a dedicated pipeline with specific grok patterns for Proxmox logs would be created.


Part 5: Visualization and Analysis in Kibana

With data flowing into Elasticsearch, the next step is to use Kibana to visualize it. A well-designed dashboard transforms raw data into an intuitive security overview, allowing for the rapid identification of trends and anomalies. The goal is not just to display data, but to create visualizations that answer specific security questions.

5.1 First Look: Navigating the Kibana Interface

Before building, it is essential to understand Kibana’s core applications:

  • Discover: The primary interface for exploring raw log data. It allows for searching, filtering, and inspecting individual log documents.4

  • Visualize Library: A workshop for creating individual charts, graphs, maps, and tables. Each visualization is saved as an independent object.7

  • Dashboard: A canvas where saved visualizations are arranged to create comprehensive, interactive overviews.7

  • Stack Management: The administrative section for managing Kibana, including the creation of Data Views (formerly Index Patterns), which tell Kibana how to interpret the fields in your Elasticsearch indices.

5.2 Building a Security Overview Dashboard

This tutorial outlines the creation of a dashboard tailored to the ingested homelab data.

  1. Create Data Views:

    • Navigate to Stack Management > Data Views.

    • Click “Create data view”.

    • Create a view for the OPNsense logs with the name opnsense-* and select @timestamp as the time field.

    • Repeat the process to create views for winlogbeat-* and filebeat-*.

  2. Create Key Security Visualizations:

    • Navigate to the Visualize Library and create the following visualizations:

      • [Map] Inbound Connections by Country:

        • Type: Maps

        • Layer: Documents

        • Data View: opnsense-*

        • Geo Field: destination_geo.location

        • Tooltip Fields: source.ip, destination.port, opnsense.action

        • This visualization answers: “Where in the world is my inbound traffic coming from?”

      • [Pie Chart] Firewall Actions:

        • Type: Pie

        • Data View: opnsense-*

        • Slice By: Terms aggregation on the opnsense.action.keyword field.

        • This answers: “What is the ratio of allowed versus blocked traffic on my firewall?”

      • ** Top Blocked Source IPs**:

        • Type: Data Table

        • Data View: opnsense-*

        • Filter: opnsense.action.keyword : "block"

        • Bucket: Terms aggregation on source.ip.keyword, sorted by count descending.

        • This answers: “Who are the most persistent entities attempting to connect through my firewall?”

      • ** Windows Authentication Events**:

        • Type: Bar (Vertical, Stacked)

        • Data View: winlogbeat-*

        • X-Axis: Date Histogram on @timestamp.

        • Split Series: Terms aggregation on winlog.event_data.SubjectLogonId.keyword (or similar field indicating success/failure, often requires a custom field). A simpler approach is to filter by event.code (4624 for success, 4625 for failure).

        • This answers: “What are the trends of successful versus failed user logins on my Windows machines?”

      • ** Linux Sudo Commands**:

        • Type: Data Table

        • Data View: filebeat-*

        • Filter: process.name : "sudo"

        • Columns: @timestamp, host.name, process.command_line.

        • This answers: “What privileged commands are being executed on my Linux systems?”

  3. Assemble the Dashboard:

    • Navigate to Dashboard and click “Create dashboard”.

    • Use the “Add from library” function to add each of the visualizations created above.

    • Arrange, resize, and save the dashboard with a descriptive name like “Homelab Security Overview”.

5.3 Leveraging Community Resources

Building every visualization from scratch is not always necessary. The security community provides pre-built dashboards that can be imported directly into Kibana.

  • Stamus Networks Dashboards: For users running Suricata IDS/IPS on OPNsense, Stamus Networks maintains a GitHub repository of nearly 30 threat hunting and network security monitoring dashboards.25 These can be downloaded as .ndjson files and imported via Stack Management > Saved Objects > Import.

  • Elastic Content Share: Elastic also hosts a platform for sharing pre-built content, including dashboards for specific use cases like monitoring AWS CloudTrail or VPC Flow logs, which can serve as excellent templates or starting points.26

By adopting a common data schema, such as the Elastic Common Schema (ECS), it becomes possible to create unified dashboards. Renaming parsed fields in Logstash (e.g., source_ip to source.ip, destination_port to destination.port) allows a single visualization to display data from OPNsense, Windows, and Linux sources simultaneously, dramatically increasing the analytical power of the SIEM.


Part 6: Proactive Threat Detection with Alerting

While dashboards are excellent for human-driven analysis, a modern SIEM must also be a proactive detection system. Kibana’s alerting framework transforms the SIEM from a passive forensic tool into an active, 24/7 monitor that pushes critical information to the administrator as it happens.

6.1 Introduction to Kibana Alerting

The alerting system in Kibana is built on two core concepts: rules and connectors.27

  • Rules: A rule defines a condition that is checked on a recurring schedule. For example, a rule can run an Elasticsearch query every five minutes to search for specific events. When the query results meet a defined threshold, the rule is triggered.28

  • Connectors (Actions): A connector defines what happens when a rule is triggered. This could be sending an email, posting a message to Slack, calling a generic webhook, or simply writing a new document back into an Elasticsearch index.27

Effective alerting is about achieving a high signal-to-noise ratio. An alert that triggers too frequently on benign events (“false positives”) will lead to alert fatigue, causing real threats to be overlooked. Therefore, rules must be carefully tuned to be specific and high-fidelity.

6.2 Practical Alerting Tutorial: Detecting Brute-Force Attacks

This tutorial demonstrates how to create a high-fidelity alert to detect a potential brute-force login attack against a Windows machine.29

  • Objective: Create an alert that triggers when more than 10 failed login attempts (Windows Event ID 4625) are detected from a single source IP address within a 15-minute time window.

Step-by-Step Guide:

  1. Navigate to Security > Rules in the Kibana main menu.

  2. Click Create new rule.

  3. Rule Type: Select Threshold.

  4. Define the query:

    • Index patterns: winlogbeat-*

    • KQL query: event.code : "4625"

  5. Define the condition:

    • Count: * (all documents)

    • Threshold: is above 10

    • Group by: source.ip

    • Time window: Last 15 minutes

  6. Schedule:

    • Run every: 5 minutes
  7. Actions:

    • For simplicity, select the Index action.

    • Index: .siem-alerts-default (or a custom alerts index). This will write a new document containing the alert details into Elasticsearch whenever the rule triggers. These alerts can then be viewed on the Security > Alerts page.

    • More advanced actions, like sending an email, can be configured under Stack Management > Connectors.

  8. About rule: Give the rule a name (e.g., “Potential Brute-Force Activity Detected”) and a description. Set the severity (e.g., “High”).

  9. Save and enable the rule.

6.3 Building a Detection Ruleset

Beyond brute-force detection, several other high-value alerts should be created to form a basic detection ruleset:

  • Security Log Cleared: Alert when Windows Event ID 1102 is detected. This is a common tactic used by attackers to cover their tracks after compromising a system.30

  • New Administrative User Created: Alert on Windows Event ID 4720. This can indicate an attacker creating a persistent backdoor account.

  • Firewall Rule Modification: Create a rule that looks for logs from configd.py in the OPNsense data stream containing keywords like “firewall rule changed.” This can detect unauthorized changes to the network perimeter.

  • Suspicious PowerShell Execution: Create a rule based on PowerShell logs (Event ID 4104) that looks for encoded commands or suspicious keywords often used in fileless malware attacks.


Part 7: Showcasing Your Work - The Resume Entry

A well-executed homelab project is a powerful asset for a technology professional’s resume. It provides tangible proof of practical skills, initiative, and a passion for the field. This section provides a ready-to-use entry to showcase this SIEM project effectively.

7.1 Translating Experience to Impact

When describing a personal project on a resume, the focus should be on the skills demonstrated and the scope of the work, not merely listing the technologies used. Instead of “Installed ELK,” a more impactful description would be “Engineered a robust data ingestion pipeline…” This reframes the task as a demonstration of a valuable skill. It is highly recommended to create a public GitHub repository containing the project’s configuration files (e.g., docker-compose.yml, Logstash pipeline files) to provide verifiable evidence of the work.

7.2 Ready-to-Use Project Description and Bullet Points

This customizable entry can be added to a “Personal Projects” or “Technical Experience” section of a resume. The bullet points use impactful action verbs common in SIEM engineer job descriptions to highlight the skills developed during the project.31


Homelab SIEM Implementation with the Elastic Stack

Designed and deployed a comprehensive Security Information and Event Management (SIEM) solution from the ground up to provide centralized logging, security monitoring, and threat detection for a heterogeneous homelab network of 5+ virtual machines and network devices.

  • Architected and deployed a multi-component Elastic Stack (Elasticsearch, Logstash, Kibana) using Docker Compose on a Proxmox VE virtual machine, creating a scalable and reproducible infrastructure.

  • Engineered a robust data ingestion pipeline, integrating and normalizing log data from diverse sources including an OPNsense firewall (syslog), Windows Servers (Winlogbeat), Linux containers (Filebeat), and the Proxmox hypervisor.

  • Developed custom Logstash filters using grok, csv, and geoip to parse unstructured firewall logs into a structured, ECS-compliant format, enriching data to enable advanced geographical and threat analysis.

  • Constructed custom security dashboards in Kibana to visualize key metrics in real-time, including firewall traffic patterns, user authentication successes and failures, and top potential threat actors by source IP.

  • Implemented a proactive threat detection capability by creating custom correlation rules in Kibana to automatically alert on suspicious activities, such as brute-force login attempts and security log tampering events.

SOC Part II: Wazuh to SOAR implementation