Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't enable SSL with MariaDB driver library #1182

Closed
vakuum opened this issue Apr 9, 2021 · 28 comments
Closed

Can't enable SSL with MariaDB driver library #1182

vakuum opened this issue Apr 9, 2021 · 28 comments

Comments

@vakuum
Copy link

vakuum commented Apr 9, 2021

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 [email protected]
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"}
@junaruga
Copy link
Contributor

@vakuum thank you for the detailed report and the investigation!

When the libmariadb-dev-compat:amd64 1:10.3.25 returns the client version 100325, why is the patch || (version >= 100200 && version < 110000)? For example why not || (version >= 100100 && version < 110000). I do not understand it.

We have CI cases on GitHub Actions. Could you sent the PR for your patch, adding your case to the GitHub Actions as one case in build.yml - include syntax?

# Allow failure due to Mysql2::Error: Unknown system variable 'session_track_system_variables'.
- {os: ubuntu-16.04, ruby: 2.4, db: mariadb10.0, allow-failure: true}
# Comment out due to ci/setup.sh stucking.
# - {os: ubuntu-18.04, ruby: 2.4, db: mariadb10.1}
# `service mysql restart` fails.
- {os: ubuntu-20.04, ruby: 2.4, db: mariadb10.3, allow-failure: true}
- {os: ubuntu-18.04, ruby: 2.4, db: mysql57}
# Allow failure due to the issue #1165.
- {os: ubuntu-20.04, ruby: 2.4, db: mysql80, allow-failure: true}
- {os: ubuntu-18.04, ruby: 'head', db: '', allow-failure: true}

