Shell脚本如何监控域名解析记录

wen 实用脚本 1

本文目录导读:

Shell脚本如何监控域名解析记录

  1. 基础DNS解析监控脚本
  2. 带解析记录日志的监控脚本
  3. 多域名批量监控脚本
  4. 支持CNAME和MX记录的监控
  5. 系统服务化配置
  6. 使用建议

我来详细介绍几种Shell脚本监控域名解析记录的方法:

基础DNS解析监控脚本

#!/bin/bash
# DNS监控脚本 - 检查域名解析是否正常
DOMAIN="example.com"
DNS_SERVER="8.8.8.8"  # 可选DNS服务器
# 获取当前解析IP
CURRENT_IP=$(dig +short $DOMAIN @$DNS_SERVER | tail -n1)
# 或使用nslookup
# CURRENT_IP=$(nslookup $DOMAIN | grep 'Address:' | tail -n1 | awk '{print $2}')
# 或使用host命令
# CURRENT_IP=$(host $DOMAIN | grep 'has address' | awk '{print $4}')
echo "当前解析: $CURRENT_IP"

带解析记录日志的监控脚本

#!/bin/bash
# 配置变量
DOMAIN="example.com"
EXPECTED_IP="192.168.1.100"  # 期望的IP地址
LOG_FILE="/var/log/dns_monitor.log"
CHECK_INTERVAL=300  # 检查间隔(秒)
# 日志函数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 获取解析记录
get_dns_record() {
    dig +short $DOMAIN @8.8.8.8 | tail -n1
}
# 主监控函数
monitor_dns() {
    log_message "开始监控域名: $DOMAIN"
    while true; do
        CURRENT_IP=$(get_dns_record)
        if [ -z "$CURRENT_IP" ]; then
            log_message "WARNING: 无法解析域名 $DOMAIN"
        elif [ "$CURRENT_IP" != "$EXPECTED_IP" ]; then
            log_message "ALERT: DNS解析发生变化!"
            log_message "原记录: $EXPECTED_IP"
            log_message "新记录: $CURRENT_IP"
            # 发送通知(可选)
            # send_alert "$CURRENT_IP"
        else
            log_message "正常 - 解析: $CURRENT_IP"
        fi
        sleep $CHECK_INTERVAL
    done
}
# 发送告警通知
send_alert() {
    local new_ip=$1
    # 邮件通知
    # echo "域名 $DOMAIN DNS记录已更改至 $new_ip" | mail -s "DNS变更告警" admin@example.com
    # Webhook通知
    # curl -X POST -H "Content-Type: application/json" \
    #      -d "{\"domain\":\"$DOMAIN\",\"new_ip\":\"$new_ip\"}" \
    #      https://hooks.example.com/alert
}
# 启动监控
monitor_dns

多域名批量监控脚本

