logstash-input-beats 6.4.4-java → 6.6.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,6 +6,8 @@ require "logstash/codecs/multiline"
6
6
  require "logstash/util"
7
7
  require "logstash-input-beats_jars"
8
8
  require "logstash/plugin_mixins/ecs_compatibility_support"
9
+ require 'logstash/plugin_mixins/plugin_factory_support'
10
+ require "logstash/plugin_mixins/normalize_config_support"
9
11
  require 'logstash/plugin_mixins/event_support/event_factory_adapter'
10
12
  require_relative "beats/patch"
11
13
 
@@ -58,6 +60,10 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
58
60
 
59
61
  include LogStash::PluginMixins::EventSupport::EventFactoryAdapter
60
62
 
63
+ include LogStash::PluginMixins::PluginFactorySupport
64
+
65
+ include LogStash::PluginMixins::NormalizeConfigSupport
66
+
61
67
  config_name "beats"
62
68
 
63
69
  default :codec, "plain"
@@ -71,11 +77,16 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
71
77
  # Events are by default sent in plain text. You can
72
78
  # enable encryption by setting `ssl` to true and configuring
73
79
  # the `ssl_certificate` and `ssl_key` options.
74
- config :ssl, :validate => :boolean, :default => false
80
+ config :ssl, :validate => :boolean, :default => false, :deprecated => "Use 'ssl_enabled' instead."
75
81
 
76
82
  # SSL certificate to use.
77
83
  config :ssl_certificate, :validate => :path
78
84
 
85
+ # Events are by default sent in plain text. You can
86
+ # enable encryption by setting `ssl_enabled` to true and configuring
87
+ # the `ssl_certificate` and `ssl_key` options.
88
+ config :ssl_enabled, :validate => :boolean, :default => false
89
+
79
90
  # SSL key to use.
80
91
  # NOTE: This key need to be in the PKCS8 format, you can convert it with https://www.openssl.org/docs/man1.1.0/apps/pkcs8.html[OpenSSL]
81
92
  # for more information.
@@ -91,6 +102,14 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
91
102
  #
92
103
  config :ssl_certificate_authorities, :validate => :array, :default => []
93
104
 
105
+ # Controls the server’s behavior in regard to requesting a certificate from client connections.
106
+ # `none`: No client authentication
107
+ # `optional`: Requests a client certificate but the client is not required to present one.
108
+ # `required`: Forces a client to present a certificate.
109
+ #
110
+ # This option needs to be used with `ssl_certificate_authorities` and a defined list of CAs.
111
+ config :ssl_client_authentication, :validate => %w[none optional required], :default => 'none'
112
+
94
113
  # By default the server doesn't do any client verification.
95
114
  #
96
115
  # `peer` will make the server ask the client to provide a certificate.
@@ -100,13 +119,13 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
100
119
  # If the client doesn't provide a certificate, the connection will be closed.
101
120
  #
102
121
  # This option needs to be used with `ssl_certificate_authorities` and a defined list of CAs.
103
- config :ssl_verify_mode, :validate => ["none", "peer", "force_peer"], :default => "none"
122
+ config :ssl_verify_mode, :validate => ["none", "peer", "force_peer"], :default => "none", :deprecated => "Set 'ssl_client_authentication' instead."
104
123
 
105
124
  # Enables storing client certificate information in event's metadata. You need
106
125
  # to configure the `ssl_verify_mode` to `peer` or `force_peer` to enable this.
107
- config :ssl_peer_metadata, :validate => :boolean, :default => false
126
+ config :ssl_peer_metadata, :validate => :boolean, :default => false, :deprecated => "use `enrich` option to configure which enrichments to perform"
108
127
 
109
- config :include_codec_tag, :validate => :boolean, :default => true
128
+ config :include_codec_tag, :validate => :boolean, :default => true, :deprecated => "use `enrich` option to configure which enrichments to perform"
110
129
 