You can use ubuntu-20.04 on it. Maybe you see a test failure with the mysql-server-8.0 (#1165), but you can set allow-failure: true on the CI.

@junaruga
Copy link
Contributor

Maybe we can modify the comment in rb_set_ssl_mode_option like this.

// Either MySQL 5.7.3 - 5.7.10, Connector/C 6.1.3 - 6.1.x, or MariaDB n.n.n - n.n.n

@junaruga
Copy link
Contributor

When the libmariadb-dev-compat:amd64 1:10.3.25 returns the client version 100325, why is the patch || (version >= 100200 && version < 110000)? For example why not || (version >= 100100 && version < 110000). I do not understand it.

I guess the || (version >= 100200 && version < 110000) means "MariaDB 10.2.0 - (< 11)". If the range of the versions in the MariaDB client is right, the comment could be like this.

// Either MySQL 5.7.3 - 5.7.10, Connector/C 6.1.3 - 6.1.x, or MariaDB 10.2.0 - (< 11).

@junaruga
Copy link
Contributor

@vakuum Do you know how can we enable HAVE_CONST_MYSQL_OPT_SSL_ENFORCE used in client.c? I think it is necessary to reproduce the warning warning: Your mysql client library does not support ssl_mode as expected.?

@junaruga
Copy link
Contributor

@sodabrew Do you know how to enable the macro HAVE_CONST_MYSQL_OPT_SSL_ENFORCE related to #1186 ?

I see you worked on this kind of things in the past. ff05239

@junaruga
Copy link
Contributor

This one?

https://dev.mysql.com/doc/c-api/5.7/en/mysql-options.html

MYSQL_OPT_SSL_ENFORCE (argument type: my_bool *)
Whether to require the connection to use SSL. If enabled and an encrypted connection cannot be established, the connection attempt fails.
This option is deprecated as of MySQL 5.7.11 and is removed in MySQL 8.0. Instead, use MYSQL_OPT_SSL_MODE with a value of SSL_MODE_REQUIRED.

@junaruga
Copy link
Contributor

I got a feedback at #1186 . Maybe we should not add the new CI case: DB server: MySQL, and DB client: MariaDB for now. Instead of that, we need to add a new unit test that can detect this issue. Because on the current unit tests on the current CI cases, this issue (the warning) is not detected.

@junaruga
Copy link
Contributor

I captured the compiler's flags used for ext/mysql2/client.c by a patch #1187 . I just checked the following 3 cases. And I could not find the HAVE_CONST_MYSQL_OPT_SSL_ENFORCE macro. Possibly there is no CI case enabling the macro right now on CI. It's better to add the case on CI, isn't it?

GitHub - Build Ruby 3.0 case.

gcc -I. -I/opt/hostedtoolcache/Ruby/3.0.1/x64/include/ruby-3.0.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.0.1/x64/include/ruby-3.0.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.0.1/x64/include/ruby-3.0.0 -I../../../../ext/mysql2 -I/usr/include/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_SSL_MODE_DISABLED -DHAVE_CONST_SSL_MODE_PREFERRED -DHAVE_CONST_SSL_MODE_REQUIRED -DHAVE_CONST_SSL_MODE_VERIFY_CA -DHAVE_CONST_SSL_MODE_VERIFY_IDENTITY -DHAVE_MYSQL_NET_VIO -DHAVE_ST_NET_VIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL -I/opt/hostedtoolcache/Ruby/3.0.1/x64/include -DENABLE_PATH_CHECK=0   -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -DFULL_SSL_MODE_SUPPORT -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o client.o -c ../../../../ext/mysql2/client.c

GitHub - Container CentOS 7 Ruby 2.0.0 case.

gcc -I. -I/usr/include -I/usr/include/ruby/backward -I/usr/include -I../../../../ext/mysql2 -I/usr/include/mysql -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQL_NET_VIO -DHAVE_ST_NET_VIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -mtune=generic -fPIC -DNO_SSL_MODE_SUPPORT -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused -m64 -o client.o -c ../../../../ext/mysql2/client.c

Travis Ruby 2.4 DB=mariadb10.3 case.

gcc -I. -I/home/travis/.rvm/rubies/ruby-2.4.10/include/ruby-2.4.0/x86_64-linux -I/home/travis/.rvm/rubies/ruby-2.4.10/include/ruby-2.4.0/ruby/backward -I/home/travis/.rvm/rubies/ruby-2.4.10/include/ruby-2.4.0 -I../../../../ext/mysql2 -I/usr/include/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_MYSQL_NET_VIO -DHAVE_ST_NET_VIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -Wsuggest-attribute=noreturn -Wsuggest-attribute=format  -fPIC -DNO_SSL_MODE_SUPPORT -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o client.o -c ../../../../ext/mysql2/client.c

@vakuum
Copy link
Author

vakuum commented Apr 11, 2021

@junaruga The macro HAVE_CONST_MYSQL_OPT_SSL_ENFORCE is defined in the generated Makefile when using the MariaDB driver:

$ grep HAVE_CONST_MYSQL_OPT_SSL_ENFORCE -r $(bundle show mysql2)
...
/home/clemens/.rvm/gems/ruby-2.6.6@test/gems/mysql2-0.5.3/ext/mysql2/Makefile:CPPFLAGS = -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL  $(DEFS) $(cppflags)

The following spec fails without the change of https://github.com/brianmario/mysql2/blob/0.5.3/ext/mysql2/client.c#L117 and the warning "Your mysql client library does not support ssl_mode as expected" is also printed:

$ sudo apt-get install libmariadb-dev-compat

$ git clone https://github.com/brianmario/mysql2.git

$ cd mysql2

$ vim spec/mysql2/client_spec.rb
...

$ git diff
diff --git a/spec/mysql2/client_spec.rb b/spec/mysql2/client_spec.rb
index 5e330f6..38df666 100644
--- a/spec/mysql2/client_spec.rb
+++ b/spec/mysql2/client_spec.rb
@@ -1122,4 +1122,8 @@ RSpec.describe Mysql2::Client do # rubocop:disable Metrics/BlockLength
   it "should respond to #encoding" do
     expect(@client).to respond_to(:encoding)
   end
+
+  it 'should use SSL' do
+    expect(new_client(ssl_mode: :required).query('SHOW STATUS LIKE "Ssl_cipher"').first['Value']).to_not eq('')
+  end
 end

$ bundle

$ bundle exec rake clean

$ bundle exec rake compile

$ ldd tmp/x86_64-linux/stage/lib/mysql2/mysql2.so
        ...
        libmariadb.so.3 => /usr/lib/x86_64-linux-gnu/libmariadb.so.3 (0x00007f484af74000)
        ...

$ bundle exec rake
...
Mysql2::Client
  ...
/home/clemens/mysql2/lib/mysql2/client.rb:51: warning: Your mysql client library does not support ssl_mode as expected.
  should use SSL (FAILED - 1)
  ...

  1) Mysql2::Client should use SSL
     Failure/Error: expect(new_client(ssl_mode: :required).query('SHOW STATUS LIKE "Ssl_cipher"').first['Value']).to_not eq('')

       expected: value != ""
            got: ""

       (compared using ==)
     # ./spec/mysql2/client_spec.rb:1127:in `block (2 levels) in <top (required)>'
  ...

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.

