服务器运维笔记(03):DNS 与域名管理
DNS(Domain Name System)是互联网的"电话簿"——它把人类可读的域名翻译成机器可读的 IP 地址。对于服务器运维工程师来说,DNS 不仅是"能用就行"的基础配置,更是影响可用性、性能和安全的关键基础设施。
本篇从原理到实战,系统梳理 DNS 与域名管理的核心知识。
一、DNS 基础
1.1 DNS 查询流程
一次完整的 DNS 解析经历以下路径:
客户端 → 本地缓存 → 递归解析器 → 根域名服务器 → TLD 服务器 → 权威域名服务器 → 返回结果1.2 递归查询 vs 迭代查询
实际观察递归查询过程:
# 使用 dig +trace 追踪完整解析链路
dig +trace example.com
# 输出示例:
# . 518400 IN NS a.root-servers.net.
# com. 172800 IN NS a.gtld-servers.net.
# example.com. 172800 IN NS a.iana-servers.net.
# example.com. 86400 IN A 93.184.216.341.3 权威域名服务器
权威服务器是某个域名的"官方数据源",存储该域名的原始 DNS 记录。
# 查询某个域名的权威 NS 记录
dig NS example.com +short
# a.iana-servers.net.
# b.iana-servers.net.
# 直接向权威服务器查询(绕过缓存)
dig @a.iana-servers.net example.com A1.4 DNS 缓存机制
DNS 缓存存在于多个层级,由 TTL(Time To Live)控制有效期:
# 清除本地 DNS 缓存
# macOS
sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder
# Windows
ipconfig /flushdns
# systemd-resolved(Ubuntu 18.04+)
sudo systemd-resolve --flush-caches
# 查看缓存统计
sudo systemd-resolve --statistics二、记录类型详解
2.1 A 记录 —— IPv4 地址映射
将域名指向一个 IPv4 地址,是最基础的 DNS 记录。
# 查询 A 记录
dig A example.com +short
# 93.184.216.34
# 配置示例(BIND zone 文件)
# example.com. IN A 93.184.216.34
# www IN A 93.184.216.342.2 AAAA 记录 —— IPv6 地址映射
# 查询 AAAA 记录
dig AAAA example.com +short
# 2606:2800:220:1:248:1893:25c8:1946
# 配置示例
# example.com. IN AAAA 2606:2800:220:1:248:1893:25c8:19462.3 CNAME 记录 —— 别名
将一个域名指向另一个域名,最终解析到目标域名的 A/AAAA 记录。
# 查询 CNAME
dig CNAME blog.example.com +short
# example.github.io.
# ⚠️ 注意:CNAME 不能与其他记录共存(同一名称下)
# 错误示例:blog.example.com 同时有 CNAME 和 MX 记录
# RFC 规定 CNAME 与其他记录互斥,但 ALIAS/ANAME 可以规避此限制常见用途:
# CDN 加速域名
cdn.example.com CNAME cdn.provider.com.
# 第三方服务验证
_sip._tcp.example.com SRV ...
# GitHub Pages
www.example.com CNAME username.github.io.2.4 MX 记录 —— 邮件交换
指定负责处理该域名邮件的服务器,带有优先级。
# 查询 MX 记录
dig MX example.com +short
# 10 mail.example.com.
# 20 mail2.example.com.
# 配置示例
# example.com. IN MX 10 mail.example.com.
# example.com. IN MX 20 mail2.example.com.
# 测试邮件服务器连通性
telnet mail.example.com 25常见邮件服务商 MX 配置:
2.5 TXT 记录 —— 文本信息
用于域名验证、SPF、DKIM、DMARC 等。
# SPF 记录(防止邮件伪造)
# example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
# DKIM 记录
# google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGf..."
# DMARC 记录
# _dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"
# 域名所有权验证(常见服务商)
# _dnsauth.example.com. IN TXT "202306101200005abc..."2.6 SRV 记录 —— 服务发现
指定特定服务的主机和端口,格式为 _service._proto.domain。
# 查询 SRV 记录
dig SRV _sip._tcp.example.com +short
# 10 60 5060 sip1.example.com.
# 20 60 5060 sip2.example.com.
# 格式:优先级 权重 端口 目标主机
# _sip._tcp.example.com. IN SRV 10 60 5060 sip1.example.com.2.7 NS 记录 —— 域名服务器
指定该域名由哪些 DNS 服务器解析。
dig NS example.com +short
# a.iana-servers.net.
# b.iana-servers.net.2.8 SOA 记录 —— 起始授权
每个 DNS 区域的核心记录,包含序列号、刷新间隔等管理信息。
dig SOA example.com +short
# a.iana-servers.net. hostmaster.iana.org. 2023061001 3600 900 604800 86400
# 字段含义:
# 主DNS 管理员邮箱 序列号 刷新间隔 重试间隔 过期时间 最小TTL2.9 CAA 记录 —— 证书颁发机构授权
限制哪些 CA 可以为该域名签发证书,提升 TLS 安全性。
# 查询 CAA 记录
dig CAA example.com +short
# 0 issue "letsencrypt.org"
# 0 issuewild "letsencrypt.org"
# 0 iodef "mailto:security@example.com"
# 配置示例
# example.com. IN CAA 0 issue "letsencrypt.org" # 允许签发
# example.com. IN CAA 0 issuewild "letsencrypt.org" # 允许通配符签发
# example.com. IN CAA 0 iodef "mailto:ca-alerts@example.com" # 违规通知2.10 PTR 记录 —— 反向解析
将 IP 地址映射回域名,常用于邮件服务器验证。
# 反向解析查询
dig -x 93.184.216.34 +short
# example.com.
# ⚠️ PTR 记录需要在 IP 所属的 ISP/托管商处配置,不能在域名 DNS 面板设置
# 配置方式:在云服务器控制台的"反向解析"或"rDNS"功能中设置三、常见 DNS 服务商配置
3.1 阿里云 DNS
配置要点:
# 1. 域名添加后,需将 NS 记录修改为阿里云分配的 DNS 服务器
# 例如:dns1.hichina.com / dns2.hichina.com
# 2. 添加解析记录示例
# 主机记录: www
# 记录类型: A
# 记录值: 47.100.1.1
# TTL: 600
# 3. 智能解析(按运营商/地域分线路)
# 默认线路: 47.100.1.1(阿里云 ECS)
# 电信线路: 114.114.1.1
# 联通线路: 202.106.0.1
# 4. API 操作(阿里云 OpenAPI)
# 安装 SDK
pip install alibabacloud-alidns20150109API 自动化示例:
# 通过 API 自动更新动态 DNS 记录
from alibabacloud_alidns20150109.client import Client
from alibabacloud_alidns20150109 import models
config = Config(
access_key_id="YOUR_AK",
access_key_secret="YOUR_SK",
endpoint="alidns.cn-hangzhou.aliyuncs.com"
)
client = Client(config)
# 更新 A 记录
request = models.UpdateDomainRecordRequest(
record_id="12345678",
RR="www",
type="A",
value="47.100.1.2"
)
client.update_domain_record(request)3.2 腾讯云 DNS
控制台: console.cloud.tencent.com/cns
配置要点:
# 1. NS 修改:指向腾讯云 DNSPod 服务器
# f1g1ns1.dnspod.net / f1g1ns2.dnspod.net
# 2. 记录管理(控制台)
# 主机记录: @ 记录类型: A 记录值: 1.2.3.4 TTL: 600
# 主机记录: www 记录类型: CNAME 记录值: example.com TTL: 600
# 3. DNSPod 特色功能
# - 子域名递归解析
# - URL 转发(显性/隐性)
# - 搜索引擎推送
# 4. API 操作
pip install tencentcloud-sdk-python-dnspodAPI 自动化示例:
from tencentcloud.dnspod.v20210323 import dnspod_client, models
import json
cred = credential.Credential("SecretId", "SecretKey")
client = dnspod_client.DnspodClient(cred, "ap-guangzhou")
# 修改记录
req = models.ModifyRecordRequest()
req.Domain = "example.com"
req.RecordId = 12345678
req.RecordType = "A"
req.RecordLine = "默认"
req.Value = "1.2.3.5"
client.ModifyRecord(req)3.3 Cloudflare DNS
控制台: dash.cloudflare.com
配置要点:
# 1. 添加站点后,Cloudflare 会分配两个 NS 服务器
# 例如:aria.ns.cloudflare.com / ben.ns.cloudflare.com
# 2. 代理模式(橙色云朵 vs 灰色云朵)
# 🟠 橙色云朵:流量经过 Cloudflare 代理(CDN/WAF/DDoS 防护)
# ⚪ 灰色云朵:仅 DNS 解析,不经过代理
# 3. Cloudflare 独有功能
# - CNAME Flattening(根域名 CNAME 支持)
# - Page Rules(基于 URL 的 DNS 策略)
# - DNSSEC 一键开启
# - Argo Smart Routing(智能路由加速)
# 4. API 操作
# 获取 Zone ID
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json"
# 添加 A 记录
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "A",
"name": "www",
"content": "1.2.3.4",
"ttl": 600,
"proxied": true
}'3.4 三家服务商对比
四、CDN 接入与 CNAME 配置
4.1 CDN 接入原理
CDN 接入的核心是将域名通过 CNAME 指向 CDN 分配的加速域名,由 CDN 的 DNS 调度系统将用户引导至最近的边缘节点。
用户请求 → DNS 解析 www.example.com → CNAME → cdn.example.com → CDN 调度 → 最近节点 IP4.2 主流 CDN 接入配置
阿里云 CDN:
# 1. 添加加速域名:www.example.com
# 2. CDN 分配 CNAME:www.example.com.cdn.dnsv1.com
# 3. 在 DNS 中添加 CNAME 记录
# 主机记录: www
# 记录类型: CNAME
# 记录值: www.example.com.cdn.dnsv1.com
# 验证 CNAME 是否生效
dig CNAME www.example.com +short
# www.example.com.cdn.dnsv1.com.Cloudflare CDN(代理模式):
# Cloudflare 使用代理模式接入,不需要手动配置 CNAME
# 1. 添加 A 记录指向源站 IP
# www → 1.2.3.4(橙色云朵开启)
# 2. Cloudflare 自动代理流量
# 关闭代理(仅 DNS 模式)时,才需要 CNAME 指向第三方 CDN腾讯云 CDN:
# 1. 添加域名:www.example.com
# 2. 获取 CNAME:www.example.com.cdn.dnsv1.com
# 3. DNSPod 中配置:
# www → CNAME → www.example.com.cdn.dnsv1.com4.3 根域名(@)的 CDN 接入
根域名不能直接使用 CNAME(RFC 限制),解决方案:
# 方案一:使用 ALIAS/ANAME 记录(阿里云、DNSPod 支持)
# 记录类型: 显性URL / 隐性URL
# 记录值: https://www.example.com
# 方案二:Cloudflare CNAME Flattening
# Cloudflare 会将根域名的 CNAME "扁平化"为 A/AAAA 记录返回
# 方案三:使用 DNS 服务商的 ALIAS 记录
# 阿里云:将 @ 的 CNAME 记录改为 ALIAS 类型
# DNSPod:使用 @ 的 CNAME 记录(自动扁平化)
# 方案四:直接使用 A 记录指向 CDN Anycast IP五、DNS 负载均衡
5.1 加权轮询(Weighted Round Robin)
按权重比例分配流量到不同服务器。
# 阿里云加权轮询配置
# www A 记录值: 1.2.3.4 权重: 70 线路: 默认
# www A 记录值: 5.6.7.8 权重: 30 线路: 默认
# Cloudflare 负载均衡(Load Balancing 功能)
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/load_balancers" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
--data '{
"name": "www.example.com",
"fallback_pool": "pool-backup",
"default_pools": ["pool-primary", "pool-secondary"],
"steering_policy": "weighted",
"session_affinity": "cookie"
}'5.2 地理路由(GeoDNS)
根据用户所在地区返回不同的 IP 地址。
# PowerDNS GeoIP 配置示例(geoipbackend)
# /etc/pdns/geoip.yaml
domains:
- domain: example.com
ttl: 300
records:
www:
- a:
- 1.2.3.4 # 默认(亚洲)
- 5.6.7.8 # 欧洲
- 9.10.11.12 # 北美
- a:
default: 1.2.3.4
eu: 5.6.7.8
na: 9.10.11.12
cn: 47.100.1.1 # 中国阿里云智能解析(简化版 GeoDNS):
# 运营商线路解析
www A 47.100.1.1 线路: 电信
www A 119.29.1.1 线路: 联通
www A 101.226.1.1 线路: 移动
# 地域线路解析(付费版)
www A 47.100.1.1 线路: 华东
www A 119.29.1.1 线路: 华南
www A 101.226.1.1 线路: 华北5.3 故障转移(Failover)
当主服务器不可用时,自动切换到备用服务器。
# Cloudflare Load Balancing 健康检查配置
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/pools" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
--data '{
"name": "pool-primary",
"origins": [
{"name": "primary", "address": "1.2.3.4", "enabled": true},
{"name": "secondary", "address": "5.6.7.8", "enabled": true}
],
"minimum_origins": 1,
"monitor": {
"type": "https",
"expected_codes": "200",
"method": "GET",
"path": "/health",
"interval": 60,
"timeout": 5,
"retries": 2
}
}'
# DNS 服务商的故障转移(需付费支持)
# 阿里云:全局流量管理(GTM)
# 腾讯云:DNSPod 企业版 Failover简单的脚本实现(基于 DNS API 的故障转移):
#!/bin/bash
# health_check_failover.sh - 简易 DNS 故障转移脚本
PRIMARY="1.2.3.4"
BACKUP="5.6.7.8"
DOMAIN="www.example.com"
while true; do
if ! curl -sf --max-time 5 "http://${PRIMARY}/health" > /dev/null; then
echo "[$(date)] Primary down, switching to backup..."
# 调用 DNS API 切换记录(以阿里云为例)
aliyun alidns UpdateDomainRecord \
--RecordId "12345678" \
--RR "www" \
--Type "A" \
--Value "${BACKUP}"
fi
sleep 30
done六、DNSSEC 原理与配置
6.1 DNSSEC 工作原理
DNSSEC 通过数字签名保护 DNS 响应的完整性和真实性,防止 DNS 缓存投毒攻击。
信任链:
根域(.)→ 签发 → TLD(.com)→ 签发 → 域名(example.com)→ 签发 → 记录
关键记录:
- DNSKEY:存储公钥,用于验证签名
- RRSIG:资源记录签名,每条记录对应一个签名
- DS:Delegation Signer,父域存储的子域 DNSKEY 哈希
- NSEC/NSEC3:用于证明"域名不存在"(Authenticated Denial)6.2 Cloudflare DNSSEC 一键配置
# Cloudflare 配置 DNSSEC 最简单
# 1. 控制台:DNS → Settings → Enable DNSSEC
# 2. Cloudflare 自动生成密钥对
# 3. 在域名注册商处添加 DS 记录(Cloudflare 提供具体值)
# 通过 API 启用
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dnssec" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
--data '{"status": "active"}'
# 获取 DS 记录信息(添加到注册商)
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dnssec" \
-H "Authorization: Bearer YOUR_API_TOKEN"6.3 手动配置 DNSSEC(BIND)
# 1. 生成 ZSK(Zone Signing Key)
dnssec-keygen -a ECDSAP256SHA256 -n ZONE example.com
# 2. 生成 KSK(Key Signing Key)
dnssec-keygen -a ECDSAP256SHA256 -n ZONE -f KSK example.com
# 3. 将密钥包含到 zone 文件
# $INCLUDE "Kexample.com.+013+12345.key"
# $INCLUDE "Kexample.com.+013+67890.key"
# 4. 签名 zone 文件
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) \
-N INCREMENT -o example.com -t example.com.zone
# 5. 验证签名
dnssec-verify -o example.com example.com.zone.signed
# 6. 更新 BIND 配置,加载签名后的 zone 文件
# 7. 在注册商处添加 DS 记录
dnssec-dsfromkey -f Kexample.com.+013+67890.key example.com6.4 验证 DNSSEC
# 使用 dig 验证 DNSSEC
dig +dnssec example.com A
# 检查 DS 记录
dig DS example.com +short
# 使用在线工具验证
# https://dnssec-analyzer.verisignlabs.com/example.com
# https://dnsviz.net/d/example.com/dnssec/
# 使用 delv 工具深入验证
delv @8.8.8.8 example.com A +rtrace七、子域名管理策略
7.1 通配符域名
通配符(Wildcard)记录匹配所有未明确定义的子域名。
# 通配符 A 记录
# *.example.com IN A 1.2.3.4
# 测试通配符
dig test123.example.com +short
# 1.2.3.4
# ⚠️ 注意事项:
# 1. 通配符不会匹配已明确定义的子域名
# 2. 通配符只匹配一级子域名(*.example.com 不匹配 a.b.example.com)
# 3. 需要多级匹配时,每级都要单独配置通配符安全风险提醒:
# 通配符 + 泛解析可能导致子域名接管风险
# 攻击者可以通过 CNAME 指向已接管的第三方服务
# 建议:避免使用通配符,使用明确的子域名列表
# 使用 amass/subfinder 扫描暴露的子域名
amass enum -d example.com -o subdomains.txt
subfinder -d example.com -silent7.2 泛解析的实际应用
# 场景一:SaaS 平台多租户
# 每个租户分配子域名:tenant1.example.com, tenant2.example.com
# 使用通配符 + 应用层路由实现
# 场景二:开发环境
# *.dev.example.com → 开发服务器
# dev.example.com → 开发环境入口
# 场景三:短链接服务
# 通配符指向短链接服务器,应用层解析路径
# BIND 配置示例
# $ORIGIN example.com.
# * IN A 1.2.3.4
# @ IN A 1.2.3.4
# www IN A 1.2.3.5 # 明确定义,不受通配符影响7.3 多级子域管理
# 常见的子域名分层策略
# 主站: example.com
# 国家站: cn.example.com, us.example.com
# 环境: staging.example.com, dev.example.com
# 服务: api.example.com, app.example.com, admin.example.com
# 团队: team-a.dev.example.com, team-b.dev.example.com
# 子域名委派(将子域的 DNS 管理权限交给其他 DNS 服务器)
# dev.example.com. IN NS ns1.dev.internal.
# dev.example.com. IN NS ns2.dev.internal.
# 这样 dev 团队可以独立管理 *.dev.example.com7.4 子域名安全加固
# 1. 使用 CAA 记录限制证书颁发
# *.example.com IN CAA 0 issue "letsencrypt.org"
# 2. 定期扫描子域名
# 使用 crt.sh 查询证书透明度日志
curl -s "https://crt.sh/?q=%.example.com&output=json" | jq '.[].name_value' | sort -u
# 3. 监控新增子域名
# 设置告警:当发现新的 DNS 记录时通知八、DNS 诊断工具
8.1 dig —— DNS 查询瑞士军刀
# 基本查询
dig example.com A
# 指定 DNS 服务器
dig @8.8.8.8 example.com A
# 查询所有记录类型
dig example.com ANY
# 精简输出
dig example.com +short
# 追踪解析路径
dig example.com +trace
# 查看完整响应(包含 TTL、flags 等)
dig example.com +noall +answer +comments
# 批量查询
dig -f domains.txt +short
# 查询特定类(CH=Chaosnet, 用于查询 BIND 版本)
dig @ns1.example.com CH TXT version.bind
# TCP 查询(而非默认的 UDP)
dig example.com +tcp8.2 nslookup —— 交互式查询
# 交互模式
nslookup
> server 8.8.8.8
> set type=MX
> example.com
> exit
# 非交互模式
nslookup -type=MX example.com 8.8.8.8
nslookup -type=TXT example.com
# 反向解析
nslookup 93.184.216.348.3 host —— 简洁查询
# 基本查询
host example.com
# 查询特定类型
host -t MX example.com
host -t TXT example.com
# 反向解析
host 93.184.216.34
# 指定 DNS 服务器
host example.com 8.8.8.8
# 显示详细信息
host -v example.com8.4 whois —— 域名注册信息
# 查询域名注册信息
whois example.com
# 查询 IP 归属
whois 1.2.3.4
# 安装 whois
# Ubuntu/Debian
sudo apt install whois
# CentOS/RHEL
sudo yum install whois
# 过滤关键信息
whois example.com | grep -E "Name Server|Expiry|Registrar"8.5 DNS 传播检查
# 全球 DNS 传播检查在线工具
# https://www.whatsmydns.net/
# https://dnschecker.org/
# https://dns.google/query?name=example.com
# 使用脚本检查多个公共 DNS 的解析结果
#!/bin/bash
DOMAIN="example.com"
DNS_SERVERS=(
"8.8.8.8" # Google
"1.1.1.1" # Cloudflare
"223.5.5.5" # 阿里
"119.29.29.29" # 腾讯
"114.114.114.114" # 114DNS
"9.9.9.9" # Quad9
)
echo "=== DNS Propagation Check: $DOMAIN ==="
for dns in "${DNS_SERVERS[@]}"; do
result=$(dig @$dns $DOMAIN A +short 2>/dev/null | head -1)
printf "%-15s → %s\n" "$dns" "${result:-TIMEOUT}"
done输出示例:
=== DNS Propagation Check: example.com ===
8.8.8.8 → 93.184.216.34
1.1.1.1 → 93.184.216.34
223.5.5.5 → 93.184.216.34
119.29.29.29 → 93.184.216.34
114.114.114.114 → 93.184.216.34
9.9.9.9 → 93.184.216.348.6 其他实用工具
# dnstracer - 追踪完整解析路径
dnstracer example.com
# drill - dig 的现代替代(LDNS 工具包)
drill example.com @8.8.8.8
# dog - 更友好的 DNS 查询工具(Rust 编写)
dog example.com A @8.8.8.8
# dnsx - 快速批量 DNS 解析(ProjectDiscovery)
echo "example.com" | dnsx -a -resp
# massdns - 高性能批量 DNS 解析
massdns -r resolvers.txt -t A -o S domains.txt九、常见 DNS 问题排查
9.1 解析不生效
排查步骤:
# 步骤一:确认记录已正确添加
dig @ns1.your-dns.com example.com A +short
# 步骤二:检查 NS 记录是否已切换
dig NS example.com +short
# 步骤三:检查 TTL 和缓存
dig example.com A +noall +answer
# 查看 TTL 值,等待其过期后重试
# 步骤四:检查是否存在 CNAME 冲突
dig example.com ANY +noall +answer
# 步骤五:清除本地缓存
sudo systemd-resolve --flush-caches # Linux
sudo dscacheutil -flushcache # macOS常见原因:
1. NS 记录未生效(需等待 24-48 小时)
2. TTL 未过期,旧记录仍被缓存
3. CNAME 与其他记录冲突
4. 记录值格式错误(如末尾多了空格)
5. DNS 服务商配置未保存/未发布9.2 缓存污染
DNS 缓存污染(Cache Poisoning)是指恶意数据被注入 DNS 缓存。
# 检测方法:对比不同 DNS 服务器的解析结果
dig @8.8.8.8 example.com A +short
dig @1.1.1.1 example.com A +short
dig @114.114.114.114 example.com A +short
# 如果结果不一致,可能存在缓存污染
# 缓解措施:
# 1. 使用支持 DNSSEC 的 DNS 服务器
# 2. 使用 DNS over HTTPS (DoH) 或 DNS over TLS (DoT)
# 3. 部署本地 DNS 缓存(如 unbound)
# 配置 DoH(Cloudflare)
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1
DNSOverTLS=yes9.3 TTL 调优
# TTL 值选择参考
# 类型 推荐 TTL 说明
# 高频变更(迁移中) 60-300s 切换最快,但 DNS 查询量大
# 常规 Web 服务 600-3600s 平衡性能与灵活性
# 稳定服务(MX/NS) 86400s 变更频率低,减少查询
# CDN CNAME 300-600s 需要快速切换时
# 实际调优示例:迁移前降低 TTL
# 迁移前 72 小时:TTL 设置为 300
# 迁移完成后:TTL 恢复为 3600
# 这样可以确保切换后 5 分钟内全球生效TTL 与查询量的关系:
TTL=60 → 1440 次/天/客户端(高查询量,快速生效)
TTL=3600 → 24 次/天/客户端(低查询量,1小时生效)
TTL=86400 → 1 次/天/客户端(极低查询量,24小时生效)9.4 DNS 劫持
# DNS 劫持类型:
# 1. 运营商 DNS 劫持(插入广告、重定向)
# 2. 路由器 DNS 劫持(恶意修改路由器 DNS 设置)
# 3. 本地恶意软件修改 hosts 文件
# 检测方法
# 对比本地解析与权威服务器解析
dig @ns1.iana-servers.net example.com A +short # 权威结果
dig example.com A +short # 本地结果
# 检查 hosts 文件
cat /etc/hosts | grep example.com
# 防护措施
# 1. 使用加密 DNS(DoH/DoT)
# 2. 定期检查路由器 DNS 设置
# 3. 使用 VPN
# 配置 DoH 客户端
# 安装 cloudflared
cloudflared proxy-dns --port 5053 --upstream https://1.1.1.1/dns-query
# systemd-resolved 配置 DoT
# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com
DNSOverTLS=yes十、最佳实践
10.1 TTL 选择策略
┌─────────────────────────────────────────────────────────┐
│ TTL 选择决策树 │
├─────────────────────────────────────────────────────────┤
│ │
│ 是否在迁移/变更中? │
│ ├─ 是 → TTL = 60~300s │
│ └─ 否 → 是否使用 CDN/负载均衡? │
│ ├─ 是 → TTL = 300~600s │
│ └─ 否 → 是否为关键基础设施(MX/NS)? │
│ ├─ 是 → TTL = 3600~86400s │
│ └─ 否 → TTL = 600~3600s(默认) │
│ │
└─────────────────────────────────────────────────────────┘10.2 DNS 迁移步骤
# 完整的 DNS 迁移流程
# 阶段一:准备(T-7天)
# 1. 在新 DNS 服务商添加所有记录
# 2. 验证记录完整性(逐条比对)
# 3. 将 TTL 降低至 300s(在旧 DNS 服务商操作)
# 验证脚本
#!/bin/bash
OLD_DNS="old-ns.example.com"
NEW_DNS="new-ns.example.com"
DOMAINS=("example.com" "www.example.com" "api.example.com" "mail.example.com")
for domain in "${DOMAINS[@]}"; do
old=$(dig @$OLD_DNS $domain +short | sort)
new=$(dig @$NEW_DNS $domain +short | sort)
if [ "$old" = "$new" ]; then
echo "✅ $domain: 一致"
else
echo "❌ $domain: 不一致"
echo " 旧: $old"
echo " 新: $new"
fi
done
# 阶段二:切换(T=0)
# 4. 在域名注册商处修改 NS 记录
# 旧:dns1.old.com, dns2.old.com
# 新:ns1.new.com, ns2.new.com
# 阶段三:验证(T+1~2天)
# 5. 全球 NS 传播检查
dig NS example.com @8.8.8.8 +short
dig NS example.com @1.1.1.1 +short
# 6. 检查旧 DNS 服务器查询量是否归零
# 阶段四:收尾(T+7天)
# 7. 确认旧 DNS 无查询后,删除旧记录
# 8. 恢复正常 TTL(3600s 或更高)10.3 多 DNS 服务商容灾
# 方案一:多 NS 记录(最简单)
# example.com. IN NS ns1.primary-dns.com.
# example.com. IN NS ns2.primary-dns.com.
# example.com. IN NS ns1.backup-dns.com.
# example.com. IN NS ns2.backup-dns.com.
# DNS 查询会随机选择一个 NS 服务器,天然容灾
# 方案二:使用 DNS 服务商的 Anycast 网络
# Cloudflare:全球 300+ 节点
# 阿里云:全球 30+ 节点
# Anycast 网络本身具有容灾能力
# 方案三:DNS 区域传输(AXFR/IXFR)
# 在两个 DNS 服务商之间同步 zone 数据
# /etc/named.conf(主 DNS 服务器)
zone "example.com" {
type master;
file "example.com.zone";
allow-transfer { 1.2.3.4; }; # 备用 DNS 服务器 IP
also-notify { 1.2.3.4; };
};
# 方案四:使用 OctoDNS 管理多服务商
# pip install octodns
# octodns-sync --config-file=config.yamlOctoDNS 配置示例:
# config.yaml
providers:
cloudflare:
class: octodns_cloudflare.CloudflareProvider
token: YOUR_CLOUDFLARE_TOKEN
route53:
class: octodns_route53.Route53Provider
access_key_id: YOUR_AWS_KEY
secret_access_key: YOUR_AWS_SECRET
zones:
example.com.:
sources:
- config
targets:
- cloudflare
- route5310.4 DNS 安全加固清单
□ 启用 DNSSEC(防止缓存投毒)
□ 配置 CAA 记录(限制证书颁发)
□ 使用 DoH/DoT(加密 DNS 查询)
□ 配置 SPF/DKIM/DMARC(防止邮件伪造)
□ 定期扫描子域名(发现影子资产)
□ 监控 DNS 记录变更(及时发现异常)
□ 禁用不必要的区域传输(AXFR)
□ 使用强密码保护 DNS 管理账号
□ 启用双因素认证(2FA)
□ 审计 DNS 日志(发现异常查询)10.5 监控与告警
# DNS 监控脚本(定期检查解析状态)
#!/bin/bash
# dns_monitor.sh
DOMAINS=("example.com" "api.example.com" "www.example.com")
EXPECTED_IP="1.2.3.4"
ALERT_EMAIL="ops@example.com"
for domain in "${DOMAINS[@]}"; do
current_ip=$(dig +short $domain A @8.8.8.8 | head -1)
if [ "$current_ip" != "$EXPECTED_IP" ]; then
echo "[ALERT] $domain resolved to $current_ip (expected $EXPECTED_IP)" | \
mail -s "DNS Alert: $domain" $ALERT_EMAIL
fi
done
# crontab 配置(每 5 分钟执行一次)
# */5 * * * * /opt/scripts/dns_monitor.sh >> /var/log/dns_monitor.log 2>&1附录:速查表
常用 DNS 服务器
常用命令速查
# 查询
dig example.com A # A 记录
dig example.com MX # 邮件记录
dig example.com +trace # 追踪解析路径
dig @8.8.8.8 example.com +short # 指定 DNS 查询
# 反向解析
dig -x 1.2.3.4
# DNSSEC 验证
dig +dnssec example.com
# 区域传输
dig @ns1.example.com example.com AXFR
# 批量查询
dig -f domains.txt +short
# 在线工具
# https://dns.google/query
# https://www.whatsmydns.net
# https://dnsviz.net运维格言: DNS 是互联网中最容易被忽视、也最容易引发故障的基础设施。90% 的"网站打不开"问题,最终都指向 DNS。把 DNS 管理好,就是把运维的根基打牢。