111
130
  # Time in milliseconds for an incomplete ssl handshake to timeout
112
131
  config :ssl_handshake_timeout, :validate => :number, :default => 10000
@@ -136,8 +155,44 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
136
155
  # 1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2
137
156
  config :tls_max_version, :validate => :number, :default => TLS.max.version, :deprecated => "Set 'ssl_supported_protocols' instead."
138
157
 
158
+ ENRICH_DEFAULTS = {
159
+ 'source_metadata' => true,
160
+ 'codec_metadata' => true,
161
+ 'ssl_peer_metadata' => false,
162
+ }.freeze
163
+
164
+ ENRICH_ALL = ENRICH_DEFAULTS.keys.freeze
165
+ ENRICH_DEFAULT = ENRICH_DEFAULTS.select { |_,v| v }.keys.freeze
166
+ ENRICH_NONE = ['none'].freeze
167
+ ENRICH_ALIASES = %w(none all)
168
+
169
+ config :enrich, :validate => (ENRICH_ALL | ENRICH_ALIASES), :list => true
170
+
139
171
  attr_reader :field_hostname, :field_hostip
140
172
  attr_reader :field_tls_protocol_version, :field_tls_peer_subject, :field_tls_cipher
173
+ attr_reader :include_source_metadata
174
+
175
+ NON_PREFIXED_SSL_CONFIGS = Set[
176
+ 'tls_min_version',
177
+ 'tls_max_version',
178
+ 'cipher_suites',
179
+ ].freeze
180
+
181
+ SSL_CLIENT_AUTH_NONE = 'none'.freeze
182
+ SSL_CLIENT_AUTH_OPTIONAL = 'optional'.freeze
183
+ SSL_CLIENT_AUTH_REQUIRED = 'required'.freeze
184
+
185
+ SSL_VERIFY_MODE_TO_CLIENT_AUTHENTICATION_MAP = {
186
+ 'none' => SSL_CLIENT_AUTH_NONE,
187
+ 'peer' => SSL_CLIENT_AUTH_OPTIONAL,
188
+ 'force_peer' => SSL_CLIENT_AUTH_REQUIRED
189
+ }.freeze
190
+
191
+ private_constant :SSL_CLIENT_AUTH_NONE
192
+ private_constant :SSL_CLIENT_AUTH_OPTIONAL
193
+ private_constant :SSL_CLIENT_AUTH_REQUIRED
194
+ private_constant :NON_PREFIXED_SSL_CONFIGS
195
+ private_constant :SSL_VERIFY_MODE_TO_CLIENT_AUTHENTICATION_MAP
141
196
 
142
197
  def register
143
198
  # For Logstash 2.4 we need to make sure that the logger is correctly set for the
@@ -149,44 +204,25 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
149
204
  LogStash::Logger.setup_log4j(@logger)
150
205
  end
151
206
 
152
- if @ssl
153
- if @ssl_key.nil? || @ssl_key.empty?
154
- configuration_error "ssl_key => is a required setting when ssl => true is configured"
155
- end
156
- if @ssl_certificate.nil? || @ssl_certificate.empty?
157
- configuration_error "ssl_certificate => is a required setting when ssl => true is configured"
158
- end
207
+ setup_ssl_params!
159
208
 
160
- if require_certificate_authorities? && !client_authentification?
161
- configuration_error "ssl_certificate_authorities => is a required setting when ssl_verify_mode => '#{@ssl_verify_mode}' is configured"
162
- end
209
+ validate_ssl_config!
163
210
 
164
- if client_authentication_metadata? && !require_certificate_authorities?
165
- configuration_error "Configuring ssl_peer_metadata => true requires ssl_verify_mode => to be configured with 'peer' or 'force_peer'"
166
- end
211
+ active_enrichments = resolve_enriches
167
212
 
