1+ filter {
2+ if [type] == "mod_security" {
3+
4+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5+ # Due to the complexity of the collapsed single string
6+ # we get from multiline and the variance of exactly
7+ # which modsec sections (A-K) may or may not be in each
8+ # log entry, we run some custom ruby code that will
9+ # split on each modsec "section" and store each found in
10+ # new fields named "rawSection[A-K]" as appropriate, the value
11+ # of each of these fields contains the raw un-parsed data
12+ # from that modsec section. Sections that are non-existant
13+ # will not have a key in "fields"
14+ #
15+ # A bit long and crazy yes, but after spending many hours
16+ # just doing this w/ grok patterns, this ended up being the
17+ # most reliable way to break up this in-consistent format into
18+ # more usable blocks
19+ #
20+ # @see https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats
21+ #
22+ # READ the above to get a good understanding of the sections
23+ # and which ones can actively contain data depending on your modsec
24+ # version and environment!
25+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26+
27+ ruby {
28+ code => "
29+ if !event['message'].nil?
30+ modSecSectionData = event['message'].split(/(?:--[a-fA-F0-9]{8}-([A-Z])--)/)
31+ modSecSectionData.shift
32+ for i in 0..((modSecSectionData.length-1)/2)
33+ sectionName = 'rawSection'.concat(modSecSectionData.shift)
34+ sectionData = modSecSectionData.shift
35+ sectionName = sectionName.strip
36+ if !sectionData.nil?
37+ sectionData = sectionData.strip
38+ end
39+ event.to_hash.merge!(sectionName => sectionData)
40+ end
41+ end
42+ "
43+ }
44+ }
45+ }
0 commit comments