@junaruga
Copy link
Contributor

@vakuum Thanks for the info.

OK. You see the macro definition. I also can see the macro on my local. The defined macro The macro in the Makefile CPPFLAGS (right?) is used as a compiler's flags.
So, if you run the following command. You can see the macro on the command line to compile client.c.

bundle exec rake clean
MAKE="make V=1" bundle exec rake compile

I found the reason. How the macro is defined, and used.

First the maccos are checked from the MySQL/MariaDB client library's header.

add_ssl_defines(mysql_h)

Then,

all_modes_found = %w[SSL_MODE_DISABLED SSL_MODE_PREFERRED SSL_MODE_REQUIRED SSL_MODE_VERIFY_CA SSL_MODE_VERIFY_IDENTITY].inject(true) do |m, ssl_mode|
m && have_const(ssl_mode, header)
end
$CFLAGS << ' -DFULL_SSL_MODE_SUPPORT' if all_modes_found
# if we only have ssl toggle (--ssl,--disable-ssl) from 5.7.3 to 5.7.10
has_no_support = all_modes_found ? false : !have_const('MYSQL_OPT_SSL_ENFORCE', header)
$CFLAGS << ' -DNO_SSL_MODE_SUPPORT' if has_no_support

When have_const('MYSQL_OPT_SSL_ENFORCE', header) executes and the have_const returns true, "maybe" the HAVE_CONST_MYSQL_OPT_SSL_ENFORCE is set to the Makefile internally by Ruby's mkmf library.

For the above GitHub - Build Ruby 3.0 case, I found the -DFULL_SSL_MODE_SUPPORT in the commands to compile client.c.
For the above GitHub - Container CentOS 7 Ruby 2.0.0 case and Travis Ruby 2.4 DB=mariadb10.3 case, I found the -DNO_SSL_MODE_SUPPORT in the commands to compile client.c.

And seeing the logic in the extconf.rb, for both cases, the have_const('MYSQL_OPT_SSL_ENFORCE', header) is not executed. That's why we do not see the macro HAVE_CONST_MYSQL_OPT_SSL_ENFORCE on the current CI cases.

@junaruga
Copy link
Contributor

@vakuum Have you tried to install and start the daemon of the Ubuntu mariadb-server-10.3 on your Ubuntu 20.04 (focal) environment? Because we can not start the MariaDB 10.3 on GitHub Actions Ubuntu focal (#1184). If you succeed to start the daemon, we can add the MariaDB 10.3 case with the client library libmariadb-dev-compat.

@junaruga
Copy link
Contributor

@vakuum Can you paste the output of MAKE="make V=1" bundle exec rake compile on your environment here? I want to see it.

@junaruga
Copy link
Contributor

As a reference, here is a log on my local.

@junaruga
Copy link
Contributor

junaruga commented Apr 11, 2021

I could found the HAVE_CONST_MYSQL_OPT_SSL_ENFORCE on our current fedora:rawhide and fedora:latest cases on GitHub Actions. the log. But in these case, the DB client library is mariadb-c-connector, not mariadb's client library. That's why we could not detect this issue on the CI cases.

@junaruga
Copy link
Contributor

@vakuum On the #1184 (comment) , I was able to run MariaDB server on GitHub Actions using MariaDB's official container. So, I will prepare to verify your patch.

@vakuum
Copy link
Author

vakuum commented Apr 12, 2021

@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. :-)