168
- if original_params.key?('cipher_suites') && original_params.key?('ssl_cipher_suites')
169
- raise LogStash::ConfigurationError, "Both `ssl_cipher_suites` and (deprecated) `cipher_suites` were set. Use only `ssl_cipher_suites`."
170
- elsif original_params.key?('cipher_suites')
171
- @ssl_cipher_suites_final = @cipher_suites
172
- else
173
- @ssl_cipher_suites_final = @ssl_cipher_suites
174
- end
213
+ @include_source_metadata = active_enrichments.include?('source_metadata')
214
+ @include_codec_tag = original_params.include?('include_codec_tag') ? params['include_codec_tag'] : active_enrichments.include?('codec_metadata')
215
+ @ssl_peer_metadata = original_params.include?('ssl_peer_metadata') ? params['ssl_peer_metadata'] : active_enrichments.include?('ssl_peer_metadata')
175
216
 
176
- if original_params.key?('tls_min_version') && original_params.key?('ssl_supported_protocols')
177
- raise LogStash::ConfigurationError, "Both `ssl_supported_protocols` and (deprecated) `tls_min_ciphers` were set. Use only `ssl_supported_protocols`."
178
- elsif original_params.key?('tls_max_version') && original_params.key?('ssl_supported_protocols')
179
- raise LogStash::ConfigurationError, "Both `ssl_supported_protocols` and (deprecated) `tls_max_ciphers` were set. Use only `ssl_supported_protocols`."
217
+ # intentionally ask users to provide codec when they want to use the codec metadata
218
+ # second layer enrich is also a controller, provide enrich => ['codec_metadata' or/with 'source_metadata'] with codec if you override event original
219
+ unless active_enrichments.include?('codec_metadata')
220
+ if original_params.include?('codec')
221
+ @logger.warn("An explicit `codec` is specified but `enrich` does not include `codec_metadata`. ECS compatibility will remain aligned on the pipeline or codec's `ecs_compatibility` (enabled by default).")
180
222
  else
181
- if original_params.key?('tls_min_version') || original_params.key?('tls_max_version')
182
- @ssl_supported_protocols_final = TLS.get_supported(tls_min_version..tls_max_version).map(&:name)
183
- else
184
- @ssl_supported_protocols_final = @ssl_supported_protocols
185
- end
223
+ @codec = plugin_factory.codec('plain').new('ecs_compatibility' => 'disabled')
224
+ @logger.debug('Disabling `ecs_compatibility` for the default codec since `enrich` configuration does not include `codec_metadata` and no explicit codec is set.')
186
225
  end
187
- else
188
- @logger.warn("configured ssl_certificate => #{@ssl_certificate.inspect} will not be used") if @ssl_certificate
189
- @logger.warn("configured ssl_key => #{@ssl_key.inspect} will not be used") if @ssl_key
190
226
  end
191
227
 
192
228
  # Logstash 6.x breaking change (introduced with 4.0.0 of this gem)
@@ -208,18 +244,7 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
208
244
 
209
245
  def create_server
210
246
  server = org.logstash.beats.Server.new(@host, @port, @client_inactivity_timeout, @executor_threads)
211
- if @ssl
212
- ssl_context_builder = new_ssl_context_builder
213
- if client_authentification?
214
- if @ssl_verify_mode == "force_peer"
215
- ssl_context_builder.setVerifyMode(SslContextBuilder::SslClientVerifyMode::FORCE_PEER)
216
- elsif @ssl_verify_mode == "peer"
217
- ssl_context_builder.setVerifyMode(SslContextBuilder::SslClientVerifyMode::VERIFY_PEER)
218
- end
219
- ssl_context_builder.setCertificateAuthorities(@ssl_certificate_authorities)
220
- end
221
- server.setSslHandlerProvider(new_ssl_handshake_provider(ssl_context_builder))
222
- end
247
+ server.setSslHandlerProvider(new_ssl_handshake_provider(new_ssl_context_builder)) if @ssl_enabled
223
248
  server
224
249
  end
