mysql2: Can't enable SSL with MariaDB driver library
It is currently not possible to enable SSL through the ssl_mode parameter when using the MariaDB driver library.
This is critical because you can’t connect to a MySQL server with a user that requires SSL.
How to reproduce?
Versions:
$ lsb_release -d
Description: Ubuntu 20.04.2 LTS
$ ruby --version
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]
$ gem --version
3.0.9
$ bundle --version
Bundler version 1.17.3
$ dpkg --list mysql-server-8.0
ii mysql-server-8.0 8.0.23-0ubuntu0.20.04.1 amd64 MySQL database server binaries and system database setup
Create a MySQL database user with “REQUIRE SSL”:
> CREATE USER IF NOT EXISTS test@127.0.0.1
IDENTIFIED WITH mysql_native_password BY 'test'
REQUIRE SSL;
Create a test script:
$ vim Gemfile
source 'https://rubygems.org'
gem 'mysql2'
$ vim test.rb
require 'mysql2'
client = Mysql2::Client.new(host: '127.0.0.1', username: 'test', password: 'test', ssl_mode: :required)
puts client.query('SHOW STATUS LIKE "Ssl_cipher"').first.inspect
🔴 Test with the MariaDB driver library
Install the driver library and the mysql2 gem:
$ sudo apt-get install libmariadb-dev-compat
$ dpkg --list libmariadb-dev-compat
...
ii libmariadb-dev-compat:amd64 1:10.3.25-0ubuntu0.20.04.1 amd64 MariaDB Connector/C, compatibility symlinks
$ bundle exec gem uninstall mysql2
Successfully uninstalled mysql2-0.5.3
$ bundle
...
Installing mysql2 0.5.3 with native extensions
...
$ ldd $(bundle show mysql2)/lib/mysql2/mysql2.so
...
libmariadb.so.3 => /usr/lib/x86_64-linux-gnu/libmariadb.so.3 (0x00007efe06293000)
...
Run the test script:
$ bundle exec ruby test.rb
/home/clemens/.rvm/gems/ruby-2.6.6/gems/mysql2-0.5.3/lib/mysql2/client.rb:51: warning: Your mysql client library does not support ssl_mode as expected.
Traceback (most recent call last):
3: from test.rb:2:in `<main>'
2: from test.rb:2:in `new'
1: from /home/clemens/.rvm/gems/ruby-2.6.6/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `initialize'
/home/clemens/.rvm/gems/ruby-2.6.6/gems/mysql2-0.5.3/lib/mysql2/client.rb:90:in `connect': Access denied for user 'test'@'localhost' (using password: YES) (Mysql2::Error::ConnectionError)
🟢 Test with the MySQL driver library
Install the driver library and the mysql2 gem:
$ sudo apt-get install libmysqlclient-dev
$ dpkg --list libmysqlclient-dev
...
ii libmysqlclient-dev 8.0.23-0ubuntu0.20.04.1 amd64 MySQL database development files
$ bundle exec gem uninstall mysql2
Successfully uninstalled mysql2-0.5.3
$ bundle
...
Installing mysql2 0.5.3 with native extensions
...
$ ldd $(bundle show mysql2)/lib/mysql2/mysql2.so
...
libmysqlclient.so.21 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.21 (0x00007f0ac5a7b000)
...
Run the test script:
$ bundle exec ruby test.rb
{"Variable_name"=>"Ssl_cipher", "Value"=>"TLS_AES_256_GCM_SHA384"}
🟢 Solution?
With the MariaDB driver, the “mysql_get_client_version” at https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L107 returns 100325 and HAVE_CONST_MYSQL_OPT_SSL_ENFORCE at https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L113 is defined. The version that “mysql_get_client_version” returns is calculated at https://github.com/mariadb-corporation/mariadb-connector-c/blob/v3.1.12/CMakeLists.txt#L173.
With the MySQL driver, the “mysql_get_client_version” at https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L107 returns 80023 and FULL_SSL_MODE_SUPPORT at https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L131 is defined.
After adding a new version range for the MariaDB driver to https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L117 the ssl_mode is correctly set and SSL is used for the database connection.
1. Create a patched mysql2 gem
$ git clone https://github.com/brianmario/mysql2.git
$ cd mysql2
$ git checkout 0.5.3
$ vim ext/mysql2/client.c
...
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200) || (version >= 100200 && version < 110000)) {
...
$ git diff
diff --git a/ext/mysql2/client.c b/ext/mysql2/client.c
index 13fd2dd..e484fa0 100644
--- a/ext/mysql2/client.c
+++ b/ext/mysql2/client.c
@@ -114,7 +114,7 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
GET_CLIENT(self);
int val = NUM2INT( setting );
// Either MySQL 5.7.3 - 5.7.10, or Connector/C 6.1.3 - 6.1.x
- if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200)) {
+ if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200) || (version >= 100200 && version < 110000)) {
if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
my_bool b = ( val == SSL_MODE_REQUIRED );
int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
$ gem build mysql2
$ cp mysql2-0.5.3.gem /tmp
2. Install the MariaDB driver library and the patched mysql2 gem
$ sudo apt-get install libmariadb-dev-compat
$ dpkg --list libmariadb-dev-compat
...
ii libmariadb-dev-compat:amd64 1:10.3.25-0ubuntu0.20.04.1 amd64 MariaDB Connector/C, compatibility symlinks
$ bundle exec gem uninstall mysql2
Successfully uninstalled mysql2-0.5.3
$ gem install /tmp/mysql2-0.5.3.gem
...
Successfully installed mysql2-0.5.3
...
$ ldd $(bundle show mysql2)/lib/mysql2/mysql2.so
...
libmariadb.so.3 => /usr/lib/x86_64-linux-gnu/libmariadb.so.3 (0x00007f4576d6e000)
...
3. Run the test script
$ bundle exec ruby test.rb
{"Variable_name"=>"Ssl_cipher", "Value"=>"TLS_AES_256_GCM_SHA384"}
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 28 (21 by maintainers)
Commits related to this issue
- #1182: Can't enable SSL with MariaDB driver library. — committed to vakuum/mysql2 by vakuum 3 years ago
- Can't enable SSL with MariaDB driver library. (#1182) — committed to vakuum/mysql2 by vakuum 3 years ago
- Revert "Can't enable SSL with MariaDB driver library. (#1182)" This reverts commit 22fce00a93b19f3d4eadd29d1a60775433aac7bf. — committed to junaruga/mysql2 by junaruga 3 years ago
- Revert "Can't enable SSL with MariaDB driver library. (#1182)" This reverts commit 22fce00a93b19f3d4eadd29d1a60775433aac7bf. — committed to junaruga/mysql2 by vakuum 3 years ago
- Can't enable SSL with MariaDB driver library. (#1182) — committed to junaruga/mysql2 by vakuum 3 years ago
- Can't enable SSL with MariaDB driver library. (#1182) — committed to junaruga/mysql2 by vakuum 3 years ago
- Merge pull request #1183 from vakuum/master Can't enable SSL with MariaDB driver library. (#1182) — committed to brianmario/mysql2 by sodabrew 3 years ago
@junaruga I get the same results with mariadb-server-10.3 as with mysql-server-8.0.
The Makefile contains
HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
and the spec from above fails.And after adding the new version range to https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L117 the spec turns green.
It was a surprise to me that mariadb-server-10.3 doesn’t have a working SSL configuration out of the box. 😃
Adding the new version range: