This issue reflects changes we should make with regards to hardening and documentation for Kibana's supported SSL/TLS protocols and ciphers.
Kibana relies on Node.js (and by extension, OpenSSL) to handle TLS connections. The supported TLS protocols and ciphers can be configured using the server.ssl.supportedProtocols and server.ssl.cipherSuites settings, respectively.
For a browser to make a successful connection to a web server, both the client and server must have overlap in supported TLS protocols and ciphers. Qualys provides a great resource to see which browsers support which protocols and ciphers (click each user agent to see more details about ciphers), but it appears that their tested user agents are quite outdated.
The terms "SSL" and "TLS" are often used interchangeably, but it's important to know that SSL is actually an old encryption protocol that was phased out in favor of TLS.
Supported browsers
Given that a successful TLS handshake depends on both the client and the server supporting overlapping TLS protocols/ciphers, it's important to know what we should be targeting.
According to our support page, each Kibana release supports the latest versions of the Big 4 browsers at the time of release. For Kibana 8.3.0, at the time of this writing this is:
However, this setting is superseded by Node.js start arguments, and with the 8.0 release we effectively only support TLS 1.2+ out of the box, see the 8.0.0-alpha1 release notes for more details.
Before looking at ciphers, it's good to know that most ciphers for TLS 1.2 and earlier have three different names: an IANA name, an OpenSSL name, and a GnuTLS name. These are just implementation details, but they are a huge source of confusion when talking about ciphers. For TLS 1.2 and later, the OpenSSL name and IANA name are the same. For this issue, I will refer to all ciphers by their OpenSSL names. Here are some good resources for learning about TLS ciphers:
Kibana currently supports ciphers that are considered to be weak. These normally won't be used; during the TLS handshake, the client and the server will negotiate a mutually-supported cipher that is highest in the list -- e.g., the strongest cipher. However, a browser could be forced to use a weaker supported cipher due to a downgrade attack.
The current Elastic Cloud cipher list is stronger, but it also includes some cipher suites can be considered weak:
ECDHE-RSA-AES128-SHA256 -- this relies on Cipher Block Chaining (CBC) which is vulnerable to the Lucky 13 attack
We can change Kibana's default supported ciphers to a stronger list (selecting strong ciphers, omitting those that use CBC and those that do not provide PFS)
Order matters, I have the 128-bit ciphers higher in the list because that level of encryption is widely considered to be unbreakable, and preferring a 256-bit cipher doesn't provide any tangible security benefit. For the same reason, I have AES ciphers prioritized over CHACHA20 ciphers, because AES ciphers will be more performant on laptop/desktop CPUs that include dedicated instructions for AES.
In TLS 1.2 and earlier, ECDSA ciphers can only be used with ECC certificates, while RSA ciphers can only be used with older RSA certificates. Starting in TLS 1.3, the cipher no longer differentiates which type of key (ECC or RSA) is used for the certificate.
According to Mozilla, these ciphers are supported on Chrome 31+, Firefox 27+, Edge 12+, and Safari 9+, and "nearly every client released in the last five (or more) years".
Proposed changes
Given all of the above, here's what I think we need to do:
[ ] We should change the documentation for server.ssl.supportedProtocols to mention that enabling TLS 1.1 (for example) would also require setting the --tls-min-1.1 option in the node.options configuration file as described in the release note above. In other words, both that and the server.ssl.supportedProtocols setting must match.
OpenSSL cipher list for TLS 1.3: TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
OpenSSL cipher list for TLS 1.2: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
Overview
This issue reflects changes we should make with regards to hardening and documentation for Kibana's supported SSL/TLS protocols and ciphers.
Kibana relies on Node.js (and by extension, OpenSSL) to handle TLS connections. The supported TLS protocols and ciphers can be configured using the
server.ssl.supportedProtocols
andserver.ssl.cipherSuites
settings, respectively.For a browser to make a successful connection to a web server, both the client and server must have overlap in supported TLS protocols and ciphers. Qualys provides a great resource to see which browsers support which protocols and ciphers (click each user agent to see more details about ciphers), but it appears that their tested user agents are quite outdated.
The terms "SSL" and "TLS" are often used interchangeably, but it's important to know that SSL is actually an old encryption protocol that was phased out in favor of TLS.
Supported browsers
Given that a successful TLS handshake depends on both the client and the server supporting overlapping TLS protocols/ciphers, it's important to know what we should be targeting.
According to our support page, each Kibana release supports the latest versions of the Big 4 browsers at the time of release. For Kibana 8.3.0, at the time of this writing this is:
102.0.5005.63
101.0
15.4
100.0.1185.39
TLS protocols
According to the documentation for
server.ssl.supportedProtocols
, Kibana supports TLS 1.1+ out of the box.However, this setting is superseded by Node.js start arguments, and with the 8.0 release we effectively only support TLS 1.2+ out of the box, see the 8.0.0-alpha1 release notes for more details.
TLS 1.1 and earlier are deprecated, vulnerable to various attacks, and widely considered to be weak. All modern browsers support TLS 1.2, and some of them support TLS 1.3.
TLS ciphers
Before looking at ciphers, it's good to know that most ciphers for TLS 1.2 and earlier have three different names: an IANA name, an OpenSSL name, and a GnuTLS name. These are just implementation details, but they are a huge source of confusion when talking about ciphers. For TLS 1.2 and later, the OpenSSL name and IANA name are the same. For this issue, I will refer to all ciphers by their OpenSSL names. Here are some good resources for learning about TLS ciphers:
According to the documentation for
server.ssl.cipherSuites
, Kibana currently supports the following TLS ciphers out of the box:That OpenSSL cipher list format contains some lists, which computes to these supported ciphers as tested by the
sslscan
tool:Contrast that with the much smaller list of supported ciphers by Elastic Cloud (note it does not yet support TLS 1.3):
Kibana currently supports ciphers that are considered to be weak. These normally won't be used; during the TLS handshake, the client and the server will negotiate a mutually-supported cipher that is highest in the list -- e.g., the strongest cipher. However, a browser could be forced to use a weaker supported cipher due to a downgrade attack.
The current Elastic Cloud cipher list is stronger, but it also includes some cipher suites can be considered weak:
ECDHE-RSA-AES128-SHA256
-- this relies on Cipher Block Chaining (CBC) which is vulnerable to the Lucky 13 attackAES128-GCM-SHA256
-- this does not support Perfect Forward Secrecy (PFS)AES256-GCM-SHA384
-- this does not support PFSWe can change Kibana's default supported ciphers to a stronger list (selecting strong ciphers, omitting those that use CBC and those that do not provide PFS)
A couple of notes:
ECDSA
ciphers can only be used with ECC certificates, whileRSA
ciphers can only be used with older RSA certificates. Starting in TLS 1.3, the cipher no longer differentiates which type of key (ECC or RSA) is used for the certificate.Proposed changes
Given all of the above, here's what I think we need to do:
server.ssl.supportedProtocols
to mention that enabling TLS 1.1 (for example) would also require setting the--tls-min-1.1
option in thenode.options
configuration file as described in the release note above. In other words, both that and theserver.ssl.supportedProtocols
setting must match.server.ssl.supportedProtocols
accordingly.server.ssl.cipherSuites
accordingly.TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384