225
250
 
@@ -241,24 +266,116 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
241
266
  !@target_codec_on_field.empty?
242
267
  end
243
268
 
244
- def client_authentification?
269
+ def client_authentication_enabled?
270
+ if original_params.include?('ssl_client_authentication')
271
+ return client_authentication_optional? || client_authentication_required?
272
+ end
273
+
274
+ # Keep backward compatibility with the deprecated `ssl_verify_mode` until it's not removed.
275
+ # When it's explicitly set (or both settings are absent), it should use the ssl_certificate_authorities
276
+ # to enable/disable the client authentication. (even if ssl_verify_mode => none)
277
+ certificate_authorities_configured?
278
+ end
279
+
280
+ def certificate_authorities_configured?
245
281
  @ssl_certificate_authorities && @ssl_certificate_authorities.size > 0
246
282
  end
247
283
 
248
284
  def client_authentication_metadata?
249
- @ssl_peer_metadata && ssl_configured? && client_authentification?
285
+ @ssl_enabled && @ssl_peer_metadata && ssl_configured? && client_authentication_enabled?
250
286
  end
251
287
 
252
288
  def client_authentication_required?
253
- @ssl_verify_mode == "force_peer"
289
+ @ssl_client_authentication && @ssl_client_authentication.downcase == SSL_CLIENT_AUTH_REQUIRED
290
+ end
291
+
292
+ def client_authentication_optional?
293
+ @ssl_client_authentication && @ssl_client_authentication.downcase == SSL_CLIENT_AUTH_OPTIONAL
294
+ end
295
+
296
+ def client_authentication_none?
297
+ @ssl_client_authentication && @ssl_client_authentication.downcase == SSL_CLIENT_AUTH_NONE
254
298
  end
255
299
 
256
300
  def require_certificate_authorities?
257
- @ssl_verify_mode == "force_peer" || @ssl_verify_mode == "peer"
301
+ client_authentication_required? || client_authentication_optional?
302
+ end
303
+
304
+ def include_source_metadata?
305
+ return @include_source_metadata
258
306
  end
259
307
 
260
308
  private
261
309
 
