Skip to content

[BUG] Self-signed certificates are not issued by the selected CA: each certificate generates a temporary self-signed root CA, causing TLS verification to fail for all clients that trust the server’s root certificate. #13560

Description

@van-chin

Contact Information

No response

1Panel Version

v2.2.5

Problem Description

版本 / 环境:v2.2.5 (stable, 2026-08-07 发布);Debian 13 x86_64,两台独立服务器均复现;通过面板 UI 签发,非 API。

现象:通过面板「证书 → 申请证书」类型选择「自签证书」为站点签发证书后,下载的 fullchain.pem 实际包含 3 张证书:

  1. 叶子证书(站点域名,如 gitea.example.com)
  2. 服务器根证书(即「证书 → CA 证书」中默认的 1Panel CA,serial 6A39ECE8)——仅被拼进 fullchain,未参与签名
  3. 一张每次签发临时生成的「per-site 自签根」(CN=1Panel-CA、CA:TRUE pathlen:0、serial = 叶子 serial − 1)——真正给叶子签名的是它,且它是自签的

后果 / 影响

  • 将服务器根证书分发给自动化客户端(composer cafile / SSL_CERT_FILE / NODE_EXTRA_CA_CERTS / 系统信任库)后,访问任何 UI 自签站点全部 TLS 失败(报 x509: certificate signed by unknown authority
  • 浏览器即使导入了服务器根,访问站点依旧警告
  • 多站点场景无法「信任一把根覆盖所有站点」;每张证书需单独信任其临时根,同一域名重签后临时根更换、信任再次失效

根因分析(源码对照)

  • 公开源码中该逻辑从未存在此问题ObtainSSL 明确用所选 CA 私钥给中间证书签名(x509.CreateCertificate(rand.Reader, interCsr, rootCsr, interPublicKey, rootPrivateKey)
  • 版本历史核对(以下版本的 agent/app/service/website_ca.go 该行完全一致,文件字节数相同):v2.1.13(2025-05)/ v2.2.3 / v2.2.5 / dev-v2 当前分支——均使用 rootPrivateKey;且 dev-v2 该文件自 2026-06-17 后无任何提交,不存在「已修复未发布」的代码
  • 但 v2.1.x~v2.2.5 各版本发行二进制实测均为自签中间证书(2026-06 由旧版本签发的历史证书同样结构),与公开源码行为不一致
  • 疑似发行构建源与公开仓库不一致(源码内含 xpack 企业功能引用,发行版或由私有分支构建),请维护者确认

Steps to Reproduce

  1. 面板「证书 → 申请证书」,类型选择「自签证书」,CA 选择默认的 1Panel CA,为任意域名签发
  2. 取出站点证书链 /opt/1panel/www/sites/<域名>/ssl/fullchain.pem
  3. 拆开并逐张验证:
# 拆开 fullchain(c1=叶子, c2=服务器根, c3=临时根)
awk '/BEGIN CERTIFICATE/{n++} {print > ("/tmp/c" n ".pem")}' /opt/1panel/www/sites/<域名>/ssl/fullchain.pem
# ① 叶子(c1)由第3张(c3)签发(确认真正签名者是临时根)
openssl verify -CAfile /tmp/c3.pem /tmp/c1.pem
# ② 叶子应链到所选 CA(确认服务器根是否参与签名)
openssl verify -CAfile /opt/1panel/tmp/ssl/1Panel/ca.crt -untrusted /tmp/c3.pem /tmp/c1.pem
# ③ 第3张(c3)应由所选 CA 签名
openssl verify -CAfile /opt/1panel/tmp/ssl/1Panel/ca.crt /tmp/c3.pem

实测输出(两台 v2.2.5 服务器、6 个站点全部一致):

① → /tmp/c1.pem: OK
② → error /tmp/c1.pem: verification failed
③ → error 18 at 0 depth lookup: self-signed certificate
④ openssl s_client -CAfile ca.crt -verify_return_error -servername <域名> ...
   → Verify return code: 19 (self-signed certificate in certificate chain)

补充观察:临时根 serial 与叶子相邻(叶子 = 临时根 + 1,对应代码 time.Now().Unix()+3 / +2),证明两证在同一签发流程内生成;2026-06 签发的历史证书(旧版本 1Panel 签发)同样结构,问题存在已久,非 v2.2.5 新引入。

The expected correct result

签发结果应为标准证书链:叶子 ← 中间证书 ← 所选 CA(根)

openssl verify -CAfile <所选CA.crt> -untrusted <中间证书.pem> <叶子.pem>   # 应输出 OK

即:客户端仅信任所选 CA(服务器根),即可验证该 CA 签发的所有站点证书。

Related log output

Additional Information

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions