fix(agent,acme,cert,web): 修 frps 安装 404 与 nginx 探测两处,证书颁发机构用 LiteSSL 替换 Buypass(v1.2.14)
CI / verify (push) Canceled after 0s
CI / verify (push) Canceled after 0s
- frps 安装/升级一直 404:frp 官方校验文件名始终是 frp_sha256_checksums.txt(不带版本号),代码却拼 frp_<版本>_sha256sums.txt;现按候选名依次尝试并在失败时列出尝试项。同一条 bug 也存在于本机下载 frpc 的路径,一并修复(SHA-256 校验逻辑未改) - nginx 探测(agent):nginxPath() 不再回落到配置里的裸名字 nginx(否则「未安装」被误报为配置校验失败,且一键安装入口永不出现);vhost 目录探测不再要求被加载文件带 .conf 后缀(Debian 的 sites-enabled/default 不带,导致只剩主配置目录可试,报「均无法放置完整 server 配置」),失败信息补上具体原因 - 证书 CA:LiteSSL(亚数 TrustAsia,90 天,支持单域名/通配符/多域名)替换 Buypass。LiteSSL 目录 meta.externalAccountRequired=true,强制 EAB——在 FreeSSL 创建后填 Kid/HMAC 即可,HMAC 只回掩码;Buypass 保留常量与展示元数据但不再可选 - 前端申请证书弹窗的颁发机构卡片改为前端可控清单(原先后端 /api/certs/options 的结果不参与渲染,后端改了弹窗不变) - 测试:internal/frp 校验文件候选名与 sha256sum 解析;internal/acme LiteSSL 目录/别名/通配符/Buypass 停用提示。gofmt / go build / go vet / go test / vue-tsc / vite build 全绿 - AgentVersion 0.12.4 → 0.12.7,双架构二进制已重编:VPS 上需点「升级 Agent」
This commit is contained in:
@@ -216,8 +216,12 @@
|
||||
<p v-if="applyCA === 'zerossl' && !zerosslApiKey" class="ca-hint ca-hint--warn">
|
||||
使用 ZeroSSL 需在「设置」中配置 API Key
|
||||
</p>
|
||||
<p v-if="applyCA === 'litessl'" class="ca-hint">
|
||||
LiteSSL(亚数 TrustAsia)免费 DV 证书,支持单域名 / 通配符 / 多域名;
|
||||
首次使用需在设置里填 EAB 凭据(FreeSSL 平台「证书自动化 → EAB 管理」创建)
|
||||
</p>
|
||||
<p v-if="applyCA === 'buypass'" class="ca-hint ca-hint--warn">
|
||||
Buypass 已于 2025-10-15 停止签发证书,请改选 Let's Encrypt 或 ZeroSSL
|
||||
Buypass 已于 2025-10-15 停止签发证书,请改选 Let's Encrypt 或 LiteSSL
|
||||
</p>
|
||||
</div>
|
||||
</n-form-item>
|
||||
@@ -486,7 +490,7 @@ const caOptions = ref<CertificateCAOption[]>([])
|
||||
const applyCAOptions = [
|
||||
{ value: 'letsencrypt', label: "Let's Encrypt" },
|
||||
{ value: 'zerossl', label: 'ZeroSSL' },
|
||||
{ value: 'buypass', label: 'Buypass' },
|
||||
{ value: 'litessl', label: 'LiteSSL' },
|
||||
]
|
||||
const applyCA = ref('letsencrypt')
|
||||
const zerosslApiKey = ref('')
|
||||
@@ -547,7 +551,9 @@ const caCardMeta: Record<string, { title: string; sub: string }> = {
|
||||
letsencrypt: { title: "Let's Encrypt", sub: '免费 · 自动续期' },
|
||||
'letsencrypt-staging': { title: "Let's Encrypt 测试", sub: '仅用于验证流程' },
|
||||
zerossl: { title: 'ZeroSSL', sub: '免费 · 稳定' },
|
||||
buypass: { title: 'Buypass', sub: '免费 · 备用' },
|
||||
// Buypass 已停服:仍保留元数据,历史证书记录要能正常显示
|
||||
buypass: { title: 'Buypass', sub: '已停止签发' },
|
||||
litessl: { title: 'LiteSSL', sub: '免费 · 国内根' },
|
||||
}
|
||||
|
||||
function providerLabel(v: string) {
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<div class="settings-field">
|
||||
<div class="settings-field__label">ACME 邮箱</div>
|
||||
<n-input v-model:value="acmeEmail" placeholder="admin@example.com" />
|
||||
<p class="field-hint">用于 Let's Encrypt / ZeroSSL 账户注册</p>
|
||||
<p class="field-hint">用于 Let's Encrypt / ZeroSSL / LiteSSL 账户注册</p>
|
||||
</div>
|
||||
<ConfiguredSecretField
|
||||
v-model="zerosslApiKey"
|
||||
@@ -88,6 +88,20 @@
|
||||
多个用逗号分隔,不写端口默认 53。
|
||||
</p>
|
||||
</div>
|
||||
<div class="settings-field">
|
||||
<div class="settings-field__label">LiteSSL EAB Kid</div>
|
||||
<n-input v-model:value="litesslEabKid" placeholder="FreeSSL → 证书自动化 → EAB 管理 里创建后粘贴" />
|
||||
<p class="field-hint">
|
||||
只在用 LiteSSL 申请时必填。LiteSSL 的目录要求 EAB(externalAccountRequired),
|
||||
凭据在 FreeSSL 平台的「证书自动化 → EAB 管理」创建;EAB Kid 不是密钥,可回显。
|
||||
</p>
|
||||
</div>
|
||||
<ConfiguredSecretField
|
||||
v-model="litesslEabHmac"
|
||||
label="LiteSSL EAB HMAC"
|
||||
:configured="litesslEabHmacConfigured"
|
||||
placeholder="用 LiteSSL 申请证书时填写"
|
||||
/>
|
||||
</div>
|
||||
</FonuCard>
|
||||
|
||||
@@ -1026,6 +1040,10 @@ const certThreshold = ref(30)
|
||||
const logRetention = ref(30)
|
||||
const acmeEmail = ref('')
|
||||
const acmeResolvers = ref('')
|
||||
// LiteSSL 的 EAB 凭据:kid 不是秘密(可回显),hmac 是秘密(只回掩码、重输才提交)
|
||||
const litesslEabKid = ref('')
|
||||
const litesslEabHmac = ref('')
|
||||
const litesslEabHmacConfigured = ref(false)
|
||||
const zerosslApiKey = ref('')
|
||||
const zerosslHasKey = ref(false)
|
||||
const trustedProxyEnabled = ref(false)
|
||||
@@ -1120,6 +1138,9 @@ function applySettingsToForm(settings: Record<string, string>) {
|
||||
statusPageConfigured.value = statusPageCode.value === MASKED_SECRET
|
||||
acmeEmail.value = settings.acme_email ?? ''
|
||||
acmeResolvers.value = settings.acme_dns_resolvers ?? ''
|
||||
litesslEabKid.value = settings.litessl_eab_kid ?? ''
|
||||
litesslEabHmacConfigured.value = Boolean(settings.litessl_eab_hmac?.trim())
|
||||
litesslEabHmac.value = ''
|
||||
zerosslHasKey.value = Boolean(settings.zerossl_api_key?.trim())
|
||||
zerosslApiKey.value = ''
|
||||
chinaCIDRHours.value = Number(settings.china_cidr_update_interval_hours ?? 24)
|
||||
@@ -1592,6 +1613,7 @@ function buildSavePayload() {
|
||||
log_retention_days: String(logRetention.value),
|
||||
acme_email: acmeEmail.value.trim(),
|
||||
acme_dns_resolvers: acmeResolvers.value.trim(),
|
||||
litessl_eab_kid: litesslEabKid.value.trim(),
|
||||
trusted_proxy_json: buildTrustedProxyJSON(),
|
||||
global_ip_blacklist: buildGlobalIPListJSON(globalIPBlacklistText.value),
|
||||
global_ip_whitelist: buildGlobalWhitelistJSON(),
|
||||
@@ -1604,6 +1626,10 @@ function buildSavePayload() {
|
||||
if (zerosslKey) {
|
||||
payload.zerossl_api_key = zerosslKey
|
||||
}
|
||||
const litesslHmac = litesslEabHmac.value.trim()
|
||||
if (litesslHmac) {
|
||||
payload.litessl_eab_hmac = litesslHmac
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user