关键在于检查iptables OUTPUT链是否DROP UDP 53端口规则,执行iptables -L OUTPUT -n --line-numbers | grep :53定位丢弃规则;firewalld用户需用firewall-cmd --list-ports确认53/udp是否开放,并通过tcpdump -i any port 53 and udp验证DNS请求是否发出。

Linux 系统中排查本地防火墙拦截 DNS 报文,关键在于确认防火墙是否在出站(OUTPUT)或转发(FORWARD)链中主动丢弃了目标端口为 53 的 UDP(或 TCP)流量。DNS 查询默认走 UDP 53,大响应或区域传输才用 TCP 53,因此优先查 UDP。
检查 iptables 是否 DROP 了 UDP 53 出站规则
执行以下命令查看 OUTPUT 链中是否有明确拒绝 DNS 流量的规则:
-
列出所有 OUTPUT 规则并过滤端口 53:
iptables -L OUTPUT -n | grep :53 -
带行号显示,便于定位和删除:
iptables -L OUTPUT -n --line-numbers | grep :53 - 若看到类似
DROP udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53的条目,说明该规则正在拦截本机发出的 DNS 请求
确认 firewalld 是否限制了 DNS 流量
使用 firewalld 的系统(如 CentOS/RHEL 7+、Fedora)需检查服务规则或端口放行状态:
-
查看当前启用的服务:
firewall-cmd --list-services—— 若输出不含dns,不代表一定拦截,但建议显式添加 -
检查是否开放了 UDP 53 端口:
firewall-cmd --list-ports—— 若未出现53/udp,需手动添加:firewall-cmd --add-port=53/udp --permanent && firewall-cmd --reload -
临时放行 DNS 服务更稳妥:
firewall-cmd --add-service=dns --permanent && firewall-cmd --reload
验证 DNS 流量是否真实被拦截
仅看规则还不够,需实测流量走向:
-
用 dig 强制指定 DNS 服务器并加超时:
dig @8.8.8.8 google.com +time=2 +tries=1—— 若超时且无响应,配合 iptables 规则更可疑 -
抓包确认请求是否发出:
tcpdump -i any port 53 and udp -nn -c 4,再执行一次 dig;若无任何输出,说明请求根本没发出去,极可能被 OUTPUT 链拦截 -
对比禁用防火墙前后的行为:
systemctl stop firewalld(或iptables -P OUTPUT ACCEPT临时清空策略),再测试 dig;恢复后问题重现,则基本锁定防火墙
注意 systemd-resolved 与防火墙的交互
启用 systemd-resolved 的系统(如 Ubuntu 20.04+、Fedora 默认),DNS 请求可能先发给本地 127.0.0.53:53,再由 resolved 转发。此时需额外确认:
- OUTPUT 链是否允许发往 127.0.0.53:53?通常不会拦,但自定义规则可能误伤
- resolved 自身是否正常:
resolvectl status查看 “DNS Servers” 是否列出有效地址,“Current Scopes” 是否含 “DNS” - 若 resolved 使用了转发模式,它发出的上游请求仍走 UDP 53,仍受 OUTPUT 链影响


















