Skip to main content

Logto | 控制台出现 Internal server error

·1033 words·3 mins
Work Web Docker
葛世杰
Author
葛世杰
Student @ Soochow
Table of Contents

在更换 SSL 证书后,Logto 控制台出现 Internal server error.

参考:Chat GPT,Emmanuel Corrales.

一、报错
#

课题组登录的 lobe chat database (GPT 代理网站)由 Logto 作为鉴权应用,前几日更换了 Let’s encrypt 颁发的证书,发现 Logto 登录页面无法访问,访问控制台出现 Internal server error. 查看 docker 日志有:

[cause]: Error: unable to verify the first certificate
      at TLSSocket.onConnectSecure (node:_tls_wrap:1677:34)
      at TLSSocket.emit (node:events:518:28)
      at TLSSocket._finishInit (node:_tls_wrap:1076:8)
      at ssl.onhandshakedone (node:_tls_wrap:862:12) {
    code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'

询问 GPT 给出的答案均为: 在 SSL/TLS 连接过程中,客户端无法验证服务器证书的有效性,由于能够正常访问其他该 SSL 证书加密的网站。

二、排查
#

我第一反应是 Logto 缓存中停留的上一份 SSL 证书与当前证书不匹配。在仔细研究 Logto 的部署文档,重新调试了 docker 容器均无果,于是在 bing 上搜索。在 Emmanuel Corrales 的博文:nodejs debugging and fixing https ssl issues caused by changing the self signed certificate 找到了类似问题的原因。

​![[image-20250107085331-b9z89l3.png]]

image

根据测试 SSL 命令有:

root$ openssl s_client -connect api.example.com:443

...
    Start Time: 1736184337
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK

可以发现与 docker 日志中出现了相同的 unable to verify the first certificate​ ,证明是 SSL 的问题。

三、解决
#

查看之前的 nginx SSL 证书文件发现,之前的证书文件夹都是 4 个文件,而新安装的证书只有两个文件cert.pem privkey.pem​ 。

于是将申请证书生成的 cert.pem chain.pem fullchain.pem privkey.pem​ 四个文件拷贝到 nginx docker 挂载的证书目录中 ./nginx/data/custom_ssl/npm-27​ ,重启 docker 容器,问题解决 ~

cert.pem(有时也称为 server.crt 或 public.crt): 这个文件包含了你的公钥证书,也就是由证书颁发机构(CA)签名的数字证书。它用来证明网站的身份,并且包含公钥,客户端可以用这个公钥来加密与服务器之间的通信。

chain.pem(有时也称为 ca_bundle.crt): 该文件包含了中间证书链,这些证书链接了你的证书(cert.pem)到CA的根证书。不是所有的情况都需要这个文件,取决于CA和你所使用的证书类型。但是,提供完整的证书链可以确保浏览器能够验证你的证书,从而顺利完成SSL/TLS握手。

fullchain.pem : 这个文件是一个组合文件,它将你的证书(cert.pem)和整个证书链(chain.pem)合并到了一个文件中。使用这个文件可以让服务器更容易地配置SSL/TLS,因为只需要指定一个文件即可提供所有的证书信息。

privkey.pem(有时也称为private.key): 这个文件包含了与你的公钥证书相对应的私钥。私钥用于解密用公钥加密的数据,并且在建立安全连接时进行身份验证。私钥必须严格保密,不应该泄露给任何人。