脚本如何检测DNS解析是否正常

wen 实用脚本 1

本文目录导读:

脚本如何检测DNS解析是否正常

  1. 使用命令行工具
  2. 脚本检测方法
  3. 高级检测功能
  4. 使用场景示例

我来介绍几种检测DNS解析是否正常的方法:

使用命令行工具

Linux/Mac

# 使用nslookup
nslookup example.com
# 使用dig
dig example.com
# 使用host
host example.com
# 使用ping(简单检测)
ping -c 1 example.com

Windows

# 使用nslookup
nslookup example.com
# 使用ping
ping -n 1 example.com

脚本检测方法

Python脚本

import socket
import dns.resolver
import subprocess
import sys
def check_dns_resolution(domain):
    """使用socket检查DNS解析"""
    try:
        ip = socket.gethostbyname(domain)
        print(f"DNS解析成功: {domain} -> {ip}")
        return True
    except socket.gaierror as e:
        print(f"DNS解析失败: {e}")
        return False
def check_dns_with_dnspython(domain):
    """使用dnspython库(需要安装: pip install dnspython)"""
    try:
        resolver = dns.resolver.Resolver()
        answers = resolver.resolve(domain, 'A')
        for rdata in answers:
            print(f"DNS记录: {domain} -> {rdata.address}")
        return True
    except Exception as e:
        print(f"DNS查询失败: {e}")
        return False
def check_multiple_dns_servers(domain):
    """检查多个DNS服务器"""
    dns_servers = [
        ('Google', '8.8.8.8'),
        ('Cloudflare', '1.1.1.1'),
        ('114DNS', '114.114.114.114')
    ]
    for name, server in dns_servers:
        try:
            resolver = dns.resolver.Resolver()
            resolver.nameservers = [server]
            answers = resolver.resolve(domain, 'A', lifetime=3)
            print(f"✓ {name} ({server}): {answers[0].address}")
        except Exception as e:
            print(f"✗ {name} ({server}): 失败 - {e}")
def complete_dns_check(domain):
    """完整的DNS检测"""
    print(f"开始检测域名: {domain}")
    print("-" * 50)
    # 1. 基础socket检测
    print("1. 基础DNS解析检测:")
    if check_dns_resolution(domain):
        print("   ✓ 基础解析成功")
    # 2. DNS记录类型检测
    print("\n2. DNS记录类型检测:")
    for record_type in ['A', 'AAAA', 'MX', 'CNAME', 'NS']:
        try:
            resolver = dns.resolver.Resolver()
            answers = resolver.resolve(domain, record_type, lifetime=5)
            print(f"   ✓ {record_type}记录: {[str(rdata) for rdata in answers[:3]]}")
        except:
            print(f"   - {record_type}记录: 无或查询失败")
    # 3. DNS服务器响应检测
    print("\n3. DNS服务器响应检测:")
    check_multiple_dns_servers(domain)
    return True
# 使用示例
if __name__ == "__main__":
    domain = "example.com"
    complete_dns_check(domain)

Shell脚本

#!/bin/bash
# DNS检测函数
check_dns() {
    local domain=$1
    local dns_server=${2:-"8.8.8.8"}
    echo "检测域名: $domain"
    echo "DNS服务器: $dns_server"
    # 使用nslookup
    if nslookup "$domain" "$dns_server" > /dev/null 2>&1; then
        echo "✓ DNS解析正常"
        nslookup "$domain" "$dns_server" | grep "Address"
    else
        echo "✗ DNS解析失败"
        return 1
    fi
    # 使用dig获取详细信息
    echo ""
    echo "详细DNS记录:"
    dig @"$dns_server" "$domain" +short
}
# 批量检测域名
check_multiple_domains() {
    local domains=("google.com" "baidu.com" "github.com")
    for domain in "${domains[@]}"; do
        echo "======== 检测: $domain ========"
        check_dns "$domain"
        echo ""
    done
}
# 检测DNS服务器连通性
check_dns_server() {
    local servers=(
        "8.8.8.8"    # Google
        "1.1.1.1"    # Cloudflare
        "114.114.114.114"  # 114DNS
    )
    for server in "${servers[@]}"; do
        if ping -c 1 -W 1 "$server" > /dev/null 2>&1; then
            echo "✓ DNS服务器 $server 可访问"
        else
            echo "✗ DNS服务器 $server 不可访问"
        fi
    done
}
# 主函数
main() {
    case "$1" in
        "single")
            check_dns "$2"
            ;;
        "multiple")
            check_multiple_domains
            ;;
        "server")
            check_dns_server
            ;;
        *)
            echo "用法: $0 {single|multiple|server} [domain]"
            ;;
    esac
}
main "$@"

Node.js脚本