$ git clone https://github.com/brianmario/mysql2.git

$ cd mysql2

$ sudo apt-get install libmariadb-dev-compat

$ sudo apt-get install mariadb-server-10.3

$ cat /etc/apparmor.d/abstractions/mysql
  ...
  /var/lib/mysql{,d}/mysql{,d}.sock rw,
  ...

$ sudo vim /etc/mysql/mariadb.conf.d/50-server.cnf
...
[mysqld]
ssl = on
ssl-ca = /var/lib/mysql/ca-cert.pem
ssl-cert = /var/lib/mysql/server-cert.pem
ssl-key = /var/lib/mysql/server-key.pem
...

$ sudo cp spec/ssl/ca-cert.pem /var/lib/mysql
$ sudo cp spec/ssl/server-cert.pem /var/lib/mysql
$ sudo cp spec/ssl/server-key.pem /var/lib/mysql

$ sudo systemctl restart mariadb.service

$ sudo mysql
...
Server version: 10.3.25-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04
...

MariaDB> SHOW VARIABLES LIKE '%ssl%';
+---------------------+--------------------------------+
| Variable_name       | Value                          |
+---------------------+--------------------------------+
| have_openssl        | NO                             |
| have_ssl            | YES                            |
| ssl_ca              | /var/lib/mysql/ca-cert.pem     |
| ssl_capath          |                                |
| ssl_cert            | /var/lib/mysql/server-cert.pem |
| ssl_cipher          |                                |
| ssl_crl             |                                |
| ssl_crlpath         |                                |
| ssl_key             | /var/lib/mysql/server-key.pem  |
| version_ssl_library | YaSSL 2.4.4                    |
+---------------------+--------------------------------+
10 rows in set (0.001 sec)

MariaDB> ALTER USER 'root'@'localhost' IDENTIFIED BY 'root';
Query OK, 0 rows affected (0.000 sec)

MariaDB> CREATE DATABASE test;
Query OK, 1 row affected (0.000 sec)

MariaDB> CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';
Query OK, 0 rows affected (0.000 sec)

MariaDB> GRANT ALL PRIVILEGES ON test.* TO 'test'@'localhost';
Query OK, 0 rows affected (0.000 sec)

MariaDB> quit
Bye

$ cp spec/configuration.yml.example spec/configuration.yml

$ vim spec/configuration.yml
root:
  host: localhost
  username: root
  password: root
  database: test

user:
  host: localhost
  username: test
  password: test
  database: test

$ vim spec/mysql2/client_spec.rb
...
  it 'should use SSL' do
    expect(new_client(ssl_mode: :required).query('SHOW STATUS LIKE "Ssl_cipher"').first['Value']).to_not eq('')
  end
end

$ bundle

$ bundle exec rake clean

$ MAKE="make V=1" bundle exec rake compile &> compile.log

$ grep HAVE_CONST_MYSQL_OPT_SSL_ENFORCE tmp/x86_64-linux/mysql2/2.6.6/Makefile 
CPPFLAGS = -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL  $(DEFS) $(cppflags)

