使用带有--ssl的PHP PDO连接MySQL / MariaDB而不使用证书

时间:2017-10-23 18:17:53

标签: php mysql ssl pdo mariadb

我可以通过提供没有任何证书的--ssl选项从Sequel Pro(参见this post)和控制台连接到MySQL / MariaDB:

$ mysql -u myusername -p -h 10.123.45.67 --ssl
Enter password:
Welcome to the MariaDB monitor.

无法使用--ssl连接,因为用户需要SSL:

$ mysql -u myusername -p -h 10.123.45.67
Enter password:
ERROR 1045 (28000): Access denied for user 'myusername'@'10.123.45.67' (using password: YES)

如何在PHP中使用PDO实现相同的目标?

我在过去几个小时内一直在研究,但没有找到解决方案。我尝试修改提供给PDO构造函数的dsn和options参数,但没有成功。我最终得到错误代码1045(访问被拒绝)或2002(无法通过套接字连接):

$pdo = new PDO('mysql:dbname=...;host=10.123.45.67;port=3306', 'myusername', '...');
  

PHP致命错误:未捕获PDOException:SQLSTATE [HY000] [1045]拒绝访问用户' myusername' @' 10.123.45.67' (使用密码:是)

PDO::MYSQL_ATTR_SSL_KEY(以及其他)添加为PDO构造函数的选项,导致2002(这些选项毫无意义,因为我没有密钥等)。虽然我不知道如何以与从控制台或Sequel Pro内部相同的方式设置连接。

2 个答案:

答案 0 :(得分:1)

https://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.html说:

  

- SSL模式=模式

     

此选项仅适用于客户端程序,而不适用于服务器。它   指定与服务器的连接的安全状态。这些   允许使用选项值:

     
      
  • 首选:如果服务器支持加密连接,则建立加密连接,如果是,则回退到未加密的连接   加密连接无法建立。这是默认值    - 未指定--ssl-mode。

  •   
  • REQUIRED:如果服务器支持加密连接,则建立加密连接。如果加密,连接尝试将失败   无法建立联系。

  •   

这是什么意思?当您使用--ssl-mode=PREFERRED且服务器具有SSL证书时,客户端将使用它进行身份验证,然后您将获得加密连接。

但是,如果服务器没有SSL证书,尽管您使用--ssl客户端选项提出了请求,但您没有获得加密连接。

(使用已弃用的--ssl客户端选项等同于使用--ssl-mode=PREFERRED。它允许在没有加密的情况下打开连接。)

您如何知道您是否有SSL连接?在mysql客户端中,运行:

mysql> status

它会告诉您SSL是否正在使用中。见https://dba.stackexchange.com/questions/36776/how-can-i-verify-im-using-ssl-to-connect-to-mysql

底线:

  • 您必须在MySQL服务器上启用SSL证书。
  • 如果您没有证书,则无法获得加密连接。

答案 1 :(得分:0)

通过设置传递给PDO构造函数的选项,我能够在不启用客户端证书认证的情况下启用SSL连接。我将CA设置为true,并关闭了服务器证书验证:

$options = [
    PDO::MYSQL_ATTR_SSL_CA => '/dev/null',
    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
];

如果要验证服务器证书,则需要将CA设置为包含真实CA证书链的文件(尽管如果使用的是Azure MySQL实例,目前尚无法做到这一点-您始终需要禁用服务器证书验证,因为PDO不遵循CNAME记录,但这是another issue entirely)。

从PHP 7.3开始有效。不确定PHP的早期版本。

编辑 事实证明,只要禁用服务器验证,PDO::MYSQL_ATTR_SSL_CA就会被完全忽略。您仍然必须将其设置为SOMETHING非空:

$options = [
    PDO::MYSQL_ATTR_SSL_CA => true,
    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
];