nslookup 命令详解#

nslookup(Name Server Lookup)是 Linux 系统中用于查询 DNS(Domain Name System)信息的命令行工具。它可以查询域名对应的 IP 地址、反向查询、DNS 记录类型等,是网络管理员和开发人员进行 DNS 故障排查的重要工具。

入门#

基本用法#

# 查询域名的 IP 地址
nslookup google.com

# 查询特定类型的 DNS 记录
nslookup -type=MX google.com

# 指定 DNS 服务器查询
nslookup google.com 8.8.8.8

# 交互式查询
nslookup
> google.com
> exit

常用选项#

选项说明
-type指定查询的记录类型(A、MX、NS、CNAME 等)
-query-type
-debug显示调试信息
-port指定 DNS 服务器端口
-timeout设置查询超时时间
-retry设置重试次数
-vc使用 TCP 协议查询

常用记录类型#

类型说明
AIPv4 地址记录
AAAAIPv6 地址记录
MX邮件交换记录
NS名称服务器记录
CNAME别名记录
TXT文本记录
SOA授权起始记录
PTR反向 DNS 记录

基本示例#

# 查询 A 记录
nslookup google.com

# 输出示例:
# Server:		192.168.1.1
# Address:	192.168.1.1#53
#
# Non-authoritative answer:
# Name:	google.com
# Address: 142.250.188.46

# 查询 MX 记录
nslookup -type=MX google.com

# 查询 NS 记录
nslookup -type=NS google.com

# 指定 DNS 服务器
nslookup google.com 8.8.8.8

中级#

查询不同记录类型#

# 查询 A 记录(IPv4 地址)
nslookup -type=A google.com

# 查询 AAAA 记录(IPv6 地址)
nslookup -type=AAAA google.com

# 查询 MX 记录(邮件服务器)
nslookup -type=MX gmail.com

# 查询 NS 记录(名称服务器)
nslookup -type=NS google.com

# 查询 CNAME 记录(别名)
nslookup -type=CNAME www.google.com

# 查询 TXT 记录(文本信息)
nslookup -type=TXT google.com

# 查询 SOA 记录(授权起始)
nslookup -type=SOA google.com

反向 DNS 查询#

# 反向查询 IP 地址对应的域名
nslookup 8.8.8.8

# 输出示例:
# 8.8.8.8.in-addr.arpa	name = dns.google.

# 查询多个 IP 地址
nslookup 8.8.8.8
nslookup 1.1.1.1
nslookup 208.67.222.222

指定 DNS 服务器#

# 使用 Google DNS
nslookup google.com 8.8.8.8

# 使用 Cloudflare DNS
nslookup google.com 1.1.1.1

# 使用 OpenDNS
nslookup google.com 208.67.222.222

# 使用本地 DNS 服务器
nslookup google.com 192.168.1.1

# 使用多个 DNS 服务器
nslookup google.com 8.8.8.8 8.8.4.4

高级#

交互式模式#

# 进入交互式模式
nslookup

# 在交互式模式中
> server 8.8.8.8          # 设置 DNS 服务器
> set type=MX            # 设置查询类型
> google.com             # 查询域名
> set type=A             # 更改查询类型
> www.google.com         # 查询另一个域名
> set debug              # 启用调试模式
> google.com             # 查看详细信息
> exit                   # 退出

高级查询选项#

# 启用调试模式
nslookup -debug google.com

# 设置查询超时时间
nslookup -timeout=5 google.com

# 设置重试次数
nslookup -retry=3 google.com

# 使用 TCP 协议查询
nslookup -vc google.com

# 指定 DNS 服务器端口
nslookup -port=5353 google.com 127.0.0.1

# 禁用递归查询
nslookup -norecurse google.com

DNS 故障排查#

# 检查 DNS 解析是否正常
nslookup google.com

# 检查特定 DNS 服务器
nslookup google.com 8.8.8.8

# 检查 MX 记录
nslookup -type=MX gmail.com

