高安全架构 学习笔记(第 7 部分)
4.3 DNS 劫持防护
javascript
// DNS 安全检查
class DNSSecurity {
constructor() {
this.authorizedIPs = new Map()
}
// DNS 解析验证
async verifyDNSResolution(domain) {
// 从多个 DNS 服务器获取解析结果
const dnsServers = [
'8.8.8.8', // Google DNS
'1.1.1.1', // Cloudflare DNS
'114.114.114.114' // 114 DNS
]
const results = await Promise.all(
dnsServers.map(dns => this.resolveDNS(domain, dns))
)
// 检查解析结果是否一致
const uniqueIPs = new Set(results)
if (uniqueIPs.size > 1) {
console.warn('DNS 解析结果不一致,可能遭受 DNS 劫持')
console.log('解析结果:', results)
return {
safe: false,
reason: 'DNS 解析结果不一致',
results
}
}
// 验证 IP 是否在授权列表中
const ip = results[0]
const authorized = this.authorizedIPs.get(domain)
if (authorized && !authorized.includes(ip)) {
return {
safe: false,
reason: '解析 IP 不在授权列表中',
ip,
authorized
}
}
return {
safe: true,
ip
}
}
// DNS 解析
async resolveDNS(domain, dnsServer) {
// 实际实现:使用 DNS 解析库
const dns = require('dns').promises
const result = await dns.resolve4(domain)
return result[0]
}
// DNSSEC 验证
async verifyDNSSEC(domain) {
// DNSSEC 签名验证
console.log(`验证 ${domain} 的 DNSSEC 签名`)
return {
verified: true,
chainOfTrust: 'valid'
}
}
// HTTPS 证书验证
async verifyCertificate(domain) {
const tls = require('tls')
return new Promise((resolve, reject) => {
const socket = tls.connect(443, domain, {
servername: domain
}, () => {
const cert = socket.getPeerCertificate()
// 检查证书是否有效
const valid = socket.authorized
// 检查证书域名
const domainMatch = this.checkCertificateDomain(cert, domain)
socket.end()
resolve({
valid,
domainMatch,
issuer: cert.issuer,
validFrom: cert.valid_from,
validTo: cert.valid_to
})
})
socket.on('error', reject)
})
}
// 检查证书域名
checkCertificateDomain(cert, domain) {
// 检查 CN 和 SAN
const cn = cert.subject.CN
const san = cert.subjectaltname
if (cn === domain) return true
if (san && san.includes(domain)) return true
// 通配符证书
if (cn.startsWith('*.')) {
const baseDomain = cn.substring(2)
if (domain.endsWith(baseDomain)) return true
}
return false
}
}
// 使用示例
const dnsSecurity = new DNSSecurity()
// 验证 DNS 解析
dnsSecurity.verifyDNSResolution('example.com')
.then(result => console.log('DNS 安全检查:', result))