使用带有 --ssl 的 PHP PDO 连接到 MySQL/MariaDB,无需证书
Posted
技术标签:
【中文标题】使用带有 --ssl 的 PHP PDO 连接到 MySQL/MariaDB,无需证书【英文标题】:Connect to MySQL/MariaDB with PHP PDO with --ssl without certificate 【发布时间】:2018-04-04 09:23:24 【问题描述】:我可以从 Sequel Pro(参见 this post)和控制台通过提供不带任何证书的 --ssl 选项连接到 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”的访问被拒绝(使用密码:YES)
将PDO::MYSQL_ATTR_SSL_KEY
(和其他)添加为 PDO 构造函数的选项,导致 2002(这些选项没有意义,因为我没有密钥等)。虽然我不知道如何以与从控制台或在 Sequel Pro 内部相同的方式设置连接。
【问题讨论】:
我们总是乐于帮助和支持新的编码员,但您需要先帮助自己。 :-) 在doing more research 之后,如果您有问题发布您尝试过的方法,并清楚地解释什么不起作用并提供a Minimal, Complete, and Verifiable example。阅读How to Ask 一个好问题。请务必take the tour 并阅读this。 @JayBlanchard 我已经更新了我的问题。还有什么您认为有帮助的吗? 向我们展示您尝试连接的 PHP 代码,并向我们提供错误的全文。 如问题中所述,这是我尝试使用 MYSQL_ATTR_SSL_KEY 等常量的方法,但这没有任何意义,因为我没有证书,而且我显然也不需要它们。所以除了这些常数之外,肯定还有别的东西。能否请您删除“重复”链接? 问题是关于 Sequel Pro 和 mysql 控制台使用 --ssl 选项做什么,以及我如何可以在那里连接但不能从 PDO 连接。当给定用户需要 SSL 登录时,我无法在没有 SSL 的情况下访问,这一点很明显。但同样:我没有证书/密钥/等。提供(与链接的 Sequel Pro 问题相同)。 【参考方案1】:通过设置传递给 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,
];
【讨论】:
我用 php 7.1 进行了尝试,但遇到了与 TLS 协议版本有关的错误(抱歉,我没有错误消息的确切措辞)。我将 php 提高到 7.3,问题就消失了。 我一直在努力解决这个问题,这有助于确认我也看到了什么。【参考方案2】:https://dev.mysql.com/doc/refman/5.7/en/encrypted-connection-options.html 说:
--ssl-mode=模式
此选项仅适用于客户端程序,而不适用于服务器。它 指定与服务器的连接的安全状态。这些 允许选项值:
PREFERRED:如果服务器支持加密连接,则建立加密连接,如果服务器支持加密连接,则回退到未加密连接 无法建立加密连接。这是默认值,如果 --ssl-mode 未指定。
需要:如果服务器支持加密连接,则建立加密连接。如果加密的连接尝试失败 无法建立连接。
这是什么意思?当您使用--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 证书。 如果您没有证书,则无法获得加密连接。【讨论】:
非常感谢,这很有帮助。我发现我的机器(还)不支持“--ssl-mode=PREFERRED”,所以我选择了“--ssl”。除了其他信息“SSL:使用中的密码是 DHE-RSA-AES256-SHA”之外,在活动连接输出中输入“状态”。因此,似乎 SSL 连接已经到位。这给我留下了一个问题,即如何使用这些新知识打开与 PHP 的 PDO 的连接。 @André 您是否在 $HOME/.my.cnf 或 /etc/my.cnf 的[client]
或 [mysql]
部分下为您的客户端配置了 SSL 证书选项?
我唯一的 my.cnf 在 /etc/mysql/my.cnf 中。在 [client] 下只有端口和套接字,在 [mysql] 下没有单个条目。唯一与 SSL 相关的行被注释掉(例如:# ssl-ca=/etc/mysql/cacert.pem)。
好吧,我没什么可建议的。据我所知,SSL 连接需要客户端和服务器端的有效证书。我发现了一些参考资料,虽然 mysql 客户端可以跳过 CA 验证,但 PHP 不能。以上是关于使用带有 --ssl 的 PHP PDO 连接到 MySQL/MariaDB,无需证书的主要内容,如果未能解决你的问题,请参考以下文章
通过 SSL 上的 PHP PDO 连接到 MSSQL 服务器
如何使用 PDO ssl 连接到 azure mysql 数据库