# 检查 NS 记录
nslookup -type=NS google.com

# 检查 DNS 传播
nslookup -type=A newdomain.com

# 检查 DNS 缓存
nslookup -type=A google.com

大师#

DNS 批量查询#

#!/bin/bash
# DNS 批量查询脚本

DOMAIN_LIST="domains.txt"
OUTPUT_FILE="dns_query_results.txt"

# 从文件批量查询
batch_query() {
    local record_type=$1
    
    echo "Batch DNS Query - $(date)" > $OUTPUT_FILE
    echo "Record Type: $record_type" >> $OUTPUT_FILE
    echo "" >> $OUTPUT_FILE
    
    while IFS= read -r domain; do
        if [ -n "$domain" ] && [[ ! $domain =~ ^# ]]; then
            echo "Querying: $domain"
            echo "=== $domain ===" >> $OUTPUT_FILE
            nslookup -type=$record_type $domain >> $OUTPUT_FILE 2>&1
            echo "" >> $OUTPUT_FILE
        fi
    done < "$DOMAIN_LIST"
    
    echo "Batch query completed. Results saved to: $OUTPUT_FILE"
}

# 查询多个记录类型
multi_type_query() {
    local domain=$1
    local types=("A" "AAAA" "MX" "NS" "TXT")
    
    echo "=== Multi-type Query for $domain ==="
    
    for type in "${types[@]}"; do
        echo "--- $type Record ---"
        nslookup -type=$type $domain
        echo ""
    done
}

# 对比多个 DNS 服务器
compare_dns_servers() {
    local domain=$1
    shift
    local servers=("$@")
    
    echo "=== DNS Server Comparison for $domain ==="
    
    for server in "${servers[@]}"; do
        echo "--- Server: $server ---"
        nslookup $domain $server
        echo ""
    done
}

# 主函数
main() {
    case "$1" in
        batch)
            batch_query "$2"
            ;;
        multi)
            multi_type_query "$2"
            ;;
        compare)
            compare_dns_servers "$2" "${@:3}"
            ;;
        *)
            echo "Usage: $0 {batch|multi|compare}"
            exit 1
            ;;
    esac
}

main "$@"

DNS 监控#

#!/bin/bash
# DNS 监控脚本

DOMAINS=("google.com" "baidu.com" "github.com")
LOG_FILE="dns_monitor.log"

# 监控 DNS 解析
monitor_dns() {
    while true; do
        TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
        
        for DOMAIN in "${DOMAINS[@]}"; do
            RESULT=$(nslookup -timeout=2 $DOMAIN 2>&1)
            
            if echo "$RESULT" | grep -q "Address:"; then
                IP=$(echo "$RESULT" | grep "Address:" | tail -1 | awk '{print $2}')
                echo "$TIMESTAMP - $DOMAIN - $IP" >> $LOG_FILE
            else
                echo "$TIMESTAMP - $DOMAIN - FAILED" >> $LOG_FILE
            fi
        done
        
        sleep 300
    done
}

# 检查 DNS 变化
check_dns_changes() {
    local domain=$1
    local cache_file="dns_cache_${domain}.txt"
    
    if [ ! -f "$cache_file" ]; then
        nslookup $domain | grep "Address:" > $cache_file
        echo "Cache created for $domain"
        return 0
    fi
    
    local current=$(nslookup $domain | grep "Address:")
    local cached=$(cat $cache_file)
    
    if [ "$current" != "$cached" ]; then
        echo "DNS change detected for $domain!"
        echo "Old: $cached"
        echo "New: $current"
        echo "$current" > $cache_file
    else
        echo "No DNS change for $domain"
    fi
}

# DNS 性能测试
dns_performance_test() {
    local domain=$1
    local servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
    
    echo "=== DNS Performance Test for $domain ==="
    
    for server in "${servers[@]}"; do
        local start_time=$(date +%s.%N)
        nslookup -timeout=2 $domain $server > /dev/null 2>&1
        local end_time=$(date +%s.%N)
        local duration=$(echo "$end_time - $start_time" | bc)
        
        echo "$server: ${duration}s"
    done
}

