资讯动态

Joplin 同步报 “Certificate has expired“ 错误:Let‘s Encrypt 根证书过期事件复盘与 TLS 忽略选项的源码级解析

发布时间:2026/9/16 13:20:03 来源:尧图企业网站定制
Joplin 同步报 Certificate has expired 错误Lets Encrypt 根证书过期事件复盘与 TLS 忽略选项的源码级解析【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin2021 年 9 月 30 日Lets Encrypt 的根证书到期导致 Joplin 桌面端在同步 Joplin Cloud以及部分其他同步服务时出现 Certificate has expired 错误。本文以 Joplin 官方发布的故障通告readme/news/20210930-163458.md为骨架完整还原事件背景、官方临时解决方案的操作路径并深入 packages/lib 源码剖析 Ignore TLS certificate errors 选项的底层实现原理、适用同步目标与安全边界帮助你在遇到同类 TLS 证书问题时快速定位、临时规避并选择更安全的修复方案。事件背景Lets Encrypt 根证书过期引发的连锁故障原通告指出本次故障的根因是Lets Encrypt 的根证书于 2021 年 9 月 30 日到期而 Lets Encrypt 更换后的新信任链方案与 Joplin 桌面应用所依赖的 Electron 旧证书校验逻辑不兼容导致同步握手阶段证书验证失败。这类问题并非 Joplin 独有。通告明确说明This actually affects thousands of applications, not just Joplin。当时围绕该问题Lets Encrypt 社区与 Electron 仓库分别有公开讨论原通告引用了 Lets Encrypt 社区话题 Issue with Electron and expired root 与 Electron 仓库 issue Lets Encrypt root CA isnt working properly。从原理上可以推断大量基于 Electron 构建的桌面应用其内置的 Node/Chromium 版本信任链与 CA 根证书轮换策略之间存在兼容窗口CA 切换信任锚trust anchor后旧的证书链校验路径便不再成立。故障现象同步时报证书已过期受影响用户在 Joplin 桌面端执行同步时会收到类似Certificate has expired的错误提示受影响范围包括Joplin CloudJoplin 官方同步服务通告提到possibly other services即使用相似证书链的其它同步服务同样可能触发。值得注意的是在 Joplin 后续的源码注释中这一问题的变体仍然被持续关注。packages/lib/models/settings/builtInMetadata.ts 在解释为何该选项也要对 Joplin Cloud 开放时写道Needs to be enabled for Joplin Cloud too because some companies filter all traffic and swap TLS certificates, which result in errorUNABLE_TO_GET_ISSUER_CERT_LOCALLY也就是说企业网络中间设备替换 TLS 证书、CA 信任链异常等场景都可能让 Joplin 在同步时抛出证书类错误这与本次根证书过期事件属于同一类 TLS 校验问题。官方临时解决方案勾选 Ignore TLS certificate errors在原通告发布时官方给出的临时解决路径为打开 Joplin 桌面端的Configuration配置进入Synchronisation同步设置页展开Advanced Options高级选项勾选Ignore TLS certificate errors忽略 TLS 证书错误重新执行同步。该选项的作用是让 Joplin 在建立同步连接时跳过 TLS 证书校验从而绕过因根证书过期导致的握手失败。通告特别提醒这是一个临时 workaround官方随后会在 Joplin Cloud 服务端实施临时修复并在后续桌面应用版本中提供更彻底的永久修复。源码视角该选项在 Joplin 内部是如何生效的1. 设置项定义在 packages/lib/models/settings/builtInMetadata.ts 中net.ignoreTlsErrors被定义为同步section: sync下的高级布尔设置net.ignoreTlsErrors: { value: false, type: SettingItemType.Bool, advanced: true, section: sync, show: settings { return (shim.isNode() || shim.mobilePlatform() android) [ SyncTargetRegistry.nameToId(amazon_s3), SyncTargetRegistry.nameToId(nextcloud), SyncTargetRegistry.nameToId(webdav), SyncTargetRegistry.nameToId(joplinServer), SyncTargetRegistry.nameToId(joplinServerSaml), SyncTargetRegistry.nameToId(joplinCloud), ].indexOf(settings[sync.target]) 0; }, public: true, label: () _(Ignore TLS certificate errors), storage: SettingStorage.File, },从定义可以提取出以下关键信息默认值false默认严格校验 TLS 证书可见条件仅当运行环境为 Node桌面端 / CLI或 Android且当前同步目标属于上述六类之一时才显示。Joplin Cloud 被显式列入正是为了应对本次根证书过期及企业网络替换证书的场景存储方式SettingStorage.File即持久化到本地配置文件中重启后依然生效。2. 生效逻辑直接改写 Node 的 TLS 全局开关packages/lib/BaseApplication.ts 中注册了该设置变更的副作用处理net.ignoreTlsErrors: async () { process.env[NODE_TLS_REJECT_UNAUTHORIZED] Setting.value(net.ignoreTlsErrors) ? 0 : 1; },当用户勾选该选项时Joplin 会将环境变量NODE_TLS_REJECT_UNAUTHORIZED置为0即对底层 Node 发起的 HTTPS 请求全局关闭未授权证书拒绝行为取消勾选则恢复为1。这意味着该开关是一个进程级的全局开关影响当前应用实例内所有基于 Node TLS 栈的网络连接而非仅针对某一个同步目标。3. 各同步目标如何消费该开关在具体同步目标实现中该设置会被传递到对应的文件 API 驱动packages/lib/SyncTargetWebDAV.ts 与 packages/lib/SyncTargetWebDAV.ts通过options.ignoreTlsErrors()读取设置并注入 WebDAV 请求packages/lib/WebDavApi.ts将ignoreTlsErrors写入fetchOptions随请求一起交给底层shim.fetch执行packages/lib/SyncTargetNextcloud.tsNextcloud 目标同样读取Setting.value(net.ignoreTlsErrors)packages/lib/SyncTargetAmazonS3.js 与 packages/lib/SyncTargetAmazonS3.jsAmazon S3 目标的初始化与配置检查均使用该设置。可以看到net.ignoreTlsErrors是一个被多个同步后端共用的统一开关WebDAV / Nextcloud / Amazon S3 / Joplin Server / Joplin Cloud 等目标在发起 HTTPS 请求时都会读取它。4. 更安全的替代方案自定义 TLS 证书在同一段设置定义中紧邻net.ignoreTlsErrors的是 net.customCertificates 设置packages/lib/models/settings/builtInMetadata.ts#L2045-L2052net.customCertificates: { ... label: () _(Custom TLS certificates), description: () _(Comma-separated list of paths to directories to load the certificates from, or path to individual cert files. For example: /my/cert_dir, /other/custom.pem. Note that if you make changes to the TLS settings, you must save your changes before clicking on Check synchronisation configuration.), storage: SettingStorage.File, },该选项允许以逗号分隔的形式指定自定义 CA 证书目录或单个证书文件路径例如/my/cert_dir, /other/custom.pem。底层实现位于 packages/lib/BaseApplication.ts通过syswidecas.addCAs(f)将指定路径下的证书加载进系统 CA 池。相比忽略全部证书错误自定义证书能在保留证书校验能力的前提下修复信任链是更安全、更精准的长期方案。设置变更后需先保存再点击同步配置中的 Check synchronisation configuration 验证。修复进展与后续处理原通告末尾的更新明确了两点后续进展服务端临时修复已上线Joplin Cloud 服务端已实施临时修复大部分用户的问题在该修复后得到解决客户端永久修复待发布桌面应用后续版本会内置更彻底的永久修复届时用户即可取消 Ignore TLS certificate errors 勾选。因此如果你在故障期间勾选了该选项待桌面应用更新到包含永久修复的版本后应及时回到 Configuration Synchronisation Advanced Options 取消勾选恢复默认的严格证书校验避免长期处于跳过证书校验的不安全状态。安全提醒与最佳实践Ignore TLS certificate errors 会通过NODE_TLS_REJECT_UNAUTHORIZED0关闭 Node 全局的证书拒绝行为等同于放弃对服务端身份的完整性校验存在中间人攻击风险仅适合在官方明确告知的故障窗口期作为临时应急手段涉及自建 Joplin Server、私有 WebDAV / Nextcloud 等场景时优先使用Custom TLS certificates导入自家 CA 证书而不是全局忽略错误故障排查顺序建议为确认系统时间正确 → 检查证书链是否完整可借助 Check synchronisation configuration 验证→ 属于 CA 根证书轮换类问题时先尝试自定义证书导入最后才考虑临时勾选忽略选项。小结Certificate has expired 是 TLS 信任链失效的典型症状。通过本文可以掌握Joplin 官方在 2021 年 Lets Encrypt 根证书过期事件中的完整应对流程临时忽略 → 服务端修复 → 客户端永久修复以及net.ignoreTlsErrors与net.customCertificates两个设置在 packages/lib/models/settings/builtInMetadata.ts 中的定义、在 packages/lib/BaseApplication.ts 中的进程级生效机制以及它们在 WebDAV / Nextcloud / Amazon S3 / Joplin Server / Joplin Cloud 各同步后端中的传递链路。遇到类似证书错误时你可以据此快速判断是信任链问题还是中间设备替换证书问题并选择自定义证书或临时忽略两种不同风险的应对策略。【免费下载链接】joplinJoplin - the privacy-focused note taking app with sync capabilities for Windows, macOS, Linux, Android and iOS.项目地址: https://gitcode.com/GitHub_Trending/jo/joplin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价