我有一个带有 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/