# 主函数
main() {
    case "$1" in
        monitor)
            monitor_dns
            ;;
        check)
            check_dns_changes "$2"
            ;;
        performance)
            dns_performance_test "$2"
            ;;
        *)
            echo "Usage: $0 {monitor|check|performance}"
            exit 1
            ;;
    esac
}

main "$@"

DNS 故障诊断#

#!/bin/bash
# DNS 故障诊断工具

DOMAIN=$1
DIAGNOSTIC_LOG="dns_diagnostic_$(date +%Y%m%d_%H%M%S).log"

# 基本解析测试
basic_resolution_test() {
    echo "=== Basic Resolution Test ===" >> $DIAGNOSTIC_LOG
    
    nslookup $DOMAIN >> $DIAGNOSTIC_LOG 2>&1
    
    if [ $? -eq 0 ]; then
        echo "✓ Basic resolution successful" >> $DIAGNOSTIC_LOG
    else
        echo "✗ Basic resolution failed" >> $DIAGNOSTIC_LOG
    fi
    echo "" >> $DIAGNOSTIC_LOG
}

# 多记录类型测试
multi_record_test() {
    local types=("A" "AAAA" "MX" "NS" "TXT")
    
    echo "=== Multi-record Type Test ===" >> $DIAGNOSTIC_LOG
    
    for type in "${types[@]}"; do
        echo "--- $type Record ---" >> $DIAGNOSTIC_LOG
        nslookup -type=$type $DOMAIN >> $DIAGNOSTIC_LOG 2>&1
        echo "" >> $DIAGNOSTIC_LOG
    done
}

# 多 DNS 服务器测试
multi_server_test() {
    local servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
    
    echo "=== Multi-server Test ===" >> $DIAGNOSTIC_LOG
    
    for server in "${servers[@]}"; do
        echo "--- Server: $server ---" >> $DIAGNOSTIC_LOG
        nslookup $DOMAIN $server >> $DIAGNOSTIC_LOG 2>&1
        echo "" >> $DIAGNOSTIC_LOG
    done
}

# DNS 传播测试
propagation_test() {
    local servers=("8.8.8.8" "1.1.1.1" "208.67.222.222" "192.168.1.1")
    
    echo "=== DNS Propagation Test ===" >> $DIAGNOSTIC_LOG
    
    for server in "${servers[@]}"; do
        local result=$(nslookup $DOMAIN $server 2>&1)
        local ip=$(echo "$result" | grep "Address:" | tail -1 | awk '{print $2}')
        
        echo "$server: $ip" >> $DIAGNOSTIC_LOG
    done
    echo "" >> $DIAGNOSTIC_LOG
}

# 生成诊断报告
generate_diagnostic_report() {
    echo "DNS Diagnostic Report - $(date)" > $DIAGNOSTIC_LOG
    echo "=============================" >> $DIAGNOSTIC_LOG
    echo "Domain: $DOMAIN" >> $DIAGNOSTIC_LOG
    echo "" >> $DIAGNOSTIC_LOG
    
    basic_resolution_test
    multi_record_test
    multi_server_test
    propagation_test
    
    echo "Diagnostic completed. Log saved to: $DIAGNOSTIC_LOG"
}

# 主函数
main() {
    if [ -z "$DOMAIN" ]; then
        echo "Usage: $0 <domain>"
        exit 1
    fi
    
    generate_diagnostic_report
}

main "$@"

无敌#

企业级 DNS 监控系统#

#!/bin/bash
# 企业级 DNS 监控系统

CONFIG_FILE="/etc/dns_monitor/config.conf"
LOG_DIR="/var/log/dns_monitor"
ALERT_SCRIPT="/usr/local/bin/send_alert.sh"

mkdir -p $LOG_DIR

# 加载配置
source $CONFIG_FILE

