Created
February 5, 2025 02:34
-
-
Save greenido/90994e70458b3cc0b8a5fe745a6dfc82 to your computer and use it in GitHub Desktop.
Checking the DNS or CloudFlare (both 9.9.9.9 and 1.1.1.3)
This file contains 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
// Save this file as dns-check.mjs | |
import fetch from 'node-fetch'; | |
import { performance } from 'perf_hooks'; | |
// Configure DoH endpoints | |
const quad9 = { | |
name: 'Quad9', | |
endpoint: 'https://dns.quad9.net:5053/dns-query' | |
}; | |
const cloudflareSecure = { | |
name: 'Cloudflare Security', | |
endpoint: 'https://security.cloudflare-dns.com/dns-query' | |
}; | |
// Test URLs | |
const safeUrls = [ | |
'google.com', | |
'microsoft.com', | |
'amazon.com', | |
'github.com', | |
'netflix.com' | |
]; | |
const suspiciousUrls = [ | |
'githb.co', // REAL ungly domain | |
'malware.testcategory.quad9.net', | |
'eicartest.quad9.net', // Quad9 test domain | |
'eicar.ph', // Known malware test domain | |
'blocked.quad9.net', // Quad9 test domain | |
'fraud.sb' // Known fraud domain | |
]; | |
async function dnsQuery(domain, dnsServer) { | |
const startTime = performance.now(); | |
try { | |
// Make DoH request | |
const response = await fetch(`${dnsServer.endpoint}?name=${domain}&type=A`, { | |
headers: { | |
'accept': 'application/dns-json', | |
'Content-Type': 'application/dns-json' | |
} | |
}); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
const data = await response.json(); | |
const endTime = performance.now(); | |
const responseTime = (endTime - startTime).toFixed(2); | |
// More detailed status checking | |
let status = 'ALLOWED'; | |
let addresses = []; | |
let rcode = data.Status || 0; | |
switch (rcode) { | |
case 0: // NOERROR | |
if (data.Answer) { | |
addresses = data.Answer | |
.filter(record => record.type === 1) // Type A records | |
.map(record => record.data); | |
status = addresses.length > 0 ? 'ALLOWED' : 'NO RECORDS'; | |
} else { | |
status = 'NO RECORDS'; | |
} | |
break; | |
case 2: // SERVFAIL | |
status = 'BLOCKED (SERVFAIL)'; | |
break; | |
case 3: // NXDOMAIN | |
status = 'BLOCKED (NXDOMAIN)'; | |
break; | |
case 5: // REFUSED | |
status = 'BLOCKED (REFUSED)'; | |
break; | |
default: | |
status = `UNKNOWN (${rcode})`; | |
} | |
return { | |
domain, | |
dnsServer: dnsServer.name, | |
status, | |
responseTime: `${responseTime}ms`, | |
addresses, | |
rcode | |
}; | |
} catch (error) { | |
const endTime = performance.now(); | |
const responseTime = (endTime - startTime).toFixed(2); | |
return { | |
domain, | |
dnsServer: dnsServer.name, | |
status: `ERROR: ${error.message}`, | |
responseTime: `${responseTime}ms`, | |
addresses: [], | |
rcode: null | |
}; | |
} | |
} | |
async function runTests() { | |
console.log('Starting DNS-over-HTTPS Security Tests\n'); | |
// Test all URLs against both DNS servers | |
const allUrls = [...safeUrls, ...suspiciousUrls]; | |
const allTests = []; | |
for (const domain of allUrls) { | |
allTests.push(dnsQuery(domain, quad9)); | |
allTests.push(dnsQuery(domain, cloudflareSecure)); | |
} | |
try { | |
const results = await Promise.all(allTests); | |
// Process and display results with improved formatting | |
console.log('=== Safe URLs ==='); | |
for (const domain of safeUrls) { | |
const quad9Result = results.find(r => r.domain === domain && r.dnsServer === quad9.name); | |
const cloudflareResult = results.find(r => r.domain === domain && r.dnsServer === cloudflareSecure.name); | |
console.log(`\nDomain: ${domain}`); | |
console.log(`${quad9.name.padEnd(20)}: ${quad9Result.status.padEnd(20)} (${quad9Result.responseTime})`); | |
if (quad9Result.addresses.length > 0) { | |
console.log(`${''.padEnd(22)}IP: ${quad9Result.addresses.join(', ')}`); | |
} | |
console.log(`${cloudflareSecure.name.padEnd(20)}: ${cloudflareResult.status.padEnd(20)} (${cloudflareResult.responseTime})`); | |
if (cloudflareResult.addresses.length > 0) { | |
console.log(`${''.padEnd(22)}IP: ${cloudflareResult.addresses.join(', ')}`); | |
} | |
} | |
console.log('\n=== Suspicious URLs ==='); | |
for (const domain of suspiciousUrls) { | |
const quad9Result = results.find(r => r.domain === domain && r.dnsServer === quad9.name); | |
const cloudflareResult = results.find(r => r.domain === domain && r.dnsServer === cloudflareSecure.name); | |
console.log(`\nDomain: ${domain}`); | |
console.log(`${quad9.name.padEnd(20)}: ${quad9Result.status.padEnd(20)} (${quad9Result.responseTime})`); | |
if (quad9Result.addresses.length > 0) { | |
console.log(`${''.padEnd(22)}IP: ${quad9Result.addresses.join(', ')}`); | |
} | |
console.log(`${cloudflareSecure.name.padEnd(20)}: ${cloudflareResult.status.padEnd(20)} (${cloudflareResult.responseTime})`); | |
if (cloudflareResult.addresses.length > 0) { | |
console.log(`${''.padEnd(22)}IP: ${cloudflareResult.addresses.join(', ')}`); | |
} | |
} | |
// Calculate and display statistics | |
const quad9Times = results | |
.filter(r => r.dnsServer === quad9.name) | |
.map(r => parseFloat(r.responseTime)); | |
const cloudflareTimes = results | |
.filter(r => r.dnsServer === cloudflareSecure.name) | |
.map(r => parseFloat(r.responseTime)); | |
const avgQuad9Time = (quad9Times.reduce((a, b) => a + b, 0) / quad9Times.length).toFixed(2); | |
const avgCloudflareTime = (cloudflareTimes.reduce((a, b) => a + b, 0) / cloudflareTimes.length).toFixed(2); | |
console.log('\n=== Performance Summary ==='); | |
console.log(`${quad9.name} average response time: ${avgQuad9Time}ms`); | |
console.log(`${cloudflareSecure.name} average response time: ${avgCloudflareTime}ms`); | |
} catch (error) { | |
console.error('Error running tests:', error); | |
} | |
} | |
// Run the tests | |
runTests().catch(console.error); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment