PHP MySQL sobre SSL. O certificado de mesmo nível não corresponde
Estou tentando usar o Google Cloud SQL sobre SSL da instância do GCE (Google Compute Engine). Meu problema é que não consigo me conectar à instância do Cloud SQL por SSL.
O comando mysql funciona normalmente. Posso conectar-me à instância do Cloud SQL com arquivos de certificação.
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
No entanto, recebi aviso e erro fatal como seguidos quando acesso a partir do programa 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);
?>
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
Eu recebi o mesmo erro quando usei o 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);
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
Esta pergunta parece ser relevante para o meu caso, mas ainda não há resposta.Certificações autoassinadas SSL para conectar-se ao Mysql com PHP
Alguém sabe sobre soluções?
Atualização 1
O bug é relatado.https://bugs.php.net/bug.php?id=71003
Pergunta muito semelhante aqui.O SSL do Google Cloud SQL falha na validação de certificado de mesmo nível
Minha versão do PHP é 5.6.14. Vou atualizar para a 5.6.16 para usar MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT.
Atualização 2
Corrigido quando eu uso o mysqli
O que eu fiz são os seguintes:
1 Atualizei meu PHP para 5.6.20
sudo apt-get install php5
2 eu coloquei oMYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT opção como esta.
$mysqli->real_connect('[IP Address]', 'root', 'test', 'testdb', 3306, NULL, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
Meu aplicativo usa o mysqli e o PDO por alguns motivos. Agora estou procurando a solução do DOP.
Atualização 3
Este relatório de bug mostra o caso da DOP. Parece ainda não corrigido.
https://bugs.php.net/bug.php?id=71845
Isso também está relacionado.https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/google-cloud-sql-discuss/4HNvmq7MpU4/kuSjhkS2AwAJ
Tanto quanto eu entendo, não há como resolver a DOP.
Atualização 4
Algumas pessoas culpam o design de nomes CN do google (eu concordo com eles na verdade ..)
O pior é que vocês usam nomes CN impossíveis (:). Se o CN estiver sem dois pontos, talvez eu possa mapear o IP e o CN no meu arquivo hosts para que, quando a validação por pares for concluída, ele possa ser aprovado. Com os dois pontos, o php pensa que é host e é port
e equipe do Google? entender o problema.
Eu entendo a situação atual quando conectar por IP não é o ideal.
Mas parece que eles fornecem uma solução chamada 'proxy'.
https://groups.google.com/forum/#!topic/google-cloud-sql-discuss/gAzsuCzPlaU
Estou usando o Cloud SQL de segunda geração e meus aplicativos estão hospedados no GCE. Então, acho que posso usar o proxy. Eu vou tentar isso agora.
Atualização 5
Configure o acesso ao proxy. Resolvido o acesso ao PDO e ao mysqli.
Instale o proxy no 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
DOP
<?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);
?>
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();
refs (japonês)
http://blog.hrendoh.com/connecting-to-google-cloud-sql-using-mysql-client/ http://blog.hrendoh.com/google-appengine-php-using-cloud-sql/