310
+ def validate_ssl_config!
311
+ ssl_config_name = original_params.include?('ssl') ? 'ssl' : 'ssl_enabled'
312
+
313
+ unless @ssl_enabled
314
+ ignored_ssl_settings = original_params.select { |k| k != 'ssl_enabled' && k.start_with?('ssl_') || NON_PREFIXED_SSL_CONFIGS.include?(k) }
315
+ @logger.warn("Configured SSL settings are not used when `#{ssl_config_name}` is set to `false`: #{ignored_ssl_settings.keys}") if ignored_ssl_settings.any?
316
+ return
317
+ end
318
+
319
+ if @ssl_key.nil? || @ssl_key.empty?
320
+ configuration_error "ssl_key => is a required setting when #{ssl_config_name} => true is configured"
321
+ end
322
+
323
+ if @ssl_certificate.nil? || @ssl_certificate.empty?
324
+ configuration_error "ssl_certificate => is a required setting when #{ssl_config_name} => true is configured"
325
+ end
326
+
327
+ if require_certificate_authorities? && !certificate_authorities_configured?
328
+ config_name, config_value = provided_client_authentication_config
329
+ configuration_error "ssl_certificate_authorities => is a required setting when #{config_name} => '#{config_value}' is configured"
330
+ end
331
+
332
+ if client_authentication_metadata? && !require_certificate_authorities?
333
+ config_name, optional, required = provided_client_authentication_config([SSL_CLIENT_AUTH_OPTIONAL, SSL_CLIENT_AUTH_REQUIRED])
334
+ configuration_error "Configuring ssl_peer_metadata => true requires #{config_name} => to be configured with '#{optional}' or '#{required}'"
335
+ end
336
+
337
+ if original_params.include?('ssl_client_authentication') && certificate_authorities_configured? && !require_certificate_authorities?
338
+ configuration_error "Configuring ssl_certificate_authorities requires ssl_client_authentication => to be configured with '#{SSL_CLIENT_AUTH_OPTIONAL}' or '#{SSL_CLIENT_AUTH_REQUIRED}'"
339
+ end
340
+ end
341
+
342
+ def provided_client_authentication_config(values = [@ssl_client_authentication])
343
+ if original_params.include?('ssl_verify_mode')
344
+ ['ssl_verify_mode', *values.map { |v| SSL_VERIFY_MODE_TO_CLIENT_AUTHENTICATION_MAP.key(v) }]
345
+ else
346
+ ['ssl_client_authentication', *values]
347
+ end
348
+ end
349
+
350
+ def setup_ssl_params!
351
+ @ssl_enabled = normalize_config(:ssl_enabled) do |normalizer|
352
+ normalizer.with_deprecated_alias(:ssl)
353
+ end
354
+
355
+ @ssl_cipher_suites = normalize_config(:ssl_cipher_suites) do |normalizer|
356
+ normalizer.with_deprecated_alias(:cipher_suites)
357
+ end
358
+
359
+ @ssl_supported_protocols = normalize_config(:ssl_supported_protocols) do |normalizer|
360
+ normalizer.with_deprecated_mapping(:tls_min_version, :tls_max_version) do |tls_min_version, tls_max_version|
361
+ TLS.get_supported(tls_min_version..tls_max_version).map(&:name)
362
+ end
363
+ end
364
+
365
+ @ssl_client_authentication = normalize_config(:ssl_client_authentication) do |normalizer|
366
+ normalizer.with_deprecated_mapping(:ssl_verify_mode) do |ssl_verify_mode|
367
+ normalized_value = SSL_VERIFY_MODE_TO_CLIENT_AUTHENTICATION_MAP[ssl_verify_mode.downcase]
368
+ fail(LogStash::ConfigurationError, "Unsupported value #{ssl_verify_mode} for deprecated option `ssl_verify_mode`") unless normalized_value
369
+ normalized_value
370
+ end
371
+ end
372
+
373
+ params['ssl_enabled'] = @ssl_enabled unless @ssl_enabled.nil?
374
+ params['ssl_cipher_suites'] = @ssl_cipher_suites unless @ssl_cipher_suites.nil?
375
+ params['ssl_supported_protocols'] = @ssl_supported_protocols unless @ssl_supported_protocols.nil?
376
+ params['ssl_client_authentication'] = @ssl_client_authentication unless @ssl_client_authentication.nil?
377
+ end
378
+
262
379
  def new_ssl_handshake_provider(ssl_context_builder)
263
380
  begin
264
381
  org.logstash.netty.SslHandlerProvider.new(ssl_context_builder.build_context, @ssl_handshake_timeout)
@@ -274,17 +391,36 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
274
391
  def new_ssl_context_builder
275
392
  passphrase = @ssl_key_passphrase.nil? ? nil : @ssl_key_passphrase.value
276
393
  begin
277
- org.logstash.netty.SslContextBuilder.new(@ssl_certificate, @ssl_key, passphrase)
278
- .setProtocols(@ssl_supported_protocols_final)
394
+ ssl_context_builder = org.logstash.netty.SslContextBuilder.new(@ssl_certificate, @ssl_key, passphrase)
395
+ .setProtocols(@ssl_supported_protocols)
279
396
  .setCipherSuites(normalized_cipher_suites)
397
+
398
+ if client_authentication_enabled?
399
+ ssl_context_builder.setClientAuthentication(ssl_context_builder_verify_mode, @ssl_certificate_authorities)
400
+ end
401
+
402
+ ssl_context_builder
280
403
  rescue java.lang.IllegalArgumentException => e
281
404
  @logger.error("SSL configuration invalid", error_details(e))
282
405
  raise LogStash::ConfigurationError, e
