PHP MySQL over SSL. Peer certificate did not match
我正在尝试通过GCE(Google Compute Engine)实例通过SSL使用Google Cloud SQL。我的问题是我无法通过SSL连接到Cloud SQL实例。
mysql命令正常工作。我可以使用证书文件连接到Cloud SQL实例。
1 |
但是,当我从PHP程序访问时,出现如下警告和致命错误。
1 2 3 4 5 6 7 8 9 10 11 | <?php $pdo = new PDO('mysql:host=[IP Address];dbname=testdb', 'root', 'test', array( PDO::MYSQL_ATTR_SSL_KEY =>'/home/user/.cert/client-key.pem', PDO::MYSQL_ATTR_SSL_CERT=>'/home/user/.cert/client-cert.pem', PDO::MYSQL_ATTR_SSL_CA =>'/home/user/.cert/server-ca.pem' ) ); $stmt = $pdo->query("SHOW TABLES;"); $row = $stmt->fetch(PDO::FETCH_ASSOC); print_r($row); ?>?€€ |
?€€
1 2 | PHP Warning: PDO::__construct(): Peer certificate CN=`[GCP project name]:[Cloud SQL instance name]' did not match expected CN=`[IP Address]' in /tmp/mysql.php on line 7 Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] ' in /tmp/mysql.php on line 7 |
使用mysqli时出现相同的错误。
1 2 3 4 5 6 7 8 9 | $mysqli = mysqli_init(); mysqli_options($mysqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true); $mysqli->ssl_set('/home/user/.cert/client-key.pem', '/home/user/.cert/client-cert.pem', '/home/user/.cert/server-ca.pem', NULL,NULL); $mysqli->real_connect('[IP Address]', 'root', 'test', 'testdb', 3306, NULL, MYSQLI_CLIENT_SSL); |
?€€
1 2 | PHP Warning: mysqli::real_connect(): Peer certificate CN=`[GCP project name]:[Cloud SQL instance name]' did not match expected CN=`[IP Address]' in /tmp/mysql3.php on line 30 Warning: mysqli::real_connect(): (HY000/2002): in /tmp/mysql3.php on line 30 |
这个问题似乎与我的情况有关,但尚无答案。 SSL自签名证书,可通过PHP
与Mysql连接
有人知道解决方案吗?
更新1
已报告该错误。 https://bugs.php.net/bug.php?id=71003
非常类似的问题在这里。 Google Cloud SQL SSL无法通过对等证书验证
我的PHP版本是5.6.14。我将更新到5.6.16以使用MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT。
更新2
使用mysqli
修复
我所做的如下:
1我将PHP更新为5.6.20
1 | sudo apt-get install php5 |
2我这样放置MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT选项。
1 | $mysqli->real_connect('[IP Address]', 'root', 'test', 'testdb', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT); |
由于某些原因,我的应用程序同时使用mysqli和PDO。我现在正在寻找PDO的解决方案。
更新3
此错误报告显示有关PDO的情况。声音还没有解决。
https://bugs.php.net/bug.php?id=71845
这也有关。 https://groups.google.com/forum/?utm_medium=email
对于不使用Google云或无法从代理解决方案中受益的PDO连接,他们已修复了该错误,现已合并。
现在有一个常量(从2017年4月开始):
1 |
http://git.php.net/?p=php-src.git;a=commit;h=247ce052cd0fc7d0d8ea1a0e7ea2075e9601766a
简而言之,如果您需要同时从PDO和mysqli进行访问,请使用Cloud SQL代理。您别无选择。
https://cloud.google.com/sql/docs/sql-proxy
对于mysqli,添加:
1 | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT |
to real_connect()解决了此问题的实例。
示例(根据需要替换主机,用户,密码和数据库):
1 | $db_connection->real_connect('ip address or host', 'user', 'password', 'database', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT); |
完整的php mysqli SSL连接脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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); |
在组成群集上托管的MySQL数据库时,我遇到了同样的问题。
经过几个小时的搜索和测试,我发现最好的解决方案是使用
我还没有使用PDO进行过测试,但是使用
通常,在群集服务器上托管的数据库中会出现此问题。
CakePHP 3.5.x中的示例PHP 7.1.x SQL Google Cloud SSL
在以下位置更改文件:config / app.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | ... ... /** * 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'], ], ], ... ... |
示例PHP纯PDO SSL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $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(); |