logstash-input-elasticsearch 4.15.0 → 4.17.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: 9379a31460bf649615c038b1b35d207f6a6db869bb1a27e963da70e278ae6bcd
4
- data.tar.gz: f62823b8ddfb587ce9614a1d131be1bce2186dbd859287b1107757917a754c7e
3
+ metadata.gz: 43e3c8e44ba8bd1ce4065a1410b26a63d621180d0354b4b4aa8f3891962d9986
4
+ data.tar.gz: c9f6d3b53d1bb90c9ad77eab86b92818128f310aa95a80e2908bdc5b981a780f
5
5
  SHA512:
6
- metadata.gz: c675ed6a5d1a4a104313611e4895171c6461149d0415c5ad4c276e42b5b99672584ae38ddc37f3e32521074727051c68f0d10a37b77064d0cea6ea03f041a3b9
7
- data.tar.gz: beba1b98be77880e6e3712cebdd0474d68c33556a86236e828a3332d2e812b187e920e78f6fb006b27b82269faa0e0654568d050f7057ae7db48da7fd9a20e31
6
+ metadata.gz: 5799d6ef93349a2ca9a6408bba0bbaa78f5c985137a4d126c70efe53122b7eac4d1fcda48aeb51f629651ea04e4457e9bb9705b760744b0ff22cd462f617c7b8
7
+ data.tar.gz: f0057cebd50dc79156d8f05be48341f009366fc9057df0f61d50327a3cecf0a95ebccd05bed120173ab429caab295d5b71f25edc04232fd36ecf862ad58bd974
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## 4.17.0
2
+ - Added SSL settings for: [#185](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/185)
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
+ - Reviewed and deprecated SSL settings to comply with Logstash's naming convention
15
+ - Deprecated `ssl` in favor of `ssl_enabled`
16
+ - Deprecated `ca_file` in favor of `ssl_certificate_authorities`
17
+ - Deprecated `ssl_certificate_verification` in favor of `ssl_verification_mode`
18
+
19
+ ## 4.16.0
20
+ - Added `ssl_certificate_verification` option to control SSL certificate verification [#180](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/180)
21
+
1
22
  ## 4.15.0
2
23
  - Feat: add `retries` option. allow retry for failing query [#179](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/179)
3
24
 
data/docs/index.asciidoc CHANGED
@@ -96,13 +96,12 @@ TIP: Set the `target` option to avoid potential schema conflicts.
96
96
  [id="plugins-{type}s-{plugin}-options"]
97
97
  ==== Elasticsearch Input configuration options
98
98
 
99
- This plugin supports the following configuration options plus the <<plugins-{type}s-{plugin}-common-options>> described later.
99
+ 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.
100
100
 
101
101
  [cols="<,<,<",options="header",]
102
102
  |=======================================================================
103
103
  |Setting |Input type|Required
104
104
  | <<plugins-{type}s-{plugin}-api_key>> |<<password,password>>|No
105
- | <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|No
106
105
  | <<plugins-{type}s-{plugin}-ca_trusted_fingerprint>> |<<string,string>>|No
107
106
  | <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
108
107
  | <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
@@ -121,7 +120,19 @@ This plugin supports the following configuration options plus the <<plugins-{typ
121
120
  | <<plugins-{type}s-{plugin}-scroll>> |<<string,string>>|No
122
121
  | <<plugins-{type}s-{plugin}-size>> |<<number,number>>|No
123
122
  | <<plugins-{type}s-{plugin}-slices>> |<<number,number>>|No
124
- | <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|No
123
+ | <<plugins-{type}s-{plugin}-ssl_certificate>> |<<path,path>>|No
124
+ | <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> |list of <<path,path>>|No
125
+ | <<plugins-{type}s-{plugin}-ssl_cipher_suites>> |list of <<string,string>>|No
126
+ | <<plugins-{type}s-{plugin}-ssl_enabled>> |<<boolean,boolean>>|No
127
+ | <<plugins-{type}s-{plugin}-ssl_key>> |<<path,path>>|No
128
+ | <<plugins-{type}s-{plugin}-ssl_keystore_password>> |<<password,password>>|No
129
+ | <<plugins-{type}s-{plugin}-ssl_keystore_path>> |<<path,path>>|No
130
+ | <<plugins-{type}s-{plugin}-ssl_keystore_type>> |<<string,string>>|No
131
+ | <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<string,string>>|No
132
+ | <<plugins-{type}s-{plugin}-ssl_truststore_password>> |<<password,password>>|No
133
+ | <<plugins-{type}s-{plugin}-ssl_truststore_path>> |<<path,path>>|No
134
+ | <<plugins-{type}s-{plugin}-ssl_truststore_type>> |<<string,string>>|No
135
+ | <<plugins-{type}s-{plugin}-ssl_verification_mode>> |<<string,string>>, one of `["full", "none"]`|No
125
136
  | <<plugins-{type}s-{plugin}-socket_timeout_seconds>> | <<number,number>>|No
126
137
  | <<plugins-{type}s-{plugin}-target>> | {logstash-ref}/field-references-deepdive.html[field reference] | No
127
138
  | <<plugins-{type}s-{plugin}-retries>> | <<number,number>>|No
@@ -139,21 +150,13 @@ input plugins.
139
150
  * Value type is <<password,password>>
140
151
  * There is no default value for this setting.
141
152
 
142
- Authenticate using Elasticsearch API key. Note that this option also requires enabling the `ssl` option.
153
+ Authenticate using Elasticsearch API key. Note that this option also requires enabling the <<plugins-{type}s-{plugin}-ssl_enabled>> option.
143
154
 
144
155
  Format is `id:api_key` where `id` and `api_key` are as returned by the
145
156
  Elasticsearch
146
157
  {ref}/security-api-create-api-key.html[Create
147
158
  API key API].
148
159
 
149
- [id="plugins-{type}s-{plugin}-ca_file"]
150
- ===== `ca_file`
151
-
152
- * Value type is <<path,path>>
153
- * There is no default value for this setting.
154
-
155
- SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary.
156
-
157
160
  [id="plugins-{type}s-{plugin}-ca_trusted_fingerprint"]
158
161
  ===== `ca_trusted_fingerprint`
159
162
 
@@ -405,14 +408,138 @@ NOTE: The Elasticsearch manual indicates that there can be _negative_ performanc
405
408
  If the `slices` parameter is left unset, the plugin will _not_ inject slice
406
409
  instructions into the query.
407
410
 
408
- [id="plugins-{type}s-{plugin}-ssl"]
409
- ===== `ssl`
411
+ [id="plugins-{type}s-{plugin}-ssl_certificate"]
412
+ ===== `ssl_certificate`
413
+ * Value type is <<path,path>>
414
+ * There is no default value for this setting.
415
+
416
+ SSL certificate to use to authenticate the client. This certificate should be an OpenSSL-style X.509 certificate file.
417
+
418
+ NOTE: This setting can be used only if <<plugins-{type}s-{plugin}-ssl_key>> is set.
419
+
420
+ [id="plugins-{type}s-{plugin}-ssl_certificate_authorities"]
421
+ ===== `ssl_certificate_authorities`
422
+
423
+ * Value type is a list of <<path,path>>
424
+ * There is no default value for this setting
425
+
426
+ The `.cer` or `.pem` files to validate the server's certificate.
427
+
428
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_truststore_path>> at the same time.
429
+
430
+ [id="plugins-{type}s-{plugin}-ssl_cipher_suites"]
431
+ ===== `ssl_cipher_suites`
432
+ * Value type is a list of <<string,string>>
433
+ * There is no default value for this setting
434
+
435
+ The list of cipher suites to use, listed by priorities.
436
+ Supported cipher suites vary depending on the Java and protocol versions.
437
+
438
+ [id="plugins-{type}s-{plugin}-ssl_enabled"]
439
+ ===== `ssl_enabled`
410
440
 
411
441
  * Value type is <<boolean,boolean>>
412
- * Default value is `false`
442
+ * There is no default value for this setting.
413
443
 
414
- If enabled, SSL will be used when communicating with the Elasticsearch
415
- server (i.e. HTTPS will be used instead of plain HTTP).
444
+ Enable SSL/TLS secured communication to Elasticsearch cluster.
445
+ 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>>.
446
+ If no explicit protocol is specified plain HTTP will be used.
447
+
448
+ [id="plugins-{type}s-{plugin}-ssl_key"]
449
+ ===== `ssl_key`
450
+ * Value type is <<path,path>>
451
+ * There is no default value for this setting.
452
+
453
+ OpenSSL-style RSA private key that corresponds to the <<plugins-{type}s-{plugin}-ssl_certificate>>.
454
+
455
+ NOTE: This setting can be used only if <<plugins-{type}s-{plugin}-ssl_certificate>> is set.
456
+
457
+ [id="plugins-{type}s-{plugin}-ssl_keystore_password"]
458
+ ===== `ssl_keystore_password`
459
+
460
+ * Value type is <<password,password>>
461
+ * There is no default value for this setting.
462
+
463
+ Set the keystore password
464
+
465
+ [id="plugins-{type}s-{plugin}-ssl_keystore_path"]
466
+ ===== `ssl_keystore_path`
467
+
468
+ * Value type is <<path,path>>
469
+ * There is no default value for this setting.
470
+
471
+ The keystore used to present a certificate to the server.
472
+ It can be either `.jks` or `.p12`
473
+
474
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_certificate>> at the same time.
475
+
476
+ [id="plugins-{type}s-{plugin}-ssl_keystore_type"]
477
+ ===== `ssl_keystore_type`
478
+
479
+ * Value can be any of: `jks`, `pkcs12`
480
+ * If not provided, the value will be inferred from the keystore filename.
481
+
482
+ The format of the keystore file. It must be either `jks` or `pkcs12`.
483
+
484
+ [id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
485
+ ===== `ssl_supported_protocols`
486
+
487
+ * Value type is <<string,string>>
488
+ * Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
489
+ * Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
490
+ `'TLSv1.1'` is not considered secure and is only provided for legacy applications.
491
+
492
+ List of allowed SSL/TLS versions to use when establishing a connection to the Elasticsearch cluster.
493
+
494
+ For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the
495
+ `LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash.
496
+
497
+ NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
498
+ the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
499
+ the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.
500
+
501
+ [id="plugins-{type}s-{plugin}-ssl_truststore_password"]
502
+ ===== `ssl_truststore_password`
503
+
504
+ * Value type is <<password,password>>
505
+ * There is no default value for this setting.
506
+
507
+ Set the truststore password.
508
+
509
+ [id="plugins-{type}s-{plugin}-ssl_truststore_path"]
510
+ ===== `ssl_truststore_path`
511
+
512
+ * Value type is <<path,path>>
513
+ * There is no default value for this setting.
514
+
515
+ The truststore to validate the server's certificate.
516
+ It can be either .jks or .p12.
517
+
518
+ NOTE: You cannot use this setting and <<plugins-{type}s-{plugin}-ssl_certificate_authorities>> at the same time.
519
+
520
+ [id="plugins-{type}s-{plugin}-ssl_truststore_type"]
521
+ ===== `ssl_truststore_type`
522
+
523
+ * Value can be any of: `jks`, `pkcs12`
524
+ * If not provided, the value will be inferred from the truststore filename.
525
+
526
+ The format of the truststore file. It must be either `jks` or `pkcs12`.
527
+
528
+ [id="plugins-{type}s-{plugin}-ssl_verification_mode"]
529
+ ===== `ssl_verification_mode`
530
+
531
+ * Value can be any of: `full`, `none`
532
+ * Default value is `full`
533
+
534
+ Defines how to verify the certificates presented by another party in the TLS connection:
535
+
536
+ `full` validates that the server certificate has an issue date that’s within
537
+ the not_before and not_after dates; chains to a trusted Certificate Authority (CA), and
538
+ has a hostname or IP address that matches the names within the certificate.
539
+
540
+ `none` performs no certificate validation.
541
+
542
+ 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
416
543
 
417
544
  [id="plugins-{type}s-{plugin}-socket_timeout_seconds"]
418
545
  ===== `socket_timeout_seconds`
@@ -448,6 +575,55 @@ option when authenticating to the Elasticsearch server. If set to an
448
575
  empty string authentication will be disabled.
449
576
 
450
577
 
578
+ [id="plugins-{type}s-{plugin}-deprecated-options"]
579
+ ==== Elasticsearch Input deprecated configuration options
580
+
581
+ This plugin supports the following deprecated configurations.
582
+
583
+ WARNING: Deprecated options are subject to removal in future releases.
584
+
585
+ [cols="<,<,<",options="header",]
586
+ |=======================================================================
587
+ |Setting|Input type|Replaced by
588
+ | <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|<<plugins-{type}s-{plugin}-ssl_certificate_authorities>>
589
+ | <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|<<plugins-{type}s-{plugin}-ssl_enabled>>
590
+ | <<plugins-{type}s-{plugin}-ssl_certificate_verification>> |<<boolean,boolean>>|<<plugins-{type}s-{plugin}-ssl_verification_mode>>
591
+ |=======================================================================
592
+
593
+ [id="plugins-{type}s-{plugin}-ca_file"]
594
+ ===== `ca_file`
595
+ deprecated[4.17.0, Replaced by <<plugins-{type}s-{plugin}-ssl_certificate_authorities>>]
596
+
597
+ * Value type is <<path,path>>
598
+ * There is no default value for this setting.
599
+
600
+ SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary.
601
+
602
+ [id="plugins-{type}s-{plugin}-ssl"]
603
+ ===== `ssl`
604
+ deprecated[4.17.0, Replaced by <<plugins-{type}s-{plugin}-ssl_enabled>>]
605
+
606
+ * Value type is <<boolean,boolean>>
607
+ * Default value is `false`
608
+
609
+ If enabled, SSL will be used when communicating with the Elasticsearch
610
+ server (i.e. HTTPS will be used instead of plain HTTP).
611
+
612
+
613
+ [id="plugins-{type}s-{plugin}-ssl_certificate_verification"]
614
+ ===== `ssl_certificate_verification`
615
+ deprecated[4.17.0, Replaced by <<plugins-{type}s-{plugin}-ssl_verification_mode>>]
616
+
617
+ * Value type is <<boolean,boolean>>
618
+ * Default value is `true`
619
+
620
+ Option to validate the server's certificate. Disabling this severely compromises security.
621
+ When certificate validation is disabled, this plugin implicitly trusts the machine
622
+ resolved at the given address without validating its proof-of-identity.
623
+ In this scenario, the plugin can transmit credentials to or process data from an untrustworthy
624
+ man-in-the-middle or other compromised infrastructure.
625
+ More information on the importance of certificate verification:
626
+ **https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf**.
451
627
 
452
628
  [id="plugins-{type}s-{plugin}-common-options"]
453
629
  include::{include_path}/{type}.asciidoc[]
@@ -9,6 +9,7 @@ require 'logstash/plugin_mixins/ecs_compatibility_support'
9
9
  require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
10
10
  require 'logstash/plugin_mixins/ca_trusted_fingerprint_support'
11
11
  require "logstash/plugin_mixins/scheduler"
12
+ require "logstash/plugin_mixins/normalize_config_support"
12
13
  require "base64"
13
14
  require 'logstash/helpers/loggable_try'
14
15
 
@@ -82,6 +83,8 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
82
83
 
83
84
  include LogStash::PluginMixins::Scheduler
84
85
 
86
+ include LogStash::PluginMixins::NormalizeConfigSupport
87
+
85
88
  config_name "elasticsearch"
86
89
 
87
90
  # List of elasticsearch hosts to use for querying.
@@ -185,10 +188,60 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
185
188
  config :proxy, :validate => :uri_or_empty
186
189
 
187
190
  # SSL
188
- config :ssl, :validate => :boolean, :default => false
191
+ config :ssl, :validate => :boolean, :default => false, :deprecated => "Set 'ssl_enabled' instead."
192
+
193
+ # SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary
194
+ config :ca_file, :validate => :path, :deprecated => "Set 'ssl_certificate_authorities' instead."
195
+
196
+ # OpenSSL-style X.509 certificate certificate to authenticate the client
197
+ config :ssl_certificate, :validate => :path
198
+
199
+ # SSL Certificate Authority files in PEM encoded format, must also include any chain certificates as necessary
200
+ config :ssl_certificate_authorities, :validate => :path, :list => true
201
+
202
+ # Option to validate the server's certificate. Disabling this severely compromises security.
203
+ # For more information on the importance of certificate verification please read
204
+ # https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf
205
+ config :ssl_certificate_verification, :validate => :boolean, :default => true, :deprecated => "Set 'ssl_verification_mode' instead."
206
+
207
+ # The list of cipher suites to use, listed by priorities.
208
+ # Supported cipher suites vary depending on which version of Java is used.
209
+ config :ssl_cipher_suites, :validate => :string, :list => true
210
+
211
+ # SSL
212
+ config :ssl_enabled, :validate => :boolean
213
+
214
+ # OpenSSL-style RSA private key to authenticate the client
215
+ config :ssl_key, :validate => :path
216
+
217
+ # Set the keystore password
218
+ config :ssl_keystore_password, :validate => :password
219
+
220
+ # The keystore used to present a certificate to the server.
221
+ # It can be either .jks or .p12
222
+ config :ssl_keystore_path, :validate => :path
223
+
224
+ # The format of the keystore file. It must be either jks or pkcs12
225
+ config :ssl_keystore_type, :validate => %w[pkcs12 jks]
226
+
227
+ # Supported protocols with versions.
228
+ config :ssl_supported_protocols, :validate => %w[TLSv1.1 TLSv1.2 TLSv1.3], :default => [], :list => true
229
+
230
+ # Set the truststore password
231
+ config :ssl_truststore_password, :validate => :password
232
+
233
+ # The JKS truststore to validate the server's certificate.
234
+ # Use either `:ssl_truststore_path` or `:ssl_certificate_authorities`
235
+ config :ssl_truststore_path, :validate => :path
189
236
 
190
- # SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary
191
- config :ca_file, :validate => :path
237
+ # The format of the truststore file. It must be either jks or pkcs12
238
+ config :ssl_truststore_type, :validate => %w[pkcs12 jks]
239
+
240
+ # Options to verify the server's certificate.
241
+ # "full": validates that the provided certificate has an issue date that’s within the not_before and not_after dates;
242
+ # chains to a trusted Certificate Authority (CA); has a hostname or IP address that matches the names within the certificate.
243
+ # "none": performs no certificate validation. Disabling this severely compromises security (https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf)
244
+ config :ssl_verification_mode, :validate => %w[full none], :default => 'full'
192
245
 
193
246
  # Schedule of when to periodically run statement, in Cron format
194
247
  # for example: "* * * * *" (execute query every minute, on the minute)
@@ -214,6 +267,9 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
214
267
  def register
215
268
  require "rufus/scheduler"
216
269
 
270
+ fill_hosts_from_cloud_id
271
+ setup_ssl_params!
272
+
217
273
  @options = {
218
274
  :index => @index,
219
275
  :scroll => @scroll,
@@ -229,8 +285,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
229
285
 
230
286
  validate_authentication
231
287
  fill_user_password_from_cloud_auth
232
- fill_hosts_from_cloud_id
233
-
234
288
 
235
289
  transport_options = {:headers => {}}
236
290
  transport_options[:headers].merge!(setup_basic_auth(user, password))
@@ -241,7 +295,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
241
295
  transport_options[:socket_timeout] = @socket_timeout_seconds unless @socket_timeout_seconds.nil?
242
296
 
243
297
  hosts = setup_hosts
244
- ssl_options = setup_ssl
298
+ ssl_options = setup_client_ssl
245
299
 
246
300
  @logger.warn "Supplied proxy setting (proxy => '') has no effect" if @proxy.eql?('')
247
301
 
@@ -411,6 +465,15 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
411
465
  hosts.nil? || ( hosts.is_a?(Array) && hosts.empty? )
412
466
  end
413
467
 
468
+ def effectively_ssl?
469
+ return true if @ssl_enabled
470
+
471
+ hosts = Array(@hosts)
472
+ return false if hosts.nil? || hosts.empty?
473
+
474
+ hosts.all? { |host| host && host.to_s.start_with?("https") }
475
+ end
476
+
414
477
  def validate_authentication
415
478
  authn_options = 0
416
479
  authn_options += 1 if @cloud_auth
@@ -421,21 +484,113 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
421
484
  raise LogStash::ConfigurationError, 'Multiple authentication options are specified, please only use one of user/password, cloud_auth or api_key'
422
485
  end
423
486
 
424
- if @api_key && @api_key.value && @ssl != true
425
- raise(LogStash::ConfigurationError, "Using api_key authentication requires SSL/TLS secured communication using the `ssl => true` option")
487
+ if @api_key && @api_key.value && @ssl_enabled != true
488
+ raise(LogStash::ConfigurationError, "Using api_key authentication requires SSL/TLS secured communication using the `ssl_enabled => true` option")
426
489
  end
427
490
  end
428
491
 
429
- def setup_ssl
492
+ def setup_client_ssl
430
493
  ssl_options = {}
494
+ ssl_options[:ssl] = true if @ssl_enabled
495
+
496
+ unless @ssl_enabled
497
+ # Keep it backward compatible with the deprecated `ssl` option
498
+ ssl_options[:trust_strategy] = trust_strategy_for_ca_trusted_fingerprint if original_params.include?('ssl')
499
+ return ssl_options
500
+ end
501
+
502
+ 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')
503
+
504
+ if ssl_certificate_authorities && ssl_truststore_path
505
+ raise LogStash::ConfigurationError, 'Use either "ssl_certificate_authorities/ca_file" or "ssl_truststore_path" when configuring the CA certificate'
506
+ end
431
507
 
432
- ssl_options[:ssl] = true if @ssl
433
- ssl_options[:ca_file] = @ca_file if @ssl && @ca_file
508
+ if ssl_certificate && ssl_keystore_path
509
+ raise LogStash::ConfigurationError, 'Use either "ssl_certificate" or "ssl_keystore_path/keystore" when configuring client certificates'
510
+ end
511
+
512
+ if ssl_certificate_authorities&.any?
513
+ raise LogStash::ConfigurationError, 'Multiple values on "ssl_certificate_authorities" are not supported by this plugin' if ssl_certificate_authorities.size > 1
514
+ ssl_options[:ca_file] = ssl_certificate_authorities.first
515
+ end
516
+
517
+ if ssl_truststore_path
518
+ ssl_options[:truststore] = ssl_truststore_path
519
+ ssl_options[:truststore_type] = params["ssl_truststore_type"] if params.include?("ssl_truststore_type")
520
+ ssl_options[:truststore_password] = params["ssl_truststore_password"].value if params.include?("ssl_truststore_password")
521
+ end
522
+
523
+ if ssl_keystore_path
524
+ ssl_options[:keystore] = ssl_keystore_path
525
+ ssl_options[:keystore_type] = params["ssl_keystore_type"] if params.include?("ssl_keystore_type")
526
+ ssl_options[:keystore_password] = params["ssl_keystore_password"].value if params.include?("ssl_keystore_password")
527
+ end
528
+
529
+ ssl_key = params["ssl_key"]
530
+ if ssl_certificate
531
+ raise LogStash::ConfigurationError, 'Using an "ssl_certificate" requires an "ssl_key"' unless ssl_key
532
+ ssl_options[:client_cert] = ssl_certificate
533
+ ssl_options[:client_key] = ssl_key
534
+ elsif !ssl_key.nil?
535
+ raise LogStash::ConfigurationError, 'An "ssl_certificate" is required when using an "ssl_key"'
536
+ end
537
+
538
+ ssl_verification_mode = params["ssl_verification_mode"]
539
+ unless ssl_verification_mode.nil?
540
+ case ssl_verification_mode
541
+ when 'none'
542
+ logger.warn "You have enabled encryption but DISABLED certificate verification, " +
543
+ "to make sure your data is secure set `ssl_verification_mode => full`"
544
+ ssl_options[:verify] = :disable
545
+ else
546
+ ssl_options[:verify] = :strict
547
+ end
548
+ end
549
+
550
+ ssl_options[:cipher_suites] = params["ssl_cipher_suites"] if params.include?("ssl_cipher_suites")
551
+
552
+ protocols = params['ssl_supported_protocols']
553
+ ssl_options[:protocols] = protocols if protocols&.any?
434
554
  ssl_options[:trust_strategy] = trust_strategy_for_ca_trusted_fingerprint
435
555
 
436
556
  ssl_options
437
557
  end
438
558
 
559
+ def setup_ssl_params!
560
+ @ssl_enabled = normalize_config(:ssl_enabled) do |normalize|
561
+ normalize.with_deprecated_alias(:ssl)
562
+ end
563
+
564
+ # Infer the value if neither the deprecate `ssl` and `ssl_enabled` were set
565
+ infer_ssl_enabled_from_hosts
566
+
567
+ @ssl_certificate_authorities = normalize_config(:ssl_certificate_authorities) do |normalize|
568
+ normalize.with_deprecated_mapping(:ca_file) do |ca_file|
569
+ [ca_file]
570
+ end
571
+ end
572
+
573
+ @ssl_verification_mode = normalize_config(:ssl_verification_mode) do |normalize|
574
+ normalize.with_deprecated_mapping(:ssl_certificate_verification) do |ssl_certificate_verification|
575
+ if ssl_certificate_verification == true
576
+ "full"
577
+ else
578
+ "none"
579
+ end
580
+ end
581
+ end
582
+
583
+ params['ssl_enabled'] = @ssl_enabled
584
+ params['ssl_certificate_authorities'] = @ssl_certificate_authorities unless @ssl_certificate_authorities.nil?
585
+ params['ssl_verification_mode'] = @ssl_verification_mode unless @ssl_verification_mode.nil?
586
+ end
587
+
588
+ def infer_ssl_enabled_from_hosts
589
+ return if original_params.include?('ssl') || original_params.include?('ssl_enabled')
590
+
591
+ @ssl_enabled = params['ssl_enabled'] = effectively_ssl?
592
+ end
593
+
439
594
  def setup_hosts
440
595
  @hosts = Array(@hosts).map { |host| host.to_s } # potential SafeURI#to_s
441
596
  @hosts.map do |h|
@@ -443,7 +598,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
443
598
  h
444
599
  else
445
600
  host, port = h.split(':')
446
- { host: host, port: port, scheme: (@ssl ? 'https' : 'http') }
601
+ { host: host, port: port, scheme: (@ssl_enabled ? 'https' : 'http') }
447
602
  end
448
603
  end
449
604
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-elasticsearch'
4
- s.version = '4.15.0'
4
+ s.version = '4.17.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Reads query results from an Elasticsearch cluster"
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"
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
 
29
29
  s.add_runtime_dependency 'elasticsearch', '>= 7.17.1'
30
30
  s.add_runtime_dependency 'logstash-mixin-ca_trusted_fingerprint_support', '~> 1.0'
31
+ s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
31
32
 
32
33
  s.add_runtime_dependency 'tzinfo'
33
34
  s.add_runtime_dependency 'tzinfo-data'
@@ -681,7 +681,7 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
681
681
  end
682
682
 
683
683
  context "with ssl" do
684
- let(:config) { super().merge({ 'api_key' => LogStash::Util::Password.new('foo:bar'), "ssl" => true }) }
684
+ let(:config) { super().merge({ 'api_key' => LogStash::Util::Password.new('foo:bar'), "ssl_enabled" => true }) }
685
685
 
686
686
  it "should set authorization" do
687
687
  plugin.register
@@ -698,6 +698,14 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
698
698
  expect { plugin.register }.to raise_error LogStash::ConfigurationError, /Multiple authentication options are specified/
699
699
  end
700
700
  end
701
+
702
+ context 'ssl verification disabled' do
703
+ let(:config) { super().merge({ 'ssl_verification_mode' => 'none' }) }
704
+ it 'should warn data security risk' do
705
+ expect(plugin.logger).to receive(:warn).once.with("You have enabled encryption but DISABLED certificate verification, to make sure your data is secure set `ssl_verification_mode => full`")
706
+ plugin.register
707
+ end
708
+ end
701
709
  end
702
710
  end if LOGSTASH_VERSION > '6.0'
703
711
 
@@ -0,0 +1,265 @@
1
+ require 'stud/temporary'
2
+ require "elasticsearch"
3
+
4
+ describe "SSL options" do
5
+ let(:es_client_double) { double("Elasticsearch::Client #{self.inspect}") }
6
+ let(:hosts) {["localhost"]}
7
+ let(:settings) { { "ssl_enabled" => true, "hosts" => hosts } }
8
+
9
+ subject do
10
+ require "logstash/inputs/elasticsearch"
11
+ LogStash::Inputs::Elasticsearch.new(settings)
12
+ end
13
+
14
+ before do
15
+ allow(es_client_double).to receive(:close)
16
+ allow(es_client_double).to receive(:ping).with(any_args).and_return(double("pong").as_null_object)
17
+ allow(Elasticsearch::Client).to receive(:new).and_return(es_client_double)
18
+ end
19
+
20
+ after do
21
+ subject.close
22
+ end
23
+
24
+ context "when ssl_enabled is" do
25
+ context "true and there is no https hosts" do
26
+ let(:hosts) { %w[http://es01 http://es01] }
27
+
28
+ it "should not infer the ssl_enabled value" do
29
+ subject.register
30
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(true)
31
+ expect(subject.params).to match hash_including("ssl_enabled" => true)
32
+ end
33
+ end
34
+
35
+ context "false and cloud_id resolved host is https" do
36
+ let(:settings) {{
37
+ "ssl_enabled" => false,
38
+ "hosts" => [],
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
+ "hosts" => [],
86
+ "cloud_id" => "sample:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJGFjMzFlYmI5MDI0MTc3MzE1NzA0M2MzNGZkMjZmZDQ2OjkyNDMkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA6OTI0NA=="
87
+ }}
88
+
89
+ it "should infer the ssl_enabled value to false" do
90
+ subject.register
91
+ expect(subject.instance_variable_get(:@ssl_enabled)).to eql(true)
92
+ expect(subject.params).to match hash_including("ssl_enabled" => true)
93
+ end
94
+ end
95
+ end
96
+
97
+ context "when ssl_verification_mode" do
98
+ context "is set to none" do
99
+ let(:settings) { super().merge(
100
+ "ssl_verification_mode" => "none",
101
+ ) }
102
+
103
+ it "should print a warning" do
104
+ expect(subject.logger).to receive(:warn).with(/You have enabled encryption but DISABLED certificate verification/).at_least(:once)
105
+ allow(subject.logger).to receive(:warn).with(any_args)
106
+
107
+ subject.register
108
+ end
109
+
110
+ it "should pass the flag to the ES client" do
111
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
112
+ expect(args[:ssl]).to match hash_including(:ssl => true, :verify => :disable)
113
+ end.and_return(es_client_double)
114
+
115
+ subject.register
116
+ end
117
+ end
118
+
119
+ context "is set to full" do
120
+ let(:settings) { super().merge(
121
+ "ssl_verification_mode" => 'full',
122
+ ) }
123
+
124
+ it "should pass the flag to the ES client" do
125
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
126
+ expect(args[:ssl]).to match hash_including(:ssl => true, :verify => :strict)
127
+ end.and_return(es_client_double)
128
+
129
+ subject.register
130
+ end
131
+ end
132
+ end
133
+
134
+ context "with the conflicting configs" do
135
+ context "ssl_certificate_authorities and ssl_truststore_path set" do
136
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
137
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
138
+ let(:settings) { super().merge(
139
+ "ssl_truststore_path" => ssl_truststore_path,
140
+ "ssl_certificate_authorities" => ssl_certificate_authorities_path
141
+ ) }
142
+
143
+ after :each do
144
+ File.delete(ssl_truststore_path)
145
+ File.delete(ssl_certificate_authorities_path)
146
+ end
147
+
148
+ it "should raise a configuration error" do
149
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate_authorities\/ca_file" or "ssl_truststore_path"/)
150
+ end
151
+ end
152
+
153
+ context "ssl_certificate and ssl_keystore_path set" do
154
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
155
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
156
+ let(:settings) { super().merge(
157
+ "ssl_certificate" => ssl_certificate_path,
158
+ "ssl_keystore_path" => ssl_keystore_path
159
+ ) }
160
+
161
+ after :each do
162
+ File.delete(ssl_keystore_path)
163
+ File.delete(ssl_certificate_path)
164
+ end
165
+
166
+ it "should raise a configuration error" do
167
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Use either "ssl_certificate" or "ssl_keystore_path\/keystore"/)
168
+ end
169
+ end
170
+ end
171
+
172
+ context "when configured with Java store files" do
173
+ let(:ssl_truststore_path) { Stud::Temporary.file.path }
174
+ let(:ssl_keystore_path) { Stud::Temporary.file.path }
175
+
176
+ after :each do
177
+ File.delete(ssl_truststore_path)
178
+ File.delete(ssl_keystore_path)
179
+ end
180
+
181
+ let(:settings) { super().merge(
182
+ "ssl_truststore_path" => ssl_truststore_path,
183
+ "ssl_truststore_type" => "jks",
184
+ "ssl_truststore_password" => "foo",
185
+ "ssl_keystore_path" => ssl_keystore_path,
186
+ "ssl_keystore_type" => "jks",
187
+ "ssl_keystore_password" => "bar",
188
+ "ssl_verification_mode" => "full",
189
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
190
+ "ssl_supported_protocols" => ["TLSv1.3"]
191
+ ) }
192
+
193
+ it "should pass the parameters to the ES client" do
194
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
195
+ expect(args[:ssl]).to match hash_including(
196
+ :ssl => true,
197
+ :keystore => ssl_keystore_path,
198
+ :keystore_type => "jks",
199
+ :keystore_password => "bar",
200
+ :truststore => ssl_truststore_path,
201
+ :truststore_type => "jks",
202
+ :truststore_password => "foo",
203
+ :verify => :strict,
204
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
205
+ :protocols => ["TLSv1.3"],
206
+ )
207
+ end.and_return(es_client_double)
208
+
209
+ subject.register
210
+ end
211
+ end
212
+
213
+ context "when configured with certificate files" do
214
+ let(:ssl_certificate_authorities_path) { Stud::Temporary.file.path }
215
+ let(:ssl_certificate_path) { Stud::Temporary.file.path }
216
+ let(:ssl_key_path) { Stud::Temporary.file.path }
217
+ let(:settings) { super().merge(
218
+ "ssl_certificate_authorities" => [ssl_certificate_authorities_path],
219
+ "ssl_certificate" => ssl_certificate_path,
220
+ "ssl_key" => ssl_key_path,
221
+ "ssl_verification_mode" => "full",
222
+ "ssl_cipher_suites" => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
223
+ "ssl_supported_protocols" => ["TLSv1.3"]
224
+ ) }
225
+
226
+ after :each do
227
+ File.delete(ssl_certificate_authorities_path)
228
+ File.delete(ssl_certificate_path)
229
+ File.delete(ssl_key_path)
230
+ end
231
+
232
+ it "should pass the parameters to the ES client" do
233
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
234
+ expect(args[:ssl]).to match hash_including(
235
+ :ssl => true,
236
+ :ca_file => ssl_certificate_authorities_path,
237
+ :client_cert => ssl_certificate_path,
238
+ :client_key => ssl_key_path,
239
+ :verify => :strict,
240
+ :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
241
+ :protocols => ["TLSv1.3"],
242
+ )
243
+ end.and_return(es_client_double)
244
+
245
+ subject.register
246
+ end
247
+
248
+ context "and only the ssl_certificate is set" do
249
+ let(:settings) { super().reject { |k| "ssl_key".eql?(k) } }
250
+
251
+ it "should raise a configuration error" do
252
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /Using an "ssl_certificate" requires an "ssl_key"/)
253
+ end
254
+ end
255
+
256
+ context "and only the ssl_key is set" do
257
+ let(:settings) { super().reject { |k| "ssl_certificate".eql?(k) } }
258
+
259
+ it "should raise a configuration error" do
260
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError, /An "ssl_certificate" is required when using an "ssl_key"/)
261
+ end
262
+ end
263
+ end
264
+ end
265
+
@@ -95,13 +95,13 @@ describe LogStash::Inputs::Elasticsearch do
95
95
  end
96
96
 
97
97
  context 'with ca_file' do
98
- let(:config) { super().merge('ssl' => true, 'ca_file' => ca_file) }
98
+ let(:config) { super().merge('ssl_enabled' => true, 'ssl_certificate_authorities' => ca_file) }
99
99
  it_behaves_like 'secured_elasticsearch'
100
100
  end
101
101
 
102
102
  context 'with `ca_trusted_fingerprint`' do
103
103
  let(:ca_trusted_fingerprint) { File.read("spec/fixtures/test_certs/ca.der.sha256").chomp }
104
- let(:config) { super().merge('ssl' => true, 'ca_trusted_fingerprint' => ca_trusted_fingerprint) }
104
+ let(:config) { super().merge('ssl_enabled' => true, 'ca_trusted_fingerprint' => ca_trusted_fingerprint) }
105
105
 
106
106
  if Gem::Version.create(LOGSTASH_VERSION) >= Gem::Version.create("8.3.0")
107
107
  it_behaves_like 'secured_elasticsearch'
@@ -125,11 +125,11 @@ describe LogStash::Inputs::Elasticsearch do
125
125
 
126
126
  context 'setting host:port (and ssl)', secure_integration: true do
127
127
 
128
- let(:client_options) { { :ca_file => ca_file, :user => user, :password => password } }
128
+ let(:client_options) { { :ssl_certificate_authorities => ca_file, :user => user, :password => password } }
129
129
 
130
130
  let(:config) do
131
131
  config = super().merge "hosts" => [ESHelper.get_host_port]
132
- config.merge('user' => user, 'password' => password, 'ssl' => true, 'ca_file' => ca_file)
132
+ config.merge('user' => user, 'password' => password, 'ssl_enabled' => true, 'ssl_certificate_authorities' => ca_file)
133
133
  end
134
134
 
135
135
  it_behaves_like 'an elasticsearch index plugin'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.15.0
4
+ version: 4.17.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-08-08 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
@@ -114,6 +114,20 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '1.0'
117
+ - !ruby/object:Gem::Dependency
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '1.0'
123
+ name: logstash-mixin-normalize_config_support
124
+ prerelease: false
125
+ type: :runtime
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  requirement: !ruby/object:Gem::Requirement
119
133
  requirements:
@@ -267,6 +281,7 @@ files:
267
281
  - spec/fixtures/test_certs/es.crt
268
282
  - spec/fixtures/test_certs/es.key
269
283
  - spec/inputs/elasticsearch_spec.rb
284
+ - spec/inputs/elasticsearch_ssl_spec.rb
270
285
  - spec/inputs/integration/elasticsearch_spec.rb
271
286
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
272
287
  licenses:
@@ -301,4 +316,5 @@ test_files:
301
316
  - spec/fixtures/test_certs/es.crt
302
317
  - spec/fixtures/test_certs/es.key
303
318
  - spec/inputs/elasticsearch_spec.rb
319
+ - spec/inputs/elasticsearch_ssl_spec.rb
304
320
  - spec/inputs/integration/elasticsearch_spec.rb