#!/bin/bash
# 域名列表文件
DOMAIN_LIST="/etc/dns_monitor/domains.txt"
# 格式: domain|expected_ip
# example.com|192.168.1.100
# google.com|8.8.8.8
RESULT_FILE="/tmp/dns_check_result.txt"
ALERT_EMAIL="admin@example.com"
# 检查单个域名
check_domain() {
    local domain=$1
    local expected_ip=$2
    # 使用多个DNS服务器提高可靠性
    local dns_servers=("8.8.8.8" "1.1.1.1" "114.114.114.114")
    local resolved_ip=""
    for dns in "${dns_servers[@]}"; do
        resolved_ip=$(dig +short $domain @$dns 2>/dev/null | tail -n1)
        if [ -n "$resolved_ip" ]; then
            break
        fi
    done
    # 检查域名是否解析成功
    if [ -z "$resolved_ip" ]; then
        echo "FAIL|$domain|无法解析"
        return 1
    fi
    # 检查是否匹配期望IP
    if [ "$resolved_ip" != "$expected_ip" ]; then
        echo "CHANGED|$domain|$expected_ip->$resolved_ip"
        return 2
    fi
    echo "OK|$domain|$resolved_ip"
    return 0
}
# 批量检查所有域名
check_all_domains() {
    echo "开始检查域名解析状态..."
    echo "=== DNS检查报告 $(date) ===" > $RESULT_FILE
    while IFS='|' read -r domain expected_ip; do
        # 跳过注释和空行
        [[ $domain =~ ^# ]] && continue
        [ -z "$domain" ] && continue
        result=$(check_domain "$domain" "$expected_ip")
        echo "$result" >> $RESULT_FILE
        # 解析结果状态
        status=$(echo $result | cut -d'|' -f1)
        if [ "$status" != "OK" ]; then
            echo "WARNING: $domain - $status"
        fi
    done < "$DOMAIN_LIST"
    echo "检查完成,结果已保存至: $RESULT_FILE"
}
# 生成HTML报告
generate_html_report() {
    local html_file="/tmp/dns_report_$(date +%Y%m%d).html"
    cat > $html_file << EOF
<!DOCTYPE html>
<html>
<head>DNS监控报告</title>
    <style>
        table { border-collapse: collapse; width: 100%; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        .OK { color: green; }
        .FAIL { color: red; }
        .CHANGED { color: orange; }
    </style>
</head>
<body>
    <h1>DNS监控报告 - $(date)</h1>
    <table>
        <tr>
            <th>状态</th>
            <th>域名</th>
            <th>当前解析</th>
            <th>期望解析</th>
        </tr>
EOF
    while IFS='|' read -r status domain ip_info; do
        [ "$status" = "===" ] && continue
        echo "<tr class='$status'>" >> $html_file
        echo "<td>$status</td>" >> $html_file
        echo "<td>$domain</td>" >> $html_file
        echo "<td>$ip_info</td>" >> $html_file
        echo "</tr>" >> $html_file
    done < $RESULT_FILE
    echo "</table></body></html>" >> $html_file
    echo "HTML报告已生成: $html_file"
}
# 主函数
main() {
    check_all_domains
    # 检查是否有异常
    if grep -q "FAIL\|CHANGED" $RESULT_FILE; then
        echo "发现DNS异常,发送告警..."
        generate_html_report
        # 发送邮件通知
        # mail -s "DNS监控告警" $ALERT_EMAIL < $RESULT_FILE
    else
        echo "所有域名解析正常"
    fi
}
main

支持CNAME和MX记录的监控

#!/bin/bash
# 监控多种DNS记录类型
monitor_all_records() {
    local domain="example.com"
    echo "=== DNS记录监控 ==="
    echo "域名: $domain"
    echo "检查时间: $(date)"
    echo "------------------------"
    # 检查A记录
    echo "A记录:"
    dig +short A $domain
    # 检查AAAA记录(IPv6)
    echo "AAAA记录 (IPv6):"
    dig +short AAAA $domain
    # 检查CNAME记录
    echo "CNAME记录:"
    dig +short CNAME $domain
    # 检查MX记录
    echo "MX记录:"
    dig +short MX $domain | sort
    # 检查NS记录
    echo "NS记录:"
    dig +short NS $domain | sort
    # 检查TXT记录
    echo "TXT记录:"
    dig +short TXT $domain
    echo "------------------------"
}
# 检测DNS记录变更
detect_dns_changes() {
    local domain=$1
    local record_type=${2:-"A"}
    local history_file="/tmp/dns_history_${domain}_${record_type}.txt"
    # 获取当前记录
    current_record=$(dig +short $record_type $domain | sort | tr '\n' ' ')
    # 检查历史文件
    if [ -f "$history_file" ]; then
        previous_record=$(cat $history_file)
        if [ "$current_record" != "$previous_record" ]; then
            echo "检测到 $domain 的 $record_type 记录变更!"
            echo "之前: $previous_record"
            echo " $current_record"
            # 更新历史记录
            echo "$current_record" > $history_file
            return 1
        fi
    else
        # 首次运行,保存记录
        echo "$current_record" > $history_file
        echo "初始化 $domain 的 $record_type 记录: $current_record"
    fi
    return 0
}
# 使用示例
monitor_all_records
detect_dns_changes "example.com" "A"
detect_dns_changes "example.com" "MX"

系统服务化配置

创建systemd服务文件 /etc/systemd/system/dns-monitor.service:

[Unit]
Description=DNS Monitoring Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/dns_monitor.sh
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target

启用服务:

sudo systemctl daemon-reload
sudo systemctl enable dns-monitor
sudo systemctl start dns-monitor

使用建议

  1. 增强可靠性:使用多个DNS服务器
  2. 缓存策略:注意本地DNS缓存
  3. 告警机制:集成邮件、Slack、钉钉等通知
  4. 日志管理:实施日志轮转策略
  5. 性能优化:使用超时控制

这些脚本可以根据实际需求进行定制和扩展。

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