$ grep HAVE_CONST_MYSQL_OPT_SSL_ENFORCE compile.log
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGmhm@ubuntu:~/mysql2$ grep HAVE_CONST_MYSQL_OPT_SSL_ENFORCE compile.log
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o client.o -c ../../../../ext/mysql2/client.c
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o infile.o -c ../../../../ext/mysql2/infile.c
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o mysql2_ext.o -c ../../../../ext/mysql2/mysql2_ext.c
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o result.o -c ../../../../ext/mysql2/result.c
gcc -I. -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/x86_64-linux -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0/ruby/backward -I/home/clemens/.rvm/rubies/ruby-2.6.6/include/ruby-2.6.0 -I../../../../ext/mysql2 -I/usr/include/mariadb -I/usr/include/mariadb/mysql -DHAVE_RB_ABSINT_SIZE -DHAVE_RB_ABSINT_SINGLEBIT_P -DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_MYSQL_H -DHAVE_ERRMSG_H -DHAVE_CONST_MYSQL_OPT_SSL_ENFORCE -DHAVE_MYSQL_NET_PVIO -DHAVE_ST_NET_PVIO -DHAVE_CONST_MYSQL_ENABLE_CLEARTEXT_PLUGIN -DHAVE_CONST_SERVER_QUERY_NO_GOOD_INDEX_USED -DHAVE_CONST_SERVER_QUERY_NO_INDEX_USED -DHAVE_CONST_SERVER_QUERY_WAS_SLOW -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_ON -DHAVE_CONST_MYSQL_OPTION_MULTI_STATEMENTS_OFF -DHAVE_TYPE_MY_BOOL    -fPIC -O3 -ggdb3 -Wall -Wextra -Wdeclaration-after-statement -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wrestrict -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable  -fPIC -Wno-bad-function-cast -Wno-conditional-uninitialized -Wno-covered-switch-default -Wno-declaration-after-statement -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-missing-field-initializers -Wno-missing-variable-declarations -Wno-padded -Wno-reserved-id-macro -Wno-sign-conversion -Wno-static-in-inline -Wno-switch-enum -Wno-undef -Wno-unreachable-code -Wno-used-but-marked-unused  -o statement.o -c ../../../../ext/mysql2/statement.c

$ ldd tmp/x86_64-linux/stage/lib/mysql2/mysql2.so
        ...
        libmariadb.so.3 => /usr/lib/x86_64-linux-gnu/libmariadb.so.3 (0x00007f15669bb000)
        ...

$ bundle exec rake 
...
Mysql2::Client
  ...
/home/mhm/mysql2/lib/mysql2/client.rb:51: warning: Your mysql client library does not support ssl_mode as expected.
  should use SSL (FAILED - 1)
  ...

Adding the new version range:

$ vim ext/mysql2/client.c
...
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200) || (version >= 100000 && version < 110000)) {
...

$ bundle exec rake clean

$ bundle exec rake compile

$ bundle exec rake
...
Mysql2::Client
  ...
  should use SSL
  ...

@junaruga
Copy link
Contributor

@vakuum Nice!

Right now the mariadb10.3 case using mariadb-server mariadb-server-10.3 is disabled because the MariaDB server does not start.

It's great if you can fix it, and enable the case.

.github/workflows/build.yml

          # `service mysql restart` fails.
          - {os: ubuntu-20.04, ruby: 2.4, db: mariadb10.3, allow-failure: true}

As a note, I noticed today that on the GitHub focal, the libmysqlclient-dev (including /usr/bin/mysql_config), the MySQL client library is installed as a default. It triggers not intended library is used.

So, I am using this script to remove and to install the package DB_CLIENT on my forked repo's working branch.

$ cat ci/db_client.sh 
#!/usr/bin/env bash

set -eux

DB_CLIENT="${DB_CLIENT:-}"

# If mysql_config is found, remove it.
# On Ubuntu:focal the libmysqlclient-dev for MySQL is the package.
if command -v mysql_config > /dev/null; then
  PKG=$(dpkg-query -S "$(command -v mysql_config)" | cut -d ':' -f 1)
  echo "A installed database client package: ${PKG} found. Removing it ..."
  sudo apt-get remove -qq "${PKG}"
  sudo apt-get purge -qq "${PKG}"
  sudo apt-get autoremove -qq "${PKG}"
  sudo apt-get clean -qq
fi

if [ -n "${DB_CLIENT}" ]; then
  sudo apt-get install -qq "${DB_CLIENT}"
fi

@junaruga
Copy link
Contributor

If you want to check the used DB client library, the following command might be useful, as you may know it.

$ ruby -I lib -r mysql2 -e 'p Mysql2::Client.info'
{:id=>100505, :version=>"10.5.5", :header_version=>"10.5.5"}

@junaruga
Copy link
Contributor

junaruga commented Apr 13, 2021

@vakuum I was able to run MariaDB 10.0, 10.1, 10.2, 10.3, 10.4, 10.5 with SSL mode by MariaDB official container on my testing repository. I will prepare to contribute the cases to this repository's GitHub Actions. So, we can reproduce this issue on GitHub Actions. Your working log for MariaDB helped me to do it. Thanks!
https://github.com/junaruga/mysql-test

If you are working on fixing the current mariadb-server mariadb-server-10.3 case, my situation does not stop your work. Personally I want to see the CI case where MariaDB is directly running on GitHub Actions.

@vakuum
Copy link
Author

vakuum commented Apr 15, 2021

@junaruga I added a commit to #1183 for fixing the MariaDB 10.3 installation under Ubuntu 20.04.

The following issues caused the installation to fail:

After installing the mariadb-server-10.3 package with ci/setup.sh the /var/log/mysql/error.log contained some additional errors:

+ cat /var/log/mysql/error.log
Error: -15 12:02:59 0 [ERROR] InnoDB: Invalid flags 0x4800 in ./ibdata1
+ exit 1
Error: -15 12:02:59 0 [ERROR] InnoDB: Plugin initialization aborted with error Data structure corruption
Error: -15 12:03:00 0 [ERROR] Plugin 'InnoDB' init function returned error.
Error: -15 12:03:00 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
Error: -15 12:03:00 0 [ERROR] Unknown/unsupported storage engine: InnoDB
Error: -15 12:03:00 0 [ERROR] Aborting
...

The /var/lib/mysql directory already contained some database files from the preinstalled MySQL 8.0 installation. And these database files were not compatible with MariaDB 10.3.

So I modified ci/setup.sh to remove the MySQL packages and directories before installing the MariaDB packages:

$ vim ci/setup.sh
...
# Install MariaDB 10.3 if DB=mariadb10.3
if [[ -n ${GITHUB_ACTIONS-} && -n ${DB-} && x$DB =~ ^xmariadb10.3 ]]; then
  sudo apt-get purge -y 'mysql-common*' 'mysql-server*' 'mysql-client*'
  sudo rm -rf /etc/mysql /var/lib/mysql
  sudo apt-get install -y -o Dpkg::Options::='--force-confnew' mariadb-server mariadb-server-10.3 libmariadb-dev
  CHANGED_PASSWORD=true
  sudo cat /var/log/mysql/error.log
  exit 1
fi
...

With the above change, the installation of MariaDB hanged forever at this step:

+ sudo apt-get install -y -o Dpkg::Options::=--force-confnew mariadb-server mariadb-server-10.3 libmariadb-dev
...
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /lib/systemd/system/mariadb.service.

The /var/log/mysql/error.log looked good:

+ sudo cat /var/log/mysql/error.log
2021-04-15 13:41:39 0 [Note] InnoDB: Using Linux native AIO
2021-04-15 13:41:39 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2021-04-15 13:41:39 0 [Note] InnoDB: Uses event mutexes
2021-04-15 13:41:39 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2021-04-15 13:41:39 0 [Note] InnoDB: Number of pools: 1
2021-04-15 13:41:39 0 [Note] InnoDB: Using SSE2 crc32 instructions
2021-04-15 13:41:39 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2021-04-15 13:41:39 0 [Note] InnoDB: Completed initialization of buffer pool
2021-04-15 13:41:39 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2021-04-15 13:41:39 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2021-04-15 13:41:39 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2021-04-15 13:41:39 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2021-04-15 13:41:39 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2021-04-15 13:41:39 0 [Note] InnoDB: 10.3.25 started; log sequence number 1625443; transaction id 21
2021-04-15 13:41:39 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2021-04-15 13:41:39 0 [Note] Plugin 'FEEDBACK' is disabled.
2021-04-15 13:41:39 0 [Note] InnoDB: Buffer pool(s) load completed at 210415 13:41:39
2021-04-15 13:41:39 0 [Note] Server socket created on IP: '127.0.0.1'.
2021-04-15 13:41:39 0 [Note] Reading of all Master_info entries succeeded
2021-04-15 13:41:39 0 [Note] Added new Master_info '' to hash table
2021-04-15 13:41:39 0 [Note] /usr/sbin/mysqld: ready for connections.
Version: '10.3.25-MariaDB-0ubuntu0.20.04.1'  socket: '/run/mysqld/mysqld.sock'  port: 3306  Ubuntu 20.04

But the output of journalctl contained an apparmor error for /usr/sbin/mysqld:

Apr 15 13:41:39 fv-az243-582 systemd[1]: /etc/systemd/system/runner-provisioner.service:3: Invalid URL, ignoring: None
Apr 15 13:41:39 fv-az243-582 systemd[1]: Starting MariaDB 10.3.25 database server...
Apr 15 13:41:39 fv-az243-582 mysqld[4602]: 2021-04-15 13:41:39 0 [Note] /usr/sbin/mysqld (mysqld 10.3.25-MariaDB-0ubuntu0.20.04.1) starting as process 4602 ...
Warning: :41:39 fv-az243-582 mysqld[4602]: 2021-04-15 13:41:39 0 [Warning] Could not increase number of max_open_files to more than 16384 (request: 32184)
Apr 15 13:41:39 fv-az243-582 audit[4602]: AVC apparmor="DENIED" operation="sendmsg" info="Failed name lookup - disconnected path" error=-13 profile="/usr/sbin/mysqld" name="run/systemd/notify" pid=4602 comm="mysqld" requested_mask="w" denied_mask="w" fsuid=115 ouid=0
Apr 15 13:41:39 fv-az243-582 kernel: audit: type=1400 audit(1618494099.578:34): apparmor="DENIED" operation="sendmsg" info="Failed name lookup - disconnected path" error=-13

So the apparmor for /usr/sbin/mysqld had to be disabled before the preinstalled MySQL packages are removed:

$ vim ci/setup.sh
...
# Install MariaDB 10.3 if DB=mariadb10.3
if [[ -n ${GITHUB_ACTIONS-} && -n ${DB-} && x$DB =~ ^xmariadb10.3 ]]; then
  sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
  sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
  sudo apt-get purge -y 'mysql-common*' 'mysql-client*' 'mysql-server*'
  sudo rm -rf /etc/mysql /var/lib/mysql
  sudo apt-get install -y -o Dpkg::Options::='--force-confnew' mariadb-server mariadb-server-10.3 libmariadb-dev
  CHANGED_PASSWORD=true
fi
...

junaruga added a commit to junaruga/mysql2 that referenced this issue Apr 15, 2021
junaruga pushed a commit to junaruga/mysql2 that referenced this issue Apr 15, 2021
junaruga pushed a commit to junaruga/mysql2 that referenced this issue Apr 15, 2021
junaruga pushed a commit to junaruga/mysql2 that referenced this issue Apr 15, 2021
@junaruga
Copy link
Contributor

junaruga commented Apr 15, 2021

@vakuum Fantastic!

I have 2 things for your PR.

First, seeing the MariaDB 10.3 case you fixed, there are 3 failures.

https://github.com/brianmario/mysql2/pull/1183/checks?check_run_id=2354587767#step:9:520

  1) Mysql2::Client should set custom connect_attrs
     Failure/Error: expect(results['program_name']).to eq('my_program_name')

       expected: "my_program_name"
            got: nil

       (compared using ==)
     # ./spec/mysql2/client_spec.rb:496:in `block (2 levels) in <top (required)>'

  2) Mysql2::Client should set default program_name in connect_attrs
     Failure/Error: expect(result.first['attr_value']).to eq($PROGRAM_NAME)

     NoMethodError:
       undefined method `[]' for nil:NilClass
     # ./spec/mysql2/client_spec.rb:487:in `block (2 levels) in <top (required)>'

  3) Mysql2::Client session_track returns multiple session track type values when available
     Failure/Error: expect(res).to eq(["________"])

       expected: ["________"]
            got: nil

       (compared using ==)
     # ./spec/mysql2/client_spec.rb:1053:in `block (3 levels) in <top (required)>'