# 监控 DNS 解析
monitor_dns_resolution() {
    local domain=$1
    local log_file="$LOG_DIR/${domain}_monitor.log"
    
    local result=$(nslookup -timeout=$TIMEOUT $DOMAIN_SERVER $domain 2>&1)
    
    if echo "$result" | grep -q "Address:"; then
        local ip=$(echo "$result" | grep "Address:" | tail -1 | awk '{print $2}')
        local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
        
        echo "$timestamp - $domain - $ip" >> $log_file
        return 0
    else
        local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
        echo "$timestamp - $domain - FAILED" >> $log_file
        return 1
    fi
}

# 检测 DNS 变化
detect_dns_changes() {
    local domain=$1
    local cache_file="$LOG_DIR/${domain}_cache.txt"
    local log_file="$LOG_DIR/${domain}_changes.log"
    
    local current_ip=$(nslookup -timeout=$TIMEOUT $DOMAIN_SERVER $domain 2>&1 | grep "Address:" | tail -1 | awk '{print $2}')
    
    if [ -f "$cache_file" ]; then
        local cached_ip=$(cat $cache_file)
        
        if [ "$current_ip" != "$cached_ip" ]; then
            local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
            echo "$timestamp - DNS change detected for $domain: $cached_ip -> $current_ip" >> $log_file
            
            $ALERT_SCRIPT "DNS change detected for $domain: $cached_ip -> $current_ip"
            
            echo "$current_ip" > $cache_file
        fi
    else
        echo "$current_ip" > $cache_file
    fi
}

# 监控多个域名
monitor_multiple_domains() {
    while true; do
        for domain in "${MONITOR_DOMAINS[@]}"; do
            monitor_dns_resolution $domain
            detect_dns_changes $domain
        done
        
        sleep $MONITOR_INTERVAL
    done
}

# 生成监控报告
generate_monitor_report() {
    local report_file="$LOG_DIR/monitor_report_$(date +%Y%m%d).txt"
    
    echo "DNS Monitor Report - $(date +%Y-%m-%d)" > $report_file
    echo "========================" >> $report_file
    echo "" >> $report_file
    
    for domain in "${MONITOR_DOMAINS[@]}"; do
        echo "=== $domain ===" >> $report_file
        tail -10 $LOG_DIR/${domain}_monitor.log >> $report_file
        echo "" >> $report_file
    done
    
    echo "Report saved to: $report_file"
}

# 主函数
main() {
    case "$1" in
        monitor)
            monitor_multiple_domains
            ;;
        report)
            generate_monitor_report
            ;;
        *)
            echo "Usage: $0 {monitor|report}"
            exit 1
            ;;
    esac
}

main "$@"

DNS 性能基准测试#

#!/bin/bash
# DNS 性能基准测试工具

DOMAIN="google.com"
TEST_COUNT=100
OUTPUT_FILE="dns_performance_$(date +%Y%m%d_%H%M%S).txt"

# 测试单个 DNS 服务器
test_dns_server() {
    local server=$1
    local total_time=0
    local success_count=0
    local fail_count=0
    
    echo "Testing DNS server: $server" >> $OUTPUT_FILE
    
    for ((i=1; i<=TEST_COUNT; i++)); do
        local start_time=$(date +%s.%N)
        nslookup -timeout=2 $DOMAIN $server > /dev/null 2>&1
        local end_time=$(date +%s.%N)
        local duration=$(echo "$end_time - $start_time" | bc)
        
        if [ $? -eq 0 ]; then
            total_time=$(echo "$total_time + $duration" | bc)
            success_count=$((success_count + 1))
        else
            fail_count=$((fail_count + 1))
        fi
    done
    
    local avg_time=$(echo "scale=3; $total_time / $success_count" | bc)
    local success_rate=$(echo "scale=2; $success_count * 100 / $TEST_COUNT" | bc)
    
    echo "Server: $server" >> $OUTPUT_FILE
    echo "Average response time: ${avg_time}s" >> $OUTPUT_FILE
    echo "Success rate: ${success_rate}%" >> $OUTPUT_FILE
    echo "Success count: $success_count" >> $OUTPUT_FILE
    echo "Fail count: $fail_count" >> $OUTPUT_FILE
    echo "" >> $OUTPUT_FILE
}

