DNS(Domain Name System)是域名系统,将人类可读的域名(如 example.com)转换为机器可读的 IP 地址(如 93.184.216.34)。
根域 (.) | +------+------+------+ | | | | com edu net org | +--+--+--+ | | | | google baidu yahoo example
用户访问 www.example.com 的完整流程:
浏览器 → 查找本地 DNS 缓存 → 找到则返回,未找到继续
# Linux/Mac cat /etc/hosts # Windows type C:\Windows\System32\drivers\etc\hosts
操作系统 → 向本地 DNS 服务器(ISP 提供)发送查询
本地 DNS → 根服务器 (.) ↓ 不知道,返回 com 服务器地址 本地 DNS → com 服务器 ↓ 不知道,返回 example.com 服务器地址 本地 DNS → example.com 服务器 ↓ 返回 www.example.com 的 IP 地址
客户端发送查询,DNS 服务器负责返回最终结果。
客户端依次查询多个 DNS 服务器。
www.example.com. IN A 93.184.216.34
www.example.com. IN AAAA 2606:2800:220:1:248:1893:25c8:1946
www.example.com. IN CNAME example.com.
example.com. IN MX 10 mail.example.com.
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
example.com. IN NS ns1.example.com.
@ IN SOA ns1.example.com. admin.example.com. ( 2024010101 ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum @ IN NS ns1.example.com. @ IN NS ns2.example.com. @ IN A 93.184.216.34 @ IN AAAA 2606:2800:220:1:248:1893:25c8:1946 www IN A 93.184.216.34 mail IN A 93.184.216.35 @ IN MX 10 mail.example.com. @ IN TXT "v=spf1 mx -all"
TTL(Time To Live)设置:
缓存策略:
<!-- HTML 中预解析 DNS --> <link rel="dns-prefetch" href="https://cdn.example.com"> <link rel="preconnect" href="https://api.example.com">
// 浏览器自动预解析 window.performance.getEntriesByType('dns').forEach(entry => { console.log('DNS lookup:', entry.name, entry.duration); });
原理:多个地理位置的 DNS 服务器使用相同的 IP 地址。
用户 → 最近的 DNS 服务器(基于 BGP 路由)
优势:
1. 用户请求 www.example.com 2. DNS 解析到 CDN 节点 IP 3. CDN 节点检查缓存 4. 缓存命中则直接返回 5. 缓存未命中则从源站获取并缓存
基于地理位置的 DNS 解析:
def smart_dns_resolver(client_ip): # 根据 IP 判断地理位置 location = geoip_lookup(client_ip) # 返回最近的 CDN 节点 if location in ['Beijing', 'Tianjin', 'Hebei']: return '1.2.3.4' # 华北节点 elif location in ['Shanghai', 'Jiangsu', 'Zhejiang']: return '5.6.7.8' # 华东节点 else: return '9.10.11.12' # 默认节点
攻击方式:
防护措施:
原理:使用数字签名验证 DNS 响应的真实性。
@ IN SOA ns1.example.com. admin.example.com. ( 2024010101 ; Serial 3600 ; Refresh 1800 ; Retry 604800 ; Expire 86400 ) ; Minimum @ IN NS ns1.example.com. @ IN DNSKEY 256 3 13 ( AQIDBAUGBwgJ... ) ; ZSK @ IN DNSKEY 257 3 13 ( AQIDBAUGBwgJ... ) ; KSK www IN A 93.184.216.34 IN RRSIG A 13 2 3600 ( 20240101000000 20240110000000 12345 example.com. ABI2C4RA6D4... )
配置示例:
# 使用 Cloudflare DoH https://1.1.1.1/dns-query # 使用 Google DoH https://8.8.8.8/dns-query
@ IN A 1.2.3.4 @ IN A 5.6.7.8 @ IN A 9.10.11.12
@ IN A 1.2.3.4 ; 权重 1 @ IN A 5.6.7.8 ; 权重 2 @ IN A 5.6.7.8 ; 重复增加权重 @ IN A 9.10.11.12 ; 权重 1
# 使用 GeoDNS 库 from geoip import geolite2 from dns import resolver def geo_dns_handler(query): client_ip = query.client_address location = geolite2.lookup(client_ip) if location.country == 'CN': return '1.2.3.4' # 中国服务器 elif location.country == 'US': return '5.6.7.8' # 美国服务器 else: return '9.10.11.12' # 默认服务器
# 基本 DNS 查询 dig example.com # 查询特定记录类型 dig example.com MX dig example.com TXT # 查询并显示完整过程 dig +trace example.com # 指定 DNS 服务器 dig @8.8.8.8 example.com # 反向查询 dig -x 93.184.216.34
# Windows 工具 nslookup example.com # 指定 DNS 服务器 nslookup example.com 8.8.8.8 # 查询特定记录 nslookup -type=MX example.com
# 简单查询 host example.com # 详细信息 host -v example.com # 反向查询 host 93.184.216.34
import time import socket def measure_dns_latency(domain, dns_server='8.8.8.8'): start = time.time() try: socket.getaddrinfo(domain, 80) latency = (time.time() - start) * 1000 return latency except socket.gaierror: return None # 使用示例 latency = measure_dns_latency('www.example.com') print(f"DNS latency: {latency:.2f}ms")
from collections import defaultdict class DNSMonitor: def __init__(self): self.cache_hits = 0 self.cache_misses = 0 def record_query(self, cached): if cached: self.cache_hits += 1 else: self.cache_misses += 1 def cache_hit_rate(self): total = self.cache_hits + self.cache_misses if total == 0: return 0 return self.cache_hits / total # 使用示例 monitor = DNSMonitor() monitor.record_query(cached=True) monitor.record_query(cached=False) print(f"Cache hit rate: {monitor.cache_hit_rate():.2%}")
记录类型 推荐 TTL A/AAAA 300-3600s MX 3600-86400s TXT 300-3600s NS 86400-172800s SOA 86400s
@ IN NS ns1.example.com. @ IN NS ns2.example.com. @ IN NS ns3.example.com. ns1 IN A 1.2.3.4 ns2 IN A 5.6.7.8 ns3 IN A 9.10.11.12
#!/bin/bash # DNS 健康检查脚本 DOMAINS=("example.com" "google.com" "baidu.com") DNS_SERVERS=("8.8.8.8" "1.1.1.1") for domain in "${DOMAINS[@]}"; do for dns in "${DNS_SERVERS[@]}"; do if dig @$dns $domain +time=2 > /dev/null 2>&1; then echo "✓ $domain via $dns: OK" else echo "✗ $domain via $dns: FAILED" fi done done
DNS 是互联网的基础设施:
良好的 DNS 配置可以显著提升应用性能和用户体验!