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

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.
@@ -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"