codeigniter 4 通过 php 扩展实现 mysql ssl 连接,需服务端配置 ca.pem/server-cert.pem/server-key.pem(权限600),ci4 数据库配置中设 sslmode 为 verify_identity 并指定绝对路径 sslcert;两端均需验证:服务端 show variables like 'have_ssl' 返回 yes,客户端连接后 status 显示 “cipher in use”。

CodeIgniter 4 本身不直接管理 MySQL 的 SSL 证书,它依赖 PHP 的 MySQLi 或 PDO 扩展来建立连接。要让 CI4 应用通过加密连接访问 MySQL,关键不是 CI4 做了什么,而是 PHP 连接层是否传入了正确的 SSL 证书路径,且 MySQL 服务端已正确配置并启用 SSL。
必须准备的三类证书文件
MySQL 服务端必须已生成并加载以下三个 PEM 格式文件(由同一 CA 签发):
- ca.pem:CA 根证书(服务端和客户端共用)
- server-cert.pem:MySQL 服务器证书(服务端使用)
- server-key.pem:MySQL 服务器私钥(权限必须为 600,不能有密码)
注意:CodeIgniter 4 连接时 不需要 client-cert.pem 和 client-key.pem,除非你启用了双向 SSL(即用户账户设为 REQUIRE X509)。普通加密连接(单向)只要求服务端提供证书,客户端只需验证 CA 即可。
CI4 数据库配置中需指定的参数
在 app/Config/Database.php 的 MySQL 配置数组中,除常规 host/user/pass/db 外,必须显式添加 SSL 相关选项:
-
'SSLMode' => 'VERIFY_CA'或'VERIFY_IDENTITY'(推荐后者,校验主机名) -
'SSLCert' => '/path/to/ca.pem'(必须是绝对路径,指向 CA 证书) -
'SSLKey' => ''(单向连接可留空;若用双向则填 client-key.pem) -
'SSLCert' => ''(同上,单向连接无需客户端证书)
示例片段:
'DSN' => '', 'hostname' => '192.168.100.10', 'username' => 'app_user', 'password' => 'xxx', 'database' => 'mydb', 'DBDriver' => 'MySQLi', 'port' => 3306, 'SSLMode' => 'VERIFY_IDENTITY', 'SSLCert' => '/etc/mysql/ssl/ca.pem', 'SSLKey' => '', 'SSLCA' => '/etc/mysql/ssl/ca.pem', // 部分驱动也认这个键名
服务端证书必须满足的关键细节
MySQL 8.4+ 使用 OpenSSL 3.0+,对证书校验极严格,以下任一缺失都会导致连接失败(报错如 SSL_CTX_set_verify_depth not supported 等误导信息):
- 服务端证书(server-cert.pem)的 subjectAltName(SAN)必须包含你连接时用的地址,例如:
DNS:db.example.com或IP:192.168.100.10 - 不能只靠 CommonName(CN)匹配;localhost 和 127.0.0.1 不等价,IP 和域名必须明确列出
- 所有证书路径在 MySQL 配置(
my.cnf)中必须是 绝对路径,且不能是符号链接 - MySQL 进程用户(如
mysql)需对证书目录有x权限,对文件有r权限
验证是否真正生效
仅配 CI4 不够,必须确认两端都就绪:
- MySQL 侧执行:
SHOW VARIABLES LIKE 'have_ssl';→ 必须返回YES - 再执行:
SHOW VARIABLES LIKE 'ssl%';→ 确认ssl_ca/ssl_cert/ssl_key指向正确绝对路径 - CI4 连接后,在 MySQL 中执行:
STATUS;→ 查看 “SSL” 行是否显示Cipher in use is ... - 或查:
SELECT Ssl_cipher FROM performance_schema.status_by_thread WHERE thread_id = CONNECTION_ID();











