TimWolla / docker-adminer

Database management in a single PHP file
https://hub.docker.com/_/adminer/
157 stars 69 forks source link

Switch MySQL driver to mysqli instead of pdo_mysql #109

Closed colinmollenhour closed 2 years ago

colinmollenhour commented 2 years ago

I could not connect to my server using SSL and PDO MySQL and had to install mysqli instead to get SSL to work. I believe Mysqli is the preferred client library anyway.

TimWolla commented 2 years ago

Can you clarify what data I need to enter within the login to test SSL support so that I can test this myself?

colinmollenhour commented 2 years ago

You have to enable it using a plugin which implements the connectSsl method, for example:

<?php

class AdminerLoginSsl {
        /** @access protected */
        var $ssl;

        /**
        * @param array array("key" => filename, "cert" => filename, "ca" => filename)
        */
        function __construct($ssl) {
                $this->ssl = $ssl;
        }

        function connectSsl() {
                if ( ! isset($this->ssl[SERVER])) {
                        return NULL;
                }
                if ( ! is_readable($this->ssl[SERVER]['key'])
                  || ! is_readable($this->ssl[SERVER]['cert'])
                  || ! is_readable($this->ssl[SERVER]['ca'])
                ) {
                        throw new Exception('Cannot read certificate for '.SERVER);
                }
                return $this->ssl[SERVER];
        }

}

return new AdminerLoginSsl([
  'server1' => [
    'key' => '/certs/server1/adminer-key.pem',
    'cert' => '/certs/server1/adminer-cert.pem',
    'ca' => '/certs/server1/ca.pem',
  ],
  'server2' => [
    'key' => '/certs/server2/client-key.pem',
    'cert' => '/certs/server2/client-cert.pem',
    'ca' => '/certs/server2/ca.pem',
  ],
]);

The Adminer mysql driver is written such that if mysqli is available it will use it, otherwise it will fall back to PDO. I don't know why PDO wouldn't work with SSL in my case but it took me quite a while to realize that the Docker image wasn't even using mysqli.

colinmollenhour commented 2 years ago

My workaround is the following which is what I'm now using successfully, but it took quite a while just to get this to build due to some weird bug with docker-php-ext-install mysqli.

FROM adminer:latest

USER    root
WORKDIR /
RUN     set -x \
&&      docker-php-ext-install \
        mysqli \
USER    adminer
WORKDIR /var/www/html
TimWolla commented 2 years ago

It appears there is SSL support for PDO in Adminer: https://github.com/vrana/adminer/blob/v4.7.1/adminer/drivers/mysql.inc.php#L239-L246

You are indeed correct in that Adminer apparently prefers the MySQLi extension: https://github.com/vrana/adminer/blob/88647b93e467210f270340e758af6771e2c5638a/adminer/drivers/mysql.inc.php#L6

I guess it makes sense to switch to MySQLi, but then the pdo_mysql driver line should be removed. Would you do this? I'll then perform a few tests (as time permits) before merging.

colinmollenhour commented 2 years ago

It appears there is SSL support for PDO in Adminer: https://github.com/vrana/adminer/blob/v4.7.1/adminer/drivers/mysql.inc.php#L239-L246

Yes, but I couldn't get it to work.. It may have been due to lack of this option as I am using a self-signed cert:

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,

I guess it makes sense to switch to MySQLi, but then the pdo_mysql driver line should be removed. Would you do this? I'll then perform a few tests (as time permits) before merging.

Yes I suppose since there is no way to select between them there should be only one in the image.

TimWolla commented 2 years ago

Thanks. I also updated the Dockerfile within the fastcgi/ folder, squashed the commits and slightly rephrased the commit message.

colinmollenhour commented 2 years ago

Thanks, Tim!