DNS-星耀云
发布时间:2026-04-26 20:01
一、前言
搞过DNS的人都知道,最烦的是服务器明明在跑,但解析就是不通,排查半天发现是 rndc key 写错了或者zone文件语法有问题没人发现。这篇聊的是BIND日常巡检和常见故障排查的实战套路,别整那些"首先然后最后"的学生腔,直接上硬货。
二、操作步骤
第1步:确认BIND服务存活
# CentOS/RHEL
systemctl status named | head -20
# Ubuntu
systemctl status bind9 | head -20
预期输出:
● named.service - Berkeley Internet Name Domain (DNS)
Loaded: loaded (/usr/lib/systemd/system/named.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2024-01-16 08:30:00 CST; 2h 30min ago
Main PID: 1234 (named)
CGroup: /system.slice/named.service
└─1234 /usr/sbin/named -u named -c /etc/named.conf
看到"active (running)"才算数,等半天没反应那就是进程挂了。别光看返回码,status 命令的输出才是真相。
第2步:本地递归查询测试
# 使用dig测试本机递归解析能力
dig @127.0.0.1 www.baidu.com +short
# 测试反向解析
dig @127.0.0.1 -x 8.8.8.8 +short
预期输出:
139.159.xxx.xxx # 正常返回A记录IP
# 空输出或"SERVFAIL"说明递归挂了
返回IP说明递归正常,返回空或SERVFAIL说明服务有问题。如果加了 +short 还是没输出,先别急着骂娘,继续往下看日志。
第3步:检查配置语法
# CentOS/RHEL
named-checkconf /etc/named.conf
# Ubuntu
named-checkconf /etc/bind/named.conf
预期输出(无输出=正常):
[root@dns-server ~]# named-checkconf /etc/named.conf
[root@dns-server ~]# echo $?
0
如果语法有问题,会直接打印行号和错误。如果配置文件引用了其他文件,逐个检查:
# 检查zone文件语法
named-checkzone example.com /var/named/example.com.zone
# 或 Ubuntu
named-checkzone example.com /var/cache/bind/example.com.zone
预期输出:
zone example.com/IN: loaded serial 2024011601
OK
第4步:查看实时查询日志
# 先查看当前日志配置
grep -A5 "logging" /etc/named.conf | head -20
预期输出:
logging {
channel query_log {
file "/var/log/named/query.log" versions 3 size 5m;
severity info;
print-time yes;
print-category yes;
};
category queries { query_log; };
};
没有query日志就加一个,然后tail -f 看实时请求:
tail -f /var/log/named/query.log
预期输出:
16-Jan-2024 10:23:45.192 queries: info: client 192.168.1.100#54321: query: www.example.com IN A + (192.168.1.1)
16-Jan-2024 10:23:46.201 queries: info: client 192.168.1.100#54322: query: api.example.com IN A + (192.168.1.1)
看到大量"SERVFAIL"或"REFUSED"就要警惕了,说明上游或者配置有问题。
第5步:检查NS记录和SOA信息
# 查看zone的SOA和NS记录
dig ns example.com @127.0.0.1 +short
# 查看SOA详细信息
dig soa example.com @127.0.0.1 +nostats +nocomments
预期输出:
ns1.example.com.
ns2.example.com.
; <<>> DiG 9.18.24 <<>> soa example.com @127.0.0.1
;; global options: +cmd
example.com. 3600 IN SOA ns1.example.com. admin.example.com. 2024011601 7200 3600 1209600 86400
关注serial字段,每年至少要更新一次incremental序列号,否则slave不会同步。
第6步:检查从服务器同步状态
# 查看zone传输统计
rndc status
预期输出:
number of zones: 15
debug level: 0
xfers running: 0
xfers deferred: 0
soa queries in progress: 0
query logging is on
server is up and running
# 手动触发一次zone transfer测试(生产环境慎用)
rndc retransfer example.com
预期输出:
zone transfer in progress: example.com
第7步:检查stats和内存使用
# 生成统计信息
rndc stats
# 查看统计文件
cat /var/named/named.stats
# 或 Ubuntu: cat /var/cache/bind/named.stats
预期输出(截取关键部分):
+++ Statistics Clear +++
...
AQUERY 45678 # 收到的查询总数
AXFR 2 # 区域传输次数
Lame 15 # 错误配置的对端数量
...
# 查看BIND进程内存占用
ps aux | grep named | grep -v grep | awk '{print $6/1024" MB"}'
预期输出:
128.56 MB # 正常情况下内存占用
如果内存持续增长超过2GB,要考虑配置递归查询限制或者打补丁。
第8步:验证DNSSEC状态
# 检查DNSSEC签名状态
rndc signing -list example.com
预期输出:
example.com: pending secure
# 手动触发RRSIG生成
rndc sign example.com
三、常见问题FAQ
Q:客户端能ping通但dig解析超时是怎么回事?
A:八成是防火墙把DNS的TCP/UDP 53端口给拦了。运维老狗都知道先跑这个命令:netstat -tulnp | grep :53,确认53端口在listen。然后用tcpdump -i eth0 port 53 -c 10抓包看请求到底到没到。防火墙iptables规则没写对是最常见的,我见过好多人配完iptables之后DNS挂了还一脸懵。另外检查下listen-on配置,BIND默认可能只监听127.0.0.1。
Q:域名解析正常但外网访问慢,DNS要背锅吗?
A:先别急着甩锅。排查套路是:dig一下看看递归查询时间,dig @127.0.0.1 www.baidu.com +stats,看Query time那一行,超过500ms就要查上游递归是否正常。如果用的是转发模式(fowarders),检查forwarders IP的响应速度,别用8.8.8.8或者1.1.1.1测,那玩意儿出了墙抖得跟筛子似的。还可以调低max-cache-ttl,缓存太多有时候反而拖累。另外看看query日志里有没有大量递归到外网的请求,如果有,考虑用DNS缓存层(dnsmasq、unbound)分流。
Q:怎么让日志更详细但不占满磁盘?
A:生产环境别开debug模式,真要查问题临时开一会儿就关。日志文件要带版本轮转:
channel query_log {
file "/var/log/named/query.log" versions 5 size 100m; # 5个版本,单文件最大100M
severity info;
print-time yes;
};
然后在 /etc/logrotate.d/named 里配自动轮转。别用syslog输出DNS查询日志,syslog吞吐不够,日志一多直接卡死。建议独立目录存放,/var/log/named/ 给足磁盘空间,大型DNS每天日志几个G不是开玩笑。
Q:修改zone文件后serial没改,slave不更新怎么办?
A:警告:强行触发Zone Transfer会占用服务器资源,生产环境操作要谨慎。 先检查master的serial,然后在slave上手动更新serial或者触发reload:rndc reload example.com,如果还不行,上狠招:rndc retransfer example.com -client IP_OF_SLAVE,指定slave来拉取。最佳实践是用notify配置自动推送,或者做TSIG认证后加行:also-notify { slave_ip; };
四、总结
核心要点:
- 每天巡检必做:服务状态 + 本地递归测试 + 配置语法检查
- 故障排查顺序:netstat查端口 → tcpdump抓包 → 看query日志 → named-checkconf验配置
- Zone文件修改三步走:改文件 → 改serial → rndc reload
- 生产环境关闭query logging或者限制详细度,防磁盘爆满
- 转发生成环境务必配置备用forwarders,单点故障会死人
延伸阅读:
- BIND 9 Administrator Reference Manual(官方文档,永远的神)
- ISC Knowledge Repository(已知问题和补丁汇总)
- DNS Security Extension (DNSSEC) 操作指南(后续专题会讲)
- 《DNS and BIND》Cricket Liu著(DNS领域的圣经)