本文目录导读:

- 核心检测逻辑
- 方案一:Shell 脚本(Linux/macOS 环境)
- 方案二:Python 脚本(跨平台,更灵活)
- 方案三:PowerShell(Windows 环境)
- 方案四:使用现成的监控工具(不写脚本)
- 高级自动化场景与技巧
在脚本中实现DNS解析检测的自动化,通常是为了监控域名解析的正确性、响应时间、或检测是否存在DNS劫持、污染等问题。
根据你的使用场景(Linux Shell、Python、Windows Batch/PowerShell),以下是几种常见的自动化实现方案:
核心检测逻辑
无论使用什么语言,自动化DNS检测通常包括:
- 解析域名:将域名转换为IP地址。
- 比对结果:与预期的IP地址或正则表达式进行比对。
- 记录结果:输出成功/失败,记录响应时间。
- 触发告警:当检测到异常时,执行后续操作(如发邮件、重启服务、切换DNS)。
Shell 脚本(Linux/macOS 环境)
适合服务器本地监控、Cron定时任务。
场景:检测域名是否解析到正确的IP地址
#!/bin/bash
# 配置区域
DOMAIN="example.com"
EXPECTED_IP="1.2.3.4"
DNS_SERVER="8.8.8.8" # 可选,不指定用系统默认
LOG_FILE="/var/log/dns_check.log"
# 1. 使用 dig 命令解析(推荐,信息更详细)
RESOLVED_IP=$(dig +short "$DOMAIN" @$DNS_SERVER | tail -n1)
# 或者使用 host 命令
# RESOLVED_IP=$(host "$DOMAIN" $DNS_SERVER | grep "has address" | awk '{print $4}')
# 2. 检测是否为空(解析失败)
if [ -z "$RESOLVED_IP" ]; then
echo "$(date) - ERROR: DNS resolution failed for $DOMAIN" >> $LOG_FILE
# 这里可以触发告警, curl -X POST https://alert.manager ...
exit 1
fi
# 3. 比对IP
if [ "$RESOLVED_IP" == "$EXPECTED_IP" ]; then
echo "$(date) - OK: $DOMAIN -> $RESOLVED_IP" >> $LOG_FILE
else
echo "$(date) - MISMATCH: Expected $EXPECTED_IP, but got $RESOLVED_IP for $DOMAIN" >> $LOG_FILE
# 触发告警
fi
# 4. (可选) 检测解析耗时
# RESOLVE_TIME=$(dig +time=5 +tries=1 "$DOMAIN" @$DNS_SERVER | grep "Query time:" | awk '{print $4}')
# if [ "$RESOLVE_TIME" -gt 500 ]; then
# echo "$(date) - SLOW: Resolution took ${RESOLVE_TIME}ms for $DOMAIN" >> $LOG_FILE
# fi
自动化执行:
# 添加到 crontab,每5分钟执行一次 */5 * * * * /path/to/your_dns_check_script.sh
Python 脚本(跨平台,更灵活)
Python拥有强大的库,适合复杂逻辑、多域名批量检测、结果分析。
场景:批量检测多个域名,分析响应时间
#!/usr/bin/env python3
import dns.resolver
import time
import json
import logging
# 配置区域
DOMAINS = ["google.com", "github.com", "your-own-app.com"]
EXPECTED_IPS = {
"google.com": ["142.250.80.142", "142.250.80.132"], # 允许存在多个IP
"github.com": ["140.82.121.3"],
}
DNS_SERVERS = ["8.8.8.8", "1.1.1.1"]
TIMEOUT = 2 # 秒
logging.basicConfig(filename='dns_check.log', level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s')
def check_dns(domain, expected_ips, dns_servers):
resolver = dns.resolver.Resolver()
resolver.nameservers = dns_servers
resolver.timeout = TIMEOUT
resolver.lifetime = TIMEOUT
try:
start = time.time()
answers = resolver.resolve(domain, 'A')
elapsed = (time.time() - start) * 1000 # ms
resolved_ips = [str(answer) for answer in answers]
logging.info(f"Check {domain}: Resolved to {resolved_ips} in {elapsed:.2f}ms")
# 比对
if expected_ips:
# 检查解析出的IP是否在预期IP列表内
match = any(ip in expected_ips for ip in resolved_ips)
if match:
logging.info(f"Result: MATCH for {domain}")
return True
else:
logging.warning(f"Result: MISMATCH for {domain}. Expected {expected_ips}, Got {resolved_ips}")
return False
else:
# 未配置预期IP,仅检查是否能解析成功
logging.info(f"Result: RESOLVED for {domain} (no expected IP configured)")
return True
except dns.resolver.NoAnswer:
logging.error(f"Result: FAIL - No answer for {domain}")
return False
except dns.resolver.NXDOMAIN:
logging.error(f"Result: FAIL - Domain {domain} does not exist")
return False
except dns.exception.Timeout:
logging.error(f"Result: FAIL - Timeout resolving {domain}")
return False
except Exception as e:
logging.error(f"Result: FAIL - Exception: {e}")
return False
# 主循环
if __name__ == "__main__":
results = {}
for domain in DOMAINS:
result = check_dns(domain, EXPECTED_IPS.get(domain), DNS_SERVERS)
results[domain] = result
# 汇总报告
failures = [k for k, v in results.items() if not v]
if failures:
logging.error(f"Summary: Failed domains: {failures}")
# 此处可调用 webhook 发送告警
# import requests
# requests.post("https://hooks.slack.com/...", json={"text": f"DNS Check Failed: {failures}"})
else:
logging.info("Summary: All checks passed.")
安装依赖:
pip install dnspython
自动化执行:
# 使用 systemd timer 或 crontab 定时执行 python 脚本 # * * * * * /usr/bin/python3 /path/to/dns_check.py
PowerShell(Windows 环境)
场景:单域名检测,输出到 Windows 事件日志
# 配置
$Domain = "example.com"
$ExpectedIP = "1.2.3.4"
$DnsServer = "8.8.8.8"
# 1. 解析 DNS
$Result = Resolve-DnsName -Name $Domain -Server $DnsServer -Type A -ErrorAction SilentlyContinue
if ($Result -eq $null) {
Write-EventLog -LogName Application -Source "DNS Monitor" -EventId 1001 -EntryType Error -Message "DNS resolution failed for $Domain"
Exit 1
}
$ResolvedIP = $Result.IPAddress
# 2. 比对
if ($ResolvedIP -eq $ExpectedIP) {
Write-EventLog -LogName Application -Source "DNS Monitor" -EventId 1000 -EntryType Information -Message "DNS OK: $Domain -> $ResolvedIP"
} else {
Write-EventLog -LogName Application -Source "DNS Monitor" -EventId 1002 -EntryType Error -Message "DNS Mismatch for $Domain. Expected $ExpectedIP, Got $ResolvedIP"
}
自动化执行:
- 使用 Windows Task Scheduler 定时执行 PS1 脚本。
使用现成的监控工具(不写脚本)
如果你不想维护脚,可以考虑将这些逻辑集成到成熟的监控系统中:
-
Prometheus + Blackbox Exporter:
- 支持
dns_probe模块,可以配置预期响应。 - 可以自动生成时间序列数据,便于 Grafana 可视化。
- 支持告警规则 (Alertmanager)。
- 支持
-
Zabbix:
- 自带
dns类型的监控项(net.dns)。 - 可以设置触发器,当解析失败或IP不符时报警。
- 自带
-
Nagios/Icinga:
- 使用
check_dns插件。
- 使用
高级自动化场景与技巧
-
检测 DNS 劫持/污染:
- 对比法:同时向多个公共DNS(如
8.8.8、114.114.114、本地DNS)发起查询。 - 如果本地DNS结果与公共DNS结果不一致,且本地返回的IP是广告页面或非预期IP,则说明可能被劫持。
- 脚本逻辑:分别解析,
set运算对比。
# Python 示例 local_result = set(["1.1.1.1"]) public_result = set(["2.2.2.2", "3.3.3.3"]) if local_result != public_result: print("Suspicious: Possible DNS Hijacking detected!") - 对比法:同时向多个公共DNS(如
-
DNSSEC 验证:
- 使用
dig example.com +dnssec检查ad(authentic data) 标志位。 - 在 Python 中,使用
dns.resolver的dnssec参数。
- 使用
-
大规模域名 / CNAME 链检测:
- 递归解析 CNAME,直到获得 A/AAAA 记录。
- 检查整个解析链是否指向正确的 CDN 或云服务商。
-
结果存储与可视化:
- 将每次检测的
域名、IP、耗时、状态、时间戳写入数据库 (InfluxDB, MySQL)。 - 搭建一个简易的 Flask 页面展示历史趋势。
- 将每次检测的
- 简单快速:用 Shell +
dig。 - 灵活可扩展:用 Python +
dnspython。 - Windows 集成:用 PowerShell。
- 生产环境监控:用 Prometheus + Blackbox Exporter 或 Zabbix。
始终建议进行“预期值比对”,而不仅仅是“是否能解析”,这样可以发现重定向、劫持或配置错误。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播