logstash-codec-cef 0.1.4 → 0.1.5
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/.gitignore +3 -0
- data/CHANGELOG.md +0 -0
- data/CONTRIBUTORS +1 -0
- data/NOTICE.TXT +5 -0
- data/README.md +12 -3
- data/docker-compose.yml +5 -0
- data/lib/logstash/codecs/cef.rb +36 -41
- data/logstash-codec-cef.gemspec +1 -1
- data/spec/codecs/cef_spec.rb +56 -12
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01d1c0ba310055e838ee41c651075e1aa1ee7189
|
4
|
+
data.tar.gz: 6f05794989c0ed626c67aa95ef4d81fbbbb046d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 90b949419c532e776a5f86ed660f99e67c343d25c2d4fd93927519a3ed200f9ed0d840593b87c252a35bbf9372f56ae66ad778838a5a99a0839d9787e1d9d15e
|
7
|
+
data.tar.gz: 200cb50dff68168aac3e81bc64247899c149ac76dc7281cd3454f4f1d7394a6e3b8d6257513f370bd3f444d138abe273dc2c56d547284c8fbbff412aa516defb
|
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
File without changes
|
data/CONTRIBUTORS
CHANGED
@@ -10,6 +10,7 @@ Contributors:
|
|
10
10
|
* Nick Ethier (nickethier)
|
11
11
|
* Pete Fritchman (fetep)
|
12
12
|
* Pier-Hugues Pellerin (ph)
|
13
|
+
* Karl Stoney (Stono)
|
13
14
|
|
14
15
|
Note: If you've sent us patches, bug reports, or otherwise contributed to
|
15
16
|
Logstash, and you aren't on the list above and want to be, please let us know
|
data/NOTICE.TXT
ADDED
data/README.md
CHANGED
@@ -13,9 +13,18 @@ Logstash provides infrastructure to automatically generate documentation for thi
|
|
13
13
|
|
14
14
|
## Need Help?
|
15
15
|
|
16
|
-
Need help? Try #logstash on freenode IRC or the logstash
|
16
|
+
Need help? Try #logstash on freenode IRC or the https://discuss.elastic.co/c/logstash discussion forum.
|
17
17
|
|
18
|
-
## Developing
|
18
|
+
## Developing with Docker
|
19
|
+
You can use a docker container with all of the requirements pre installed to save you installing the development environment on your host.
|
20
|
+
|
21
|
+
### 1. Starting the container
|
22
|
+
Simply type `docker-compose run devenv` and you'll be entered into the container. Then you'll need to do `jruby -S bundle install` to get all the dependencies down.
|
23
|
+
|
24
|
+
### 2. Running tests
|
25
|
+
Once you've done #1 above, you can run your tests with `jruby -S bundle exec rspec`
|
26
|
+
|
27
|
+
## Developing without Docker
|
19
28
|
|
20
29
|
### 1. Plugin Developement and Testing
|
21
30
|
|
@@ -83,4 +92,4 @@ Programming is not a required skill. Whatever you've seen about open source and
|
|
83
92
|
|
84
93
|
It is more important to the community that you are able to contribute.
|
85
94
|
|
86
|
-
For more information about contributing, see the [CONTRIBUTING](https://github.com/elasticsearch/logstash/blob/master/CONTRIBUTING.md) file.
|
95
|
+
For more information about contributing, see the [CONTRIBUTING](https://github.com/elasticsearch/logstash/blob/master/CONTRIBUTING.md) file.
|
data/docker-compose.yml
ADDED
data/lib/logstash/codecs/cef.rb
CHANGED
@@ -2,11 +2,6 @@ require "logstash/codecs/base"
|
|
2
2
|
|
3
3
|
class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
4
4
|
config_name "cef"
|
5
|
-
|
6
|
-
|
7
|
-
# Specify if the Syslog header will be expected
|
8
|
-
config :syslog, :validate => :boolean, :default => false
|
9
|
-
|
10
5
|
config :signature, :validate => :string, :default => "Logstash"
|
11
6
|
config :name, :validate => :string, :default => "Logstash"
|
12
7
|
config :sev, :validate => :number, :default => 6
|
@@ -20,31 +15,44 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
20
15
|
|
21
16
|
public
|
22
17
|
def decode(data)
|
23
|
-
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
18
|
+
# Strip any quotations at the start and end, flex connectors seem to send this
|
19
|
+
if data[0] == "\""
|
20
|
+
data = data[1..-2]
|
21
|
+
end
|
22
|
+
event = LogStash::Event.new
|
23
|
+
|
24
|
+
# Split by the pipes
|
25
|
+
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 /(?<!\\)[\|]/
|
26
|
+
|
27
|
+
# Try and parse out the syslog header if there is one
|
28
|
+
if event['cef_version'].include? ' '
|
29
|
+
event['syslog'], unused, event['cef_version'] = event['cef_version'].rpartition(' ')
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get rid of the CEF bit in the version
|
33
|
+
event['cef_version'].sub! /^CEF:/, ''
|
34
|
+
|
35
|
+
# Strip any whitespace from the message
|
36
|
+
if not message.nil? and message.include? '='
|
37
|
+
message = message.strip
|
38
|
+
|
39
|
+
# If the last KVP has no value, add an empty string, this prevents hash errors below
|
40
|
+
if message.end_with?("=")
|
41
|
+
message=message + ' '
|
42
|
+
end
|
43
|
+
|
44
|
+
# Now parse the key value pairs into it
|
45
|
+
extensions = {}
|
39
46
|
message = message.split(/ ([\w\.]+)=/)
|
47
|
+
key, value = message.shift.split('=', 2)
|
48
|
+
extensions[key] = value
|
49
|
+
|
50
|
+
Hash[*message].each{ |k, v| extensions[k] = v }
|
51
|
+
|
52
|
+
# And save the new has as the extensions
|
53
|
+
event['cef_ext'] = extensions
|
54
|
+
end
|
40
55
|
|
41
|
-
key, value = message.shift.split('=',2)
|
42
|
-
@logger.debug(message)
|
43
|
-
kv = Hash[*message]
|
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 #
|
48
56
|
yield event
|
49
57
|
end
|
50
58
|
|
@@ -62,19 +70,6 @@ class LogStash::Codecs::CEF < LogStash::Codecs::Base
|
|
62
70
|
@on_event.call(header + " " + values + "\n")
|
63
71
|
end
|
64
72
|
|
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
73
|
private
|
79
74
|
def get_value(name, event)
|
80
75
|
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 = 'logstash-codec-cef'
|
4
|
-
s.version = '0.1.
|
4
|
+
s.version = '0.1.5'
|
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
@@ -16,29 +16,73 @@ describe LogStash::Codecs::CEF do
|
|
16
16
|
context "#decode" do
|
17
17
|
let (:message) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
18
18
|
|
19
|
-
|
19
|
+
def validate(e)
|
20
|
+
insist { e.is_a?(LogStash::Event) }
|
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"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse the cef headers" do
|
20
29
|
subject.decode(message) do |e|
|
21
|
-
|
22
|
-
|
30
|
+
validate(e)
|
31
|
+
ext = e['cef_ext']
|
23
32
|
insist { e["cef_vendor"] } == "security"
|
24
33
|
insist { e["cef_product"] } == "threatmanager"
|
25
|
-
insist { e["cef_device_version"] } == "1.0"
|
26
|
-
insist { e["cef_sigid"] } == "100"
|
27
|
-
insist { e["cef_name"] } == "trojan successfully stopped"
|
28
|
-
insist { e["cef_severity"] } == "10"
|
29
|
-
insist { e["message"] } == "src=10.0.0.192 dst=12.121.122.82 spt=1232"
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
33
37
|
it "should parse the cef body" do
|
34
38
|
subject.decode(message) do |e|
|
35
|
-
|
36
|
-
insist {
|
37
|
-
insist {
|
39
|
+
ext = e['cef_ext']
|
40
|
+
insist { ext['src'] } == "10.0.0.192"
|
41
|
+
insist { ext['dst'] } == "12.121.122.82"
|
42
|
+
insist { ext['spt'] } == "1232"
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
41
|
-
|
46
|
+
let (:no_ext) { "CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|" }
|
47
|
+
it "should be OK with no extension dictionary" do
|
48
|
+
subject.decode(no_ext) do |e|
|
49
|
+
validate(e)
|
50
|
+
insist { e["cef_ext"] } == nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
let (:missing_headers) { "CEF:0|||1.0|100|trojan successfully stopped|10|src=10.0.0.192 dst=12.121.122.82 spt=1232" }
|
55
|
+
it "should be OK with missing CEF headers (multiple pipes in sequence)" do
|
56
|
+
subject.decode(missing_headers) do |e|
|
57
|
+
validate(e)
|
58
|
+
insist { e["cef_vendor"] } == ""
|
59
|
+
insist { e["cef_product"] } == ""
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
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" }
|
64
|
+
it "should strip leading whitespace from the message" do
|
65
|
+
subject.decode(leading_whitespace) do |e|
|
66
|
+
validate(e)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
let (:escaped_pipes) { 'CEF:0|security|threatmanager|1.0|100|trojan successfully stopped|10|moo=this\|has an escaped pipe' }
|
71
|
+
it "should be OK with escaped pipes in the message" do
|
72
|
+
subject.decode(escaped_pipes) do |e|
|
73
|
+
ext = e['cef_ext']
|
74
|
+
insist { ext['moo'] } == 'this\|has an escaped pipe'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
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" }
|
79
|
+
it "Should detect headers before CEF starts" do
|
80
|
+
subject.decode(syslog) do |e|
|
81
|
+
validate(e)
|
82
|
+
insist { e['syslog'] } == 'Syslogdate Sysloghost'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
42
86
|
end
|
43
87
|
|
44
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-codec-cef
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -51,11 +51,14 @@ extensions: []
|
|
51
51
|
extra_rdoc_files: []
|
52
52
|
files:
|
53
53
|
- .gitignore
|
54
|
+
- CHANGELOG.md
|
54
55
|
- CONTRIBUTORS
|
55
56
|
- Gemfile
|
56
57
|
- LICENSE
|
58
|
+
- NOTICE.TXT
|
57
59
|
- README.md
|
58
60
|
- Rakefile
|
61
|
+
- docker-compose.yml
|
59
62
|
- lib/logstash/codecs/cef.rb
|
60
63
|
- lib/logstash/version.rb
|
61
64
|
- logstash-codec-cef.gemspec
|
@@ -82,9 +85,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
85
|
version: '0'
|
83
86
|
requirements: []
|
84
87
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
88
|
+
rubygems_version: 2.4.7
|
86
89
|
signing_key:
|
87
90
|
specification_version: 4
|
88
91
|
summary: CEF codec to parse CEF formated logs
|
89
92
|
test_files:
|
90
93
|
- spec/codecs/cef_spec.rb
|
94
|
+
has_rdoc:
|