简体   繁体   English

PHP与Mysql的Mysql连接无法正常运行PDO

[英]PHP Mysql connection with SSL is not working PDO

Mysql server is running php5.3. Mysql服务器正在运行php5.3。 New webserver is running php7.1 (migrated from php5.3). 新的webserver正在运行php7.1(从php5.3迁移)。 When I try to connect Mysql server with ssl its not working. 当我尝试连接mysql服务器与ssl时,它无法正常工作。

try {
$dbh = new PDO($dsn, $user, $password, array(PDO::MYSQL_ATTR_SSL_KEY  => '/etc/mysql/client-key.pem',
                                             PDO::MYSQL_ATTR_SSL_CERT => '/etc/mysql/client-cert.pem',
                                             PDO::MYSQL_ATTR_SSL_CA   => '/etc/mysql/ca-cert.pem')
              );
    echo "Connestion established";
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

Connection failed: SQLSTATE[HY000] [2002] 连接失败:SQLSTATE [HY000] [2002]

PDO::__construct(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed PDO :: __ construct():SSL操作失败,代码为1. OpenSSL错误消息:错误:1416F086:SSL例程:tls_process_server_certificate:证书验证失败

But, When I remove SSL block from connection, its working fine. 但是,当我从连接中删除SSL块时,它的工作正常。 I don't know what's going on. 我不知道发生了什么事。 May be version mismatch of server and client. 可能是服务器和客户端的版本不匹配。 Becasue I am using old public key and private key. Becasue我使用旧的公钥和私钥。

Is it because of mysql client and server version mismatch? 是因为mysql客户端和服务器版本不匹配?

PS: I have upgraded php7 in webserver only. PS:我只在网络服务器上升级了php7。

So, after searching and reading I believe that the problem is due to the fact that SSL handling has been approved as of PHP 5.6 and peer verification is now on by default. 因此,在搜索和阅读之后,我认为问题是由于SSL处理已经从PHP 5.6批准,并且默认情况下对等验证现已启用。

While the following is not about mysql but about fsock, I think this post answers your question: https://stackoverflow.com/a/32366242/2459026 虽然以下不是关于mysql但关于fsock,我认为这篇文章回答了你的问题: https ://stackoverflow.com/a/32366242/2459026

You could either disable peer verification (which tends not to be a good idea) or fix your root certificates. 您可以禁用对等验证(这通常不是一个好主意)或修复您的根证书。 I think it would be good to test by disabling peer verification to be sure that this is your problem, indeed. 我认为最好通过禁用同行验证进行测试,以确保这确实是您的问题。

(Please note that I added a second answer, alongside my previous answer. That wasn't the answer to your question, but might be relevant to others) (请注意,我添加了第二个答案,以及我之前的答案。这不是您问题的答案,但可能与其他人相关)

You say that you "copied the SSL keys from one server to another". 您说您“将SSL密钥从一台服务器复制到另一台服务器”。 So there is a new server? 那么有一台新服务器? The new server has a new identity, so the remote server will reject the certificates because the ID doesn't match. 新服务器具有新标识,因此远程服务器将拒绝证书,因为ID不匹配。

I think you should first remove the line on the remote server from the "known_hosts" file. 我认为你应该首先从“known_hosts”文件中删除远程服务器上的行。 Then on your Nginx server you should manually connect to the remote server using those SSH keys and make the connection one time in order to add the new identity to the known_hosts. 然后在您的Nginx服务器上,您应该使用这些SSH密钥手动连接到远程服务器并进行一次连接,以便将新标识添加到known_hosts。

After that I think it should work. 在那之后,我认为它应该工作。

Even if the above doesn't work, I think it's best to debug this issue by connecting to the remote host manually. 即使以上操作不起作用,我认为最好通过手动连接到远程主机来调试此问题。 When that works you can try to setup the mysql connection. 当它工作时,您可以尝试设置mysql连接。

You could generate new SSL certificate and make sure that you use the right "Common Name": 您可以生成新的SSL证书,并确保使用正确的“通用名称”:

CA: hostname 
Server: FQDN, e.g. hostname.example.com 
Client: somename

The important part is the server certificate where the Common Name has to be the same as the host you are connecting to, eg hostname.example.com. 重要的部分是服务器证书,其中Common Name必须与您要连接的主机相同,例如hostname.example.com。

You need to generate a new SSL Certificate and test an endpoint on the server to ensure that it is working properly. 您需要生成新的SSL证书并在服务器上测试端点以确保其正常工作。 You should have no problem after. 你应该没有问题。 I recommend using Let's Encrypt : it is free, open, and highly supported. 我建议使用Let的加密 :它是免费的,开放的,并且受到高度支持。 Make sure you follow the instructions here afterword. 请务必按照此处的说明进行操作。

With some trial and error I was able to fix this issue without disabling peer verification, thanks in part to MySQL documentation: 通过一些试验和错误,我能够在不禁用对等验证的情况下解决此问题,部分归功于MySQL文档:

Important 重要

Whatever method you use to generate the certificate and key files, the Common Name value used for the server and client certificates/keys must each differ from the Common Name value used for the CA certificate. 无论您使用哪种方法生成证书和密钥文件,用于服务器和客户端证书/密钥的公用名称值都必须与用于CA证书的公用名称值不同。 Otherwise, the certificate and key files will not work for servers compiled using OpenSSL. 否则,证书和密钥文件将不适用于使用OpenSSL编译的服务器。 A typical error in this case is: 这种情况下的典型错误是:

 ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1) 

MySQL documentation MySQL文档

However, this only got me part of the way. 但是,这只是我的一部分。 By default PHP has VERIFY_IDENTITY enabled, which requires a hostname match for the Common Name. 默认情况下,PHP启用了VERIFY_IDENTITY ,这需要与Common Name匹配主机名。

This satisfies everything: 这满足了一切:

CA: assign a unique name. CA:分配唯一名称。 Can be anything. 可以是任何东西。 I just prepend root. 我只是在root. to my FQDN. 到我的FQDN。

client and server: Assign the FQDN of the MySQL server. 客户端和服务器:分配MySQL服务器的FQDN。 These two values must match. 这两个值必须匹配。

If the FQDN does not match between client and server, then VERIFY_IDENTITY will fail. 如果客户端和服务器之间的FQDN不匹配,则VERIFY_IDENTITY将失败。

If the FQDN does match between ca, client and server, then OpenSSL in PHP will fail as promised in MySQL documentation. 如果FQDN在ca,客户端和服务器之间确实匹配,则PHP中的OpenSSL将失败,如MySQL文档中所承诺的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM