soc operations

Performing Log Source Onboarding in SIEM

Perform structured log source onboarding into SIEM platforms by configuring collectors, parsers, normalization, and validation for complete security visibility.

data-ingestionlog-managementlog-onboardingnormalizationparsingsiemsoc
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Log source onboarding is the systematic process of integrating new data sources into a SIEM platform to enable security monitoring and detection. Proper onboarding requires planning data sources, configuring collection agents, building parsers, normalizing fields to a common schema, and validating data quality. According to the UK NCSC, onboarding should prioritize log sources that provide the highest security value relative to their ingestion cost.

When to Use

  • When conducting security assessments that involve performing log source onboarding in siem
  • When following incident response procedures for related security events
  • When performing scheduled security testing or auditing activities
  • When validating security controls through hands-on testing

Prerequisites

  • SIEM platform deployed (Splunk, Elastic, Sentinel, QRadar, or similar)
  • Network access from source systems to SIEM collectors
  • Administrative access on source systems for agent installation
  • Common Information Model (CIM) or equivalent schema documentation
  • Change management approval for production system modifications

Log Source Priority Framework

Tier 1 - Critical (Onboard First)

Source Log Type Security Value
Active Directory Security Event Logs Authentication, privilege escalation
Firewalls Traffic logs Network access, C2 detection
EDR/AV Endpoint alerts Malware, process execution
VPN/Remote Access Connection logs Unauthorized access
DNS Servers Query logs C2 beaconing, data exfiltration
Email Gateway Email security logs Phishing, BEC

Tier 2 - High Priority

Source Log Type Security Value
Web Proxy HTTP/HTTPS logs Web-based attacks, data exfiltration
Cloud platforms (AWS/Azure/GCP) Audit logs Cloud security posture
Database servers Audit/query logs Data access, SQL injection
DHCP/IPAM Address allocation Asset tracking
File servers Access logs Data access monitoring

Tier 3 - Standard

Source Log Type Security Value
Application servers App logs Application-level attacks
Print servers Print logs Data loss prevention
Badge/physical access Access logs Physical security correlation
Network devices (switches/routers) Syslog Network anomalies

Onboarding Process

Step 1: Discovery and Assessment

1. Identify the log source:
   - System type and version
   - Log format (syslog, CEF, JSON, Windows Events, etc.)
   - Log volume estimate (EPS - events per second)
   - Network location and firewall requirements
 
2. Assess security value:
   - What threats can this source help detect?
   - Which MITRE ATT&CK techniques does it cover?
   - Is there an existing SIEM parser?
 
3. Estimate ingestion cost:
   - Daily volume in GB
   - License impact (per-GB or per-EPS pricing)
   - Storage retention requirements

Step 2: Configure Log Collection

Syslog-Based Collection (Firewalls, Network Devices)

# rsyslog configuration for receiving syslog
# /etc/rsyslog.d/10-siem-collection.conf
 
# UDP reception
module(load="imudp")
input(type="imudp" port="514" ruleset="siem_forwarding")
 
# TCP reception
module(load="imtcp")
input(type="imtcp" port="514" ruleset="siem_forwarding")
 
# TLS reception
module(load="imtcp" StreamDriver.AuthMode="x509/name"
       StreamDriver.Mode="1" StreamDriver.Name="gtls")
input(type="imtcp" port="6514" ruleset="siem_forwarding")
 
ruleset(name="siem_forwarding") {
    # Forward to SIEM
    action(type="omfwd" target="siem.company.com" port="9514"
           protocol="tcp" queue.type="LinkedList"
           queue.filename="siem_fwd" queue.maxdiskspace="1g"
           queue.saveonshutdown="on" action.resumeRetryCount="-1")
}

Windows Event Log Collection (Splunk Universal Forwarder)

