Skip to content

Commit d8b3ca5

Browse files
kareskarenzone
andauthored
Feat: review and deprecate ssl protocol/cipher settings (#450)
Co-authored-by: Karen Metts <[email protected]>
1 parent 41ccca3 commit d8b3ca5

File tree

6 files changed

+150
-63
lines changed

6 files changed

+150
-63
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 6.4.0
2+
- Feat: review and deprecate ssl protocol/cipher settings [#450](https://github.com/logstash-plugins/logstash-input-beats/pull/450)
3+
14
## 6.3.1
25
- Fix: Removed use of deprecated `import` of java classes in ruby [#449](https://github.com/logstash-plugins/logstash-input-beats/pull/449)
36

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6.3.1
1+
6.4.0

docs/index.asciidoc

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ This plugin supports the following configuration options plus the <<plugins-{typ
159159
[cols="<,<,<",options="header",]
160160
|=======================================================================
161161
|Setting |Input type|Required
162-
| <<plugins-{type}s-{plugin}-add_hostname>> |<<boolean,boolean>>|No
163-
| <<plugins-{type}s-{plugin}-cipher_suites>> |<<array,array>>|No
162+
| <<plugins-{type}s-{plugin}-add_hostname>> |<<boolean,boolean>>|__Deprecated__
163+
| <<plugins-{type}s-{plugin}-cipher_suites>> |<<array,array>>|__Deprecated__
164164
| <<plugins-{type}s-{plugin}-client_inactivity_timeout>> |<<number,number>>|No
165165
| <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
166166
| <<plugins-{type}s-{plugin}-executor_threads>> |<<number,number>>|No
@@ -173,10 +173,11 @@ This plugin supports the following configuration options plus the <<plugins-{typ
173173
| <<plugins-{type}s-{plugin}-ssl_handshake_timeout>> |<<number,number>>|No
174174
| <<plugins-{type}s-{plugin}-ssl_key>> |a valid filesystem path|No
175175
| <<plugins-{type}s-{plugin}-ssl_key_passphrase>> |<<password,password>>|No
176-
| <<plugins-{type}s-{plugin}-ssl_verify_mode>> |<<string,string>>, one of `["none", "peer", "force_peer"]`|No
177176
| <<plugins-{type}s-{plugin}-ssl_peer_metadata>> |<<boolean,boolean>>|No
178-
| <<plugins-{type}s-{plugin}-tls_max_version>> |<<number,number>>|No
179-
| <<plugins-{type}s-{plugin}-tls_min_version>> |<<number,number>>|No
177+
| <<plugins-{type}s-{plugin}-ssl_supported_protocols>> |<<array,array>>|No
178+
| <<plugins-{type}s-{plugin}-ssl_verify_mode>> |<<string,string>>, one of `["none", "peer", "force_peer"]`|No
179+
| <<plugins-{type}s-{plugin}-tls_max_version>> |<<number,number>>|__Deprecated__
180+
| <<plugins-{type}s-{plugin}-tls_min_version>> |<<number,number>>|__Deprecated__
180181
|=======================================================================
181182

182183
Also see <<plugins-{type}s-{plugin}-common-options>> for a list of options supported by all
@@ -194,17 +195,13 @@ input plugins.
194195

195196
Flag to determine whether to add `host` field to event using the value supplied by the {plugin-singular} in the `hostname` field.
196197

197-
198198
[id="plugins-{type}s-{plugin}-cipher_suites"]
199199
===== `cipher_suites`
200+
deprecated[6.4.0, Replaced by <<plugins-{type}s-{plugin}-ssl_cipher_suites>>]
200201

201202
* Value type is <<array,array>>
202-
* Default value is `java.lang.String[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256]@459cfcca`
203203

204-
The list of ciphers suite to use, listed by priorities.
205-
This default list applies for OpenJDK 11.0.14 and higher.
206-
For older JDK versions, the default list includes only suites supported by that version.
207-
For example, the ChaCha20 family of ciphers is not supported in older versions.
204+
The list of cipher suites to use, listed by priorities.
208205

209206
[id="plugins-{type}s-{plugin}-client_inactivity_timeout"]
210207
===== `client_inactivity_timeout`
@@ -217,14 +214,14 @@ Close Idle clients after X seconds of inactivity.
217214
[id="plugins-{type}s-{plugin}-ecs_compatibility"]
218215
===== `ecs_compatibility`
219216

220-
* Value type is <<string,string>>
221-
* Supported values are:
222-
** `disabled`: unstructured connection metadata added at root level
223-
** `v1`: structured connection metadata added under ECS v1 compliant namespaces
224-
** `v8`: structured connection metadata added under ECS v8 compliant namespaces
225-
* Default value depends on which version of Logstash is running:
226-
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
227-
** Otherwise, the default value is `disabled`.
217+
* Value type is <<string,string>>
218+
* Supported values are:
219+
** `disabled`: unstructured connection metadata added at root level
220+
** `v1`: structured connection metadata added under ECS v1 compliant namespaces
221+
** `v8`: structured connection metadata added under ECS v8 compliant namespaces
222+
* Default value depends on which version of Logstash is running:
223+
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
224+
** Otherwise, the default value is `disabled`.
228225

229226
Refer to <<plugins-{type}s-{plugin}-ecs_metadata,ECS mapping>> for detailed information.
230227

@@ -300,6 +297,16 @@ You can define multiple files or paths. All the certificates will
300297
be read and added to the trust store. You need to configure the `ssl_verify_mode`
301298
to `peer` or `force_peer` to enable the verification.
302299

300+
[id="plugins-{type}s-{plugin}-ssl_cipher_suites"]
301+
===== `ssl_cipher_suites`
302+
303+
* Value type is <<array,array>>
304+
* Default value is `['TLS_AES_256_GCM_SHA384', 'TLS_AES_128_GCM_SHA256', 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256']`
305+
306+
The list of cipher suites to use, listed by priorities.
307+
This default list applies for OpenJDK 11.0.14 and higher.
308+
For older JDK versions, the default list includes only suites supported by that version.
309+
For example, the ChaCha20 family of ciphers is not supported in older versions.
303310

304311
[id="plugins-{type}s-{plugin}-ssl_handshake_timeout"]
305312
===== `ssl_handshake_timeout`
@@ -333,6 +340,33 @@ openssl pkcs8 -inform PEM -in path/to/logstash.key -topk8 -nocrypt -outform PEM
333340

334341
SSL key passphrase to use.
335342

343+
[id="plugins-{type}s-{plugin}-ssl_peer_metadata"]
344+
===== `ssl_peer_metadata`
345+
346+
* Value type is <<boolean,boolean>>
347+
* Default value is `false`
348+
349+
Enables storing client certificate information in event's metadata.
350+
351+
This option is only valid when `ssl_verify_mode` is set to `peer` or `force_peer`.
352+
353+
[id="plugins-{type}s-{plugin}-ssl_supported_protocols"]
354+
===== `ssl_supported_protocols`
355+
356+
* Value type is <<array,array>>
357+
* Allowed values are: `'TLSv1.1'`, `'TLSv1.2'`, `'TLSv1.3'`
358+
* Default depends on the JDK being used. With up-to-date Logstash, the default is `['TLSv1.2', 'TLSv1.3']`.
359+
`'TLSv1.1'` is not considered secure and is only provided for legacy applications.
360+
361+
List of allowed SSL/TLS versions to use when establishing a connection to the HTTP endpoint.
362+
363+
For Java 8 `'TLSv1.3'` is supported only since **8u262** (AdoptOpenJDK), but requires that you set the
364+
`LS_JAVA_OPTS="-Djdk.tls.client.protocols=TLSv1.3"` system property in Logstash.
365+
366+
NOTE: If you configure the plugin to use `'TLSv1.1'` on any recent JVM, such as the one packaged with Logstash,
367+
the protocol is disabled by default and needs to be enabled manually by changing `jdk.tls.disabledAlgorithms` in
368+
the *$JDK_HOME/conf/security/java.security* configuration file. That is, `TLSv1.1` needs to be removed from the list.
369+
336370
[id="plugins-{type}s-{plugin}-ssl_verify_mode"]
337371
===== `ssl_verify_mode`
338372

@@ -349,33 +383,23 @@ If the client doesn't provide a certificate, the connection will be closed.
349383

350384
This option needs to be used with `ssl_certificate_authorities` and a defined list of CAs.
351385

352-
[id="plugins-{type}s-{plugin}-ssl_peer_metadata"]
353-
===== `ssl_peer_metadata`
354-
355-
* Value type is <<boolean,boolean>>
356-
* Default value is `false`
357-
358-
Enables storing client certificate information in event's metadata.
359-
360-
This option is only valid when `ssl_verify_mode` is set to `peer` or `force_peer`.
361-
362386
[id="plugins-{type}s-{plugin}-tls_max_version"]
363387
===== `tls_max_version`
388+
deprecated[6.4.0, Replaced by <<plugins-{type}s-{plugin}-ssl_supported_protocols>>]
364389

365390
* Value type is <<number,number>>
366-
* Default value is `1.3`
367391

368-
The maximum TLS version allowed for the encrypted connections. The value must be the one of the following:
369-
1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2, 1.3 for TLS 1.3
392+
The maximum TLS version allowed for the encrypted connections.
393+
The value must be the one of the following: 1.1 for TLS 1.1, 1.2 for TLS 1.2, 1.3 for TLSv1.3
370394

371395
[id="plugins-{type}s-{plugin}-tls_min_version"]
372396
===== `tls_min_version`
397+
deprecated[6.4.0, Replaced by <<plugins-{type}s-{plugin}-ssl_supported_protocols>>]
373398

374399
* Value type is <<number,number>>
375-
* Default value is `1`
376400

377-
The minimum TLS version allowed for the encrypted connections. The value must be one of the following:
378-
1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2, 1.3 for TLS 1.3
401+
The minimum TLS version allowed for the encrypted connections.
402+
The value must be one of the following: 1.1 for TLS 1.1, 1.2 for TLS 1.2, 1.3 for TLS 1.3
379403

380404

381405

lib/logstash/inputs/beats.rb

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
5151
require "logstash/inputs/beats/message_listener"
5252
require "logstash/inputs/beats/tls"
5353

54+
java_import 'org.logstash.netty.SslContextBuilder'
55+
5456
# adds ecs_compatibility config which could be :disabled or :v1
5557
include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled,:v1, :v8 => :v1)
5658

@@ -89,9 +91,6 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
8991
#
9092
config :ssl_certificate_authorities, :validate => :array, :default => []
9193

92-
# Flag to determine whether to add host information (provided by the beat in the 'hostname' field) to the event
93-
config :add_hostname, :validate => :boolean, :default => false, :deprecated => 'This option will be removed in the future as beats determine the event schema'
94-
9594
# By default the server doesn't do any client verification.
9695
#
9796
# `peer` will make the server ask the client to provide a certificate.
@@ -112,22 +111,31 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
112111
# Time in milliseconds for an incomplete ssl handshake to timeout
113112
config :ssl_handshake_timeout, :validate => :number, :default => 10000
114113

115-
# The minimum TLS version allowed for the encrypted connections. The value must be one of the following:
116-
# 1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2
117-
config :tls_min_version, :validate => :number, :default => TLS.min.version
114+
config :ssl_cipher_suites, :validate => SslContextBuilder::SUPPORTED_CIPHERS.to_a,
115+
:default => SslContextBuilder.getDefaultCiphers, :list => true
118116

119-
# The maximum TLS version allowed for the encrypted connections. The value must be the one of the following:
120-
# 1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2
121-
config :tls_max_version, :validate => :number, :default => TLS.max.version
117+
config :ssl_supported_protocols, :validate => ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], :default => ['TLSv1.2', 'TLSv1.3'], :list => true
122118

123-
# The list of ciphers suite to use, listed by priorities.
124-
config :cipher_suites, :validate => :array, :default => org.logstash.netty.SslContextBuilder.getDefaultCiphers
125119
# Close Idle clients after X seconds of inactivity.
126120
config :client_inactivity_timeout, :validate => :number, :default => 60
127121

128122
# Beats handler executor thread
129123
config :executor_threads, :validate => :number, :default => LogStash::Config::CpuCoreStrategy.maximum
130124

125+
# Flag to determine whether to add host information (provided by the beat in the 'hostname' field) to the event
126+
config :add_hostname, :validate => :boolean, :default => false, :deprecated => 'This option will be removed in the future as beats determine the event schema'
127+
128+
# The list of ciphers suite to use, listed by priorities.
129+
config :cipher_suites, :validate => :array, :default => [], :deprecated => "Set 'ssl_cipher_suites' instead."
130+
131+
# The minimum TLS version allowed for the encrypted connections. The value must be one of the following:
132+
# 1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2
133+
config :tls_min_version, :validate => :number, :default => TLS.min.version, :deprecated => "Set 'ssl_supported_protocols' instead."
134+
135+
# The maximum TLS version allowed for the encrypted connections. The value must be the one of the following:
136+
# 1.0 for TLS 1.0, 1.1 for TLS 1.1, 1.2 for TLS 1.2
137+
config :tls_max_version, :validate => :number, :default => TLS.max.version, :deprecated => "Set 'ssl_supported_protocols' instead."
138+
131139
attr_reader :field_hostname, :field_hostip
132140
attr_reader :field_tls_protocol_version, :field_tls_peer_subject, :field_tls_cipher
133141

@@ -156,6 +164,26 @@ def register
156164
if client_authentication_metadata? && !require_certificate_authorities?
157165
configuration_error "Configuring ssl_peer_metadata => true requires ssl_verify_mode => to be configured with 'peer' or 'force_peer'"
158166
end
167+
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
175+
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`."
180+
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
186+
end
159187
else
160188
@logger.warn("configured ssl_certificate => #{@ssl_certificate.inspect} will not be used") if @ssl_certificate
161189
@logger.warn("configured ssl_key => #{@ssl_key.inspect} will not be used") if @ssl_key
@@ -184,9 +212,9 @@ def create_server
184212
ssl_context_builder = new_ssl_context_builder
185213
if client_authentification?
186214
if @ssl_verify_mode == "force_peer"
187-
ssl_context_builder.setVerifyMode(org.logstash.netty.SslContextBuilder::SslClientVerifyMode::FORCE_PEER)
215+
ssl_context_builder.setVerifyMode(SslContextBuilder::SslClientVerifyMode::FORCE_PEER)
188216
elsif @ssl_verify_mode == "peer"
189-
ssl_context_builder.setVerifyMode(org.logstash.netty.SslContextBuilder::SslClientVerifyMode::VERIFY_PEER)
217+
ssl_context_builder.setVerifyMode(SslContextBuilder::SslClientVerifyMode::VERIFY_PEER)
190218
end
191219
ssl_context_builder.setCertificateAuthorities(@ssl_certificate_authorities)
192220
end
@@ -247,20 +275,16 @@ def new_ssl_context_builder
247275
passphrase = @ssl_key_passphrase.nil? ? nil : @ssl_key_passphrase.value
248276
begin
249277
org.logstash.netty.SslContextBuilder.new(@ssl_certificate, @ssl_key, passphrase)
250-
.setProtocols(convert_protocols)
251-
.setCipherSuites(normalized_ciphers)
278+
.setProtocols(@ssl_supported_protocols_final)
279+
.setCipherSuites(normalized_cipher_suites)
252280
rescue java.lang.IllegalArgumentException => e
253281
@logger.error("SSL configuration invalid", error_details(e))
254282
raise LogStash::ConfigurationError, e
255283
end
256284
end
257285

258-
def normalized_ciphers
259-
@cipher_suites.map(&:upcase)
260-
end
261-
262-
def convert_protocols
263-
TLS.get_supported(@tls_min_version..@tls_max_version).map(&:name)
286+
def normalized_cipher_suites
287+
@ssl_cipher_suites_final.map(&:upcase)
264288
end
265289

266290
def configuration_error(message)

spec/inputs/beats_spec.rb

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
end
4848

4949
context "with ssl enabled" do
50+
51+
let(:config) { { "ssl" => true, "port" => port, "ssl_key" => certificate.ssl_key, "ssl_certificate" => certificate.ssl_cert } }
52+
5053
context "without certificate configuration" do
5154
let(:config) { { "port" => 0, "ssl" => true, "ssl_key" => certificate.ssl_key, "type" => "example" } }
5255

@@ -78,7 +81,7 @@
7881
end
7982

8083
context "with invalid ciphers" do
81-
let(:config) { super().merge("ssl" => true, "cipher_suites" => "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA38") }
84+
let(:config) { super().merge("cipher_suites" => "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA38") }
8285

8386
it "should raise a configuration error" do
8487
plugin = LogStash::Inputs::Beats.new(config)
@@ -92,7 +95,7 @@
9295

9396
context "verify_mode" do
9497
context "verify_mode configured to PEER" do
95-
let(:config) { super().merge("ssl" => true, "ssl_verify_mode" => "peer") }
98+
let(:config) { super().merge("ssl_verify_mode" => "peer") }
9699

97100
it "raise a ConfigurationError when certificate_authorities is not set" do
98101
plugin = LogStash::Inputs::Beats.new(config)
@@ -107,7 +110,7 @@
107110
end
108111

109112
context "verify_mode configured to FORCE_PEER" do
110-
let(:config) { super().merge("ssl" => true, "ssl_verify_mode" => "force_peer") }
113+
let(:config) { super().merge("ssl_verify_mode" => "force_peer") }
111114

112115
it "raise a ConfigurationError when certificate_authorities is not set" do
113116
plugin = LogStash::Inputs::Beats.new(config)
@@ -120,6 +123,40 @@
120123
expect {plugin.register}.not_to raise_error
121124
end
122125
end
126+
127+
context "with ssl_cipher_suites and cipher_suites set" do
128+
let(:config) do
129+
super().merge('ssl_cipher_suites' => ['TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'],
130+
'cipher_suites' => ['TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384'])
131+
end
132+
133+
it "should raise a configuration error" do
134+
plugin = LogStash::Inputs::Beats.new(config)
135+
expect { plugin.register }.to raise_error LogStash::ConfigurationError, /Use only .?ssl_cipher_suites.?/i
136+
end
137+
end
138+
139+
context "with ssl_supported_protocols and tls_min_version set" do
140+
let(:config) do
141+
super().merge('ssl_supported_protocols' => ['TLSv1.2'], 'tls_min_version' => 1.2)
142+
end
143+
144+
it "should raise a configuration error" do
145+
plugin = LogStash::Inputs::Beats.new(config)
146+
expect { plugin.register }.to raise_error LogStash::ConfigurationError, /Use only .?ssl_supported_protocols.?/i
147+
end
148+
end
149+
150+
context "with ssl_supported_protocols and tls_max_version set" do
151+
let(:config) do
152+
super().merge('ssl_supported_protocols' => ['TLSv1.2'], 'tls_max_version' => 1.2)
153+
end
154+
155+
it "should raise a configuration error" do
156+
plugin = LogStash::Inputs::Beats.new(config)
157+
expect { plugin.register }.to raise_error LogStash::ConfigurationError, /Use only .?ssl_supported_protocols.?/i
158+
end
159+
end
123160
end
124161
end
125162

0 commit comments

Comments
 (0)