hpess-logstash-codec-cef 0.1.6 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/logstash/codecs/cef.rb +17 -37
- data/logstash-codec-cef.gemspec +1 -1
- data/spec/codecs/cef_spec.rb +22 -13
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57330ab16e56eb40f97c35161a31a89ef0a53db1
|
4
|
+
data.tar.gz: 279a1861c849597fa62833fb3bcb674dfd913c51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca205a4e25ec02147459e40d90608b861a4b308c33bab64b400c9bfee6637bb7cf55e265ffaa3b16480f968dc1cd3c99a50d47c9dffc29a10f8b233bf0a1b737
|
7
|
+
data.tar.gz: eb5375a8477c2a1f8c74e9a0c8c6ea7535d8190e5a86bee7782d20d8e8e599acdd6fe7a047e2458a1a4b229fe20ef114ac96d9d2b1c2e9473a03cbab8cdd2f3b
|
data/lib/logstash/codecs/cef.rb
CHANGED
@@ -2,7 +2,6 @@ require "logstash/codecs/base"
|
|
2
2
|
|
3
3
|
class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
4
4
|
config_name "cef"
|
5
|
-
config :syslog, :validate => :boolean, :default => false
|
6
5
|
config :signature, :validate => :string, :default => "Logstash"
|
7
6
|
config :name, :validate => :string, :default => "Logstash"
|
8
7
|
config :sev, :validate => :number, :default => 6
|
@@ -18,33 +17,27 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
18
17
|
def decode(data)
|
19
18
|
# %{SYSLOGDATE} %{HOST} CEF:Version|Device Vendor|Device Product|Device Version|SignatureID|Name|Severity|Extension
|
20
19
|
event = LogStash::Event.new()
|
21
|
-
if
|
22
|
-
|
23
|
-
|
24
|
-
# Since we have the syslog headers, lets pull them out first and put them into their own field to be handled
|
25
|
-
else
|
26
|
-
# We don't have syslog headers, so we just need to remove CEF:
|
27
|
-
data.sub! /^CEF:/, ''
|
28
|
-
end
|
20
|
+
event['syslog'], data = data.split('CEF:', 2) if not data.index('CEF:') == 0
|
21
|
+
data.sub! /^CEF:/, ''
|
22
|
+
event['cef_version'], event['cef_vendor'], event['cef_product'], event['cef_device_version'], event['cef_sigid'], event['cef_name'], event['cef_severity'], message = data.split /(?<!\\)[\|]/
|
29
23
|
|
30
|
-
#
|
31
|
-
|
24
|
+
# Strip any whitespace from the message
|
25
|
+
message = message.to_s.strip
|
32
26
|
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# Now, try to break out the Extension Dictionary
|
38
|
-
if message.length != 0
|
27
|
+
# Now parse the key value pairs into it
|
28
|
+
extensions = {}
|
29
|
+
if message.length != 0 and message.include? "="
|
39
30
|
message = message.split(/ ([\w\.]+)=/)
|
31
|
+
key, value = message.shift.split('=', 2)
|
32
|
+
extensions[key] = value
|
33
|
+
|
34
|
+
Hash[*message].each{|k, v|
|
35
|
+
extensions[k] = v
|
36
|
+
}
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
@logger.debug(kv)
|
45
|
-
addKey(kv,key,value)
|
46
|
-
event.to_hash.merge!(Hash[kv.map{ |k,v| ["cef_ext_"+k,v] }])
|
47
|
-
end #
|
38
|
+
# And save the new has as the extensions
|
39
|
+
event['cef_extension'] = extensions
|
40
|
+
end
|
48
41
|
yield event
|
49
42
|
end
|
50
43
|
|
@@ -62,19 +55,6 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
62
55
|
@on_event.call(header + " " + values + "\n")
|
63
56
|
end
|
64
57
|
|
65
|
-
private
|
66
|
-
def addKey(kv_keys, key, value)
|
67
|
-
if kv_keys.has_key?(key)
|
68
|
-
if kv_keys[key].is_a? Array
|
69
|
-
kv_keys[key].push(value)
|
70
|
-
else
|
71
|
-
kv_keys[key] = [kv_keys[key], value]
|
72
|
-
end
|
73
|
-
else
|
74
|
-
kv_keys[key] = value
|
75
|
-
end
|
76
|
-
end # addKey
|
77
|
-
|
78
58
|
private
|
79
59
|
def get_value(name, event)
|
80
60
|
val = event[name]
|
data/logstash-codec-cef.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'hpess-logstash-codec-cef'
|
4
|
-
s.version = '0.
|
4
|
+
s.version = '0.2.0'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "CEF codec to parse CEF formated logs"
|
7
7
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
data/spec/codecs/cef_spec.rb
CHANGED
@@ -18,17 +18,17 @@ describe LogStash::Codecs::CEF do
|
|
18
18
|
|
19
19
|
def validate(e)
|
20
20
|
insist { e.is_a?(LogStash::Event) }
|
21
|
-
insist { e[
|
22
|
-
insist { e[
|
23
|
-
insist { e[
|
24
|
-
insist { e[
|
25
|
-
insist { e[
|
26
|
-
insist { e["message"] } == "src=10.0.0.192 dst=12.121.122.82 spt=1232"
|
21
|
+
insist { e['cef_version'] } == "0"
|
22
|
+
insist { e['cef_device_version'] } == "1.0"
|
23
|
+
insist { e['cef_sigid'] } == "100"
|
24
|
+
insist { e['cef_name'] } == "trojan successfully stopped"
|
25
|
+
insist { e['cef_severity'] } == "10"
|
27
26
|
end
|
28
27
|
|
29
28
|
it "should parse the cef headers" do
|
30
29
|
subject.decode(message) do |e|
|
31
30
|
validate(e)
|
31
|
+
ext = e['cef_extension']
|
32
32
|
insist { e["cef_vendor"] } == "security"
|
33
33
|
insist { e["cef_product"] } == "threatmanager"
|
34
34
|
end
|
@@ -36,9 +36,10 @@ describe LogStash::Codecs::CEF do
|
|
36
36
|
|
37
37
|
it "should parse the cef body" do
|
38
38
|
subject.decode(message) do |e|
|
39
|
-
|
40
|
-
insist {
|
41
|
-
insist {
|
39
|
+
ext = e['cef_extension']
|
40
|
+
insist { ext['src'] } == "10.0.0.192"
|
41
|
+
insist { ext['dst'] } == "12.121.122.82"
|
42
|
+
insist { ext['spt'] } == "1232"
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -51,18 +52,26 @@ describe LogStash::Codecs::CEF do
|
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
54
|
-
let (:leading_whitespace) { "CEF:0|security|
|
55
|
+
let (:leading_whitespace) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10| src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
55
56
|
it "should strip leading whitespace from the message" do
|
56
57
|
subject.decode(leading_whitespace) do |e|
|
57
58
|
validate(e)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
|
-
|
62
|
-
let (:escaped_pipes) { 'CEF:0|||1.0|100|trojan successfully stopped|10|moo=this\|has an escaped pipe' }
|
62
|
+
let (:escaped_pipes) { 'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|moo=this\|has an escaped pipe' }
|
63
63
|
it "should be OK with escaped pipes in the message" do
|
64
64
|
subject.decode(escaped_pipes) do |e|
|
65
|
-
|
65
|
+
ext = e['cef_extension']
|
66
|
+
insist { ext['moo'] } == 'this\|has an escaped pipe'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
let (:syslog) { "Syslogdate Sysloghost CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
71
|
+
it "Should detect headers before CEF starts" do
|
72
|
+
subject.decode(syslog) do |e|
|
73
|
+
validate(e)
|
74
|
+
insist { e['syslog'] } == 'Syslogdate Sysloghost '
|
66
75
|
end
|
67
76
|
end
|
68
77
|
|