const dns = require('dns');
const { promisify } = require('util');
// 将回调函数转为Promise
const resolveDns = promisify(dns.resolve);
const reverseDns = promisify(dns.reverse);
const lookupDns = promisify(dns.lookup);
async function checkDNS(domain) {
    console.log(`检测域名: ${domain}`);
    console.log('-'.repeat(50));
    // 1. 基础DNS查询
    try {
        const addresses = await lookupDns(domain);
        console.log(`✓ 基础查询成功: ${domain} -> ${addresses.address}`);
    } catch (error) {
        console.log(`✗ 基础查询失败: ${error.message}`);
        return;
    }
    // 2. 查询各种DNS记录
    const recordTypes = ['A', 'AAAA', 'MX', 'NS', 'TXT', 'CNAME'];
    for (const type of recordTypes) {
        try {
            const records = await resolveDns(domain, type);
            console.log(`✓ ${type}记录: ${JSON.stringify(records.slice(0, 3))}`);
        } catch (error) {
            if (error.code === 'ENODATA') {
                console.log(`- ${type}记录: 不存在`);
            } else {
                console.log(`- ${type}记录: 查询失败`);
            }
        }
    }
    // 3. DNS响应时间测试
    console.log('\n3. DNS响应时间:');
    for (const server of ['8.8.8.8', '1.1.1.1', '114.114.114.114']) {
        const start = Date.now();
        try {
            await lookupDns(domain, { server: server });
            const duration = Date.now() - start;
            console.log(`   ✓ ${server}: ${duration}ms`);
        } catch (error) {
            console.log(`   ✗ ${server}: 超时或失败`);
        }
    }
}
// 实时监控DNS状态
async function monitorDNS(domain, interval = 5000) {
    console.log(`开始监控 ${domain} 的DNS状态 (每${interval/1000}秒)`);
    setInterval(async () => {
        try {
            const start = Date.now();
            await lookupDns(domain);
            const duration = Date.now() - start;
            console.log(`[${new Date().toLocaleTimeString()}] ✓ DNS正常 (${duration}ms)`);
        } catch (error) {
            console.log(`[${new Date().toLocaleTimeString()}] ✗ DNS异常: ${error.message}`);
        }
    }, interval);
}
// 使用示例
checkDNS('example.com');
// monitorDNS('example.com', 10000);  // 10秒监控间隔

高级检测功能

检测DNS劫持

import socket
import hashlib
def check_dns_hijacking(domain):
    """检测DNS劫持"""
    trusted_dns = [
        ('8.8.8.8', 53),      # Google
        ('1.1.1.1', 53),      # Cloudflare
        ('208.67.222.222', 53) # OpenDNS
    ]
    results = []
    for dns_server, port in trusted_dns:
        try:
            # 使用特定DNS服务器查询
            resolver = dns.resolver.Resolver()
            resolver.nameservers = [dns_server]
            answers = resolver.resolve(domain, 'A', lifetime=3)
            results.append(answers[0].address)
        except:
            results.append(None)
    # 比较结果是否一致
    unique_ips = set(filter(None, results))
    if len(unique_ips) > 1:
        print("⚠️ 可能存在DNS劫持: 不同DNS服务器返回不同IP")
        for dns, ip in zip(['Google', 'Cloudflare', 'OpenDNS'], results):
            print(f"  {dns}: {ip}")
    else:
        print("✅ DNS解析一致,未检测到劫持")
# 使用示例
check_dns_hijacking("example.com")

检测缓存污染

def check_dns_cache_poisoning(domain):
    """检测DNS缓存污染"""
    import time
    print(f"检测DNS缓存污染: {domain}")
    # 连续多次查询,检查结果是否变化
    results = []
    for i in range(5):
        try:
            ip = socket.gethostbyname(domain)
            results.append(ip)
            time.sleep(0.1)
        except:
            pass
    # 如果多次查询结果不一致,可能存在缓存污染
    if len(set(results)) > 1:
        print("⚠️ 检测到DNS缓存可能被污染!")
        print(f"  结果变化: {set(results)}")
    else:
        print(f"✅ DNS查询结果稳定: {results[0]}")

使用场景示例

网站可用性监控

def check_site_availability(domain):
    """检查网站DNS和连通性"""
    import requests
    print(f"检查网站: {domain}")
    # 1. DNS检测
    dns_ok = check_dns_resolution(domain)
    if not dns_ok:
        return False
    # 2. HTTP连接检测
    try:
        response = requests.get(
            f"https://{domain}", 
            timeout=5,
            allow_redirects=True
        )
        print(f"✓ HTTP连接成功 (状态码: {response.status_code})")
        return True
    except requests.RequestException as e:
        print(f"✗ HTTP连接失败: {e}")
        return False
# 批量检测
sites = ["google.com", "github.com", "stackoverflow.com"]
for site in sites:
    check_site_availability(site)
    print()

这些脚本可以帮助你:

  • 快速检测DNS解析是否正常
  • 检测DNS响应时间
  • 发现DNS劫持或缓存污染
  • 监控DNS服务稳定性

选择哪种方法取决于你的具体需求和使用环境。

抱歉,评论功能暂时关闭!