logstash-filter-elasticsearch 3.13.0 → 3.15.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
  SHA256:
3
- metadata.gz: 3d55417f0b601e60aa33702b94eec237fc3ed47dc37e06bfa83b1f8b3f2c0884
4
- data.tar.gz: 335f6c76502901f6b0021d8fd89be14b716c2c0f493e22c4d59bd865bcce91db
3
+ metadata.gz: c988a59e14c49b5b169b0b797cc2844d747d1cb67c7daef426d1008b10064c79
4
+ data.tar.gz: 20febabc910c17435dca65e5d326e73ea48b3897743e19102101fba316a5e96c
5
5
  SHA512:
6
- metadata.gz: cd657fd129d3972aff051cf111e15f18b40861631e3d47249887023e3779d6c9cbd09b515dcb7beb5d6783b73f5fef69d3e57425115f100b6cf7576984da832b
7
- data.tar.gz: 410cdfcd7857b6522f91549b8e57244624385f1dde1ddc393bbadb4a8c7468ea5e4df91697b9b5cb1221a1c99a0c4ea054a6a21a0babb52617bb0b54b71bd4bb
6
+ metadata.gz: 6d22b647190c79c1ef8ce703a2212ca7bbedd2f6ce621b81a0bd305c9e523371eb1f6e6bc2435952c2d5d776779588aba7e45fb3e4e07227648f399ed41651b3
7
+ data.tar.gz: 529b58bb8a8a7097cfc4c205044f2eb3d478300f9c6d5273446063afdf55402a5f76157f7e98e51bf4491a9ddc3a6e2ed572ae1fd4110737b2bbd2be829c52f7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## 3.15.0
2
+ - Added SSL settings for: [#168](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/168)
3
+ - `ssl_enabled`: Enable/disable the SSL settings. If not provided, the value is inferred from the hosts scheme
4
+ - `ssl_certificate`: OpenSSL-style X.509 certificate file to authenticate the client
5
+ - `ssl_key`: OpenSSL-style RSA private key that corresponds to the `ssl_certificate`
6
+ - `ssl_truststore_path`: The JKS truststore to validate the server's certificate
7
+ - `ssl_truststore_type`: The format of the truststore file
8
+ - `ssl_truststore_password`: The truststore password
9
+ - `ssl_keystore_path`: The keystore used to present a certificate to the server
10
+ - `ssl_keystore_type`: The format of the keystore file
11
+ - `ssl_keystore_password`: The keystore password
12
+ - `ssl_cipher_suites`: The list of cipher suites to use
13
+ - `ssl_supported_protocols`: Supported protocols with versions
14
+ - `ssl_verification_mode`: Defines how to verify the certificates presented by another party in the TLS connection
15
+ - Reviewed and deprecated SSL settings to comply with Logstash's naming convention
16
+ - Deprecated `ssl` in favor of `ssl_enabled`
17
+ - Deprecated `ca_file` in favor of `ssl_certificate_authorities`
18
+ - Deprecated `keystore` in favor of `ssl_keystore_path`
19
+ - Deprecated `keystore_password` in favor of `ssl_keystore_password`
20
+
21
+ ## 3.14.0
22
+ - Added support for configurable retries with new `retry_on_failure` and `retry_on_status` options [#160](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/160)
23
+
1
24
  ## 3.13.0
2
25
  - Added support for this plugin identifying itself to Elasticsearch with an SSL/TLS client certificate using a new `keystore` option [#162](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/162)
3
26
 
data/docs/index.asciidoc CHANGED
@@ -121,14 +121,13 @@ The `monitoring` permission at cluster level is necessary to perform periodic co
121
121
  [id="plugins-{type}s-{plugin}-options"]
122
122
  ==== Elasticsearch Filter Configuration Options
123
123
 
124
- This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>> described later.
124
+ This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>> and the <<plugins-{type}s-{plugin}-deprecated-options>> described later.
125
125
 
126
126
  [cols="<,<,<",options="header",]
127
127
  |=======================================================================
128
128
  |Setting |Input type|Required
129
129
  | <<plugins-{type}s-{plugin}-aggregation_fields>> |<<hash,hash>>|No
130
130
  | <<plugins-{type}s-{plugin}-api_key>> |<<password,password>>|No
131
- | <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|No
132
131
  | <<plugins-{type}s-{plugin}-ca_trusted_fingerprint>> |<<string,string>>|No
133
132
  | <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
134
133
  | <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
@@ -142,10 +141,23 @@ This plugin supports the following configuration options plus the <<plugins-{typ
142
141
  | <<plugins-{type}s-{plugin}-query>> |<<string,string>>|No
143
142
  | <<plugins-{type}s-{plugin}-query_template>> |<<string,string>>|No
144
143
  | <<plugins-{type}s-{plugin}-result_size>> |<<number,number>>|No
144
+ | <<plugins-{type}s-{plugin}-retry_on_failure>> |<<number,number>>|No
145
+ | <<plugins-{type}s-{plugin}-retry_on_status>> |<<number,number list>>|No
145
146
  | <<plugins-{type}s-{plugin}-sort>> |<<string,string>>|No
146
- | <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|No
147
- | <<plugins-{type}s-{plugin}-keystore>> |a valid filesystem path|No
148
- | <<plugins-{type}s-{plugin}-keystore_password>> |<<password,password>>|No
147
+ | <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|__Deprecated__
148
+ | <<plugins-{type}s-{plugin}-ssl_certificate>> |<<path,path>>|No
149
+ | <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> |list of <<path,path>>|No
150
+ | <<plugins-{type}s-{plugin}-ssl_cipher_suites>> |list of <<string,string>>|No
151
+ | <<plugins-{type}s-{plugin}-ssl_enabled>> |<<boolean,boolean>>|No
152
+ | <<plugins-{type}s-{plugin}-ssl_key>> |<<path,path>>|No
153
+ | <<plugins-{type}s-{plugin}-ssl_keystore_password>> |<<password,password>>|No
154
+ | <<plugins-{type}s-{plugin}-ssl_keystore_path>> |<<path,path>>|No
155
+ | <<plugins-{type}s-{plugin}-ssl_keystore_type>> |<<string,string>>|No
156
+ | <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<string,string>>|No
157
+ | <<plugins-{type}s-{plugin}-ssl_truststore_password>> |<<password,password>>|No
158
+ | <<plugins-{type}s-{plugin}-ssl_truststore_path>> |<<path,path>>|No
159
+ | <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>|No
160
+ | <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>, one of `["full", "none"]`|No
149
161
  | <<plugins-{type}s-{plugin}-tag_on_failure>> |<<array,array>>|No
150
162
  | <<plugins-{type}s-{plugin}-user>> |<<string,string>>|No
151
163
  |=======================================================================
@@ -180,19 +192,11 @@ Example:
180
192
  * There is no default value for this setting.
181
193
 
182
194
  Authenticate using Elasticsearch API key. Note that this option also requires
183
- enabling the `ssl` option.
195
+ enabling the <<plugins-{type}s-{plugin}-ssl_enabled>> option.
184
196
 
185
197
  Format is `id:api_key` where `id` and `api_key` are as returned by the
186
198
  Elasticsearch {ref}/security-api-create-api-key.html[Create API key API].
187
199
 
188
- [id="plugins-{type}s-{plugin}-ca_file"]
189
- ===== `ca_file`
190
-
191
- * Value type is <<path,path>>
192
- * There is no default value for this setting.
193
-
194
- SSL Certificate Authority file
195
-
196
200
  [id="plugins-{type}s-{plugin}-ca_trusted_fingerprint"]
197
201
  ===== `ca_trusted_fingerprint`
198
202
 
@@ -330,11 +334,30 @@ the {ref}/query-dsl.html[Elasticsearch query documentation].
330
334
  [id="plugins-{type}s-{plugin}-result_size"]
331
335
  ===== `result_size`
332
336
 
333
- * Value type is <<number,number>>
334
- * Default value is `1`
337
+ * Value type is <<number,number>>
338
+ * Default value is `1`
335
339
 
336
340
  How many results to return
337
341
 
342
+ [id="plugins-{type}s-{plugin}-retry_on_failure"]
343
+ ===== `retry_on_failure`
344
+
345
+ * Value type is <<number,number>>
346
+ * Default value is `0` (retries disabled)
347
+
348
+ How many times to retry an individual failed request.
349
+
350
+ When enabled, retry requests that result in connection errors or an HTTP status code included in <<plugins-{type}s-{plugin}-retry_on_status>>
351
+
352
+ [id="plugins-{type}s-{plugin}-retry_on_status"]
353
+ ===== `retry_on_status`
354
+
355
+ * Value type is <<number,number list>>
356
+ * Default value is an empty list `[]`
357
+
358
+ Which HTTP Status codes to consider for retries (in addition to connection errors) when using <<plugins-{type}s-{plugin}-retry_on_failure>>,
359
+
360
+
338
361
  [id="plugins-{type}s-{plugin}-sort"]
339
362
  ===== `sort`
340
363
 
@@ -343,30 +366,140 @@ How many results to return
343
366
 
344
367
  Comma-delimited list of `<field>:<direction>` pairs that define the sort order
345
368
 
346
- [id="plugins-{type}s-{plugin}-ssl"]
347
- ===== `ssl`
369
+ [id="plugins-{type}s-{plugin}-ssl_certificate"]
370
+ ===== `ssl_certificate`
371
+ * Value type is <<path,path>>
372
+ * There is no default value for this setting.
348
373
 
349
- * Value type is <<boolean,boolean>>
350
- * Default value is `false`
374
+ SSL certificate to use to authenticate the client. This certificate should be an OpenSSL-style X.509 certificate file.
351
375
 
352
- SSL
376
+ NOTE: This setting can be used only if <<plugins-{type}s-{plugin}-ssl_key>> is set.
353
377
 
354
- [id="plugins-{type}s-{plugin}-keystore"]
355
- ===== `keystore`
378
+ [id="plugins-{type}s-{plugin}-ssl_certificate_authorities"]
379
+ ===== `ssl_certificate_authorities`
380
+
381
+ * Value type is a list of <<path,path>>
382
+ * There is no default value for this setting
383
+
384
+ The .cer or .pem files to validate the server's certificate.
385
+
386
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_truststore_path>> at the same time.
387
+
388
+ [id="plugins-{type}s-{plugin}-ssl_cipher_suites"]
389
+ ===== `ssl_cipher_suites`
390
+ * Value type is a list of <<string,string>>
391
+ * There is no default value for this setting
392
+
393
+ The list of cipher suites to use, listed by priorities.
394
+ Supported cipher suites vary depending on the Java and protocol versions.
356
395
 
396
+
397
+ [id="plugins-{type}s-{plugin}-ssl_enabled"]
398
+ ===== `ssl_enabled`
399
+
400
+ * Value type is <<boolean,boolean>>
401
+ * There is no default value for this setting.
402
+
403
+ Enable SSL/TLS secured communication to Elasticsearch cluster.
404
+ Leaving this unspecified will use whatever scheme is specified in the URLs listed in <<plugins-{type}s-{plugin}-hosts>> or extracted from the <<plugins-{type}s-{plugin}-cloud_id>>.
405
+ If no explicit protocol is specified plain HTTP will be used.
406
+
407
+ [id="plugins-{type}s-{plugin}-ssl_key"]
408
+ ===== `ssl_key`
357
409
  * Value type is <<path,path>>
358
410
  * There is no default value for this setting.
359
411
 
360
- The keystore used to present a certificate to the server. It can be either .jks or .p12
412
+ OpenSSL-style RSA private key that corresponds to the <<plugins-{type}s-{plugin}-ssl_certificate>>.
361
413
 
362
- [id="plugins-{type}s-{plugin}-keystore_password"]
363
- ===== `keystore_password`
414
+ NOTE: This setting can be used only if <<plugins-{type}s-{plugin}-ssl_certificate>> is set.
415
+
416
+ [id="plugins-{type}s-{plugin}-ssl_keystore_password"]
417
+ ===== `ssl_keystore_password`
364
418
 
365
419
  * Value type is <<password,password>>
366
420
  * There is no default value for this setting.
367
421
 
368
422
  Set the keystore password
369
423
 
424
+ [id="plugins-{type}s-{plugin}-ssl_keystore_path"]
425
+ ===== `ssl_keystore_path`
426
+
427
+ * Value type is <<path,path>>
428
+ * There is no default value for this setting.
429
+
430
+ The keystore used to present a certificate to the server.
431
+ It can be either `.jks` or `.p12`
432
+
433
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_certificate>> at the same time.
434
+
435
+ [id="plugins-{type}s-{plugin}-ssl_keystore_type"]
436
+ ===== `ssl_keystore_type`
437
+
438
+ * Value can be any of: `jks`, `pkcs12`
439
+ * If not provided, the value will be inferred from the keystore filename.
440
+
441
+ The format of the keystore file. It must be either `jks` or `pkcs12`.
442
+
443
+ [id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
444
+ ===== `ssl_supported_protocols`
445
+
446
+ * Value type is <<string,string>>
447
+ * Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
448
+ * Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
449
+ `'TLSv1.1'` is not considered secure and is only provided for legacy applications.
450
+
451
+ List of allowed SSL/TLS versions to use when establishing a connection to the Elasticsearch cluster.
452
+
453
+ For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the
454
+ `LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash.
455
+
456
+ NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
457
+ the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
458
+ the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.
459
+
460
+ [id="plugins-{type}s-{plugin}-ssl_truststore_password"]
461
+ ===== `ssl_truststore_password`
462
+
463
+ * Value type is <<password,password>>
464
+ * There is no default value for this setting.
465
+
466
+ Set the truststore password
467
+
468
+ [id="plugins-{type}s-{plugin}-ssl_truststore_path"]
469
+ ===== `ssl_truststore_path`
470
+
471
+ * Value type is <<path,path>>
472
+ * There is no default value for this setting.
473
+
474
+ The truststore to validate the server's certificate.
475
+ It can be either `.jks` or `.p12`.
476
+
477
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> at the same time.
478
+
479
+ [id="plugins-{type}s-{plugin}-ssl_truststore_type"]
480
+ ===== `ssl_truststore_type`
481
+
482
+ * Value can be any of: `jks`, `pkcs12`
483
+ * If not provided, the value will be inferred from the truststore filename.
484
+
485
+ The format of the truststore file. It must be either `jks` or `pkcs12`.
486
+
487
+ [id="plugins-{type}s-{plugin}-ssl_verification_mode"]
488
+ ===== `ssl_verification_mode`
489
+
490
+ * Value can be any of: `full`, `none`
491
+ * Default value is `full`
492
+
493
+ Defines how to verify the certificates presented by another party in the TLS connection:
494
+
495
+ `full` validates that the server certificate has an issue date that’s within
496
+ the not_before and not_after dates; chains to a trusted Certificate Authority (CA), and
497
+ has a hostname or IP address that matches the names within the certificate.
498
+
499
+ `none` performs no certificate validation.
500
+
501
+ WARNING: Setting certificate verification to `none` disables many security benefits of SSL/TLS, which is very dangerous. For more information on disabling certificate verification please read https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf
502
+
370
503
  [id="plugins-{type}s-{plugin}-tag_on_failure"]
371
504
  ===== `tag_on_failure`
372
505
 
@@ -384,5 +517,57 @@ Tags the event on failure to look up previous log event information. This can be
384
517
  Basic Auth - username
385
518
 
386
519
 
520
+ [id="plugins-{type}s-{plugin}-deprecated-options"]
521
+ ==== Elasticsearch Filter Deprecated Configuration Options
522
+
523
+ This plugin supports the following deprecated configurations.
524
+
525
+ WARNING: Deprecated options are subject to removal in future releases.
526
+
527
+ [cols="<,<,<",options="header",]
528
+ |=======================================================================
529
+ |Setting|Input type|Replaced by
530
+ | <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|<<plugins-{type}s-{plugin}-ssl_certificate_authorities>>
531
+ | <<plugins-{type}s-{plugin}-keystore>> |a valid filesystem path|<<plugins-{type}s-{plugin}-ssl_keystore_path>>
532
+ | <<plugins-{type}s-{plugin}-keystore_password>> |<<password,password>>|<<plugins-{type}s-{plugin}-ssl_keystore_password>>
533
+ |=======================================================================
534
+
535
+ [id="plugins-{type}s-{plugin}-ca_file"]
536
+ ===== `ca_file`
537
+ deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_certificate_authorities>>]
538
+
539
+ * Value type is <<path,path>>
540
+ * There is no default value for this setting.
541
+
542
+ SSL Certificate Authority file
543
+
544
+ [id="plugins-{type}s-{plugin}-ssl"]
545
+ ===== `ssl`
546
+ deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_enabled>>]
547
+
548
+ * Value type is <<boolean,boolean>>
549
+ * Default value is `false`
550
+
551
+ SSL
552
+
553
+ [id="plugins-{type}s-{plugin}-keystore"]
554
+ ===== `keystore`
555
+ deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_keystore_path>>]
556
+
557
+ * Value type is <<path,path>>
558
+ * There is no default value for this setting.
559
+
560
+ The keystore used to present a certificate to the server. It can be either .jks or .p12
561
+
562
+ [id="plugins-{type}s-{plugin}-keystore_password"]
563
+ ===== `keystore_password`
564
+ deprecated[3.15.0, Replaced by <<plugins-{type}s-{plugin}-ssl_keystore_password>>]
565
+
566
+ * Value type is <<password,password>>
567
+ * There is no default value for this setting.
568
+
569
+ Set the keystore password
570
+
571
+
387
572
  [id="plugins-{type}s-{plugin}-common-options"]
388
573
  include::{include_path}/{type}.asciidoc[]
@@ -11,9 +11,6 @@ module LogStash
11
11
  attr_reader :client
12
12
 
13
13
  def initialize(logger, hosts, options = {})
14
- ssl = options.fetch(:ssl, false)
15
- keystore = options.fetch(:keystore, nil)
16
- keystore_password = options.fetch(:keystore_password, nil)
17
14
  user = options.fetch(:user, nil)
18
15
  password = options.fetch(:password, nil)
19
16
  api_key = options.fetch(:api_key, nil)
@@ -28,21 +25,22 @@ module LogStash
28
25
  logger.warn "Supplied proxy setting (proxy => '') has no effect" if @proxy.eql?('')
29
26
  transport_options[:proxy] = proxy.to_s if proxy && !proxy.eql?('')
30
27
 
31
- hosts = setup_hosts(hosts, ssl)
28
+ ssl_options = options.fetch(:ssl, { :enabled => false })
29
+ ssl_enabled = ssl_options.fetch(:enabled, false)
32
30
 
33
- ssl_options = {}
34
- # set ca_file even if ssl isn't on, since the host can be an https url
35
- ssl_options.update(ssl: true, ca_file: options[:ca_file]) if options[:ca_file]
36
- ssl_options.update(ssl: true, trust_strategy: options[:ssl_trust_strategy]) if options[:ssl_trust_strategy]
31
+ hosts = setup_hosts(hosts, ssl_enabled)
37
32
 
38
- if keystore
39
- ssl_options[:keystore] = keystore
40
- logger.debug("Keystore for client certificate", :keystore => keystore)
41
- ssl_options[:keystore_password] = keystore_password.value if keystore_password
42
- end
33
+ client_options = {
34
+ hosts: hosts,
35
+ transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore,
36
+ transport_options: transport_options,
37
+ ssl: ssl_options,
38
+ retry_on_failure: options[:retry_on_failure],
39
+ retry_on_status: options[:retry_on_status]
40
+ }
43
41
 
44
42
  logger.info("New ElasticSearch filter client", :hosts => hosts)
45
- @client = ::Elasticsearch::Client.new(hosts: hosts, transport_options: transport_options, transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore, :ssl => ssl_options)
43
+ @client = ::Elasticsearch::Client.new(client_options)
46
44
  end
47
45
 
48
46
  def search(params)
@@ -51,13 +49,14 @@ module LogStash
51
49
 
52
50
  private
53
51
 
54
- def setup_hosts(hosts, ssl)
52
+ def setup_hosts(hosts, ssl_enabled)
53
+ hosts = Array(hosts).map { |host| host.to_s } # potential SafeURI#to_s
55
54
  hosts.map do |h|
56
55
  if h.start_with?('http:/', 'https:/')
57
56
  h
58
57
  else
59
58
  host, port = h.split(':')
60
- { host: host, port: port, scheme: (ssl ? 'https' : 'http') }
59
+ { host: host, port: port, scheme: (ssl_enabled ? 'https' : 'http') }
61
60
  end
62
61
  end
63
62
  end
@@ -3,6 +3,7 @@ require "logstash/filters/base"
3
3
  require "logstash/namespace"
4
4
  require "logstash/json"
5
5
  require 'logstash/plugin_mixins/ca_trusted_fingerprint_support'
6
+ require "logstash/plugin_mixins/normalize_config_support"
6
7
 
7
8
  require_relative "elasticsearch/client"
8
9
  require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
@@ -61,17 +62,62 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
61
62
  config :proxy, :validate => :uri_or_empty
62
63
 
63
64
  # SSL
64
- config :ssl, :validate => :boolean, :default => false
65
+ config :ssl, :validate => :boolean, :default => false, :deprecated => "Set 'ssl_enabled' instead."
65
66
 
66
67
  # SSL Certificate Authority file
67
- config :ca_file, :validate => :path
68
+ config :ca_file, :validate => :path, :deprecated => "Set 'ssl_certificate_authorities' instead."
68
69
 
69
70
  # The keystore used to present a certificate to the server.
70
71
  # It can be either .jks or .p12
71
- config :keystore, :validate => :path
72
+ config :keystore, :validate => :path, :deprecated => "Use 'ssl_keystore_path' instead."
72
73
 
73
74
  # Set the keystore password
74
- config :keystore_password, :validate => :password
75
+ config :keystore_password, :validate => :password, :deprecated => "Use 'ssl_keystore_password' instead."
76
+
77
+ # OpenSSL-style X.509 certificate certificate to authenticate the client
78
+ config :ssl_certificate, :validate => :path
79
+
80
+ # SSL Certificate Authority files in PEM encoded format, must also include any chain certificates as necessary
81
+ config :ssl_certificate_authorities, :validate => :path, :list => true
82
+
83
+ # The list of cipher suites to use, listed by priorities.
84
+ # Supported cipher suites vary depending on which version of Java is used.
85
+ config :ssl_cipher_suites, :validate => :string, :list => true
86
+
87
+ # SSL
88
+ config :ssl_enabled, :validate => :boolean
89
+
90
+ # OpenSSL-style RSA private key to authenticate the client
91
+ config :ssl_key, :validate => :path
92
+
93
+ # Set the keystore password
94
+ config :ssl_keystore_password, :validate => :password
95
+
96
+ # The keystore used to present a certificate to the server.
97
+ # It can be either .jks or .p12
98
+ config :ssl_keystore_path, :validate => :path
99
+
100
+ # The format of the keystore file. It must be either jks or pkcs12
101
+ config :ssl_keystore_type, :validate => %w[pkcs12 jks]
102
+
103
+ # Supported protocols with versions.
104
+ config :ssl_supported_protocols, :validate => %w[TLSv1.1 TLSv1.2 TLSv1.3], :default => [], :list => true
105
+
106
+ # Set the truststore password
107
+ config :ssl_truststore_password, :validate => :password
108
+
109
+ # The JKS truststore to validate the server's certificate.
110
+ # Use either `:ssl_truststore_path` or `:ssl_certificate_authorities`
111
+ config :ssl_truststore_path, :validate => :path
112
+
113
+ # The format of the truststore file. It must be either jks or pkcs12
114
+ config :ssl_truststore_type, :validate => %w[pkcs12 jks]
115
+
116
+ # Options to verify the server's certificate.
117
+ # "full": validates that the provided certificate has an issue date that’s within the not_before and not_after dates;
118
+ # chains to a trusted Certificate Authority (CA); has a hostname or IP address that matches the names within the certificate.
119
+ # "none": performs no certificate validation. Disabling this severely compromises security (https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf)
120
+ config :ssl_verification_mode, :validate => %w[full none], :default => 'full'
75
121
 
76
122
  # Whether results should be sorted or not
77
123
  config :enable_sort, :validate => :boolean, :default => true
@@ -82,9 +128,17 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
82
128
  # Tags the event on failure to look up geo information. This can be used in later analysis.
83
129
  config :tag_on_failure, :validate => :array, :default => ["_elasticsearch_lookup_failure"]
84
130
 
131
+ # How many times to retry on failure?
132
+ config :retry_on_failure, :validate => :number, :default => 0
133
+
134
+ # What status codes to retry on?
135
+ config :retry_on_status, :validate => :number, :list => true, :default => [500, 502, 503, 504]
136
+
85
137
  # config :ca_trusted_fingerprint, :validate => :sha_256_hex
86
138
  include LogStash::PluginMixins::CATrustedFingerprintSupport
87
139
 
140
+ include LogStash::PluginMixins::NormalizeConfigSupport
141
+
88
142
  attr_reader :clients_pool
89
143
 
90
144
  ##
@@ -116,13 +170,10 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
116
170
  @query_dsl = file.read
117
171
  end
118
172
 
119
- if @keystore_password && !@keystore
120
- fail "`keystore_password` was provided, without a `keystore`"
121
- end
122
-
173
+ fill_hosts_from_cloud_id
174
+ setup_ssl_params!
123
175
  validate_authentication
124
176
  fill_user_password_from_cloud_auth
125
- fill_hosts_from_cloud_id
126
177
 
127
178
  @hosts = Array(@hosts).map { |host| host.to_s } # potential SafeURI#to_s
128
179
 
@@ -213,14 +264,80 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
213
264
  :password => @password,
214
265
  :api_key => @api_key,
215
266
  :proxy => @proxy,
216
- :ssl => @ssl,
217
- :ca_file => @ca_file,
218
- :keystore => @keystore,
219
- :keystore_password => @keystore_password,
220
- :ssl_trust_strategy => trust_strategy_for_ca_trusted_fingerprint
267
+ :ssl => client_ssl_options,
268
+ :retry_on_failure => @retry_on_failure,
269
+ :retry_on_status => @retry_on_status
221
270
  }
222
271
  end
223
272
 
273
+ def client_ssl_options
274
+ ssl_options = {}
275
+ ssl_options[:enabled] = @ssl_enabled
276
+
277
+ # If the deprecated `ssl` option was explicitly provided, it keeps the same behavior
278
+ # setting up all the client SSL configs even if ssl => false. Otherwise, it should use
279
+ # the @ssl_enabled value as it was either explicitly set by the `ssl_enabled` option or
280
+ # inferred from the hosts scheme.
281
+ return ssl_options unless @ssl_enabled || original_params.include?('ssl')
282
+
283
+ ssl_options[:enabled] = true
284
+ ssl_certificate_authorities, ssl_truststore_path, ssl_certificate, ssl_keystore_path = params.values_at('ssl_certificate_authorities', 'ssl_truststore_path', 'ssl_certificate', 'ssl_keystore_path')
285
+
286
+ if ssl_certificate_authorities && ssl_truststore_path
287
+ raise LogStash::ConfigurationError, 'Use either "ssl_certificate_authorities/ca_file" or "ssl_truststore_path" when configuring the CA certificate'
288
+ end
289
+
290
+ if ssl_certificate && ssl_keystore_path
291
+ raise LogStash::ConfigurationError, 'Use either "ssl_certificate" or "ssl_keystore_path/keystore" when configuring client certificates'
292
+ end
293
+
294
+ if ssl_certificate_authorities&.any?
295
+ raise LogStash::ConfigurationError, 'Multiple values on "ssl_certificate_authorities" are not supported by this plugin' if ssl_certificate_authorities.size > 1
296
+ ssl_options[:ca_file] = ssl_certificate_authorities.first
297
+ end
298
+
299
+ setup_client_ssl_store(ssl_options, 'truststore', ssl_truststore_path)
300
+ setup_client_ssl_store(ssl_options, 'keystore', ssl_keystore_path)
301
+ logger.debug("Keystore for client certificate", :keystore => ssl_keystore_path) if ssl_keystore_path
302
+
303
+ ssl_key = params["ssl_key"]
304
+ if ssl_certificate
305
+ raise LogStash::ConfigurationError, 'Using an "ssl_certificate" requires an "ssl_key"' unless ssl_key
306
+ ssl_options[:client_cert] = ssl_certificate
307
+ ssl_options[:client_key] = ssl_key
308
+ elsif !ssl_key.nil?
309
+ raise LogStash::ConfigurationError, 'An "ssl_certificate" is required when using an "ssl_key"'
310
+ end
311
+
312
+ ssl_verification_mode = params["ssl_verification_mode"]
313
+ unless ssl_verification_mode.nil?
314
+ case ssl_verification_mode
315
+ when 'none'
316
+ logger.warn "You have enabled encryption but DISABLED certificate verification, " +
317
+ "to make sure your data is secure set `ssl_verification_mode => full`"
318
+ ssl_options[:verify] = :disable
319
+ else
320
+ ssl_options[:verify] = :strict
321
+ end
322
+ end
323
+
324
+ ssl_options[:cipher_suites] = params["ssl_cipher_suites"] if params.include?("ssl_cipher_suites")
325
+ protocols = params['ssl_supported_protocols']
326
+ ssl_options[:protocols] = protocols if protocols&.any?
327
+ ssl_options[:trust_strategy] = trust_strategy_for_ca_trusted_fingerprint
328
+
329
+ ssl_options
330
+ end
331
+
332
+ # @param kind is a string [truststore|keystore]
333
+ def setup_client_ssl_store(ssl_options, kind, store_path)
334
+ if store_path
335
+ ssl_options[kind.to_sym] = store_path
336
+ ssl_options["#{kind}_type".to_sym] = params["ssl_#{kind}_type"] if params.include?("ssl_#{kind}_type")
337
+ ssl_options["#{kind}_password".to_sym] = params["ssl_#{kind}_password"].value if params.include?("ssl_#{kind}_password")
338
+ end
339
+ end
340
+
224
341
  def new_client
225
342
  # NOTE: could pass cloud-id/cloud-auth to client but than we would need to be stricter on ES version requirement
226
343
  # and also LS parsing might differ from ES client's parsing so for consistency we do not pass cloud options ...
@@ -282,7 +399,7 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
282
399
  raise LogStash::ConfigurationError, 'Multiple authentication options are specified, please only use one of user/password, cloud_auth or api_key'
283
400
  end
284
401
 
285
- if @api_key && @api_key.value && @ssl != true
402
+ if @api_key && @api_key.value && @ssl_enabled != true
286
403
  raise(LogStash::ConfigurationError, "Using api_key authentication requires SSL/TLS secured communication using the `ssl => true` option")
287
404
  end
288
405
  end
@@ -345,4 +462,48 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
345
462
  raise LogStash::ConfigurationError, "Could not connect to a compatible version of Elasticsearch"
346
463
  end
347
464
  end
465
+
466
+ def setup_ssl_params!
467
+ @ssl_enabled = normalize_config(:ssl_enabled) do |normalize|
468
+ normalize.with_deprecated_alias(:ssl)
469
+ end
470
+
471
+ # Infer the value if neither the deprecate `ssl` and `ssl_enabled` were set
472
+ infer_ssl_enabled_from_hosts
473
+
474
+ @ssl_keystore_path = normalize_config(:ssl_keystore_path) do |normalize|
475
+ normalize.with_deprecated_alias(:keystore)
476
+ end
477
+
478
+ @ssl_keystore_password = normalize_config(:ssl_keystore_password) do |normalize|
479
+ normalize.with_deprecated_alias(:keystore_password)
480
+ end
481
+
482
+ @ssl_certificate_authorities = normalize_config(:ssl_certificate_authorities) do |normalize|
483
+ normalize.with_deprecated_mapping(:ca_file) do |ca_file|
484
+ [ca_file]
485
+ end
486
+ end
487
+
488
+ params['ssl_enabled'] = @ssl_enabled
489
+ params['ssl_keystore_path'] = @ssl_keystore_path unless @ssl_keystore_path.nil?
490
+ params['ssl_keystore_password'] = @ssl_keystore_password unless @ssl_keystore_password.nil?
491
+ params['ssl_certificate_authorities'] = @ssl_certificate_authorities unless @ssl_certificate_authorities.nil?
492
+ end
493
+
494
+ def infer_ssl_enabled_from_hosts
495
+ return if original_params.include?('ssl') || original_params.include?('ssl_enabled')
496
+
497
+ @ssl_enabled = params['ssl_enabled'] = effectively_ssl?
498
+ end
499
+
500
+ def effectively_ssl?
501
+ return true if @ssl_enabled
502
+
503
+ hosts = Array(@hosts)
504
+ return false if hosts.nil? || hosts.empty?
505
+
506
+ hosts.all? { |host| host && host.to_s.start_with?("https") }
507
+ end
508
+
348
509
  end #class LogStash::Filters::Elasticsearch
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-elasticsearch'
4
- s.version = '3.13.0'
4
+ s.version = '3.15.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Copies fields from previous log events in Elasticsearch to current events "
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/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -24,9 +24,8 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency 'elasticsearch', ">= 7.14.0" # LS >= 6.7 and < 7.14 all used version 5.0.5
25
25
  s.add_runtime_dependency 'manticore', ">= 0.7.1"
26
26
  s.add_runtime_dependency 'logstash-mixin-ca_trusted_fingerprint_support', '~> 1.0'
27
+ s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
27
28
  s.add_development_dependency 'cabin', ['~> 0.6']
28
29
  s.add_development_dependency 'webrick'
29
-
30
30
  s.add_development_dependency 'logstash-devutils'
31
31
  end
32
-
@@ -301,6 +301,15 @@ describe LogStash::Filters::Elasticsearch do
301
301
  end
302
302
  end
303
303
 
304
+ context 'with client-level retries' do
305
+ let(:config) do
306
+ super().merge(
307
+ "retry_on_failure" => 3,
308
+ "retry_on_status" => [500]
309
+ )
310
+ end
311
+ end
312
+
304
313
  context "if query is on nested field" do
305
314
  let(:config) do
306
315
  {
@@ -515,7 +524,7 @@ describe LogStash::Filters::Elasticsearch do
515
524
  end
516
525
 
517
526
  context "with ssl" do
518
- let(:config) { super().merge({ 'api_key' => LogStash::Util::Password.new('foo:bar'), "ssl" => true }) }
527
+ let(:config) { super().merge({ 'api_key' => LogStash::Util::Password.new('foo:bar'), "ssl_enabled" => true }) }
519
528
 
520
529
  it "should set authorization" do
521
530
  plugin.register
@@ -559,11 +568,33 @@ describe LogStash::Filters::Elasticsearch do
559
568
  end
560
569
  end
561
570
  end
571
+
572
+ describe "retry_on_failure" do
573
+ let(:config) { super().merge("retry_on_failure" => 3) }
574
+
575
+ it 'propagates to the client' do
576
+ plugin.register
577
+
578
+ client = plugin.send(:get_client).client
579
+ expect( extract_transport(client).options[:retry_on_failure] ).to eq(3)
580
+ end
581
+ end
582
+
583
+ describe "retry_on_status" do
584
+ let(:config) { super().merge("retry_on_status" => [500, 502, 503, 504]) }
585
+
586
+ it 'propagates to the client' do
587
+ plugin.register
588
+
589
+ client = plugin.send(:get_client).client
590
+ expect( extract_transport(client).options[:retry_on_status] ).to eq([500, 502, 503, 504])
591
+ end
592
+ end
562
593
  end
563
594
 
564
595
  describe "ca_trusted_fingerprint" do
565
596
  let(:ca_trusted_fingerprint) { SecureRandom.hex(32) }
566
- let(:config) { {"ca_trusted_fingerprint" => ca_trusted_fingerprint}}
597
+ let(:config) { {"ssl_enabled" => true, "ca_trusted_fingerprint" => ca_trusted_fingerprint}}
567
598
 
568
599
  subject(:plugin) { described_class.new(config) }
569
600
 
@@ -599,8 +630,9 @@ describe LogStash::Filters::Elasticsearch do
599
630
 
600
631
  let(:config) do
601
632
  {
602
- 'keystore' => keystore_path,
603
- 'keystore_password' => keystore_password,
633
+ 'hosts' => 'https://localhost:9200',
634
+ 'ssl_keystore_path' => keystore_path,
635
+ 'ssl_keystore_password' => keystore_password,
604
636
  }
605
637
  end
606
638
 
@@ -0,0 +1,264 @@
1
+ require 'stud/temporary'
2
+ require "elasticsearch"
3
+ require "logstash/codecs/base"
4
+
5
+ describe "SSL options" do
6
+ let(:es_client_double) { double("Elasticsearch::Client #{self.inspect}") }
7
+ let(:hosts) {["localhost"]}
8
+ let(:settings) { { "ssl_enabled" => true, "hosts" => hosts } }
9
+
10
+ subject do
11
+ require "logstash/filters/elasticsearch"
12
+ LogStash::Filters::Elasticsearch.new(settings)
13
+ end
14
+
15
+ before do
16
+ allow(es_client_double).to receive(:close)
17
+ allow(es_client_double).to receive(:ping).with(any_args).and_return(double("pong").as_null_object)
18
+ allow(Elasticsearch::Client).to receive(:new).and_return(es_client_double)
19
+ end
20
+
21
+ after do
22
+ subject.close
23
+ end
24
+
25
+ context "when ssl_enabled is" do
26
+ context "true and there is no https hosts" do
27
+ let(:hosts) { %w[http://es01 http://es01] }
28
+
29
+ it "should not infer the ssl_enabled value" do
30
+ subject.register
31
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(true)
32
+ expect(subject.params).to match hash_including("ssl_enabled" => true)
33
+ end
34
+ end
35
+
36
+ context "false and cloud_id resolved host is https" do
37
+ let(:settings) {{
38
+ "ssl_enabled" => false,
39
+ "cloud_id" => "sample:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJGFjMzFlYmI5MDI0MTc3MzE1NzA0M2MzNGZkMjZmZDQ2OjkyNDMkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA6OTI0NA=="
40
+ }}
41
+
42
+ it "should not infer the ssl_enabled value" do
43
+ subject.register
44
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(false)
45
+ expect(subject.params).to match hash_including("ssl_enabled" => false)
46
+ end
47
+ end
48
+ end
49
+
50
+ context "when neither ssl nor ssl_enabled is set" do
51
+ let(:settings) { super().reject { |k| %w[ssl ssl_enabled].include?(k) } }
52
+
53
+ context "and there is no https hosts" do
54
+ let(:hosts) { %w[http://es01 http://es01] }
55
+
56
+ it "should infer the ssl_enabled value to false" do
57
+ subject.register
58
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(false)
59
+ expect(subject.params).to match hash_including("ssl_enabled" => false)
60
+ end
61
+ end
62
+
63
+ context "and there is https hosts" do
64
+ let(:hosts) { %w[https://sec-es01 https://sec-es01] }
65
+
66
+ it "should infer the ssl_enabled value to true" do
67
+ subject.register
68
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(true)
69
+ expect(subject.params).to match hash_including("ssl_enabled" => true)
70
+ end
71
+ end
72
+
73
+ context "and hosts have no scheme defined" do
74
+ let(:hosts) { %w[es01 es01] }
75
+
76
+ it "should infer the ssl_enabled value to false" do
77
+ subject.register
78
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(false)
79
+ expect(subject.params).to match hash_including("ssl_enabled" => false)
80
+ end
81
+ end
82
+
83
+ context "and cloud_id resolved host is https" do
84
+ let(:settings) {{
85
+ "cloud_id" => "sample:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJGFjMzFlYmI5MDI0MTc3MzE1NzA0M2MzNGZkMjZmZDQ2OjkyNDMkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA6OTI0NA=="
86
+ }}
87
+
88
+ it "should infer the ssl_enabled value to false" do
89
+ subject.register
90
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(true)
91
+ expect(subject.params).to match hash_including("ssl_enabled" => true)
92
+ end
93
+ end
94
+ end
95
+
96
+ context "when ssl_verification_mode" do
97
+ context "is set to none" do
98
+ let(:settings) { super().merge(
99
+ "ssl_verification_mode" => "none",
100
+ ) }
101
+
102
+ it "should print a warning" do
103
+ expect(subject.logger).to receive(:warn).with(/You have enabled encryption but DISABLED certificate verification/).at_least(:once)
104
+ allow(subject.logger).to receive(:warn).with(any_args)
105
+
106
+ subject.register
107
+ end
108
+
109
+ it "should pass the flag to the ES client" do
110
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
111
+ expect(args[:ssl]).to match hash_including(:enabled => true, :verify => :disable)
112
+ end.and_return(es_client_double)
113
+
114
+ subject.register
115
+ end
116
+ end
117
+
118
+ context "is set to full" do
119
+ let(:settings) { super().merge(
120
+ "ssl_verification_mode" => 'full',
121
+ ) }
122
+
123
+ it "should pass the flag to the ES client" do
124
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
125
+ expect(args[:ssl]).to match hash_including(:enabled => true, :verify => :strict)
126
+ end.and_return(es_client_double)
127
+
128
+ subject.register
129
+ end
130
+ end
131
+ end
132
+
133
+ context "with the conflicting configs" do
134
+ context "ssl_certificate_authorities and ssl_truststore_path set" do
135
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
136
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
137
+ let(:settings) { super().merge(
138
+ "ssl_truststore_path" => ssl_truststore_path,
139
+ "ssl_certificate_authorities" => ssl_certificate_authorities_path
140
+ ) }
141
+
142
+ after :each do
143
+ File.delete(ssl_truststore_path)
144
+ File.delete(ssl_certificate_authorities_path)
145
+ end
146
+
147
+ it "should raise a configuration error" do
148
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate_authorities\/ca_file" or "ssl_truststore_path"/)
149
+ end
150
+ end
151
+
152
+ context "ssl_certificate and ssl_keystore_path set" do
153
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
154
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
155
+ let(:settings) { super().merge(
156
+ "ssl_certificate" => ssl_certificate_path,
157
+ "ssl_keystore_path" => ssl_keystore_path
158
+ ) }
159
+
160
+ after :each do
161
+ File.delete(ssl_keystore_path)
162
+ File.delete(ssl_certificate_path)
163
+ end
164
+
165
+ it "should raise a configuration error" do
166
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate" or "ssl_keystore_path\/keystore"/)
167
+ end
168
+ end
169
+ end
170
+
171
+ context "when configured with Java store files" do
172
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
173
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
174
+
175
+ after :each do
176
+ File.delete(ssl_truststore_path)
177
+ File.delete(ssl_keystore_path)
178
+ end
179
+
180
+ let(:settings) { super().merge(
181
+ "ssl_truststore_path" => ssl_truststore_path,
182
+ "ssl_truststore_type" => "jks",
183
+ "ssl_truststore_password" => "foo",
184
+ "ssl_keystore_path" => ssl_keystore_path,
185
+ "ssl_keystore_type" => "jks",
186
+ "ssl_keystore_password" => "bar",
187
+ "ssl_verification_mode" => "full",
188
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
189
+ "ssl_supported_protocols" => ["TLSv1.3"]
190
+ ) }
191
+
192
+ it "should pass the parameters to the ES client" do
193
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
194
+ expect(args[:ssl]).to match hash_including(
195
+ :enabled => true,
196
+ :keystore => ssl_keystore_path,
197
+ :keystore_type => "jks",
198
+ :keystore_password => "bar",
199
+ :truststore => ssl_truststore_path,
200
+ :truststore_type => "jks",
201
+ :truststore_password => "foo",
202
+ :verify => :strict,
203
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
204
+ :protocols => ["TLSv1.3"],
205
+ )
206
+ end.and_return(es_client_double)
207
+
208
+ subject.register
209
+ end
210
+ end
211
+
212
+ context "when configured with certificate files" do
213
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
214
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
215
+ let(:ssl_key_path) { Stud::Temporary.file.path }
216
+ let(:settings) { super().merge(
217
+ "ssl_certificate_authorities" => [ssl_certificate_authorities_path],
218
+ "ssl_certificate" => ssl_certificate_path,
219
+ "ssl_key" => ssl_key_path,
220
+ "ssl_verification_mode" => "full",
221
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
222
+ "ssl_supported_protocols" => ["TLSv1.3"]
223
+ ) }
224
+
225
+ after :each do
226
+ File.delete(ssl_certificate_authorities_path)
227
+ File.delete(ssl_certificate_path)
228
+ File.delete(ssl_key_path)
229
+ end
230
+
231
+ it "should pass the parameters to the ES client" do
232
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
233
+ expect(args[:ssl]).to match hash_including(
234
+ :enabled => true,
235
+ :ca_file => ssl_certificate_authorities_path,
236
+ :client_cert => ssl_certificate_path,
237
+ :client_key => ssl_key_path,
238
+ :verify => :strict,
239
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
240
+ :protocols => ["TLSv1.3"],
241
+ )
242
+ end.and_return(es_client_double)
243
+
244
+ subject.register
245
+ end
246
+
247
+ context "and only the ssl_certificate is set" do
248
+ let(:settings) { super().reject { |k| "ssl_key".eql?(k) } }
249
+
250
+ it "should raise a configuration error" do
251
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Using an "ssl_certificate" requires an "ssl_key"/)
252
+ end
253
+ end
254
+
255
+ context "and only the ssl_key is set" do
256
+ let(:settings) { super().reject { |k| "ssl_certificate".eql?(k) } }
257
+
258
+ it "should raise a configuration error" do
259
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /An "ssl_certificate" is required when using an "ssl_key"/)
260
+ end
261
+ end
262
+ end
263
+ end
264
+
@@ -29,7 +29,7 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
29
29
 
30
30
  let(:config) do
31
31
  config = ELASTIC_SECURITY_ENABLED ? base_config.merge(credentials) : base_config
32
- config = { 'ca_file' => ca_path }.merge(config) if SECURE_INTEGRATION
32
+ config = { 'ssl_certificate_authorities' => ca_path }.merge(config) if SECURE_INTEGRATION
33
33
  config
34
34
  end
35
35
 
@@ -92,7 +92,7 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
92
92
  context 'setting host:port (and ssl)' do # reproduces GH-155
93
93
 
94
94
  let(:config) do
95
- super().merge "hosts" => [ESHelper.get_host_port], "ssl" => SECURE_INTEGRATION
95
+ super().merge "hosts" => [ESHelper.get_host_port], "ssl_enabled" => SECURE_INTEGRATION
96
96
  end
97
97
 
98
98
  it "works" do
@@ -110,9 +110,9 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
110
110
  let(:config) do
111
111
  super().merge(
112
112
  "hosts" => [ESHelper.get_host_port],
113
- "keystore" => keystore_path,
114
- "keystore_password" => keystore_password,
115
- "ssl" => true,
113
+ "ssl_keystore_path" => keystore_path,
114
+ "ssl_keystore_password" => keystore_password,
115
+ "ssl_enabled" => true,
116
116
  "fields" => { "this" => "contents", "response" => "four-oh-four" }
117
117
  )
118
118
  end
@@ -132,7 +132,7 @@ describe LogStash::Filters::Elasticsearch, :integration => true do
132
132
 
133
133
  let(:config) do
134
134
  bc = super()
135
- bc.delete('ca_file')
135
+ bc.delete('ssl_certificate_authorities')
136
136
  bc.merge({
137
137
  'ca_trusted_fingerprint' => ca_trusted_fingerprint,
138
138
  'fields' => { "this" => "contents", "response" => "four-oh-four" }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.0
4
+ version: 3.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-26 00:00:00.000000000 Z
11
+ date: 2023-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '1.0'
75
+ - !ruby/object:Gem::Dependency
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.0'
81
+ name: logstash-mixin-normalize_config_support
82
+ prerelease: false
83
+ type: :runtime
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
75
89
  - !ruby/object:Gem::Dependency
76
90
  requirement: !ruby/object:Gem::Requirement
77
91
  requirements:
@@ -135,6 +149,7 @@ files:
135
149
  - logstash-filter-elasticsearch.gemspec
136
150
  - spec/es_helper.rb
137
151
  - spec/filters/elasticsearch_spec.rb
152
+ - spec/filters/elasticsearch_ssl_spec.rb
138
153
  - spec/filters/fixtures/elasticsearch_7.x_hits_total_as_object.json
139
154
  - spec/filters/fixtures/generate_test_certs.openssl.cnf
140
155
  - spec/filters/fixtures/generate_test_certs.sh
@@ -187,6 +202,7 @@ summary: Copies fields from previous log events in Elasticsearch to current even
187
202
  test_files:
188
203
  - spec/es_helper.rb
189
204
  - spec/filters/elasticsearch_spec.rb
205
+ - spec/filters/elasticsearch_ssl_spec.rb
190
206
  - spec/filters/fixtures/elasticsearch_7.x_hits_total_as_object.json
191
207
  - spec/filters/fixtures/generate_test_certs.openssl.cnf
192
208
  - spec/filters/fixtures/generate_test_certs.sh