# inputs.conf on Splunk Universal Forwarder
[WinEventLog://Security]
disabled = 0
index = wineventlog
sourcetype = WinEventLog:Security
evt_resolve_ad_obj = 1
checkpointInterval = 5
 
[WinEventLog://System]
disabled = 0
index = wineventlog
sourcetype = WinEventLog:System
 
[WinEventLog://Microsoft-Windows-Sysmon/Operational]
disabled = 0
index = wineventlog
sourcetype = XmlWinEventLog:Microsoft-Windows-Sysmon/Operational
renderXml = true
 
[WinEventLog://Microsoft-Windows-PowerShell/Operational]
disabled = 0
index = wineventlog
sourcetype = XmlWinEventLog:Microsoft-Windows-PowerShell/Operational

Cloud Log Collection (AWS CloudTrail)

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "CloudTrailToSIEM": {
      "Type": "AWS::CloudTrail::Trail",
      "Properties": {
        "TrailName": "siem-cloudtrail",
        "S3BucketName": "company-cloudtrail-logs",
        "IsLogging": true,
        "IsMultiRegionTrail": true,
        "IncludeGlobalServiceEvents": true,
        "EnableLogFileValidation": true,
        "EventSelectors": [
          {
            "ReadWriteType": "All",
            "IncludeManagementEvents": true,
            "DataResources": [
              {
                "Type": "AWS::S3::Object",
                "Values": ["arn:aws:s3"]
              }
            ]
          }
        ]
      }
    }
  }
}

Step 3: Parse and Normalize

Custom Parser Example (Splunk props.conf/transforms.conf)

# props.conf
[custom:firewall:logs]
SHOULD_LINEMERGE = false
LINE_BREAKER = ([\r\n]+)
TIME_PREFIX = ^
TIME_FORMAT = %Y-%m-%dT%H:%M:%S%z
MAX_TIMESTAMP_LOOKAHEAD = 30
TRANSFORMS-firewall = firewall_extract_fields
FIELDALIAS-src = src_addr AS src_ip
FIELDALIAS-dst = dst_addr AS dest_ip
EVAL-action = case(fw_action=="allow", "allowed", fw_action=="deny", "blocked", true(), "unknown")
EVAL-vendor_product = "Custom Firewall"
LOOKUP-geo = geo_ip_lookup ip AS dest_ip OUTPUT country, city, latitude, longitude
 
# transforms.conf
[firewall_extract_fields]
REGEX = ^(\S+)\s+(\S+)\s+action=(\w+)\s+src=(\S+):(\d+)\s+dst=(\S+):(\d+)\s+proto=(\w+)\s+bytes=(\d+)
FORMAT = timestamp::$1 hostname::$2 fw_action::$3 src_addr::$4 src_port::$5 dst_addr::$6 dst_port::$7 protocol::$8 bytes::$9

CIM Field Mapping

Raw Field CIM Field Data Model
src_addr src_ip Network_Traffic
dst_addr dest_ip Network_Traffic
dst_port dest_port Network_Traffic
fw_action action Network_Traffic
bytes_sent + bytes_recv bytes Network_Traffic
user_name user Authentication
login_result action Authentication
process_path process Endpoint

Step 4: Validate Data Quality

# Verify events are arriving
index=new_source earliest=-1h
| stats count by sourcetype, host, source
 
# Check field extraction quality
index=new_source earliest=-1h
| stats count(src_ip) as has_src count(dest_ip) as has_dest count(action) as has_action count by sourcetype
| eval src_coverage=round(has_src/count*100,1)
| eval dest_coverage=round(has_dest/count*100,1)
| eval action_coverage=round(has_action/count*100,1)
 
# Verify CIM compliance
| datamodel Network_Traffic search
| search sourcetype=new_sourcetype
| stats count by source, sourcetype
 
# Check for timestamp parsing issues
index=new_source earliest=-1h
| eval time_diff=abs(_time - _indextime)
| stats avg(time_diff) as avg_lag max(time_diff) as max_lag by host
| where avg_lag > 300

Step 5: Enable Detection Coverage

# Verify existing correlation searches work with new source
index=new_source sourcetype=new_sourcetype
| tstats count from datamodel=Authentication by _time span=1h
| timechart span=1h count
 
# Create source-specific detection rule
[New Source - Authentication Anomaly]
search = index=new_source sourcetype=new_sourcetype action=failure \
| stats count by src_ip, user \
| where count > 10

Onboarding Checklist

  • Log source assessed and approved
  • Network connectivity verified
  • Collection agent/method configured
  • Log forwarding confirmed
  • Parser/field extraction configured
  • CIM compliance validated
  • Data model acceleration enabled
  • Volume within license budget
  • Retention policy configured
  • Detection rules enabled/created
  • Dashboard updated
  • Documentation completed
  • SOC team notified

References

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 3

api-reference.md1.6 KB

API Reference — Performing Log Source Onboarding in SIEM

Libraries Used

  • socket: Test syslog connectivity (UDP/TCP) to SIEM collectors
  • re: Log format detection via pattern matching
  • pathlib: Read log sample files

CLI Interface

python agent.py detect --file sample.log
python agent.py validate --host siem.corp.com [--port 514] [--protocol udp|tcp]
python agent.py parse-config --format syslog_rfc3164 --source-type firewall_logs
python agent.py checklist --source "Palo Alto FW" --format syslog_rfc3164 --siem-host siem.corp.com

Core Functions

detect_log_format(sample_file) — Auto-detect log format

Identifies: syslog RFC 3164/5424, CEF, LEEF, JSON, CSV, Windows Event, Apache combined.

validate_syslog_connectivity(host, port, protocol) — Test SIEM collector

Sends test syslog message via UDP or TCP. Validates port reachability.

generate_parsing_config(log_format, source_type) — Create parsing rules

Generates Splunk (props.conf/transforms.conf) and Elastic (Filebeat/Logstash) configs.

create_onboarding_checklist(...) — 10-step onboarding workflow

Covers: sample collection, format validation, connectivity, parsing, correlation rules, documentation.

Supported Log Formats

Format Pattern Indicator
syslog_rfc3164 <PRI>Mon DD HH:MM:SS
syslog_rfc5424 <PRI>VER YYYY-MM-DDT
CEF CEF:0|
LEEF LEEF:1.0|
JSON {...}
Apache combined IP - - [timestamp] "METHOD"

Dependencies

No external packages — Python standard library only.

standards.md1.2 KB

Standards - Log Source Onboarding in SIEM

Common Information Models

SIEM Platform Schema Documentation
Splunk CIM (Common Information Model) docs.splunk.com
Elastic ECS (Elastic Common Schema) elastic.co/guide/en/ecs
Microsoft Sentinel ASIM (Azure Sentinel Information Model) learn.microsoft.com
Google Chronicle UDM (Unified Data Model) cloud.google.com/chronicle
Industry Standard OCSF (Open Cybersecurity Schema Framework) ocsf.io

Log Collection Protocols

Protocol Port Use Case Security
Syslog UDP 514 Network devices, basic forwarding None
Syslog TCP 514 Reliable delivery None
Syslog TLS 6514 Encrypted syslog TLS 1.2+
HTTP/S 443/8088 REST API, HEC (Splunk) TLS
Windows WEF 5985/5986 Windows Event Forwarding Kerberos/TLS
SNMP 161/162 Network device monitoring SNMPv3
S3/Blob N/A Cloud log storage IAM/SAS

NIST SP 800-92 Log Management Guidelines

  • Establish log management infrastructure
  • Define log retention requirements
  • Ensure log data integrity (tamper evidence)
  • Configure time synchronization across all sources
  • Implement log review and analysis procedures
workflows.md1.3 KB

Workflows - Log Source Onboarding in SIEM

Onboarding Workflow

1. Request Received (ticket/email)
   |
   v
2. Discovery & Assessment (1-2 days)
   - Identify log format and volume
   - Assess security value vs cost
   - Check for existing parser
   |
   v
3. Planning (1 day)
   - Determine collection method
   - Plan network access
   - Estimate storage impact
   |
   v
4. Implementation (2-5 days)
   - Install/configure collector
   - Build/customize parser
   - Map to CIM fields
   |
   v
5. Validation (1-2 days)
   - Verify data flow
   - Check field extraction
   - Confirm CIM compliance
   - Test detection rules
   |
   v
6. Production Release (1 day)
   - Enable detection rules
   - Update dashboards
   - Document in CMDB
   - Notify SOC team

Volume Estimation Formula

Daily Volume (GB) = EPS * Average Event Size (bytes) * 86400 / 1,073,741,824
 
Example:
  EPS = 100
  Avg Event Size = 500 bytes
  Daily Volume = 100 * 500 * 86400 / 1,073,741,824 = 4.03 GB/day
  Monthly Volume = 4.03 * 30 = 120.9 GB/month

Cost-Value Assessment Matrix

Security Value Low Volume (<1GB/day) Medium (1-10GB) High (>10GB)
Critical Must have Must have Evaluate ROI
High Should have Should have Evaluate ROI
Medium Nice to have Evaluate ROI Defer
Low Defer Defer Reject

Scripts 2

agent.py7.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""Agent for performing log source onboarding in SIEM platforms."""

import json
import argparse
import socket
import re
from datetime import datetime
from pathlib import Path


SYSLOG_FACILITIES = {0: "kern", 1: "user", 2: "mail", 3: "daemon", 4: "auth", 5: "syslog",
                     6: "lpr", 7: "news", 10: "authpriv", 13: "audit", 16: "local0",
                     17: "local1", 18: "local2", 19: "local3", 20: "local4",
                     21: "local5", 22: "local6", 23: "local7"}

LOG_FORMAT_PATTERNS = {
    "syslog_rfc3164": re.compile(r"^<\d+>\w{3}\s+\d+\s+\d+:\d+:\d+"),
    "syslog_rfc5424": re.compile(r"^<\d+>\d+\s+\d{4}-\d{2}-\d{2}T"),
    "cef": re.compile(r"^CEF:\d+\|"),
    "leef": re.compile(r"^LEEF:\d+\.\d+\|"),
    "json": re.compile(r"^\s*\{"),
    "csv": re.compile(r"^[^,]+,[^,]+,[^,]+"),
    "windows_event": re.compile(r"EventID|EventRecordID"),
    "apache_combined": re.compile(r'^\S+ \S+ \S+ \[.+\] "\w+ .+ HTTP/'),
}


def detect_log_format(sample_file):
    """Detect log format from a sample file."""
    content = Path(sample_file).read_text(encoding="utf-8", errors="replace")
    lines = [l for l in content.splitlines() if l.strip()][:50]
    format_votes = {}
    for line in lines:
        for fmt, pattern in LOG_FORMAT_PATTERNS.items():
            if pattern.search(line):
                format_votes[fmt] = format_votes.get(fmt, 0) + 1
    if not format_votes:
        return {"format": "unknown", "sample_lines": lines[:5]}
    detected = max(format_votes, key=format_votes.get)
    return {
        "sample_file": sample_file,
        "detected_format": detected,
        "confidence": round(format_votes[detected] / len(lines) * 100, 1),
        "format_votes": format_votes,
        "total_lines": len(lines),
        "sample_lines": lines[:5],
    }


def validate_syslog_connectivity(host, port=514, protocol="udp"):
    """Test syslog connectivity to SIEM collector."""
    results = {"host": host, "port": port, "protocol": protocol}
    try:
        if protocol == "udp":
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.settimeout(5)
            test_msg = f"<14>1 {datetime.utcnow().isoformat()} test-agent siem-onboard - - - Test syslog connectivity"
            sock.sendto(test_msg.encode(), (host, port))
            results["status"] = "SENT"
            results["message"] = "UDP message sent (delivery not guaranteed)"
        else:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(5)
            sock.connect((host, port))
            test_msg = f"<14>1 {datetime.utcnow().isoformat()} test-agent siem-onboard - - - Test syslog connectivity\n"
            sock.send(test_msg.encode())
            results["status"] = "CONNECTED"
            results["message"] = "TCP connection established and test message sent"
        sock.close()
    except Exception as e:
        results["status"] = "FAILED"
        results["error"] = str(e)
    return results


def generate_parsing_config(log_format, source_type, fields=None):
    """Generate SIEM parsing configuration for common log formats."""
    configs = {
        "syslog_rfc3164": {
            "splunk": {
                "props_conf": f"[{source_type}]\nTIME_FORMAT = %b %d %H:%M:%S\nTIME_PREFIX = ^<\\d+>\nSHOULD_LINEMERGE = false\nLINE_BREAKER = ([\\r\\n]+)",
                "transforms_conf": f"[{source_type}_extract]\nREGEX = ^<(\\d+)>(\\w{{3}}\\s+\\d+\\s+\\d+:\\d+:\\d+)\\s+(\\S+)\\s+(\\S+?)(?:\\[(\\d+)\\])?:\\s+(.*)\nFORMAT = priority::$1 timestamp::$2 host::$3 program::$4 pid::$5 message::$6",
            },
            "elastic": {
                "filebeat_module": {"module": "system", "syslog": {"enabled": True, "var.paths": ["/var/log/syslog"]}},
            },
        },
        "json": {
            "splunk": {
                "props_conf": f"[{source_type}]\nKV_MODE = json\nSHOULD_LINEMERGE = false\nTIME_FORMAT = %Y-%m-%dT%H:%M:%S",
            },
            "elastic": {
                "filebeat_input": {"type": "filestream", "parsers": [{"ndjson": {"keys_under_root": True, "add_error_key": True}}]},
            },
        },
        "cef": {
            "splunk": {
                "props_conf": f"[{source_type}]\nSHOULD_LINEMERGE = false\nTIME_FORMAT = %b %d %Y %H:%M:%S\nTRANSFORMS-cef = cef_header,cef_extension",
            },
            "elastic": {
                "logstash_filter": 'filter { if [type] == "cef" { grok { match => { "message" => "CEF:%{INT:cef_version}\\|%{DATA:vendor}\\|%{DATA:product}\\|%{DATA:version}\\|%{DATA:signature}\\|%{DATA:name}\\|%{INT:severity}\\|%{GREEDYDATA:extension}" } } } }',
            },
        },
    }
    config = configs.get(log_format, {})
    return {
        "log_format": log_format,
        "source_type": source_type,
        "configurations": config if config else {"note": f"No template for format: {log_format}"},
    }


def create_onboarding_checklist(source_name, log_format, siem_host, siem_port=514):
    """Generate a log source onboarding checklist."""
    return {
        "source_name": source_name,
        "log_format": log_format,
        "timestamp": datetime.utcnow().isoformat(),
        "checklist": [
            {"step": 1, "task": "Collect log samples (minimum 100 lines)", "status": "pending"},
            {"step": 2, "task": f"Validate format: {log_format}", "status": "pending"},
            {"step": 3, "task": f"Test connectivity to {siem_host}:{siem_port}", "status": "pending"},
            {"step": 4, "task": "Create source type / index configuration", "status": "pending"},
            {"step": 5, "task": "Configure field extraction / parsing rules", "status": "pending"},
            {"step": 6, "task": "Verify timestamp parsing and timezone", "status": "pending"},
            {"step": 7, "task": "Validate event flow (check event count)", "status": "pending"},
            {"step": 8, "task": "Create correlation rules / alerts", "status": "pending"},
            {"step": 9, "task": "Document source in CMDB", "status": "pending"},
            {"step": 10, "task": "Monitor for 48h and verify parsing accuracy", "status": "pending"},
        ],
    }


def main():
    parser = argparse.ArgumentParser(description="SIEM Log Source Onboarding Agent")
    sub = parser.add_subparsers(dest="command")
    d = sub.add_parser("detect", help="Detect log format")
    d.add_argument("--file", required=True)
    v = sub.add_parser("validate", help="Test syslog connectivity")
    v.add_argument("--host", required=True)
    v.add_argument("--port", type=int, default=514)
    v.add_argument("--protocol", default="udp", choices=["udp", "tcp"])
    p = sub.add_parser("parse-config", help="Generate parsing config")
    p.add_argument("--format", required=True, choices=list(LOG_FORMAT_PATTERNS.keys()))
    p.add_argument("--source-type", required=True)
    c = sub.add_parser("checklist", help="Generate onboarding checklist")
    c.add_argument("--source", required=True)
    c.add_argument("--format", required=True)
    c.add_argument("--siem-host", required=True)
    c.add_argument("--siem-port", type=int, default=514)
    args = parser.parse_args()
    if args.command == "detect":
        result = detect_log_format(args.file)
    elif args.command == "validate":
        result = validate_syslog_connectivity(args.host, args.port, args.protocol)
    elif args.command == "parse-config":
        result = generate_parsing_config(args.format, args.source_type)
    elif args.command == "checklist":
        result = create_onboarding_checklist(args.source, args.format, args.siem_host, args.siem_port)
    else:
        parser.print_help()
        return
    print(json.dumps(result, indent=2, default=str))


if __name__ == "__main__":
    main()
process.py7.9 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
SIEM Log Source Onboarding Manager

Tracks log source onboarding progress, validates data quality,
and generates configuration templates for common SIEM platforms.
"""

import json
from datetime import datetime
from typing import Optional


class LogSource:
    """Represents a log source to be onboarded into a SIEM."""

    def __init__(self, name: str, source_type: str, log_format: str,
                 estimated_eps: int, avg_event_size_bytes: int = 500,
                 security_tier: str = "medium", collection_method: str = "syslog"):
        self.name = name
        self.source_type = source_type
        self.log_format = log_format
        self.estimated_eps = estimated_eps
        self.avg_event_size_bytes = avg_event_size_bytes
        self.security_tier = security_tier
        self.collection_method = collection_method
        self.status = "pending"
        self.cim_fields_mapped = []
        self.validation_results = {}

    def estimate_daily_volume_gb(self) -> float:
        return round(self.estimated_eps * self.avg_event_size_bytes * 86400 / 1_073_741_824, 2)

    def estimate_monthly_volume_gb(self) -> float:
        return round(self.estimate_daily_volume_gb() * 30, 2)

    def validate_cim_compliance(self, required_fields: list) -> dict:
        mapped = set(self.cim_fields_mapped)
        required = set(required_fields)
        missing = required - mapped
        coverage = round(len(mapped & required) / max(1, len(required)) * 100, 1)
        self.validation_results["cim_compliance"] = {
            "coverage_pct": coverage,
            "mapped_fields": list(mapped & required),
            "missing_fields": list(missing),
            "compliant": coverage >= 80,
        }
        return self.validation_results["cim_compliance"]

    def generate_splunk_inputs_conf(self) -> str:
        templates = {
            "syslog": f"""[udp://514]
connection_host = ip
sourcetype = {self.source_type}
index = main
disabled = false""",
            "windows_event": f"""[WinEventLog://Security]
disabled = 0
index = wineventlog
sourcetype = {self.source_type}
evt_resolve_ad_obj = 1
checkpointInterval = 5""",
            "file_monitor": f"""[monitor:///var/log/{self.name}/*.log]
disabled = false
sourcetype = {self.source_type}
index = main
crcSalt = <SOURCE>""",
            "http_event_collector": f"""# Configure via Splunk HEC
# POST to https://splunk:8088/services/collector/event
# Headers: Authorization: Splunk <HEC_TOKEN>
# Body: {{"event": "<log_data>", "sourcetype": "{self.source_type}", "index": "main"}}""",
        }
        return templates.get(self.collection_method, "# Unknown collection method")


class OnboardingTracker:
    """Tracks the onboarding status of multiple log sources."""

    ONBOARDING_STEPS = [
        "discovery",
        "planning",
        "collection_configured",
        "parser_built",
        "cim_mapped",
        "validation_passed",
        "detection_rules_enabled",
        "documentation_complete",
        "production_released",
    ]

    def __init__(self):
        self.sources = []
        self.step_completion = {}

    def add_source(self, source: LogSource):
        self.sources.append(source)
        self.step_completion[source.name] = {step: False for step in self.ONBOARDING_STEPS}

    def complete_step(self, source_name: str, step: str):
        if source_name in self.step_completion and step in self.step_completion[source_name]:
            self.step_completion[source_name][step] = True
            # Update status
            for src in self.sources:
                if src.name == source_name:
                    completed = sum(1 for v in self.step_completion[source_name].values() if v)
                    total = len(self.ONBOARDING_STEPS)
                    if completed == total:
                        src.status = "completed"
                    elif completed > 0:
                        src.status = "in_progress"

    def get_progress_report(self) -> dict:
        report = {
            "total_sources": len(self.sources),
            "completed": sum(1 for s in self.sources if s.status == "completed"),
            "in_progress": sum(1 for s in self.sources if s.status == "in_progress"),
            "pending": sum(1 for s in self.sources if s.status == "pending"),
            "total_daily_volume_gb": sum(s.estimate_daily_volume_gb() for s in self.sources),
            "total_monthly_volume_gb": sum(s.estimate_monthly_volume_gb() for s in self.sources),
            "sources": [],
        }
        for source in self.sources:
            steps = self.step_completion.get(source.name, {})
            completed_steps = sum(1 for v in steps.values() if v)
            report["sources"].append({
                "name": source.name,
                "type": source.source_type,
                "status": source.status,
                "progress": f"{completed_steps}/{len(self.ONBOARDING_STEPS)}",
                "daily_volume_gb": source.estimate_daily_volume_gb(),
                "security_tier": source.security_tier,
                "next_step": next((s for s, v in steps.items() if not v), "complete"),
            })
        return report


CIM_REQUIRED_FIELDS = {
    "Network_Traffic": ["src_ip", "dest_ip", "dest_port", "action", "bytes", "protocol", "transport"],
    "Authentication": ["src_ip", "user", "action", "app", "dest"],
    "Endpoint": ["dest", "process", "process_id", "user", "action"],
    "Web": ["url", "http_method", "status", "src_ip", "dest_ip", "http_user_agent"],
    "Email": ["src_user", "recipient", "subject", "action", "file_name"],
}


if __name__ == "__main__":
    tracker = OnboardingTracker()

    sources = [
        LogSource("Palo Alto Firewall", "pan:traffic", "syslog-CEF", 500, 600, "critical", "syslog"),
        LogSource("Windows Domain Controllers", "WinEventLog:Security", "windows-xml", 200, 800, "critical", "windows_event"),
        LogSource("Squid Web Proxy", "squid:access", "squid-native", 1000, 400, "high", "file_monitor"),
        LogSource("Custom App Server", "app:custom", "json", 50, 300, "medium", "http_event_collector"),
    ]

    for src in sources:
        tracker.add_source(src)

    # Simulate progress
    tracker.complete_step("Palo Alto Firewall", "discovery")
    tracker.complete_step("Palo Alto Firewall", "planning")
    tracker.complete_step("Palo Alto Firewall", "collection_configured")
    tracker.complete_step("Palo Alto Firewall", "parser_built")
    tracker.complete_step("Palo Alto Firewall", "cim_mapped")

    tracker.complete_step("Windows Domain Controllers", "discovery")
    tracker.complete_step("Windows Domain Controllers", "planning")
    tracker.complete_step("Windows Domain Controllers", "collection_configured")

    tracker.complete_step("Squid Web Proxy", "discovery")

    # CIM validation
    sources[0].cim_fields_mapped = ["src_ip", "dest_ip", "dest_port", "action", "bytes", "protocol"]
    cim_result = sources[0].validate_cim_compliance(CIM_REQUIRED_FIELDS["Network_Traffic"])

    print("=" * 70)
    print("SIEM LOG SOURCE ONBOARDING TRACKER")
    print("=" * 70)

    report = tracker.get_progress_report()
    print(f"\nTotal Sources: {report['total_sources']}")
    print(f"Completed: {report['completed']} | In Progress: {report['in_progress']} | Pending: {report['pending']}")
    print(f"Total Daily Volume: {report['total_daily_volume_gb']} GB")
    print(f"Total Monthly Volume: {report['total_monthly_volume_gb']} GB")

    print(f"\n{'Source':<30} {'Status':<15} {'Progress':<10} {'Volume/Day':<12} {'Next Step'}")
    print("-" * 85)
    for s in report["sources"]:
        print(f"{s['name']:<30} {s['status']:<15} {s['progress']:<10} {s['daily_volume_gb']:<12} {s['next_step']}")

    print(f"\nCIM Compliance - Palo Alto Firewall:")
    print(f"  Coverage: {cim_result['coverage_pct']}%")
    print(f"  Compliant: {cim_result['compliant']}")
    print(f"  Missing: {cim_result['missing_fields']}")

    print(f"\nSample inputs.conf for Palo Alto Firewall:")
    print(sources[0].generate_splunk_inputs_conf())

Assets 1

template.mdtext/markdown · 1.1 KB
Keep exploring