Skip to main content

Windows Event Log acquisition for Splunk using OpenTelemetry Collector

·3 mins

Windows Event Logs are a primary data source for SIEM systems and various setups can be used to collect these logs. One option is to configure Windows Event Forwarding to send the logs from the source computer to servers. From there, the logs are pushed to a SIEM using a 3rd party forwarding software.

Problem #

Splunk offers Universal or Heavy Forwarders for this task. They can monitor The Event Log channels, register new logs and send them to the index servers. However, fast moving channels, such as the Sysmon target performed poorly in a larger environment. I tried different configuration tweaks and adding hardware resources, but to no avail. The Universal Forwarder coldn’t keep up with the log volume, fell behind which ultimatle caused delayed and dropped events.

Solution #

The simplest solution is to avoid Splunks Event Log monitor. Most of the tools I tested did a better job of keeping up with high traffic Event Channels. But to integrate with Splunks provided Technical AddOns the format of the logs must be closely emulated.

Recently I tested the OpenTelemetry Collector and so far it is doing a good job at delivering the logs in a timely fashion. It monitors the provided Event Log Channel, sets metadata attributes as required by Splunks TA and delivers the logs to a HEC endpoint. I am using locally installed Universal Forwarders as HEC endpoint, but a load-balanced central receiver should also work.
Splunk provides their own OpenTelemetry Collector distribution that is compiled with all required modules.

Configuration #

The following configuration can be used as a reference point. It is designed to be easily adaptable and to mimic the Universal Forwarders behaviour as closely as possible.

You have to adjust the following options:

  • L5: Event Channel to monitor
  • L9: Target index
  • L18: Location for bookmarks
  • L43-47: Memory limiter parameters
  • L53: HEC token
  • L54: HEC endpoint

The COMPUTERNAME environment variable is used as hostname, to match possible transformation rules on the indexers that were setup for the Event Forwarding hosts. The standard behaviour is to extract the event sources hostname.

# OpenTelemetry WEF Collector Configuration

receivers:
  windowseventlog/forwarded_events:
    channel: ForwardedEvents
    raw: true
    attributes:
    - host.name: ${env:COMPUTERNAME}
    - com.splunk.index: target_index_name
    - com.splunk.sourcetype: XmlWinEventLog
    storage: file_storage/bookmark_sysmon
    retry_on_failure:
      enabled: true

extensions:
  file_storage/bookmark_sysmon:
    # Adjust the path according to your environment
    directory: "C:/Program Files/otel/storage/bookmark_sysmon"
    timeout: 1s
  health_check:
    endpoint: "0.0.0.0:8090"
    path: /health/status
    response_body:
        healthy: Healthy
        unhealthy: Sick
    check_collector_pipeline:
        enabled: true
        interval: 1m
        exporter_failure_threshold: 2

processors:
  batch:
    send_batch_size: 10000
    timeout: 10s
  transform:
    error_mode: ignore
    log_statements:
    - context: log
      statements:
      - set(cache, ExtractPatterns(body, ".*?\\<System\\>.*?\\<Channel\\>(?P<channel>.*?)\\<\\/Channel\\>.*?\\<\\/System\\>"))
      - set(attributes["com.splunk.source"], Concat(["XmlWinEventLog", cache["channel"]], ":"))
      - keep_keys(attributes, ["com.splunk.source", "com.splunk.index", "com.splunk.sourcetype", "host.name"])
  memory_limiter:
    # Adjust these values according to your environment, see https://github.com/open-telemetry/opentelemetry-collector/blob/main/processor/memorylimiterprocessor/README.md
    limit_mib: 1512
    spike_limit_mib: 320
    check_interval: 1s

exporters:
  splunk_hec/output:
    # The token needs write access to splunks '_internal' index if you enable the heart beat verification
    # See: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/7d62ad92dfff8ad4d17a5fc82b6eebc1cc48c2a9/exporter/splunkhecexporter/heartbeat.go#L129
    token: 'CHANGEME'
    endpoint: http://127.0.0.1:8088/services/collector
    sourcetype: XmlWinEventLog
    source: wec
    export_raw: false
    health_check_enabled: true
    index: default
    heartbeat:
      startup: true
    telemetry:
      enabled: true
  debug:
    verbosity: detailed

service:
  telemetry:
    logs:
      level: info
  pipelines:
    logs:
      receivers:
      - windowseventlog/forwarded_events
      processors:
      - memory_limiter
      - batch
      - transform
      exporters:
      - splunk_hec/output
      # - debug
  extensions:
    - health_check
    - file_storage/bookmark_sysmon

Caveats #

Using the OpenTelemetry Collector to ingest logs into Splunk will result into two additional indexed fields being saved, otel.log.severity.number and otel.log.severity.text.

Earlier Workaround #

Before migrating to the OpenTelemetry Collector I was using NXLog Community Edition to monitor the Event Channels, write the event into a plain text file on disk and read said file using Splunks monitor. This also worked reasonably well, but caused data duplication on my Forwarders.

Oliver Springer
Author
Oliver Springer
Cybersecurity Engineer