pymysql/psycopg2 连云数据库必须显式配置ssl证书路径并启用主机名校验才能生效:pymysql需设ssl={'ca': 'path', 'check_hostname': true},psycopg2需设sslmode='verify-full'且sslrootcert路径有效,否则默认明文传输。

PyMySQL/psycopg2 连云数据库时 SSL 参数怎么填才生效
不加 SSL 配置,连接默认走明文——哪怕云厂商控制台显示“SSL 已启用”,客户端不主动协商,数据照样裸奔。
关键不是开没开服务端 SSL,而是客户端有没有传对参数、有没有校验证书链。常见错误是只设 ssl=True 或 sslmode=require,但没配 ssl_ca(尤其在阿里云 RDS、腾讯云 CDB、AWS RDS 上)。
-
PyMySQL:必须显式传ssl={'ca': '/path/to/rds-combined-ca-bundle.pem'},仅ssl=True会跳过证书校验(等价于verify_none) -
psycopg2:用sslmode=verify-full时,必须同时指定sslrootcert(路径)和sslcert/sslkey(如需双向认证) - 证书文件别用浏览器导出的 `.crt`;云厂商提供的
rds-combined-ca-bundle.pem或root.crt才是正确根证书
Django settings.py 里 DATABASES 的 SSL 配置写法
Django 不会自动读取系统 CA 或云厂商证书,全靠你在 DATABASES 字典里手动塞进 SSL 相关键值,漏一个就退化成非加密连接。
PostgreSQL 示例(psycopg2 后端):
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'HOST': 'xxx.pg.rds.aliyuncs.com',
'PORT': '5432',
'NAME': 'mydb',
'USER': 'admin',
'PASSWORD': '***',
'OPTIONS': {
'sslmode': 'verify-full',
'sslrootcert': '/app/config/rds-root-ca.pem',
}
}
}
MySQL 示例(PyMySQL 后端):
OPTIONS = {
'ssl': {
'ca': '/app/config/rds-combined-ca-bundle.pem',
'check_hostname': True, # 必须开,否则不校验 CN/SAN
}
}
-
check_hostname=True是 PyMySQL 里防止中间人攻击的关键开关,不写等于白配 SSL - 路径必须是容器或部署环境里真实可读的绝对路径,Django 不会帮你 resolve 相对路径
- 如果用
mysqlclient,参数名是ssl_ca、ssl_cert等,不是嵌套字典
本地开发连云数据库时 SSL 报错 “certificate verify failed” 怎么快速定位
这个错误八成不是证书过期,而是路径错、权限错、或主机名不匹配——先别急着重下证书。
- 检查
openssl s_client -connect xxx.rds.amazonaws.com:5432 -servername xxx.rds.amazonaws.com -CAfile rds-root-ca.pem是否返回Verify return code: 0 (ok) - 确认连接字符串里的
HOST和证书 SAN 中的域名一致(比如不能用内网 IP 连公网 SSL 端点) - Python 进程用户是否有权读取证书文件?
ls -l /app/config/rds-root-ca.pem看权限,容器里常因 UID 不匹配导致 PermissionError - 别用
sslmode=prefer测试——它会在 SSL 失败时静默降级,掩盖问题
Gunicorn + uWSGI 场景下 SSL 连接池复用与证书生命周期
Web 服务器启动后,数据库连接池初始化一次,之后所有 worker 复用同一套 SSL 上下文。证书文件加载发生在进程启动时,改了证书不重启进程无效。
- 证书更新后必须滚动重启 Gunicorn/uWSGI,热重载不触发
ssl参数重解析 - 连接池满时新连接可能 fallback 到非 SSL 路径(尤其用
SQLAlchemy且pool_pre_ping=False),建议开启pool_pre_ping=True并捕获ssl.SSLError - 不要在每次请求里动态构造带 SSL 的 engine——既慢又容易泄露证书路径或引发 fd 耗尽
证书路径硬编码、hostname 校验关闭、进程不重启——这三个点,线上出问题时查得最久。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










