I\'m trying to use Google Cloud SQL over SSL from GCE(Google Compute Engine) instance. My problem is that I cannot connect to Cloud SQL instance over SSL.
mysql comm
Example in CakePHP 3.5.x + PHP 7.1.x + SQL Google Cloud + SSL
Change file in: config/app.php
...
...
/**
* The test connection is used during the test suite.
*/
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'xx.xxx.xxx.xxx',
//'port' => 'non_standard_port_number',
'username' => 'user_name_x',
'password' => 'pass_x',
'database' => 'bd_name_x',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
'log' => false,
'flags' => [
PDO::MYSQL_ATTR_SSL_KEY => CONFIG.'client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => CONFIG.'client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => CONFIG.'server-ca.pem',
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
],
//'ssl_key' => CONFIG.'client-key.pem',
//'ssl_cert' => CONFIG.'client-cert.pem',
//'ssl_ca' => CONFIG.'server-ca.pem',
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
],
],
...
...
Example PHP Pure + PDO + SSL:
$ssl_key = CONFIG.'client-key.pem';
$ssl_cert = CONFIG.'client-cert.pem';
$ssl_ca = CONFIG.'server-ca.pem';
$pdo = new PDO('mysql:host=xxx.xxx.xxx.xxx;dbname=db_name_x', 'user_name_x', 'pass_x', array(
PDO::MYSQL_ATTR_SSL_KEY => '/path/full/client-key.pem',
PDO::MYSQL_ATTR_SSL_CERT => '/path/full/client-cert.pem',
PDO::MYSQL_ATTR_SSL_CA => '/path/full/server-ca.pem',
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
)
);
$statement = $pdo->query("SHOW TABLES;");
var_dump($statement);
$row = $statement->fetch(PDO::FETCH_ASSOC);
echo json_encode($row);
exit();
For mysqli, adding:
MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT
to real_connect() solved my instance of this issue.
Example (replace host, user, password and database as needed):
$db_connection->real_connect('ip address or host', 'user', 'password', 'database', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
Full php mysqli SSL connection script:
// check if openssl is enabled on server
if(!extension_loaded('openssl')) {
throw new Exception('This app needs the Open SSL PHP extension and it is missing.');
}
// start connection
$db_connection = mysqli_init();
// set ssl config (update with your certs location)
$db_connection->ssl_set('/etc/my.cnf.d/certs/client-key.pem','/etc/my.cnf.d/certs/client-cert.pem', '/etc/my.cnf.d/certs/ca-cert.pem', NULL, NULL);
// connect (update with your host, db and credentials)
$db_connection->real_connect('ip address or host', 'user', 'password', 'database', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
I had the same problem with a MySQL database hosted at compose cluster.
After searching and testing for hours, I found out that the best solution is to disable testing the certificate provided by the server by using the MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT
flag.
I haven't tested it with PDO but with the mysqli
interface it is working for me.
In general this problem would appear with a database hosted at a cluster server.
In short, use Cloud SQL Proxy if you need to access from both PDO and mysqli. You have no choice.
https://cloud.google.com/sql/docs/sql-proxy
For PDO connections that don't use Google cloud or cannot benefit from the proxy solution, they have fixed the bug and it is merged now. There is now a constant for this (starting April 2017):
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
http://git.php.net/?p=php-src.git;a=commit;h=247ce052cd0fc7d0d8ea1a0e7ea2075e9601766a