我可以通过提供没有任何证书的--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内部相同的方式设置连接。
答案 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
底线:
答案 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,
];