# 对比多个 DNS 服务器
compare_dns_servers() {
    local servers=("8.8.8.8" "1.1.1.1" "208.67.222.222" "192.168.1.1")
    
    echo "DNS Performance Benchmark - $(date)" > $OUTPUT_FILE
    echo "Domain: $DOMAIN" >> $OUTPUT_FILE
    echo "Test count: $TEST_COUNT" >> $OUTPUT_FILE
    echo "" >> $OUTPUT_FILE
    
    for server in "${servers[@]}"; do
        test_dns_server $server
    done
    
    echo "Benchmark completed. Results saved to: $OUTPUT_FILE"
}

# 实时性能监控
realtime_performance_monitor() {
    local servers=("8.8.8.8" "1.1.1.1" "208.67.222.222")
    
    echo "Real-time DNS Performance Monitor"
    echo "================================"
    
    while true; do
        clear
        echo "DNS Performance - $(date '+%Y-%m-%d %H:%M:%S')"
        echo ""
        
        for server in "${servers[@]}"; do
            local start_time=$(date +%s.%N)
            nslookup -timeout=2 $DOMAIN $server > /dev/null 2>&1
            local end_time=$(date +%s.%N)
            local duration=$(echo "$end_time - $start_time" | bc)
            
            printf "%-20s: %6s ms\n" "$server" "$(echo "$duration * 1000" | bc | cut -d'.' -f1)"
        done
        
        sleep 5
    done
}

# 主函数
main() {
    case "$1" in
        benchmark)
            compare_dns_servers
            ;;
        monitor)
            realtime_performance_monitor
            ;;
        *)
            echo "Usage: $0 {benchmark|monitor}"
            exit 1
            ;;
    esac
}

main "$@"

智能 DNS 故障诊断系统#

#!/bin/bash
# 智能 DNS 故障诊断系统

DOMAIN=$1
DIAGNOSTIC_DB="/var/lib/dns_diagnostic"
LOG_FILE="/var/log/dns_diagnostic/diagnostic.log"

mkdir -p $DIAGNOSTIC_DB $(dirname $LOG_FILE)

# 执行诊断
perform_diagnostic() {
    local diagnostic_id=$(date +%s%N)
    local output_dir="$DIAGNOSTIC_DB/$diagnostic_id"
    
    mkdir -p $output_dir
    
    echo "Performing diagnostic for $DOMAIN (ID: $diagnostic_id)..."
    
    # 基本解析
    nslookup $DOMAIN > $output_dir/basic_resolution.txt 2>&1
    
    # 多记录类型
    for type in A AAAA MX NS TXT; do
        nslookup -type=$type $DOMAIN > $output_dir/${type}_record.txt 2>&1
    done
    
    # 多 DNS 服务器
    for server in 8.8.8.8 1.1.1.1 208.67.222.222; do
        nslookup $DOMAIN $server > $output_dir/server_${server}.txt 2>&1
    done
    
    # 保存元数据
    echo "domain=$DOMAIN" > $output_dir/metadata.txt
    echo "timestamp=$(date)" >> $output_dir/metadata.txt
    echo "diagnostic_id=$diagnostic_id" >> $output_dir/metadata.txt
    
    echo "Diagnostic completed: $output_dir"
    return $diagnostic_id
}