283
406
  end
284
407
  end
285
408
 
409
+ def ssl_context_builder_verify_mode
410
+ return SslContextBuilder::SslClientVerifyMode::OPTIONAL if client_authentication_optional?
411
+ return SslContextBuilder::SslClientVerifyMode::REQUIRED if client_authentication_required?
412
+
413
+ # Backward compatibility with the deprecated `ssl_verify_mode` and the current `none` overrides
414
+ if !original_params.include?('ssl_client_authentication') && certificate_authorities_configured?
415
+ return SslContextBuilder::SslClientVerifyMode::REQUIRED
416
+ end
417
+
418
+ return SslContextBuilder::SslClientVerifyMode::NONE if client_authentication_none?
419
+ configuration_error "Invalid `ssl_client_authentication` value #{@ssl_client_authentication}"
420
+ end
421
+
286
422
  def normalized_cipher_suites
287
- @ssl_cipher_suites_final.map(&:upcase)
423
+ @ssl_cipher_suites.map(&:upcase)
288
424
  end
289
425
 
290
426
  def configuration_error(message)
@@ -303,4 +439,21 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
303
439
  error_details
304
440
  end
305
441
 
442
+ def resolve_enriches
443
+ deprecated_flags_provided = %w(ssl_peer_metadata include_codec_tag) & original_params.keys
444
+ if deprecated_flags_provided.any? && original_params.include?('enrich')
445
+ raise LogStash::ConfigurationError, "both `enrich` and (deprecated) #{deprecated_flags_provided.join(',')} were provided; use only `enrich`"
446
+ end
447
+
448
+ aliases_provided = ENRICH_ALIASES & (@enrich || [])
449
+ if aliases_provided.any? && @enrich.size > 1
450
+ raise LogStash::ConfigurationError, "when an alias is provided to `enrich`, it must be the only value given (got: #{@enrich.inspect}, including #{aliases_provided.size > 1 ? 'aliases' : 'alias'} #{aliases_provided.join(',')})"
451
+ end
452
+
453
+ return ENRICH_ALL if aliases_provided.include?('all')
454
+ return ENRICH_NONE if aliases_provided.include?('none')
455
+ return ENRICH_DEFAULT unless original_params.include?('enrich')
456
+
457
+ return @enrich
458
+ end
306
459
  end
@@ -8,4 +8,4 @@ require_jar('io.netty', 'netty-transport', '4.1.87.Final')
8
8
  require_jar('io.netty', 'netty-handler', '4.1.87.Final')
9
9
  require_jar('io.netty', 'netty-transport-native-unix-common', '4.1.87.Final')
10
10
  require_jar('org.javassist', 'javassist', '3.24.0-GA')
11
- require_jar('org.logstash.beats', 'logstash-input-beats', '6.4.4')
11
+ require_jar('org.logstash.beats', 'logstash-input-beats', '6.6.0')
data/lib/tasks/test.rake CHANGED
@@ -28,7 +28,7 @@ namespace :test do
28
28
  end
29
29
 
30
30
  namespace :setup do
31
- desc "Download lastest stable version of Logstash-forwarder"
31
+ desc "Download latest stable version of Logstash-forwarder"
32
32
  task :lsf do
33
33
  destination = File.join(VENDOR_PATH, "logstash-forwarder")
34
34
  FileUtils.rm_rf(destination)
@@ -29,6 +29,8 @@ Gem::Specification.new do |s|
29
29
  s.add_runtime_dependency 'jar-dependencies', '~> 0.3', '>= 0.3.4'
30
30
  s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.3'
31
31
  s.add_runtime_dependency 'logstash-mixin-event_support', '~>1.0'
32
+ s.add_runtime_dependency 'logstash-mixin-plugin_factory_support', '~>1.0'
33
+ s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
32
34
 
33
35
  s.add_development_dependency "flores", "~>0.0.6"
34
36
  s.add_development_dependency "rspec"