php - PDO 使用 SSL 连接到远程数据库;验证服务器证书时出现 FastCGI 错误

标签 php mysql ssl pdo mariadb

我有一个带有 MariaDB DB 的远程服务器,它只接受特定用户的 SSL 连接,并使用以下方法生成了一些自签名 SSL 证书

# Create CA certificate
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem

# Create server certificate, remove passphrase, and sign it
# server-cert.pem = public key, server-key.pem = private key
openssl req -newkey rsa:2048 -days 3600 
        -nodes -keyout server-key.pem -out server-req.pem
openssl rsa -in server-key.pem -out server-key.pem
openssl x509 -req -in server-req.pem -days 3600 \
        -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

# Create client certificate, remove passphrase, and sign it
# client-cert.pem = public key, client-key.pem = private key
openssl req -newkey rsa:2048 -days 3600 \
        -nodes -keyout client-key.pem -out client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -req -in client-req.pem -days 3600 \
        -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

(摘自 https://dev.mysql.com/doc/refman/5.6/en/creating-ssl-files-using-openssl.html)

我如下填写了每个证书的详细信息

  • 国家名称:GB
  • 地方名称:Company Town
  • 组织名称:公司名称
  • Common Name:DEV CA、DEV Server、DEV Client(分别)

并将所有其他字段留空


远程服务器在my.cnf中有如下内容

[mariadb]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/server-cert.pem
ssl-key=/path/to/server-key.pem

我可以通过在其 my.cnf

中包含以下内容,从本地计算机的命令行进行连接
[client]
ssl-ca=/path/to/ca.pem
ssl-cert=/path/to/client-cert.pem
ssl-key=/path/to/client-key.pem

我可以使用以下方法从我的本地计算机创建 PDO 连接

$pdo = new PDO(
    'mysql:host=xxx.xxx.xxx.xxx;dbname=database_1',
    'database_user',
    'database_password',
    [
       PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
       PDO::MYSQL_ATTR_SSL_KEY => '/path/to/client-key.pem',
       PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem',
       PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem',
    ]
);

不幸的是,如果我删除该行

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,

我收到一个内部服务器错误,以下内容显示在我的 MAMP PRO apache 错误日志中

… FastCGI: incomplete headers (0 bytes) received from server …

我的 PHP 错误日志中没有错误

我只能假设证书验证出了问题,

  • 我错过了什么吗?和/或
  • PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT 设置为 false 是否安全?

最佳答案

当客户端验证服务器证书时,将检查以下内容

  • 签名
  • 证书有效期包括当前时间
  • 证书未被撤销(CRL 的一部分)
  • 主机名与 CN 或替代名称匹配
  • 根目录

带有 mysqlnd 的 PDO 使用 PHP 流,它只检查 CN 字段,而不检查主题备用名称字段。根据您的代码,您指定要连接的 IP 地址,而不是名称。

不幸的是,PHP 也没有提供额外的方法来检查对等证书的 sha 指纹。

另见:

关于php - PDO 使用 SSL 连接到远程数据库;验证服务器证书时出现 FastCGI 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57777245/

相关文章:

php - Symfony Doctrine 迁移 $connection 没有权限

php - 使用 php 框架 silex 更新行

mysql选择单元格中每个单词的第一个字母

php - 如何使用(发送网格)php api 在列表中添加联系人

PHP MySQL计算有多少行有相同的数据

mysql - cfquery 需要很长时间才能显示输出

java - 如何在 Java6 中禁用约束检查(Netscape 证书类型)?

azure - 具有 Azure 身份验证的私有(private) Web 服务器的 SSL 证书

.net - 在客户端使用 SSL 和自托管 WebAPI

php - if isset语句与javascript?