Secure communications is a core component of a robust security policy, and MySQL Server 5.7.10 – the first maintenance release of MySQL Server 5.7 – introduces needed improvements in this area. Support for TLS has been expanded from TLSv1.0 to include TLSv1.1 and TLSv1.2, default ciphers have been updated, and controls have been implemented allowing both server and client-side configuration of acceptable TLS protocol versions. This blog post will describe the changes, the context in which these changes were made, note important differences in capabilities between Community and Enterprise versions, and outline future plans.
SSL (Secure Sockets Layer) was superseded by TLS (Transport Layer Security) long ago, and TLSv1.0 has been the secure transport protocol used by MySQL Server for many years. This implementation was an effective firewall against vulnerabilities found in SSL (such as POODLE), but also prohibited timely adoption of subsequent iterations of the TLS protocol. TLSv1.0 is now also considered insufficiently secure, and the recently-released PCI DSS v3.1 standards prohibit use of TLSv1.0 as a security control, effective June 2016.
Complicating the urgent need to support TLSv1.1 and higher is the dependency MySQL Server has on two different TLS libraries. Due to license compatibility issues, OpenSSL is used in commercial-licensed MySQL Enterprise builds only, and yaSSL is leveraged to produce GPL-licensed MySQL Community builds. While yaSSL supports TLSv1.1, it lacks support for TLSv1.2. WolfSSL, the company behind yaSSL, offers another library (WolfSSL, originally known as CyaSSL). This library offers TLSv1.2 support, and WolfSSL helpfully offered Oracle patches to help mitigate the technical burden of migrating from yaSSL to the WolfSSL library. However, replacing TLS libraries is a substantial change to make, and we could not align this effort with the 5.7 release schedule.
Community and Enterprise differences
Support for TLSv1.2 is limited to builds that use the OpenSSL library. In addition to MySQL Enterprise builds produced by Oracle, MySQL Community can be built from source using OpenSSL. GPL-licensed MySQL Community builds from Oracle leverage yaSSL, and support TLSv1.0 and TLSv1.1. TLSv1.1 is sufficient for current PCI standards, though users of GPL-licensed MySQL Community may prefer to build MySQL Server from source to link OpenSSL and enable TLSv1.2.
OpenSSL-linked binaries prefer TLSv1.2 over other versions of TLS, and when TLS connections are made between a server and client that are linked to OpenSSL, TLSv1.2 will be used by default.
Better default ciphers
The default cipher used by earlier versions of MySQL Server is DHE-RSA-AES256-SHA. This is defined in RFC3268, an extension of TLSv1.0. It is also found in TLSv1.1, and is the default cipher used whenever legacy server or clients are involved, or when yaSSL-linked 5.7+ clients or servers are participants. When both client and server support TLSv1.2, the preferred cipher is DHE-RSA-AES128-GCM-SHA256.
MySQL allows control of allowed ciphers on both server and client ends using the –ssl-cipher option (which is somewhat confusingly exposed as the ssl-cipher-list status variable). The default values differ based on the library used. yaSSL-linked binaries have the following defaults:
OpenSSL-linked binaries use the following defaults:
In addition to the above, support for known weak ciphers has been removed (e.g., RC4-MD5, etc.). This helps reduce the possibility of MySQL 5.7 instances being compromised by exploits leveraging these older ciphers. In some cases, the weaker ciphers could not be seen in the ssl-cipher-list output, as that is truncated at 1024 characters.
Controlling TLS version
Even before PCI policy updates made this a requirement, security-minded MySQL community members have asked for the ability to enable or disable specific TLS versions, and MySQL 5.7.10 supports this using the new tls_version configuration option. Providing this option at startup allows users to enable only specified TLS versions, currently defined as:
Note that what I reference as TLSv1.0 is the TLSv1 option value. Thus, a configuration including tls_version=TLSv1.1,TLSv1.2 aligns with PCI DSS v3.1 guidelines.
Also worth noting, the tls_version configuration option triggers warnings – not errors – when invalid values are provided. This allows the same PCI-supporting configuration value of tls_version=TLSv1.1,TLSv1.2 to be used for both OpenSSL and yaSSL-based builds of MySQL Server, but the latter will enable only TLSv1.1. Currently, this also means that providing invalid values may result in TLS being disabled entirely (see bug reports).
The following matrix defines which TLS version will be negotiated by default by various combinations of legacy and 5.7.10+ yaSSL and OpenSSL-linked binaries. This applies not only to the standard MySQL command-line clients, but to drivers based on the libmysql client library.
|Pre-5.7.10 Server||5.7.10+ yaSSL-based Server||5.7.10+ OpenSSL-based Server|
|5.7.10+ yaSSL-based Client||TLSv1.0||TLSv1.1||TLSv1.1|
|5.7.10+ OpenSSL-based Client||TLSv1.0||TLSv1.1||TLSv1.2|
The tls_version configuration option is valid both for the MySQL Server as well as standard MySQL command-line clients. This makes it possible to restrict TLS to specific versions from either side of the connection.
Applications using the libmysql client library will find a new option – MYSQL_OPT_TLS_VERSION – which exposes the same control to applications or drivers which rely on this library.
The introduction of support for TLSv1.1 and TLSv1.2 was carefully planned to avoid incompatibilities. As a consequence, even though TLSv1.0 is no longer considered adequately secure, it remains enabled by default, as many clients and connectors leverage legacy client libraries which lack support for more recent versions. Users targeting PCI DSS v3.1 compliance will want to validate support for TLSv1.1+ for all clients/connectors, then disable TLSv1.0 on the server side.
One important aspect to consider is that failed TLS negotiation causes the server to terminate the connection request. This means that a client wanting a TLS connection, but only supporting TLSv1.0, attempting to connect to a server that supports only TLSv1.1 and TLSv1.2 will fail to connect entirely – the server won’t fail back to a non-TLS connection due to TLS negotiation failure. The following illustrates the results of attempting to connect the 5.7.9 mysql client – which prefers TLS over plain TCP/IP and only understands TLSv1.0 – with MySQL Server 5.7.10, configured for PCI compliance by setting tls_version=TLSv1.1:
D:\mysql-5.7.9-winx64>bin\mysql -uroot -P3310
ERROR 2026 (HY000): SSL connection error: protocol version mismatch
Visibility into TLS version
MySQL administrators looking to restrict TLS versions in support of PCI DSS v3.1 will want to assess potential impacts of removing TLSv1.0 support. As shown above, TLSv1.0 is required for compatibility with earlier versions of the libmysql client library, which is used by various application connectors as well as command-line tools. Removing support for TLSv1.0 may cause critical tools or systems to be unable to access MySQL Server.
Using PERFORMANCE_SCHEMA, it is easy for MySQL administrators to identify the TLS version in use for each connection. This allows critical tools and systems to be profiled by an administrator, and have visibility into what tools need to be updated prior to restricting TLSv1.0 support on the server side. Here is an example query:
-> variable_value AS tls_version,
-> processlist_user AS user,
-> processlist_host AS host
-> FROM performance_schema.status_by_thread sbt
-> JOIN performance_schema.threads t
-> ON (t.thread_id = sbt.thread_id)
-> WHERE variable_name = 'Ssl_version'
-> ORDER BY tls_version;
| tls_version | user | host |
| | root | localhost |
| TLSv1 | tv10 | localhost |
| TLSv1.1 | tv11 | localhost |
| TLSv1.2 | tv12 | localhost |
4 rows in set (0.00 sec)
This query is very similar to one I shared in a previous blog post, describing how to leverage PERFORMANCE_SCHEMA to see which TLS ciphers are being used by client connections. Both are useful tools for DBAs to evaluate potential impacts of proposed changes to improve security.
With support for TLSv1.1 and TLSv1.2 now in MySQL Server 5.7, a couple of questions remain unresolved.
Backporting to 5.6
MySQL Server 5.6 currently continues to support TLSv1.0 exclusively. Should the existing 5.7 functionality be back-ported to MySQL Server 5.6? This would decouple PCI compliance from a major server upgrade.
Adding TLSv1.2 for GPL-licensed builds
Adding support for TLSv1.2 in GPL-licensed builds means replacing yaSSL with an alternative library. Identifying and integrating another library is likely an invasive change, and it is unlikely that such a change can happen before the next major feature release of MySQL Server.
MySQL 5.7.10 provides TLS improvements necessary to support best security practices, including those mandated by recent updates to the PCI standards. There are notable differences between Enterprise and Community binaries, which are driven by library limitations, and Oracle is looking at alternative libraries to eliminate these differences in future feature releases. All TLS functionality is available to Community users who choose to build MySQL Server from source, linking against OpenSSL instead of yaSSL.