PHP 到 MySQL SSL 连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3657765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP to MySQL SSL Connections
提问by CoderChris
I have successfully setup an SSL enabled install of MySQL on one server on one network and can connect to it using SSL with the Linux command line mysql client on a different server on a different network, however every time I try to connect (using PHP 5.3.3) I keep getting:
我已经成功地在一个网络上的一台服务器上设置了启用 SSL 的 MySQL 安装,并且可以使用 SSL 连接到它,在不同网络上的另一台服务器上使用 Linux 命令行 mysql 客户端,但是每次我尝试连接时(使用 PHP 5.3 .3)我不断得到:
Warning: mysqli_real_connect(): (HY000/2026): SSL connection error in /var/www/html/test.php on line 18
警告:mysqli_real_connect():(HY000/2026):第 18 行 /var/www/html/test.php 中的 SSL 连接错误
My PHP is as follows have I done something wrong? The certs are 777 (only while testing) and the same code works for a different user's un-encrypted connection (with the SSL setting commented out i.e. mysqli
can definitely connect generally to the DB)
我的PHP如下是我做错了什么吗?证书为 777(仅在测试时)并且相同的代码适用于不同用户的未加密连接(SSL 设置被注释掉,即mysqli
绝对可以连接到数据库)
<?php
error_reporting(E_ALL);
ini_set("display_errors", "1");
$obj = mysqli_init();
mysqli_options($obj, MYSQLI_OPT_CONNECT_TIMEOUT, 5);
mysqli_ssl_set($obj,
'/mysql-ssl-certs/server-key.pem',
'/mysql-ssl-certs/server-cert.pem',
'/mysql-ssl-certs/ca-cert.pem',
NULL,
NULL);
$link = mysqli_real_connect($obj, 'localhost', 'ssluser', 'some_password', 'test');
if (!$link)
{
die('<br /><br />Connect Error (' . mysqli_connect_errno() . ') '.mysqli_connect_error());
}
echo 'Success... ' . mysqli_get_host_info($obj) . "\n";
$obj->close();
?>
回答by Bruno
Here PHP (and mysqli_real_connect
) is the client not the server. You're configuring it with mysqli_ssl_set
for client-certificate authentication (and using the server key and certificate).
这里 PHP(和mysqli_real_connect
)是客户端而不是服务器。您正在mysqli_ssl_set
为客户端证书身份验证(并使用服务器密钥和证书)配置它。
I'm not sure how you've configured your MySQL server, but there should be something like this in the (MySQL) server section of the configuration:
我不确定您是如何配置 MySQL 服务器的,但是在配置的 (MySQL) 服务器部分中应该有类似的内容:
ssl-key=/mysql-ssl-certs/server-key.pem
ssl-cert=/mysql-ssl-certs/server-cert.pem
ssl-ca=/mysql-ssl-certs/ca-cert.pem
These don't belong to the client side anyway (only the CA certificate does, but definitely not the server's private key).
这些无论如何都不属于客户端(只有 CA 证书,但绝对不是服务器的私钥)。
Once you've done this, you can try to see if the server is configured properly using the command line client:
完成此操作后,您可以尝试使用命令行客户端查看服务器是否配置正确:
mysql --ssl-verify-server-cert --ssl-ca=/mysql-ssl-certs/ca-cert.pem --ssl -h hostname ...
or perhaps this (although verify server cert should really be enabled for SSL/TLS to be useful)
或者这个(虽然验证服务器证书应该真正启用才能使 SSL/TLS 有用)
mysql --ssl-ca=/mysql-ssl-certs/ca-cert.pem --ssl -h hostname ...
This should work at least on the command line.
这至少应该在命令行上工作。
Then, from PHP, you get two options:
然后,在 PHP 中,您有两个选择:
- use
mysqli_ssl_set
like you've done, but leaving$key
and$cert
null, unless you want to use a client-certificate which really ought to be different from your server certificate. (I can't remember whether that works.) possibly easier, omit
mysqli_ssl_set
altogether and configure this in your global MySQL client configuration file (where PHP should be able to pick it up, possibly/etc/mysql/my.cnf
, but this may vary depending on your distribution):[client] ssl-ca=/mysql-ssl-certs/ca-cert.pem
mysqli_ssl_set
像你一样使用,但离开$key
并为$cert
空,除非你想使用一个真正应该与你的服务器证书不同的客户端证书。(我不记得这是否有效。)可能更简单,
mysqli_ssl_set
完全省略并在您的全局 MySQL 客户端配置文件中配置它(PHP 应该能够获取它,可能/etc/mysql/my.cnf
,但这可能会因您的发行版而异):[client] ssl-ca=/mysql-ssl-certs/ca-cert.pem
(This is similar to the server config, but on the client side/in the client section.)
(这类似于服务器配置,但在客户端/在客户端部分。)
For the authorization part (GRANT
):
对于授权部分 ( GRANT
):
REQUIRE SSL
only requires the use of SSL/TLSREQUIRE ISSUER
,REQUIRE SUBJECT
andREQUIRE X509
require the client to present a client-certificate to compare to the required values (that's the case where you'd need to usessl-key
andssl-cert
on the client side (config or withinmysqli_ssl_set
).
REQUIRE SSL
只需要使用 SSL/TLSREQUIRE ISSUER
,REQUIRE SUBJECT
并REQUIRE X509
要求客户端提供客户端证书以与所需值进行比较(在这种情况下,您需要使用ssl-key
和ssl-cert
在客户端(配置或内mysqli_ssl_set
)。
回答by VolkerK
Maybe your version of php uses mysqlndas transport driver which doesn't support ssl (yet?).
What does
也许您的 php 版本使用mysqlnd作为不支持 ssl 的传输驱动程序(还?)。
有什么作用
<?php
error_reporting(E_ALL);
ini_set("display_errors", "1");
echo 'version: ', phpversion(), "\n";
echo function_exists('mysqli_fetch_all') ? 'mysqlnd' : '--', "\n";
print?
打印?
回答by Pop
You should be careful if you're using MySQL prior to 5.7.3 and the standard PHP library:
如果你在 5.7.3 之前使用 MySQL 和标准 PHP 库,你应该小心:
Before MySQL 5.7.3, --ssl permits but does not require the client to connect to the server using SSL. Therefore, this option is not sufficient in itself to cause an SSL connection to be used. For example, if you specify this option for a client program but the server has not been configured to permit SSL connections, an unencrypted connection is used.
在 MySQL 5.7.3 之前,--ssl 允许但不要求客户端使用 SSL 连接到服务器。因此,该选项本身不足以导致使用 SSL 连接。例如,如果您为客户端程序指定此选项,但服务器尚未配置为允许 SSL 连接,则使用未加密的连接。
http://dev.mysql.com/doc/refman/5.7/en/ssl-options.html#option_general_ssl
http://dev.mysql.com/doc/refman/5.7/en/ssl-options.html#option_general_ssl
In the case of PHP, MySQL will silently fail if the server fails to support SSL
以 PHP 为例,如果服务器不支持 SSL,MySQL 将静默失败
https://www.idontplaydarts.com/2015/03/mysql-with-ssl-does-not-protect-against-active-mitm/
https://www.idontplaydarts.com/2015/03/mysql-with-ssl-does-not-protect-against-active-mitm/