1), 2) is a known issue #965.
3) is also a known issue #1165

I think it's better to update the comment

# `service mysql restart` fails.

to

# Allow failure due to the issue #965, #1165.

Could you update your PR?

Second, I noticed there is no test to test your warning case currently.
I find this issue will happen when the

  1. HAVE_CONST_MYSQL_OPT_SSL_ENFORCE should be defined.
  2. Server version is 10XXXX. (Both libmariadb-dev in the current mariadb10.3 tests and libmariadb-dev-compat in your case) has the value.
  3. client instance is created with ssl_mode option. In your case ssl_mode: required.

And simply there is not test filling the "3.". That's why we could not find the issue on the current CI.

I add the unit tests on the following commit.
junaruga@3026da1

Could you pick up the commit and add it to your PR?

Here is the result we can observe the warning as a test failure by the unit tests.
https://github.com/junaruga/mysql2/runs/2356005604?check_suite_focus=true#step:9:679

I added every ssl_mode values to the unit tests.
And after your commits, we see the warning on the tests.
https://github.com/junaruga/mysql2/runs/2356042279?check_suite_focus=true#step:9:685
This warning:

rb_warn( "MySQL client libraries between 5.7.3 and 5.7.10 only support SSL_MODE_DISABLED and SSL_MODE_REQUIRED" );
.
I suspect the condition of this warning is outdated. We need to update the logic on another PR.
As this is beyond your PR and your case, you can just remove ssl_mode values except disabled and required.

