Repository navigation
fix(ssl): 自动 SSL 初始化前校验空域名 - #372
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
首次初始化时,如果域名配置步骤尚未成功保存,
config.json中可能仍是:{ "domain": "", "domains": [], "webDomain": "" }但当前前端允许直接点击“下一步”进入 DNS/SSL 初始化,后端初始化接口也允许选择自动 HTTP / 自动 DNS 方式申请 SSL 证书。
此时
generateCertificate()会构造 ACME 账号联系人:由于
cfg.Domain为空,联系人变成i@,Let's Encrypt 注册账号失败:更关键的是,
config.ReadPrivateKey()在读取不到 ACME 私钥时会先生成并立即持久化config/ssl/account_private.pem。因此第一次注册虽然失败,私钥文件已经落盘。用户随后补填域名并再次提交 SSL 初始化时,因为私钥文件已存在,代码会走
ResolveAccountByKey()。但这个 key 从未成功注册到 ACME server,CA 会返回:于是实例进入持续坏状态,直到手工删除未注册的
account_private.pem才能恢复。修改内容
1. 前端提前拦截
在域名初始化步骤中,
smtp_domain或web_domain为空(仅空格也视为空)时:/api/setup请求;新增中英文提示文案:
SMTP域名和Web域名不能为空!SMTP domain and web domain cannot be empty!2. 后端防御性校验
SetSSL()中,选择自动 HTTP / 自动 DNS 且配置域名为空时,直接返回错误,并在写入 SSL 配置前拦截。generateCertificate()中增加同样的防御性校验,避免未来新增调用方绕过SetSSL()后仍生成无效的i@联系人。前端拦截用于提供正确的引导体验;后端校验继续保留,用于覆盖已有坏配置、直接调用 API、以及其他客户端绕过前端的情况。
对于已经处于坏状态的实例,仍然需要删除未成功注册的
config/ssl/account_private.pem后重试;accountDoesNotExist的自动自愈可以作为后续单独优化,避免本次改动过大。测试
后端:
前端:
构建成功;
git diff --check已通过。