feat(domain-intelligence): add domain intelligence lookups with RDAP and DNS enrichment
This commit is contained in:
@@ -50,6 +50,13 @@ export interface IIpIntelligenceOptions {
|
||||
dbMaxAge?: number;
|
||||
/** Timeout (ms) for RDAP/DNS/CDN requests. Default: 5000 */
|
||||
timeout?: number;
|
||||
/**
|
||||
* Optional injected smartdns client. When provided, IpIntelligence will
|
||||
* not create or destroy its own client (the owner — typically SmartNetwork —
|
||||
* manages lifecycle). When omitted, a short-lived client is created per
|
||||
* Team Cymru lookup and destroyed in finally.
|
||||
*/
|
||||
dnsClient?: InstanceType<typeof plugins.smartdns.dnsClientMod.Smartdns>;
|
||||
}
|
||||
|
||||
// CDN URLs for GeoLite2 MMDB files (served via jsDelivr from npm packages)
|
||||
@@ -93,9 +100,13 @@ export class IpIntelligence {
|
||||
private bootstrapEntries: IBootstrapEntry[] | null = null;
|
||||
private bootstrapPromise: Promise<void> | null = null;
|
||||
|
||||
// Optional injected smartdns client (shared by SmartNetwork)
|
||||
private readonly sharedDnsClient: InstanceType<typeof plugins.smartdns.dnsClientMod.Smartdns> | null;
|
||||
|
||||
constructor(options?: IIpIntelligenceOptions) {
|
||||
this.dbMaxAge = options?.dbMaxAge ?? DEFAULT_DB_MAX_AGE;
|
||||
this.timeout = options?.timeout ?? DEFAULT_TIMEOUT;
|
||||
this.sharedDnsClient = options?.dnsClient ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -385,16 +396,19 @@ export class IpIntelligence {
|
||||
* Response: "ASN | prefix | CC | rir | date"
|
||||
*/
|
||||
private async queryTeamCymru(ip: string): Promise<{ asn: number; prefix: string; country: string } | null> {
|
||||
let dnsClient: InstanceType<typeof plugins.smartdns.dnsClientMod.Smartdns> | null = null;
|
||||
const external = this.sharedDnsClient !== null;
|
||||
let dnsClient = this.sharedDnsClient;
|
||||
try {
|
||||
const reversed = ip.split('.').reverse().join('.');
|
||||
const queryName = `${reversed}.origin.asn.cymru.com`;
|
||||
|
||||
dnsClient = new plugins.smartdns.dnsClientMod.Smartdns({
|
||||
strategy: 'prefer-system',
|
||||
allowDohFallback: true,
|
||||
timeoutMs: this.timeout,
|
||||
});
|
||||
if (!dnsClient) {
|
||||
dnsClient = new plugins.smartdns.dnsClientMod.Smartdns({
|
||||
strategy: 'prefer-system',
|
||||
allowDohFallback: true,
|
||||
timeoutMs: this.timeout,
|
||||
});
|
||||
}
|
||||
|
||||
const records = await dnsClient.getRecordsTxt(queryName);
|
||||
if (!records || records.length === 0) return null;
|
||||
@@ -418,7 +432,8 @@ export class IpIntelligence {
|
||||
this.logger.debug?.(`Team Cymru DNS query failed for ${ip}: ${err.message}`);
|
||||
return null;
|
||||
} finally {
|
||||
if (dnsClient) {
|
||||
// Only destroy clients we created ourselves; leave injected ones alone.
|
||||
if (!external && dnsClient) {
|
||||
dnsClient.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user