From 41e23fb6a8f72a7fef1edb1cbaac8e144f324e76 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Sat, 29 Mar 2025 23:10:59 +0800 Subject: [PATCH] =?UTF-8?q?pref:=20=E4=BC=98=E5=8C=96=E6=9F=A5=E6=89=BETXT?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E9=80=BB=E8=BE=91=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?CNAME=E8=A7=A3=E6=9E=90=E6=95=88=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/acme-client/src/util.js | 10 ++--- packages/core/acme-client/src/verify.js | 59 +++++++++++++++---------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/packages/core/acme-client/src/util.js b/packages/core/acme-client/src/util.js index 7dde00c1..1c578501 100644 --- a/packages/core/acme-client/src/util.js +++ b/packages/core/acme-client/src/util.js @@ -219,15 +219,15 @@ function formatResponseError(resp) { async function resolveDomainBySoaRecord(recordName) { try { await dns.resolveSoa(recordName); - log(`Found SOA record, considering domain to be: ${recordName}`); + log(`找到${recordName}的SOA记录`); return recordName; } catch (e) { - log(`Unable to locate SOA record for name: ${recordName}`); + log(`找不到${recordName}的SOA记录,继续往主域名查找`); const parentRecordName = recordName.split('.').slice(1).join('.'); if (!parentRecordName.includes('.')) { - throw new Error('Unable to resolve domain by SOA record'); + throw new Error('SOA record查找失败'); } return resolveDomainBySoaRecord(parentRecordName); @@ -242,7 +242,7 @@ async function resolveDomainBySoaRecord(recordName) { */ async function getAuthoritativeDnsResolver(recordName) { - log(`Locating authoritative NS records for name: ${recordName} (获取域名的权威NS服务器)`); + log(`获取域名${recordName}的权威NS服务器: `); const resolver = new dns.Resolver(); try { @@ -250,7 +250,7 @@ async function getAuthoritativeDnsResolver(recordName) { const domain = await resolveDomainBySoaRecord(recordName); /* Resolve authoritative NS addresses */ - log(`Looking up authoritative NS records for domain(获取域名的权威NS服务器): ${domain}`); + log(`获取到权威NS服务器name: ${domain}`); const nsRecords = await dns.resolveNs(domain); log(`域名权威NS服务器:${nsRecords}`); const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r))); diff --git a/packages/core/acme-client/src/verify.js b/packages/core/acme-client/src/verify.js index 7587d71a..de0bbe5e 100644 --- a/packages/core/acme-client/src/verify.js +++ b/packages/core/acme-client/src/verify.js @@ -48,46 +48,57 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix = * Walk DNS until TXT records are found */ -async function walkDnsChallengeRecord(recordName, resolver = dns) { - /* Resolve CNAME record first */ - // try { - // log(`Checking name for CNAME records: ${recordName}`); - // const cnameRecords = await resolver.resolveCname(recordName); - // - // if (cnameRecords.length) { - // log(`CNAME record found at ${recordName}, new challenge record name: ${cnameRecords[0]}`); - // return walkDnsChallengeRecord(cnameRecords[0]); - // } - // } - // catch (e) { - // log(`No CNAME records found for name: ${recordName}`); - // } +async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) { + + let records = []; /* Resolve TXT records */ try { - log(`Checking name for TXT records: ${recordName}`); + log(`检查域名 ${recordName} 的TXT记录`); const txtRecords = await resolver.resolveTxt(recordName); if (txtRecords && txtRecords.length) { - log(`Found ${txtRecords.length} TXT records at ${recordName}`); + log(`找到 ${txtRecords.length} 条 TXT记录( ${recordName})`); log(`TXT records: ${JSON.stringify(txtRecords)}`); - return [].concat(...txtRecords); + records = records.concat(...txtRecords); } - return []; + } catch (e) { + log(`解析 TXT 记录出错, ${recordName} :${e.message}`); } - catch (e) { - log(`Resolve TXT records error, ${recordName} :${e.message}`); - throw e; + + /* Resolve CNAME record first */ + try { + log(`检查是否存在CNAME映射: ${recordName}`); + const cnameRecords = await resolver.resolveCname(recordName); + + if (cnameRecords.length) { + const cnameRecord = cnameRecords[0]; + log(`已找到${recordName}的CNAME记录,将检查: ${cnameRecord}`); + let res= await walkTxtRecord(cnameRecord,deep+1); + if (res && res.length) { + log(`从CNAME中找到TXT记录: ${JSON.stringify(res)}`); + records = records.concat(...res); + } + }else{ + log(`没有CNAME映射(${recordName})`); + } + } catch (e) { + log(`检查CNAME出错(${recordName}) :${e.message}`); } + return records } -export async function walkTxtRecord(recordName) { +export async function walkTxtRecord(recordName,deep = 0) { + if(deep >5){ + log(`walkTxtRecord too deep (#${deep}) , skip walk`) + return [] + } const txtRecords = [] try { /* Default DNS resolver first */ log('从本地DNS服务器获取TXT解析记录'); - const res = await walkDnsChallengeRecord(recordName); + const res = await walkDnsChallengeRecord(recordName,null,deep); if (res && res.length > 0) { for (const item of res) { txtRecords.push(item) @@ -102,7 +113,7 @@ export async function walkTxtRecord(recordName) { /* Authoritative DNS resolver */ log(`从域名权威服务器获取TXT解析记录`); const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName); - const res = await walkDnsChallengeRecord(recordName, authoritativeResolver); + const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep); if (res && res.length > 0) { for (const item of res) { txtRecords.push(item)