Laravel连接Linode MySQL集群报SQLSTATE[3159]SSL连接错误
报错是因为Linode托管MySQL集群默认开启require_secure_transport=ON,强制所有客户端连接必须走SSL加密通道。你通过命令行连接时显式加了--ssl-mode=required参数,所以能正常连通;但Laravel默认的PDO MySQL连接没有配置SSL相关参数,走了明文连接被服务端拦截。
Linode MySQL集群使用公共可信CA签发的SSL证书,Ubuntu系统内置的根证书库默认信任该证书,因此不需要手动下载、配置任何pem证书文件,只要在Laravel配置中开启强制SSL连接即可,和命令行连接无需指定证书的逻辑完全一致。
1. 调整项目根目录.env文件
在原有MySQL数据库配置的基础上,新增两个SSL相关配置项,同时确认数据库连接地址和你命令行使用的地址一致:
# 原有数据库配置保留,确认以下参数和实际值匹配 DB_HOST=lin-xxx-mysql-primary-private.servers.linodedb.net DB_PORT=3306 DB_DATABASE=xxxrch DB_USERNAME=xxx DB_PASSWORD=你的数据库密码 # 新增以下SSL配置 DB_SSL_MODE=required MYSQL_ATTR_SSL_VERIFY_SERVER_CERT=false
因为是通过Linode内网地址连接数据库,关闭服务端证书校验不会带来额外安全风险,同时能规避部分PHP环境下CA证书路径匹配的问题。
2. 核对config/database.php配置
打开项目下config/database.php文件,找到connections.mysql节点的options配置项,确保PDO的SSL参数能正确读取.env中的值。如果没有对应配置,直接替换为以下内容即可:
'options' => extension_loaded('pdo_mysql') ? array_filter([ PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('MYSQL_ATTR_SSL_VERIFY_SERVER_CERT', true), PDO::ATTR_SSL_MODE => env('DB_SSL_MODE', 'required'), ]) : [],
Laravel 9及以上版本默认已经内置了上述配置,只要.env中新增对应参数即可,不需要修改该文件。
配置修改完成后,在项目目录执行以下命令清除配置缓存,再重新执行迁移命令即可正常连接:
php artisan config:clear php artisan migrate
生产环境执行完验证后,可以运行
php artisan config:cache重新缓存配置,提升框架运行性能。
内容的提问来源于stack exchange,提问作者lewis

