DNS劫持主要发生在网络层,前端无法直接解决,但可以采取以下方案进行检测和缓解:
一、检测DNS劫持
// 检查当前域名是否与预期一致
const expectedDomain = 'yourdomain.com';
const currentDomain = window.location.hostname;
if (!currentDomain.endsWith(expectedDomain)) {
console.warn('可能的DNS劫持检测', {
期望域名: expectedDomain,
当前域名: currentDomain
});
// 提示用户
alert('安全警告:请检查网络连接,可能遭遇DNS劫持');
// 或重定向到HTTPS版本
window.location.href =https://${expectedDomain}${window.location.pathname};
}
// 检测静态资源是否被篡改
const checkResourceIntegrity = async () => {
const expectedHash = 'sha256-abc123...';
const response = await fetch('/critical-script.js');
const data = await response.text();
// 使用Web Crypto API验证哈希
const hashBuffer = await crypto.subtle.digest(
'SHA-256',
new TextEncoder().encode(data)
);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
if (sha256-${hashHex} !== expectedHash) {
console.error('资源已被篡改!');
}
};二、防御措施
<!-- 在HTML中 -->
<meta http-equiv="Content-Security-Policy"
content="upgrade-insecure-requests">
// 检测是否使用HTTPS
if (window.location.protocol !== 'https:') {
window.location.href =https://${window.location.host}${window.location.pathname};
}
<script src="https://cdn.example.com/jquery.min.js"
integrity="sha256-123456..."
crossorigin="anonymous"></script>
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'sha256-...';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self'">4. Service Worker劫持检测
// 注册Service Worker监控请求
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-detection.js').then(() => {
console.log('DNS劫持检测服务已启动');
});
}
// sw-detection.js
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// 检查域名
if (!url.hostname.endsWith('yourdomain.com')) {
console.warn('可疑请求:', url.hostname);
event.respondWith(
new Response('安全警告:检测到异常请求', {
status: 403,
headers: { 'Content-Type': 'text/plain' }
})
);
}
});
// 建立WebSocket连接验证后端
function setupDNSValidation() {
const ws = new WebSocket('wss://yourdomain.com/ws-detect');
ws.onopen = () => {
// 定期发送验证消息
setInterval(() => {
ws.send(JSON.stringify({
type: 'dns-check',
timestamp: Date.now(),
token: 'secure-token'
}));
}, 30000);
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'dns-response') {
validateResponse(data);
}
};
}三、用户体验优化
// 创建友好的劫持提示
function showHijackWarning() {
const warning = document.createElement('div');
warning.innerHTML = `
<div style="
position: fixed;
top: 0;
left: 0;
width: 100%;
background: #ff6b6b;
color: white;
padding: 15px;
text-align: center;
z-index: 9999;
">
⚠️ 安全警告:检测到网络异常,建议:
1. 检查DNS设置
2. 使用HTTPS访问
3. 联系网络管理员
<button onclick="this.parentNode.remove()" style="margin-left:20px;">
关闭
</button>
</div>
`;
document.body.prepend(warning);
}
// 提供备用域名访问
const backupDomains = [
'yourdomain-alternate.com',
'yourdomain-backup.com'
];
function tryBackupDomains() {
for (const domain of backupDomains) {
fetch(https://${domain}/health-check)
.then(res => {
if (res.ok) {
window.location.href =https://${domain}${window.location.pathname};
break;
}
});
}
}四、服务器端配合方案
虽然前端方案有限,但建议配合以下服务器端措施:
Nginx配置示例 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always;
- 在域名注册商处启用DNSSEC
- 确保DNS记录使用数字签名
五、最佳实践建议
1、强制使用HTTPS:全站HTTPS是最基本防御
2、定期检测:建立自动化检测机制
3、用户教育:提示用户检查浏览器地址栏
4、监控报警:建立异常访问监控
5、备用方案:准备应急访问渠道
重要说明
DNS劫持的根本解决方案需要在网络层面:
- 使用加密DNS(如DoH/DoT)
- 配置可靠DNS服务器
- 企业网络使用防火墙规则
- 手机用户建议使用可信DNS应用
前端方案主要是检测和缓解,真正的防护需要多层面配合。
文章摘自:https://idc.huochengrm.cn/dns/22173.html
评论
浑念雁
回复DNS劫持检测与缓解涉及前端和服务器端措施,前端可检测域名和资源篡改,强制HTTPS,使用SRI等,服务器端应配置安全头、DNSSEC,使用加密DNS,多层面配合才是根本防护之道。
万飞烟
回复前端解决DNS劫持问题可借助CDN、本地缓存、域名解析优化等技术手段。
休骞
回复前端解决DNS劫持问题通常涉及使用HTTPS、CDN服务、DNS解析劫持检测与替代等策略,以确保用户访问安全、可靠的网络资源。