pref: 优化查找TXT记录逻辑,提升CNAME解析效率

pull/361/head
xiaojunnuo 2025-03-29 23:10:59 +08:00
parent 4e15556e5e
commit 41e23fb6a8
2 changed files with 40 additions and 29 deletions

View File

@ -219,15 +219,15 @@ function formatResponseError(resp) {
async function resolveDomainBySoaRecord(recordName) { async function resolveDomainBySoaRecord(recordName) {
try { try {
await dns.resolveSoa(recordName); await dns.resolveSoa(recordName);
log(`Found SOA record, considering domain to be: ${recordName}`); log(`找到${recordName}的SOA记录`);
return recordName; return recordName;
} }
catch (e) { catch (e) {
log(`Unable to locate SOA record for name: ${recordName}`); log(`找不到${recordName}的SOA记录,继续往主域名查找`);
const parentRecordName = recordName.split('.').slice(1).join('.'); const parentRecordName = recordName.split('.').slice(1).join('.');
if (!parentRecordName.includes('.')) { if (!parentRecordName.includes('.')) {
throw new Error('Unable to resolve domain by SOA record'); throw new Error('SOA record查找失败');
} }
return resolveDomainBySoaRecord(parentRecordName); return resolveDomainBySoaRecord(parentRecordName);
@ -242,7 +242,7 @@ async function resolveDomainBySoaRecord(recordName) {
*/ */
async function getAuthoritativeDnsResolver(recordName) { async function getAuthoritativeDnsResolver(recordName) {
log(`Locating authoritative NS records for name: ${recordName} 获取域名的权威NS服务器`); log(`获取域名${recordName}的权威NS服务器: `);
const resolver = new dns.Resolver(); const resolver = new dns.Resolver();
try { try {
@ -250,7 +250,7 @@ async function getAuthoritativeDnsResolver(recordName) {
const domain = await resolveDomainBySoaRecord(recordName); const domain = await resolveDomainBySoaRecord(recordName);
/* Resolve authoritative NS addresses */ /* Resolve authoritative NS addresses */
log(`Looking up authoritative NS records for domain获取域名的权威NS服务器: ${domain}`); log(`获取到权威NS服务器name: ${domain}`);
const nsRecords = await dns.resolveNs(domain); const nsRecords = await dns.resolveNs(domain);
log(`域名权威NS服务器${nsRecords}`); log(`域名权威NS服务器${nsRecords}`);
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r))); const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));

View File

@ -48,46 +48,57 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix =
* Walk DNS until TXT records are found * Walk DNS until TXT records are found
*/ */
async function walkDnsChallengeRecord(recordName, resolver = dns) { async function walkDnsChallengeRecord(recordName, resolver = dns,deep = 0) {
/* Resolve CNAME record first */
// try { let records = [];
// 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}`);
// }
/* Resolve TXT records */ /* Resolve TXT records */
try { try {
log(`Checking name for TXT records: ${recordName}`); log(`检查域名 ${recordName} 的TXT记录`);
const txtRecords = await resolver.resolveTxt(recordName); const txtRecords = await resolver.resolveTxt(recordName);
if (txtRecords && txtRecords.length) { if (txtRecords && txtRecords.length) {
log(`Found ${txtRecords.length} TXT records at ${recordName}`); log(`找到 ${txtRecords.length} 条 TXT记录 ${recordName}`);
log(`TXT records: ${JSON.stringify(txtRecords)}`); 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}`); /* Resolve CNAME record first */
throw e; 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 = [] const txtRecords = []
try { try {
/* Default DNS resolver first */ /* Default DNS resolver first */
log('从本地DNS服务器获取TXT解析记录'); log('从本地DNS服务器获取TXT解析记录');
const res = await walkDnsChallengeRecord(recordName); const res = await walkDnsChallengeRecord(recordName,null,deep);
if (res && res.length > 0) { if (res && res.length > 0) {
for (const item of res) { for (const item of res) {
txtRecords.push(item) txtRecords.push(item)
@ -102,7 +113,7 @@ export async function walkTxtRecord(recordName) {
/* Authoritative DNS resolver */ /* Authoritative DNS resolver */
log(`从域名权威服务器获取TXT解析记录`); log(`从域名权威服务器获取TXT解析记录`);
const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName); const authoritativeResolver = await util.getAuthoritativeDnsResolver(recordName);
const res = await walkDnsChallengeRecord(recordName, authoritativeResolver); const res = await walkDnsChallengeRecord(recordName, authoritativeResolver,deep);
if (res && res.length > 0) { if (res && res.length > 0) {
for (const item of res) { for (const item of res) {
txtRecords.push(item) txtRecords.push(item)