PHP忽略SSL证书连接到MySQL时(PHP ignores ssl certificates w

2019-08-04 19:12发布

从PHP手册中使用的代码,发现这里和这里

<?php

$mysqli = mysqli_init();
if (!$mysqli) {
    die('mysqli_init failed');
}

$mysqli->ssl_set('/path/to/client-key.pem',   
                 '/path/to/client-cert.pem',
                 '/path/to/ca-cert.pem',
                  NULL,NULL); //<-- Doesn't matter if the paths are right or wrong

if (!$mysqli->options(MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT = 0')) {
    die('Setting MYSQLI_INIT_COMMAND failed');
}

if (!$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) {
    die('Setting MYSQLI_OPT_CONNECT_TIMEOUT failed');
}

if (!$mysqli->real_connect('xx.xx.xx.xx', 'my_user', 'my_password', 'my_db')) {
    die('Connect Error (' . mysqli_connect_errno() . ') '
            . mysqli_connect_error());
}

echo 'Success... ' . $mysqli->host_info . "\n";

$mysqli->close();
?>

我无法连接到MySQL。 它提供了以下错误:

Message: SQLSTATE[28000] [1045] Access denied for user 'my_user'@'xx.xx.xx.xx' (using password: YES) <-- the client IP

我已经缩小的问题行$mysqli->ssl_set(...)

当我通过错误路径证书,则必须抛出一个SSL certificate error ,根据这个帖子 ,其中用户从同一个问题的困扰,而不是它抛出同以前的访问被拒绝的错误。

我设法让使用Navicat的与数据库管理的通过配置SSL连接,如下所示的帮助服务器的连接:

笔记:

  1. 我的PHP版本是5.3.15
  2. 远程数据库服务器上使用MySQL的版本是5.5.13-55
  3. 两者的Navicat和PHP代码是从同一台PC上运行。
  4. 数据库管理员创建了一个专门ssl_user测试。 该用户被拒绝正常访问,而且必须使用SSL连接。
  5. 无代理使用。
  6. 我试图PDO ,它从同一个问题的困扰。
  7. 我试图mysql->connect()但它抛出一个糟糕的握手错误,并根据一些评论在手动这是行不通的。
  8. 打开SSL是从启用phpinfo()

所以,问题是,为什么PHP不抱怨错误路径中的证书? 这似乎PHP被忽略,我设置证书路径线!


更新:我试图改变在哪里进行连接,以明确设置端口,并使用线MYSQLI_CLIENT_SSL

$mysqli->real_connect('xx.xx.xx.xx', 'my_user', 'my_password', 'my_db','3306',NULL,MYSQLI_CLIENT_SSL)

不过,我得到这个错误:

Warning: mysqli::real_connect(): (08S01/1043): Bad handshake in ...

更新2:

这是tcpdump的-ING从数据库服务器的结果:

0x0040:  3142 6164 2068 616e 6473 6861 6b65       1Bad.handshake
13:16:18.133282 IP (tos 0x8, ttl  64, id 40823, offset 0, flags [DF], proto: TCP (6), length: 52) xx.xx.xx.202.mysql > xx.xx.xx.130.42766: F, cksum 0xf15f (correct), 112:112(0) ack 79 win 46 <nop,nop,timestamp 19516376 3465907>
        0x0000:  4508 0034 9f77 4000 4006 c8a7 c0a8 28ca  E..4.w@.@.....(.
        0x0010:  c0a8 2882 0cea a70e b36c 7e8b 7b4d a169  ..(......l~.{M.i
        0x0020:  8011 002e f15f 0000 0101 080a 0129 cbd8  ....._.......)..
        0x0030:  0034 e2b3                                .4..
13:16:18.133433 IP (tos 0x8, ttl  64, id 17337, offset 0, flags [DF], proto: TCP (6), length: 52) xx.xx.xx.130.42766 > xx.xx.xx.202.mysql: F, cksum 0xb695 (correct), 79:79(0) ack 113 win 92 <nop,nop,timestamp 3480910 19516376>
        0x0000:  4508 0034 43b9 4000 4006 2466 c0a8 2882  E..4C.@.@.$f..(.
        0x0010:  c0a8 28ca a70e 0cea 7b4d a169 b36c 7e8c  ..(.....{M.i.l~.
        0x0020:  8011 005c b695 0000 0101 080a 0035 1d4e  ...\.........5.N
        0x0030:  0129 cbd8                                .)..
13:16:18.133452 IP (tos 0x8, ttl  64, id 40824, offset 0, flags [DF], proto: TCP (6), length: 52) xx.xx.xx.202.mysql > xx.xx.xx.130.42766: ., cksum 0xb6c3 (correct), 113:113(0) ack 80 win 46 <nop,nop,timestamp 19516376 3480910>
        0x0000:  4508 0034 9f78 4000 4006 c8a6 c0a8 28ca  E..4.x@.@.....(.
        0x0010:  c0a8 2882 0cea a70e b36c 7e8c 7b4d a16a  ..(......l~.{M.j
        0x0020:  8010 002e b6c3 0000 0101 080a 0129 cbd8  .............)..
        0x0030:  0035 1d4e                                .5.N

xx.xx.xx.202是数据库服务器的IP。
xx.xx.xx.130是我的电脑的IP。

更新3:

我检查了使用下面的代码的密码长度:

mysql> select length(Password) from mysql.user where User='youruser'

而密码长度为41。

更新4:

有可能是当我连接通过远程服务器上的SSH使用命令行返回的错误消息的提示(我上传的整个项目到远程服务器):

mysql -u test_ssl -password --ssl-key=/usr/local/apache2/htdocs/certs/client-key.pem --ssl-cert=/usr/local/apache2/htdocs/certs/WRONG-CERTIFICATE.pem

我得到以下错误:

SSL error: Unable to get certificate from '/usr/local/apache2/htdocs/certs/WRONG-CERTIFICATE.pem'
ERROR 2026 (HY000): SSL connection error ---> notice the error here

如果我完全不提供任何证书我得到以下信息:

-bash-3.2$ mysql -u test_ssl -password
ERROR 1045 (28000): Access denied for user 'test_ssl'@'localhost' (using password: YES)

这是相同的错误,当我连接使用PHP使用的证书正确或无效的路径,我得到!

也许这意味着什么?

Answer 1:

乍一看,你没有设置MYSQLI_CLIENT_SSL选项连接。

if (!$mysqli->real_connect('localhost', 'my_user', 'my_password', 'my_db', null, MYSQLI_CLIENT_SSL)) { ... }

更新:
你可以尝试添加$mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);$mysqli->ssl_set()

此外,这对我的作品:

<?php
$pdo = new PDO('mysql:host=ip;dbname=dbname', 'username', 'password', array(
    PDO::MYSQL_ATTR_SSL_KEY    =>'/etc/mysql/ssl/client-key.pem',
    PDO::MYSQL_ATTR_SSL_CERT=>'/etc/mysql/ssl/client-cert.pem',
    PDO::MYSQL_ATTR_SSL_CA    =>'/etc/mysql/ssl/ca-cert.pem'
    )
);
$stmt = $pdo->query("SHOW TABLES;");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
print_r($row);
?>

更新2:您可能会收到一个bad handshake如果使用旧式的MySQL密码(16个字节长 )。 要检查,运行以下查询:

mysql> select length(Password) from mysql.user where User='youruser'

如果您收到16

// disable old_passwords:
mysql> SET @@session.old_passwords = 0;

// update password for user used in PHP script:
mysql> SET PASSWORD FOR 'existinguser'@'localhost' = PASSWORD('existingpass');

// check if we have a 41 bytes long password:
mysql> select length(Password) from mysql.user where User='youruser'

并再次检查从PHP脚本连接。



Answer 2:

那么我们能够解决这个问题,但我不知道这是一个实用的解决方案。

首先,我们都能够找到它是MySQL客户端库,PHP使用使用SSL连接的那些问题的根源。 PHP必须与这些库得到遵守,以便能够使用SSL连接。

此外还有MySQL客户端库和OpenSSL库之间的冲突。

我们唯一的解决办法是重新安装一切从头开始。 我们使用了新的服务器,新的Mysql(最新版​​本)的所有库,最新的PHP版本和最新的CentOS分发安装。



文章来源: PHP ignores ssl certificates when connecting to MySql