zon*_*ono 17 mysql mysqli pdo google-cloud-sql google-compute-engine
我正在尝试使用来自GCE(Google Compute Engine)实例的Google Cloud SQL over SSL.我的问题是我无法通过SSL连接到Cloud SQL实例.
mysql命令正常工作.我可以使用认证文件连接到Cloud SQL实例.
mysql -uroot -p -h [IP Address] --ssl-ca=/home/user/.cert/server-ca.pem --ssl-cert=/home/user/.cert/client-cert.pem --ssl-key=/home/user/.cert/client-key.pem
Run Code Online (Sandbox Code Playgroud)
但是,当我从PHP程序访问时,我收到了警告和致命错误.
<?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);
?>?
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
当我使用mysqli时,我得到了同样的错误.
$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);
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这个问题看起来与我的案例有关,但还没有答案.SSL自签名证书,用于与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
sudo apt-get install php5
Run Code Online (Sandbox Code Playgroud)
2我像这样放了MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT选项.
$mysqli->real_connect('[IP Address]', 'root', 'test', 'testdb', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
Run Code Online (Sandbox Code Playgroud)
我的应用程序出于某些原因使用mysqli和PDO.我现在正在寻找PDO的解决方案.
更新3
此错误报告显示了PDO的情况.听起来还没有修好.
https://bugs.php.net/bug.php?id=71845
据我了解,没有办法解决PDO.
更新4
有些人责怪谷歌的CN名称设计(我实际上同意他们......)
最糟糕的是你们使用不可能的CN名称(:).如果CN没有冒号,我可以在我的hosts文件中映射ip和CN,这样当对等验证完成时它可以通过.使用冒号,php认为是主机并且是端口
和谷歌的员工?了解问题.
我理解通过IP连接时的当前情况并不理想.
但它似乎提供了一种称为"代理"的解决方案.
https://groups.google.com/forum/#!topic/google-cloud-sql-discuss/gAzsuCzPlaU
我正在使用Cloud SQL第二代,我的应用程序是托管GCE.所以我认为我可以使用代理方式.我现在就试试吧.
更新5
设置代理访问权限.解决了PDO和mysqli访问问题.
在Ubuntu上安装代理
$ wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64
$ mv cloud_sql_proxy.linux.amd64 cloud_sql_proxy
$ chmod +x cloud_sql_proxy
$ sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
$ ./cloud_sql_proxy -dir=/cloudsql -instances=<project name>:us-central1:mydb
Run Code Online (Sandbox Code Playgroud)
PDO
<?php
$pdo = new pdo('mysql:unix_socket=/cloudsql/<project name>:us-central1:mydb;dbname=testdb','root','test');
$stmt = $pdo->query("SHOW TABLES;");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($row);
?>
Run Code Online (Sandbox Code Playgroud)
mysqli的
$mysqli = mysqli_connect('localhost', 'root', 'test', 'testdb', 3306, '/cloudsql/<project name>:us-central1');
$sql = "SELECT id FROM users";
if ($result = $mysqli->query($sql)) {
while ($row = $result->fetch_assoc()) {
echo $row["id"] . "\n";
}
$result->close();
}
$mysqli->close();
Run Code Online (Sandbox Code Playgroud)
refs(日文)
http://blog.hrendoh.com/connecting-to-google-cloud-sql-using-mysql-client/ http://blog.hrendoh.com/google-appengine-php-using-cloud-sql/
小智 9
对于不使用Google云或无法从代理解决方案中受益的PDO连接,他们已修复该错误并立即合并.现在有一个常数(从2017年4月开始):
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
Run Code Online (Sandbox Code Playgroud)
http://git.php.net/?p=php-src.git;a=commit;h=247ce052cd0fc7d0d8ea1a0e7ea2075e9601766a
希望这可以帮助.
简而言之,如果您需要从 PDO 和 mysqli 进行访问,请使用 Cloud SQL 代理。你没有选择。
https://cloud.google.com/sql/docs/sql-proxy