# 分析诊断结果
analyze_diagnostic() {
    local diagnostic_id=$1
    local output_dir="$DIAGNOSTIC_DB/$diagnostic_id"
    
    if [ ! -d "$output_dir" ]; then
        echo "Diagnostic not found: $diagnostic_id"
        return 1
    fi
    
    echo "=== Diagnostic Analysis ==="
    echo "ID: $diagnostic_id"
    echo "Domain: $(grep domain $output_dir/metadata.txt | cut -d= -f2)"
    echo ""
    
    # 基本解析结果
    echo "Basic Resolution:"
    cat $output_dir/basic_resolution.txt
    echo ""
    
    # A 记录结果
    echo "A Record:"
    cat $output_dir/A_record.txt
    echo ""
    
    # MX 记录结果
    echo "MX Record:"
    cat $output_dir/MX_record.txt
    echo ""
    
    # 健康评估
    local failed_servers=$(grep -l "timed out\|can't find" $output_dir/server_*.txt | wc -l)
    if [ $failed_servers -eq 0 ]; then
        echo "✓ DNS health: Good"
    elif [ $failed_servers -lt 2 ]; then
        echo "⚠ DNS health: Fair ($failed_servers servers failed)"
    else
        echo "✗ DNS health: Poor ($failed_servers servers failed)"
    fi
}

# 比较诊断结果
compare_diagnostics() {
    local id1=$1
    local id2=$2
    
    local dir1="$DIAGNOSTIC_DB/$id1"
    local dir2="$DIAGNOSTIC_DB/$id2"
    
    if [ ! -d "$dir1" ] || [ ! -d "$dir2" ]; then
        echo "One or both diagnostics not found"
        return 1
    fi
    
    echo "=== Diagnostic Comparison ==="
    echo "ID1: $id1"
    echo "ID2: $id2"
    echo ""
    
    echo "Basic Resolution Comparison:"
    diff $dir1/basic_resolution.txt $dir2/basic_resolution.txt
    echo ""
    
    echo "A Record Comparison:"
    diff $dir1/A_record.txt $dir2/A_record.txt
}

# 列出诊断
list_diagnostics() {
    echo "=== Available Diagnostics ==="
    
    for dir in $DIAGNOSTIC_DB/*/; do
        if [ -d "$dir" ]; then
            local id=$(basename $dir)
            local domain=$(grep domain $dir/metadata.txt | cut -d= -f2)
            local timestamp=$(grep timestamp $dir/metadata.txt | cut -d= -f2)
            
            echo "ID: $id"
            echo "Domain: $domain"
            echo "Time: $timestamp"
            echo ""
        fi
    done
}

# 主函数
main() {
    case "$1" in
        diagnose)
            perform_diagnostic
            ;;
        analyze)
            analyze_diagnostic "$2"
            ;;
        compare)
            compare_diagnostics "$2" "$3"
            ;;
        list)
            list_diagnostics
            ;;
        *)
            echo "Usage: $0 {diagnose|analyze|compare|list}"
            exit 1
            ;;
    esac
}

main "$@"

最佳实践#

  1. 使用多个 DNS 服务器:使用多个 DNS 服务器进行对比验证
  2. 设置合理的超时:根据网络环境设置合适的超时时间
  3. 记录基线:建立 DNS 解析基线,便于比较变化
  4. 监控 DNS 变化:定期检查 DNS 记录变化
  5. 测试不同记录类型:测试多种 DNS 记录类型
  6. 使用 dig 替代:在新版本系统中,考虑使用 dig 命令
  7. 记录日志:记录重要的 DNS 查询和变化
  8. 自动化监控:编写脚本实现自动化 DNS 监控

注意事项#

  • nslookup 在某些系统中已被弃用,建议使用 dig 命令
  • DNS 查询结果可能被缓存,不总是反映最新配置
  • 不同 DNS 服务器可能返回不同的结果
  • 某些 DNS 记录类型可能不被所有服务器支持
  • 注意 DNS 传播延迟,新记录可能需要时间生效
  • 在生产环境中诊断时要谨慎,避免影响服务
  • 注意隐私保护,不要查询不明来源的域名
  • 某些网络可能阻止 DNS 查询或使用自定义 DNS 服务器
  • 对于关键业务,建议使用专业的 DNS 监控工具