codeigniter4连接postgresql报ssl error的核心原因是php的pdo/pgsql驱动与postgresql服务端ssl协商不匹配,常见于服务端未真正启用ssl、pg_hba.conf缺少hostssl规则、dsn中sslmode配置不当或证书验证失败。

CodeIgniter4 连接 PostgreSQL 报 SSL error,核心原因不是框架本身的问题,而是底层 PHP 的 PDO/pgsql 驱动与 PostgreSQL 服务端在 SSL 协商阶段不匹配。常见报错如 SSL connection has been closed unexpectedly、server does not support SSL, but SSL was requested 或 unable to get local issuer certificate,本质是客户端启用了 SSL,但服务端未启用、配置不兼容,或证书验证失败。
确认 PostgreSQL 服务端是否真正支持 SSL
很多问题出在“以为开了 SSL”,其实没生效:
- 登录数据库执行
SHOW ssl;—— 必须返回on,否则服务端根本没启用 SSL - 检查
postgresql.conf中ssl = on是否已取消注释且保存生效(重启服务或 reload) - 检查
pg_hba.conf是否有hostssl规则(例如:hostssl all all 0.0.0.0/0 scram-sha-256),仅host规则不走 SSL - 云环境(如 AWS RDS、Supabase、Azure DB)默认强制 SSL,但本地自建库若没配
ssl_cert_file和ssl_key_file,即使ssl=on也会握手失败
调整 CodeIgniter4 数据库配置中的 SSL 行为
CI4 使用 PDO 连接 PostgreSQL,SSL 控制依赖 DSN 参数,不能靠环境变量或全局设置:
- 在
app/Config/Database.php的 PostgreSQL 组中,把DSN字段写完整,例如:'DSN' => 'pgsql:host=127.0.0.1;port=5432;dbname=mydb;sslmode=require;' - 开发阶段无证书可配?改用
sslmode=disable(仅限可信内网,如 Docker 或本机):'DSN' => 'pgsql:host=127.0.0.1;port=5432;dbname=mydb;sslmode=disable;' - 生产环境需证书验证?加
sslrootcert(CA 文件路径)和sslcert/sslkey(客户端证书):'DSN' => 'pgsql:host=db.example.com;dbname=mydb;sslmode=verify-full;sslrootcert=/etc/ssl/certs/ca.crt;sslcert=/etc/ssl/client.crt;sslkey=/etc/ssl/client.key;' - 注意:PHP 进程必须有权限读取证书文件路径;路径建议用绝对路径,避免相对路径失效
绕过 SSL 验证(仅限调试,禁止上线)
临时跳过证书校验可用于快速验证是否纯属证书链问题(比如自签名、时间偏差、域名不匹配),但绝不可用于生产:
- 在 DSN 中添加
sslmode=allow或sslmode=prefer(不推荐,安全性低) - 更直接的方式:在连接前禁用 OpenSSL 全局验证(危险!仅测试):
putenv('PGSSLMODE=allow');放在index.php或数据库初始化前 - 或者,在
php.ini中设openssl.cafile=留空,或指向一个包含你自签 CA 的 PEM 文件(推荐长期方案)
检查 PHP 环境与扩展兼容性
PostgreSQL + SSL 依赖 PHP 编译时启用 OpenSSL 和 pgsql/pdo_pgsql 扩展:
- 运行
php -m | grep -i "pgsql\|pdo\|openssl",确认pgsql、pdo_pgsql、openssl均已加载 - 若用的是 Alpine Linux(Docker 常见),需安装
php82-pgsql和ca-certificates包,并确保/etc/ssl/certs/ca-certificates.crt存在 - PHP 8.1+ 默认更严格校验证书;若服务器时间不准(如 Docker 容器时钟漂移),也可能触发
SSL: certificate verification failed—— 同步系统时间再试











