hpess-logstash-codec-cef 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|