Bug 62342 - apr_dbd_mysql Lacks TLS Support
Summary: apr_dbd_mysql Lacks TLS Support
Status: NEW
Alias: None
Product: APR
Classification: Unclassified
Component: APR (show other bugs)
Version: HEAD
Hardware: All All
: P2 major (vote)
Target Milestone: ---
Assignee: Apache Portable Runtime bugs mailinglist
URL:
Keywords: PatchAvailable
Depends on:
Blocks:
 
Reported: 2018-05-01 03:55 UTC by William
Modified: 2023-01-31 16:00 UTC (History)
2 users (show)



Attachments
Diff solves this BZ for the 1.5.x branch (15.17 KB, patch)
2018-05-11 22:35 UTC, William
Details | Diff
Diff solves this BZ for 2.0.x (16.17 KB, patch)
2018-05-11 22:39 UTC, William
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description William 2018-05-01 03:55:58 UTC
Overview:
When communicating with a TLS-enabled MySQL or MariaDB server, apr_dbd_mysql makes no attempt to engage TLS.

Steps to Reproduce:
1) Provision two hosts or VMs (hereafter dubbed "nodes")

2) On one of your nodes -- the "Database Server" node -- install MySQL or MariaDB with TLS support.  Properly configure TLS support for a database you intend to use for authentication with your Web Server.

3) On your other node -- the "Web Server" node -- install the Apache Web Server with apr_dbd_mysql (and requirements for your operating system like authn_dbd, et al.).

4) Attempt to configure a web site or virtual host that employs TLS to your MySQL/MariaDB server.  Note:  it's impossible because apr_dbd_mysql lacks this capability.

Actual Results:
MySQL/MariaDB traffic between the Web Server and Database Server nodes fails to employ TLS.

Expected Results:
apr_dbd_mysql should support TLS.

Build Date & Hardware
Any & Any
Sample set: apr-util-1.5.2-6.el7.x86_64.rpm & CentOS Linux release 7.4.1708 (Core)

Additional Builds and Platforms:
This issue occurs with all released versions of apr_dbd_mysql, including the present SVN trunk (at the time this report is submitted).

Additional Information
This optional capability should be supported by apr_dbd_mysql pursuant to the MySQL manual, "clients attempt to connect using encryption, falling back to an unencrypted connection if an encrypted connection cannot be established".  Note that MySQL/MaridaDB can offer TLS to clients similar to how Apache Web Server offers HTTPS -- without requiring client certificates.  Client certificate verification and server certificate verification should both be optional, never mandatory to "enable TLS" at the client.

I realize that setting up a test for this bug can be complex.  That said, you can verify the lack of TLS support by simply perusing the project's source code and note the lack of any TLS options (at the time of this writing, Revision 1830649):
https://svn.apache.org/repos/asf/apr/apr/trunk/dbd/apr_dbd_mysql.c lines 1122-1137

Also notably missing are any calls to mysql_options() using the MYSQL_OPT_SSL_* options or any call to mysql_ssl_set() before mysql_real_connect().
Comment 1 William 2018-05-11 22:35:29 UTC
Created attachment 35929 [details]
Diff solves this BZ for the 1.5.x branch

I realize the APR group is no longer interested in 1.5 but this serious security vulnerability exists for all RHEL 7 and downstream users today.  I've created this patch specifically to solve this issue for real-world users.  I tested this fix in a lab environment and it works as described.
Comment 2 William 2018-05-11 22:39:11 UTC
Created attachment 35930 [details]
Diff solves this BZ for 2.0.x

Pursuant to advice received from the APR mailing-list, I have also created a patch for 2.0.x (trunk) which solves this BZ.  I don't have an Apache Web Server build that uses APR 2, so I'm unable to directly test this patch.  That said, it is nearly code-identical to the same patch I created for the 1.5.x branch -- with the new goodies for 2.0.x -- so I have high confidence that this patch will also work as described.
Comment 3 William 2018-05-30 20:34:07 UTC
Just adding a positive note:  We've been running this modification in development and production environments for nearly 3 weeks and it works as described.  MySQL connections are encrypted between Apache Web Server and MariaDB servers on CentOS 7.
Comment 4 Tom Donovan 2023-01-31 03:14:22 UTC
Are you aware that you can connect to MySQL or MariaDB via SSL/TLS since the "group" key was added to MySQL's DBDParams back in apr-util 1.3.

To do this:  first connect manually with TLS from your web server node to your database using the MySQL interactive program "mysql", type "\s" to get status info and note the Cipher in use.  

Next, make up a name (like websvr) and add group=websvr to your DBDParams directive in httpd.conf.  Then add a [websvr] group to the MySQL/MariaDB config file on your web server node with the cipher name.  This file is usually /etc/mysql/my.cnf on unix systems.   For example:

[websvr]
ssl-cipher=TLS_AES_256_GCM_SHA384


If the MySQL server supports TLS and your local libmysqlclient.so is built with openssl (or equivalent), then your connection via apr_dbd_mysql should now use TLS.

To check that it works, you can construct a web page which executes the SQL query:

 SHOW STATUS LIKE 'ssl%' 

and displays the results.  the Ssl_cipher row will show which cipher you are using to connect, and the Ssl_cipher_list row shows all the ciphers available on the MySQL server.

Note that mod_dbd does nothing here except give you access to a named group in a MySQL config file.  TLS is established by libmysqlclient,  and is transparent to mod_dbd.  

See the documentation for the C-connector (or API-C) for your version of MySQL/MariaDB/Perconia/etc.  

See https://apr.apache.org/docs/apr-util/1.3/modules.html DBD routines apr_dbd_open_ex for the DBDParams for MySQL, and see your connector's documentation for the MYSQL_READ_DEFAULT_GROUP option it uses.