DNS解析检测与告警脚本

代码脚本 · 网络

检测多个域名的DNS解析是否正常,对比解析结果是否符合预期,检测DNS污染或解析异常,支持多个DNS服务器对比

详细内容

#!/bin/bash # ========================================== # DNS解析检测与告警脚本 # 用途:检测域名DNS解析是否正常,对比预期IP # 使用方法:bash dns_check.sh # ========================================== # ========== 配置 ========== # 检测列表:域名|预期IP(多个用逗号分隔,留空只检测是否能解析) DOMAINS=( "www.baidu.com|180.101.50.242,180.101.50.188" "www.aliyun.com|" "github.com|" # "api.example.com|1.2.3.4" ) DNS_SERVERS=("223.5.5.5" "114.114.114.114" "8.8.8.8") RESOLVE_TIMEOUT=5 LOG_FILE="/var/log/dns_check.log" ALERT_EMAIL="" WECOM_WEBHOOK="" # ========================== mkdir -p "$(dirname "$LOG_FILE")" log_msg() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } send_alert() { local title="$1" local content="$2" log_msg "【告警】$title: $content" if [ -n "$ALERT_EMAIL" ]; then echo -e "$content" | mail -s "【DNS告警】$title" "$ALERT_EMAIL" 2>/dev/null fi if [ -n "$WECOM_WEBHOOK" ]; then curl -s "$WECOM_WEBHOOK" -H "Content-Type: application/json" -d "{ "msgtype": "text", "text": {"content": "【DNS告警】$title\n$content"} }" >/dev/null 2>&1 fi } resolve_domain() { local domain="$1" local dns_server="$2" if command -v dig >/dev/null 2>&1; then dig +short +time="$RESOLVE_TIMEOUT" "@$dns_server" "$domain" A 2>/dev/null | grep -E "^[0-9]+\." | sort elif command -v nslookup >/dev/null 2>&1; then nslookup -timeout="$RESOLVE_TIMEOUT" "$domain" "$dns_server" 2>/dev/null | grep -A10 "Name:" | grep "Address:" | awk '{print $2}' | sort else getent hosts "$domain" 2>/dev/null | awk '{print $1}' | sort fi } log_msg "==========================================" log_msg " DNS解析检测报告" log_msg " 检测时间: $(date '+%Y-%m-%d %H:%M:%S')" log_msg "==========================================" ALL_OK=true for item in "${DOMAINS[@]}"; do domain=$(echo "$item" | cut -d'|' -f1) expected_ips=$(echo "$item" | cut -d'|' -f2) log_msg "" log_msg "【$domain】" ALL_IPS="" DNS_RESULTS="" for dns in "${DNS_SERVERS[@]}"; do ips=$(resolve_domain "$domain" "$dns") if [ -z "$ips" ]; then log_msg " 🔴 DNS $dns: 解析失败" DNS_RESULTS="$DNS_RESULTS $dns: 解析失败" ALL_OK=false else ip_list=$(echo "$ips" | tr '\n' ',' | sed 's/,$//') log_msg " 🟢 DNS $dns: $ip_list" DNS_RESULTS="$DNS_RESULTS $dns: $ip_list" ALL_IPS="$ALL_IPS $ips" fi done # 检查不同DNS解析结果是否一致 UNIQUE_IPS=$(echo "$ALL_IPS" | tr ' ' '\n' | grep -v '^$' | sort -u) UNIQUE_COUNT=$(echo "$UNIQUE_IPS" | grep -c .) if [ "$UNIQUE_COUNT" -gt 1 ]; then log_msg " ⚠️ 不同DNS解析结果不一致: $(echo "$UNIQUE_IPS" | tr '\n' ',')" send_alert "$domain DNS解析不一致" "不同DNS服务器解析结果不同:\n$DNS_RESULTS" ALL_OK=false fi # 对比预期IP if [ -n "$expected_ips" ]; then MATCH=false for expected in $(echo "$expected_ips" | tr ',' ' '); do if echo "$UNIQUE_IPS" | grep -q "^${expected}$"; then MATCH=true break fi done if [ "$MATCH" = false ]; then log_msg " 🔴 解析结果与预期不符!预期: $expected_ips 实际: $(echo "$UNIQUE_IPS" | tr '\n' ',')" send_alert "$domain DNS解析异常" "解析结果与预期不符!\n预期IP: $expected_ips\n实际IP: $(echo "$UNIQUE_IPS" | tr '\n' ',')\n可能存在DNS污染或解析错误" ALL_OK=false else log_msg " ✅ 解析结果与预期一致" fi fi done log_msg "" if [ "$ALL_OK" = true ]; then log_msg "✅ 所有域名DNS解析正常" else log_msg "❌ 存在DNS解析异常,请查看上方告警" fi log_msg "=========================================="

适配环境

适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+

依赖环境:bash 4.0+

参数说明

[{"name": "DOMAINS", "label": "\u57df\u540d\u5217\u8868(\u6bcf\u884c\u4e00\u4e2a\uff0c\u683c\u5f0f\uff1a\u57df\u540d|\u9884\u671fIP)", "type": "textarea", "default": "www.baidu.com|\nwww.aliyun.com|"}, {"name": "DNS_SERVERS", "label": "DNS\u670d\u52a1\u5668(\u7a7a\u683c\u5206\u9694)", "default": "223.5.5.5 114.114.114.114 8.8.8.8"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1(\u53ef\u9009)", "default": ""}]
DNS解析检测域名监控告警

更多网络