mcpField
D
dns-management

dns-management

github.com/bagelhole云与 DevOps1.2k370 次安装23 周前更新
代码仓库

关于 dns-management

dns-management 是面向生产基础设施 DNS 配置与排障的技能,适合管理域名的工程师。内容涵盖多种 DNS 提供商、Terraform 配置、解析诊断及邮件安全记录。

主要功能

  1. 01管理 DNS 区域与记录
  2. 02提供 Route 53 和 Cloudflare 示例
  3. 03展示 Terraform DNS 配置
  4. 04使用 dig 和 nslookup 排障
  5. 05配置 DNSSEC 与邮件安全记录

适用场景

  1. 01为应用、API 和邮件配置域名
  2. 02迁移 DNS 提供商或整合区域
  3. 03排查解析失败与传播延迟
  4. 04设置 SPF、DKIM 和 DMARC

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill dns-management

安装后在 Claude Code 中输入/dns-management确认已加载。

详细介绍

DNS 管理

为生产基础设施配置和管理 DNS 区域、记录及解析。

适用场景

  • 为 Web 应用、API 和电子邮件设置域名。
  • 迁移 DNS 提供商或整合 DNS 区域。
  • 为 CDN、负载均衡器和云服务配置 DNS。
  • 排查解析失败、传播延迟或配置错误。
  • 配置 DNSSEC、SPF、DKIM 和 DMARC,以增强电子邮件安全性。

前提条件

  • 已通过域名注册商注册域名(Namecheap、Route53、Google Domains、Cloudflare)。
  • 可访问 DNS 提供商的控制面板或 API。
  • 已配置 AWS CLI(适用于 Route53 示例)。
  • 本地已安装 dig 和 nslookup(大多数操作系统均已包含)。

DNS 记录类型参考

类型用途示例值
AIPv4 地址93.184.216.34
AAAAIPv6 地址2606:2800:220:1:248:1893:25c8:1946
CNAME指向其他域名的别名www.example.com -> example.com
MX带优先级的邮件服务器10 mail.example.com
TXT任意文本(SPF、DKIM、验证)v=spf1 include:_spf.google.com ~all
NS权威名称服务器ns1.example.com
SRV服务位置(主机、端口、优先级)10 5 5060 sip.example.com
CAA证书颁发机构授权0 issue "letsencrypt.org"
PTR反向 DNS 查询34.216.184.93.in-addr.arpa

AWS Route 53

托管区域管理
# Create a hosted zone
aws route53 create-hosted-zone \
  --name example.com \
  --caller-reference "$(date +%s)"

# List hosted zones
aws route53 list-hosted-zones

# Get name servers for a zone (update at your registrar)
aws route53 get-hosted-zone --id Z1234567890ABC \
  --query 'DelegationSet.NameServers'
创建和管理记录
# Create an A record
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "app.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [{"Value": "93.184.216.34"}]
      }
    }]
  }'

# Create a CNAME record
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "www.example.com",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [{"Value": "example.com"}]
      }
    }]
  }'

# Create an alias record (no TTL, Route53-specific)
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "d1234567890.cloudfront.net",
          "EvaluateTargetHealth": false
        }
      }
    }]
  }'

# List records in a zone
aws route53 list-resource-record-sets --hosted-zone-id Z1234567890ABC

# Delete a record (Action: DELETE with exact match)
aws route53 change-resource-record-sets \
  --hosted-zone-id Z1234567890ABC \
  --change-batch '{
    "Changes": [{
      "Action": "DELETE",
      "ResourceRecordSet": {
        "Name": "old.example.com",
        "Type": "A",
        "TTL": 300,
        "ResourceRecords": [{"Value": "1.2.3.4"}]
      }
    }]
  }'
Route 53 运行状况检查
# Create a health check
aws route53 create-health-check --caller-reference "$(date +%s)" \
  --health-check-config '{
    "IPAddress": "93.184.216.34",
    "Port": 443,
    "Type": "HTTPS",
    "ResourcePath": "/health",
    "RequestInterval": 30,
    "FailureThreshold": 3
  }'

Cloudflare DNS

通过 API 管理记录
# Get zone ID
ZONE_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=example.com" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')

# Create an A record (proxied through Cloudflare)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"A","name":"app","content":"93.184.216.34","proxied":true,"ttl":1}'

# Create a CNAME record (DNS only, not proxied)
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -d '{"type":"CNAME","name":"docs","content":"docs.readthedocs.io","proxied":false,"ttl":3600}'

# List all records
curl -s "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq '.result[] | {name, type, content, proxied}'

# Delete a record
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN"