As I let @sodabrew know this, I keep the logic to the commit.

That's it! Amazing work!

@junaruga
Copy link
Contributor

As this is beyond your PR and your case, you can just remove ssl_mode values except disabled and required.

Or I think it might be better to keep every ssl_mode value's test case, printing failures, because the MariaDB 10.3 has "allow_failure".

@junaruga
Copy link
Contributor

junaruga commented Apr 16, 2021

I think it's better to avoid including (brianmario#1182) in the commit message to avoid displaying a kind of message junaruga added a commit to junaruga/mysql2 that referenced this issue 12 hours ago on the ticket. When we merge a PR, we can go from a link on the merged commit on GitHub's GUI to the PR.

@vakuum
Copy link
Author

vakuum commented Apr 16, 2021

@junaruga I changed the comment in .github/workflows/build.yml and added your commit junaruga/mysql2@3026da1.

@junaruga
Copy link
Contributor

junaruga commented Apr 16, 2021

@vakuum Thank you for that. Sorry my patch causes additional tests in other CI cases such as in macOS cases in GitHub and MariaDB cases in Travis.
Could you do cherry-pick this commit junaruga@e556e03 to your PR?
I think the commit fixed the test failures in other cases. I checked it on my forked repository.

@vakuum
Copy link
Author

vakuum commented Apr 16, 2021

@junaruga I updated the PR.

sodabrew added a commit that referenced this issue Jun 1, 2021
Can't enable SSL with MariaDB driver library. (#1182)
@vakuum
Copy link
Author

vakuum commented Jun 16, 2021

PR #1183 was merged.

@vakuum vakuum closed this as completed Jun 16, 2021
@dbussink
Copy link
Collaborator

#1205 also further improves MariaDB handling by allowing VERIFY_IDENTITY to map to the equivalent setting on MariaDB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants