logstash-codec-netflow 2.1.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb68c1b451df00dd3cc4fb9a597b91cfa4892f23
4
- data.tar.gz: b1ad1a99a601cc04f7694132154bc49d5b897912
3
+ metadata.gz: 95e7e7d16a47ec1ae4535979d9792b6051e6d36f
4
+ data.tar.gz: b101a6c29ebc0fa9d65ade94fb14160cd7a1df33
5
5
  SHA512:
6
- metadata.gz: d591fd1d73dff5e68763d251182f79a8b73c1d32d2b7b16b0630d965b150d810b519be201ed079f29a1858cb59b239054938ce65f4b5e9faab39f12dea2e23e5
7
- data.tar.gz: 996c051eed7e3fc779ac08dc3b076192360aa6365e2bc0bdd8175fee3141bb8d60f1ab7e2de417e6371c05720a03fa04e65e67a4257ec67b0504a80304754e7c
6
+ metadata.gz: 776e788d36ccdb7c30844b7f4b7925eb7c4fc5a5c40371b3330376bb00b659a4338a312160634813dfe4d6f14d98fbf4f9d83c9da3533ec954c8460b749a7e04
7
+ data.tar.gz: 135bdba032f43b7855c4bf63fcf3468b40eb8faaefbb70ef9ada0ff63e2561cc230dcc87671d7f92afac0d702b1b406cccf46192ac4f12a15a351c46bb897f80
data/CHANGELOG.md CHANGED
@@ -1,30 +1,13 @@
1
- ## 2.1.1
2
-
3
- - Small update due to breaking change in BinData gem (issue #41)
4
-
5
- ## 2.1.0
6
-
7
- - Added IPFIX support
8
- - Fixed exception if Netflow data contains MAC addresses (issue #26, issue #34)
9
- - Fixed exceptions when receiving invalid Netflow v5 and v9 data (issue #17, issue 18)
10
- - Fixed decoding Netflow templates from multiple (non-identical) exporters
11
- - Add support for Cisco ASA fields
12
- - Add support for Netflow 9 options template with scope fields
13
-
1
+ ## 3.0.0
2
+ - Update the plugin to the version 2.0 of the plugin api, this change is required for Logstash 5.0 compatibility. See https://github.com/elastic/logstash/issues/5141
14
3
  # 2.0.5
15
-
16
4
  - Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
17
-
18
5
  # 2.0.4
19
-
20
6
  - New dependency requirements for logstash-core for the 5.0 release
21
-
22
7
  ## 2.0.3
23
-
24
8
  - Fixed JSON compare flaw in specs
25
9
 
26
10
  ## 2.0.0
27
-
28
11
  - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
29
12
  instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
30
13
  - Dependency on logstash-core update to 2.0
data/CONTRIBUTORS CHANGED
@@ -3,24 +3,12 @@ reports, or in general have helped logstash along its way.
3
3
 
4
4
  Contributors:
5
5
  * Aaron Mildenstein (untergeek)
6
- * Adam Kaminski (thimslugga)
7
6
  * Colin Surprenant (colinsurprenant)
8
7
  * Jordan Sissel (jordansissel)
9
- * Jorrit Folmer (jorritfolmer)
10
8
  * Matt Dainty (bodgit)
11
- * Paul Warren (pwarren)
12
9
  * Pier-Hugues Pellerin (ph)
13
- * Pulkit Agrawal (propulkit)
14
10
  * Richard Pijnenburg (electrical)
15
- * Salvador Ferrer (salva-ferrer)
16
- * Will Rigby (wrigby)
17
- * Rojuinex
18
11
  * debadair
19
- * hkshirish
20
- * jstopinsek
21
-
22
- Maintainer:
23
- * Jorrit Folmer (jorritfolmer)
24
12
 
25
13
  Note: If you've sent us patches, bug reports, or otherwise contributed to
26
14
  Logstash, and you aren't on the list above and want to be, please let us know
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
1
  source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in logstash-mass_effect.gemspec
2
4
  gemspec
@@ -3,59 +3,7 @@ require "logstash/filters/base"
3
3
  require "logstash/namespace"
4
4
  require "logstash/timestamp"
5
5
 
6
- # The "netflow" codec is used for decoding Netflow v5/v9/v10 (IPFIX) flows.
7
- #
8
- # ==== Supported Netflow/IPFIX exporters
9
- #
10
- # The following Netflow/IPFIX exporters are known to work with the most recent version of the netflow codec:
11
- #
12
- # [cols="6,^2,^2,^2,12",options="header"]
13
- # |===========================================================================================
14
- # |Netflow exporter | v5 | v9 | IPFIX | Remarks
15
- # |Softflowd | y | y | y | IPFIX supported in https://github.com/djmdjm/softflowd
16
- # |nProbe | y | y | y |
17
- # |ipt_NETFLOW | y | y | y |
18
- # |Cisco ASA | | y | |
19
- # |Cisco IOS 12.x | | y | |
20
- # |fprobe | y | | |
21
- # |===========================================================================================
22
- #
23
- # ==== Usage
24
- #
25
- # Example Logstash configuration:
26
- #
27
- # [source]
28
- # -----------------------------
29
- # input {
30
- # udp {
31
- # host => localhost
32
- # port => 2055
33
- # codec => netflow {
34
- # versions => [5, 9]
35
- # }
36
- # type => netflow
37
- # }
38
- # udp {
39
- # host => localhost
40
- # port => 4739
41
- # codec => netflow {
42
- # versions => [10]
43
- # target => ipfix
44
- # }
45
- # type => ipfix
46
- # }
47
- # tcp {
48
- # host => localhost
49
- # port => 4739
50
- # codec => netflow {
51
- # versions => [10]
52
- # target => ipfix
53
- # }
54
- # type => ipfix
55
- # }
56
- # }
57
- # -----------------------------
58
-
6
+ # The "netflow" codec is for decoding Netflow v5/v9 flows.
59
7
  class LogStash::Codecs::Netflow < LogStash::Codecs::Base
60
8
  config_name "netflow"
61
9
 
@@ -66,7 +14,7 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
66
14
  config :target, :validate => :string, :default => "netflow"
67
15
 
68
16
  # Specify which Netflow versions you will accept.
69
- config :versions, :validate => :array, :default => [5, 9, 10]
17
+ config :versions, :validate => :array, :default => [5, 9]
70
18
 
71
19
  # Override YAML file containing Netflow field definitions
72
20
  #
@@ -83,25 +31,7 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
83
31
  # - :skip
84
32
  #
85
33
  # See <https://github.com/logstash-plugins/logstash-codec-netflow/blob/master/lib/logstash/codecs/netflow/netflow.yaml> for the base set.
86
- config :netflow_definitions, :validate => :path
87
-
88
- # Override YAML file containing IPFIX field definitions
89
- #
90
- # Very similar to the Netflow version except there is a top level Private
91
- # Enterprise Number (PEN) key added:
92
- #
93
- # ---
94
- # pen:
95
- # id:
96
- # - :uintN or :ip4_addr or :ip6_addr or :mac_addr or :string
97
- # - :name
98
- # id:
99
- # - :skip
100
- #
101
- # There is an implicit PEN 0 for the standard fields.
102
- #
103
- # See <https://github.com/logstash-plugins/logstash-codec-netflow/blob/master/lib/logstash/codecs/netflow/ipfix.yaml> for the base set.
104
- config :ipfix_definitions, :validate => :path
34
+ config :definitions, :validate => :path
105
35
 
106
36
  NETFLOW5_FIELDS = ['version', 'flow_seq_num', 'engine_type', 'engine_id', 'sampling_algorithm', 'sampling_interval', 'flow_records']
107
37
  NETFLOW9_FIELDS = ['version', 'flow_seq_num']
@@ -112,7 +42,6 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
112
42
  4 => :scope_netflow_cache,
113
43
  5 => :scope_template,
114
44
  }
115
- IPFIX_FIELDS = ['version']
116
45
  SWITCHED = /_switched$/
117
46
  FLOWSET_ID = "flowset_id"
118
47
 
@@ -123,16 +52,26 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
123
52
 
124
53
  def register
125
54
  require "logstash/codecs/netflow/util"
126
- @netflow_templates = Vash.new()
127
- @ipfix_templates = Vash.new()
55
+ @templates = Vash.new()
128
56
 
129
57
  # Path to default Netflow v9 field definitions
130
58
  filename = ::File.expand_path('netflow/netflow.yaml', ::File.dirname(__FILE__))
131
- @netflow_fields = load_definitions(filename, @netflow_definitions)
132
59
 
133
- # Path to default IPFIX field definitions
134
- filename = ::File.expand_path('netflow/ipfix.yaml', ::File.dirname(__FILE__))
135
- @ipfix_fields = load_definitions(filename, @ipfix_definitions)
60
+ begin
61
+ @fields = YAML.load_file(filename)
62
+ rescue Exception => e
63
+ raise "#{self.class.name}: Bad syntax in definitions file #{filename}"
64
+ end
65
+
66
+ # Allow the user to augment/override/rename the supported Netflow fields
67
+ if @definitions
68
+ raise "#{self.class.name}: definitions file #{@definitions} does not exists" unless File.exists?(@definitions)
69
+ begin
70
+ @fields.merge!(YAML.load_file(@definitions))
71
+ rescue Exception => e
72
+ raise "#{self.class.name}: Bad syntax in definitions file #{@definitions}"
73
+ end
74
+ end
136
75
  end # def register
137
76
 
138
77
  def decode(payload, metadata = nil, &block)
@@ -157,11 +96,6 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
157
96
  decode_netflow9(flowset, record).each{|event| yield(event)}
158
97
  end
159
98
  end
160
- elsif header.version == 10
161
- flowset = IpfixPDU.read(payload)
162
- flowset.records.each do |record|
163
- decode_ipfix(flowset, record).each { |event| yield(event) }
164
- end
165
99
  else
166
100
  @logger.warn("Unsupported Netflow version v#{header.version}")
167
101
  end
@@ -217,7 +151,7 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
217
151
  record.flowset_data.templates.each do |template|
218
152
  catch (:field) do
219
153
  fields = []
220
- template.record_fields.each do |field|
154
+ template.fields.each do |field|
221
155
  entry = netflow_field_for(field.field_type, field.field_length)
222
156
  throw :field unless entry
223
157
  fields += entry
@@ -229,9 +163,9 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
229
163
  else
230
164
  key = "#{flowset.source_id}|#{template.template_id}"
231
165
  end
232
- @netflow_templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
166
+ @templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
233
167
  # Purge any expired templates
234
- @netflow_templates.cleanup!
168
+ @templates.cleanup!
235
169
  end
236
170
  end
237
171
  when 1
@@ -254,9 +188,9 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
254
188
  else
255
189
  key = "#{flowset.source_id}|#{template.template_id}"
256
190
  end
257
- @netflow_templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
191
+ @templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
258
192
  # Purge any expired templates
259
- @netflow_templates.cleanup!
193
+ @templates.cleanup!
260
194
  end
261
195
  end
262
196
  when 256..65535
@@ -267,7 +201,7 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
267
201
  else
268
202
  key = "#{flowset.source_id}|#{record.flowset_id}"
269
203
  end
270
- template = @netflow_templates[key]
204
+ template = @templates[key]
271
205
 
272
206
  unless template
273
207
  #@logger.warn("No matching template for flow id #{record.flowset_id} from #{event["source"]}")
@@ -324,164 +258,14 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
324
258
  @logger.warn("Invalid netflow packet received (#{e})")
325
259
  end
326
260
 
327
- def decode_ipfix(flowset, record)
328
- events = []
329
-
330
- case record.flowset_id
331
- when 2
332
- # Template flowset
333
- record.flowset_data.templates.each do |template|
334
- catch (:field) do
335
- fields = []
336
- template.record_fields.each do |field|
337
- field_type = field.field_type
338
- field_length = field.field_length
339
- enterprise_id = field.enterprise ? field.enterprise_id : 0
340
-
341
- if field.field_length == 0xffff
342
- # FIXME
343
- @logger.warn("Cowardly refusing to deal with variable length encoded field", :type => field_type, :enterprise => enterprise_id)
344
- throw :field
345
- end
346
-
347
- if enterprise_id == 0
348
- case field_type
349
- when 291, 292, 293
350
- # FIXME
351
- @logger.warn("Cowardly refusing to deal with complex data types", :type => field_type, :enterprise => enterprise_id)
352
- throw :field
353
- end
354
- end
355
-
356
- entry = ipfix_field_for(field_type, enterprise_id, field.field_length)
357
- throw :field unless entry
358
- fields += entry
359
- end
360
- # FIXME Source IP address required in key
361
- key = "#{flowset.observation_domain_id}|#{template.template_id}"
362
- @ipfix_templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
363
- # Purge any expired templates
364
- @ipfix_templates.cleanup!
365
- end
366
- end
367
- when 3
368
- # Options template flowset
369
- record.flowset_data.templates.each do |template|
370
- catch (:field) do
371
- fields = []
372
- (template.scope_fields.to_ary + template.option_fields.to_ary).each do |field|
373
- field_type = field.field_type
374
- field_length = field.field_length
375
- enterprise_id = field.enterprise ? field.enterprise_id : 0
376
-
377
- if field.field_length == 0xffff
378
- # FIXME
379
- @logger.warn("Cowardly refusing to deal with variable length encoded field", :type => field_type, :enterprise => enterprise_id)
380
- throw :field
381
- end
382
-
383
- if enterprise_id == 0
384
- case field_type
385
- when 291, 292, 293
386
- # FIXME
387
- @logger.warn("Cowardly refusing to deal with complex data types", :type => field_type, :enterprise => enterprise_id)
388
- throw :field
389
- end
390
- end
391
-
392
- entry = ipfix_field_for(field_type, enterprise_id, field.field_length)
393
- throw :field unless entry
394
- fields += entry
395
- end
396
- # FIXME Source IP address required in key
397
- key = "#{flowset.observation_domain_id}|#{template.template_id}"
398
- @ipfix_templates[key, @cache_ttl] = BinData::Struct.new(:endian => :big, :fields => fields)
399
- # Purge any expired templates
400
- @ipfix_templates.cleanup!
401
- end
402
- end
403
- when 256..65535
404
- # Data flowset
405
- key = "#{flowset.observation_domain_id}|#{record.flowset_id}"
406
- template = @ipfix_templates[key]
407
-
408
- unless template
409
- @logger.warn("No matching template for flow id #{record.flowset_id}")
410
- next
411
- end
412
-
413
- array = BinData::Array.new(:type => template, :read_until => :eof)
414
- records = array.read(record.flowset_data)
415
-
416
- records.each do |r|
417
- event = {
418
- LogStash::Event::TIMESTAMP => LogStash::Timestamp.at(flowset.unix_sec),
419
- @target => {}
420
- }
421
-
422
- IPFIX_FIELDS.each do |f|
423
- event[@target][f] = flowset[f].snapshot
424
- end
425
-
426
- r.each_pair do |k, v|
427
- case k.to_s
428
- when /^flow(?:Start|End)Seconds$/
429
- event[@target][k.to_s] = LogStash::Timestamp.at(v.snapshot).to_iso8601
430
- when /^flow(?:Start|End)(Milli|Micro|Nano)seconds$/
431
- divisor =
432
- case $1
433
- when 'Milli'
434
- 1_000
435
- when 'Micro'
436
- 1_000_000
437
- when 'Nano'
438
- 1_000_000_000
439
- end
440
- event[@target][k.to_s] = LogStash::Timestamp.at(v.snapshot.to_f / divisor).to_iso8601
441
- else
442
- event[@target][k.to_s] = v.snapshot
443
- end
444
- end
445
-
446
- events << LogStash::Event.new(event)
447
- end
448
- else
449
- @logger.warn("Unsupported flowset id #{record.flowset_id}")
450
- end
451
-
452
- events
453
- rescue BinData::ValidityError => e
454
- @logger.warn("Invalid IPFIX packet received (#{e})")
455
- end
456
-
457
- def load_definitions(defaults, extra)
458
- begin
459
- fields = YAML.load_file(defaults)
460
- rescue Exception => e
461
- raise "#{self.class.name}: Bad syntax in definitions file #{defaults}"
462
- end
463
-
464
- # Allow the user to augment/override/rename the default fields
465
- if extra
466
- raise "#{self.class.name}: definitions file #{extra} does not exist" unless File.exists?(extra)
467
- begin
468
- fields.merge!(YAML.load_file(extra))
469
- rescue Exception => e
470
- raise "#{self.class.name}: Bad syntax in definitions file #{extra}"
471
- end
472
- end
473
-
474
- fields
475
- end
476
-
477
261
  def uint_field(length, default)
478
262
  # If length is 4, return :uint32, etc. and use default if length is 0
479
263
  ("uint" + (((length > 0) ? length : default) * 8).to_s).to_sym
480
264
  end # def uint_field
481
265
 
482
266
  def netflow_field_for(type, length)
483
- if @netflow_fields.include?(type)
484
- field = @netflow_fields[type].clone
267
+ if @fields.include?(type)
268
+ field = @fields[type].clone
485
269
  if field.is_a?(Array)
486
270
 
487
271
  field[0] = uint_field(length, field[0]) if field[0].is_a?(Integer)
@@ -507,38 +291,4 @@ class LogStash::Codecs::Netflow < LogStash::Codecs::Base
507
291
  nil
508
292
  end
509
293
  end # def netflow_field_for
510
-
511
- def ipfix_field_for(type, enterprise, length)
512
- if @ipfix_fields.include?(enterprise)
513
- if @ipfix_fields[enterprise].include?(type)
514
- field = @ipfix_fields[enterprise][type].clone
515
- else
516
- @logger.warn("Unsupported enterprise field", :type => type, :enterprise => enterprise, :length => length)
517
- end
518
- else
519
- @logger.warn("Unsupported enterprise", :enterprise => enterprise)
520
- end
521
-
522
- return nil unless field
523
-
524
- if field.is_a?(Array)
525
- case field[0]
526
- when :skip
527
- field += [nil, {:length => length}]
528
- when :string
529
- field += [{:length => length, :trim_padding => true}]
530
- when :uint64
531
- field[0] = uint_field(length, 8)
532
- when :uint32
533
- field[0] = uint_field(length, 4)
534
- when :uint16
535
- field[0] = uint_field(length, 2)
536
- end
537
-
538
- @logger.debug("Definition complete", :field => field)
539
- [field]
540
- else
541
- @logger.warn("Definition should be an array", :field => field)
542
- end
543
- end
544
294
  end # class LogStash::Filters::Netflow