Terraform DNS 管理

使用 Terraform 管理 Route 53
# dns.tf
resource "aws_route53_zone" "main" {
  name = "example.com"
}

resource "aws_route53_record" "app" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "app.example.com"
  type    = "A"
  ttl     = 300
  records = ["93.184.216.34"]
}

resource "aws_route53_record" "www" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "www.example.com"
  type    = "CNAME"
  ttl     = 300
  records = ["example.com"]
}

# Alias record for CloudFront
resource "aws_route53_record" "cdn" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "A"

  alias {
    name                   = aws_cloudfront_distribution.main.domain_name
    zone_id                = aws_cloudfront_distribution.main.hosted_zone_id
    evaluate_target_health = false
  }
}

# Email records
resource "aws_route53_record" "mx" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "MX"
  ttl     = 3600
  records = [
    "1 aspmx.l.google.com",
    "5 alt1.aspmx.l.google.com",
    "5 alt2.aspmx.l.google.com",
  ]
}

resource "aws_route53_record" "spf" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "example.com"
  type    = "TXT"
  ttl     = 3600
  records = ["v=spf1 include:_spf.google.com ~all"]
}

resource "aws_route53_record" "dmarc" {
  zone_id = aws_route53_zone.main.zone_id
  name    = "_dmarc.example.com"
  type    = "TXT"
  ttl     = 3600
  records = ["v=DMARC1; p=quarantine; rua=mailto:[email protected]; pct=100"]
}
使用 Terraform 管理 Cloudflare
resource "cloudflare_record" "app" {
  zone_id = var.cloudflare_zone_id
  name    = "app"
  content = "93.184.216.34"
  type    = "A"
  proxied = true
}

resource "cloudflare_record" "mail" {
  zone_id  = var.cloudflare_zone_id
  name     = "@"
  content  = "aspmx.l.google.com"
  type     = "MX"
  priority = 1
}

DNS 故障排查命令

dig
# Query A record
dig app.example.com A +short

# Query from a specific DNS server
dig @8.8.8.8 app.example.com A

# Show full answer with TTL
dig app.example.com A +noall +answer

# Query MX records
dig example.com MX +short

# Trace the full resolution path
dig app.example.com +trace

# Check DNSSEC validation
dig example.com +dnssec +short

# Query TXT records (SPF, DKIM)
dig example.com TXT +short
dig default._domainkey.example.com TXT +short
nslookup
# Basic lookup
nslookup app.example.com

# Specify DNS server
nslookup app.example.com 8.8.8.8

# Query specific record type
nslookup -type=MX example.com
nslookup -type=TXT example.com
检查 DNS 传播
# Query multiple public resolvers
for dns in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
  echo "=== $dns ==="
  dig @$dns app.example.com A +short
done

电子邮件安全记录

# SPF — authorize sending servers
# TXT record on example.com
"v=spf1 include:_spf.google.com include:sendgrid.net -all"

# DKIM — email signing verification
# TXT record on google._domainkey.example.com
# (value provided by your email provider)

# DMARC — policy for failed SPF/DKIM
# TXT record on _dmarc.example.com
"v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"

TTL 策略

场景建议的 TTL原因
稳定的生产记录3600-86400(1 小时-24 小时)减少 DNS 查询,加快解析
迁移前预热60-300(1-5 分钟)在迁移前数天降低 TTL
迁移/故障转移期间60快速传播变更
迁移后冷却期逐步提高至 3600+确认稳定后恢复正常
负载均衡记录60-300支持由运行状况检查触发的故障转移

故障排查

症状原因解决方法
看不到 DNS 变更递归解析器上的 TTL 尚未过期等待旧 TTL 过期;下次变更前降低 TTL
返回 SERVFAILDNSSEC 验证失败或委派配置错误检查注册商处的 NS 记录;验证 DNSSEC 签名
有效记录返回 NXDOMAIN托管区域错误或缺少记录使用 dig @<authoritative-ns> domain 确认记录是否存在
区域顶点的 CNAME 返回错误根据 RFC,区域顶点不允许使用 CNAME使用 ALIAS(Route53)或代理 A 记录(Cloudflare)
电子邮件被归入垃圾邮件SPF/DKIM/DMARC 缺失或配置错误使用 dig example.com TXT 验证 TXT 记录;在 mail-tester.com 上测试
解析缓慢递归解析器距离权威 NS 较远使用 Anycast DNS 提供商(Cloudflare、Route53)
不同解析器返回的结果不一致传播尚未完成或缓存投毒直接查询权威 NS;检查是否存在冲突记录

相关技能

评论

支持 Markdown