Files
cmautobuy/docs/task/86-mysql公网tls-ca校验.md

3.4 KiB

86 Admin:支持校验 CA 的 MySQL 公网 TLS 连接

背景与目标

#85 开放固定公网 IP 后,MySQL 公网账号要求 SSL,但 Admin 的 Go 驱动没有启用 TLS,因此正确密码也会收到 1045 Access denied。相同账号使用 MySQL 客户端 --ssl-mode=REQUIRED 可以登录,确认直接原因是客户端缺少 TLS。

目标是让 run_admin.bat 使用公网 MySQL 时强制加密、验证服务器专属 CA,且验证 失败不能回退明文。

最终方案

  • 数据库配置增加 tls_mode 和 tls_ca,环境变量也可按字段覆盖。
  • disabled 保持同机及 SSH 隧道兼容;verify_ca 要求 TLS 1.2+、加载指定 PEM CA、 验证服务器证书链,并禁止明文回退。
  • MySQL 自动生成的服务端证书没有 SAN,不能做公网 IP 主机名匹配;客户端只信任该 服务器专属 CA,通过自定义 VerifyConnection 校验证书链,不使用单纯 skip-verify。
  • Go 驱动改用 mysql.NewConnector,确保自定义 tls.Config 不会在 DSN 格式化时 丢失。
  • 提交服务器公开 CA 证书,不包含服务器私钥。
  • 本机被 Git 忽略的 config.yaml 已设置公网地址和 verify_ca。

改了哪些

  • admin/config/config.go:增加 TLS 配置、环境变量覆盖和模式校验。
  • admin/repository/mysql_db.go:加载 CA、验证证书链、启用 TLS 1.2+,更新错误提示。
  • admin/certs/mysql84-ca.pem:服务器公开 CA,不含私钥。
  • admin/config/config_test.go:覆盖 TLS YAML、环境覆盖、非法模式和缺少 CA。
  • admin/repository/mysql_db_tls_test.go:覆盖驱动配置、损坏 CA 和公网只读 TLS 冒烟。
  • admin/mysql_public_tls_smoke_test.go:覆盖数据库连接、schema migration 和首页路由。
  • admin/config.example.yaml、admin/AGENTS.md、Admin 上手及安全文档:同步配置和门禁。

验收结果

验收标准 结果
Go 驱动通过公网账号连接 MySQL 通过
TLS cipher 非空且不能回退明文 通过,ECDHE-RSA-AES128-GCM-SHA256
使用服务器专属 CA 验证证书链 通过
CA 缺失、损坏或非法模式返回明确错误 通过
默认 disabled 保持本机部署兼容 通过
公网数据库连接、schema migration 和首页路由 通过,首页返回 303
Go 1.23.0 静态检查、构建和全部测试 通过

测试

  • 执行的命令:

    cd D:\chengma\cmautobuy\admin
    $env:GOTOOLCHAIN="go1.23.0"
    go vet ./...
    go build ./...
    go test ./... -count=1
    go test . ./repository -run '公网MySQLTLS|公网TLS只读冒烟' -v -count=1
    Remove-Item Env:GOTOOLCHAIN
    
  • 结果:全部通过;公网集成测试确认 MySQL 8.4.8 TLS cipher 为 ECDHE-RSA-AES128-GCM-SHA256,页面冒烟完成 schema 初始化并返回 303。

  • 没验证到的部分:本机执行策略禁止自动后台启动和终止临时 Admin 进程,因此 没有由自动化直接执行长期运行的 run_admin.bat;测试已覆盖其相同的配置加载、 数据库连接、migration 和路由组装路径,需用户重新启动脚本确认窗口保持运行。

相关提交

  • f0715ee feat: 支持 MySQL 公网 TLS CA 校验 (#86)