OpenWrt DNS问题排查的示例分析

这篇文章主要介绍了OpenWrt DNS问题排查的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

我们的设备在测试时发现有个别的主机,主程序DNS解释服务器域名失败。
最直接的表现就是 ping 126.com 显示:
OpenWrt DNS问题排查的示例分析

对于这个问题,最直接的方式就是打开 /etc/resolv.conf 文件查看DNS服务器是否设置正确。结果该文件显示:

search lan
nameserver 127.0.0.1

博主用 strace ping 126.com 命令,分别比较了好的有问题的设备与没问题的设备。将输出信息用 meld 进行对比,结果看到在这里出现分歧: OpenWrt DNS问题排查的示例分析
可见,ping 命令在解释 "126.com" 域名时,是 connect 127.0.0.1:53 服务。而存在问题的一边,connect这个服务被拒绝了。

于是,博主可以分析得到,好的设备一定有一个服务进程bind了53端口,并提供了 DNS 服务。而有问题的设备一定是没有该进程。
博主在好的设备上运行 netstat -nap 找到了该服务:
OpenWrt DNS问题排查的示例分析 同时我们又在问题的设备,执行 netstat -nap,证实,有问题的设备上这个 dnsmasq 服务没有运行起来。

由于OpenWrt本身就是一个路由器的系统,其自带 Dnsmasq 服务向其网络下的子网设备提供 DNS 与 DHCP 服务。而我们OpenWrt自身的程序解析域名时,也就向本地的 dnsmasq 请求解析。


那么,现在的问题是:为什么个别设备它的 dnsmasq 启动不起来? 对比好的设备,执行 ps 是能看到 dnsmasq 进程存在的。执行 /etc/init.d/dnsmasq stop 能停止它。这时候再 ping 126.com 它也是通的。为什么?博主查了一下 /etc/resolv.conf 文件,在停止 dnsmasq 之前,它的内容是:

search lan
nameserver 127.0.0.1

查一旦停止后,它就会变成:

# Interface lan
nameserver 202.96.128.166
nameserver 202.96.134.133
search bad

这是OpenWrt为了防止 dnsmasq 被停后无法解析域名,所以在停止之前,将其已知的域名服务器写入到 /etc/resolv.conf 文件中来。

相对于有问题的设备,其 /etc/resolv.conf 内容为:

search lan
nameserver 127.0.0.1

而 dnsmasq 进程并未被启动过(执行 ps 命令,列表中没有 dnsmasq 进程)。于是博主尝试执行:/etc/init.d/dnsmasq start,然后执行:ps 查看进程。结果,dnsmasq 进程并没有如愿启动起来。 直接执行 dnsmasq 命令就可以启动服务,然后 ping 126.com 也能拼通。

那么问题应该是在 /etc/init.d/dnsmasq 文件中。博主打开 /etc/init.d/dnsmasq 看了一下,太多了,就不想全部贴出来了。相信大家也没有赖心看。下面只是摘要。 /etc/init.d/dnsmasq start 时会执行到:

PROG=/usr/sbin/dnsmasq
CONFIGFILE="/var/etc/dnsmasq.conf"
<略...>
start_service() {
	include /lib/functions

	config_load dhcp

	procd_open_instance
	procd_set_param command $PROG -C $CONFIGFILE -k
	procd_set_param file $CONFIGFILE
	procd_set_param respawn
	procd_close_instance

    <略...>
}

可以了解到,真正执行的启动命令是:/usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k
手动执行这个命令,看能否启动 dnsmasq 服务:
OpenWrt DNS问题排查的示例分析
如上,出错了。/var/etc/dnsmasq.conf 文件的第11行有重复的关键字。
这是一个重要的线索!打开 /var/etc/dnsmasq.conf 文件:
OpenWrt DNS问题排查的示例分析
如上,第11行的关键字为 dhcp-leasefile。对比好的设备的该文件。经对比,完全一致。

那问题又在哪儿呢? 是不是把 /var/etc/dnsmasq.conf 文件中的11行删除就可以了呢?尝试如此操作,结果还真是可以启动。 但这没有从根本解决问题。

是不是有别的配置文件,也有 dhcp-leasefile 关键字?
打开 /etc/dnsmasq.conf,这个文件与 /var/etc/dnsmasq.conf 完全一样。但是博主尝试用 /etc/dnsmasq.conf 替代 /var/etc/dnsmasq.conf,如下执行:

/usr/sbin/dnsmasq -C /etc/dnsmasq.conf -k

结果没有问题,而如果指定的配置文件为 /var/etc/dnsmasq.conf 就有问题。博主很不理解。为了确保这两个文件是同一个,于是:

rm /var/etc/dnsmasq.conf
cp /etc/dnsmasq.conf /var/etc/dnsmasq.conf
/usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k

结果:
OpenWrt DNS问题排查的示例分析

同样是配置文件,同样的内容,只是路径变了而已。为什么放 /var/etc/dnsmasq.conf 就会出错?
是不是 dnsmasq 默认就加载了 /etc/dnsmasq.conf ?如果有指定其它的配置文件,它就会出错?
于是:

rm /var/etc/dnsmasq.conf
mv /etc/dnsmasq.conf /var/etc/dnsmasq.conf
/usr/sbin/dnsmasq -C /var/etc/dnsmasq.conf -k

结果:
OpenWrt DNS问题排查的示例分析
证实一点,dnsmasq 确实默认加载了 /etc/dnsmasq.conf,不然为什么在我们将文件移走了,会报找不到 /etc/dnsmasq.conf 文件。这也说明了为什么我们强制性指定配置文件为 /var/etc/dnsmasq.conf 时会报重复关键字了。因为 /etc/dnsmasq.conf 也被加载了的。

对比好的设备里的 /etc/dnsmasq.conf 内容,结果发现:

# Change the following lines if you want dnsmasq to serve SRV
# records.
# You may add multiple srv-host lines.
# The fields are <name>,<target>,<port>,<priority>,<weight>

# A SRV record sending LDAP for the example.com domain to
# ldapserver.example.com port 289
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389

# Two SRV records for LDAP, each with different priorities
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2

# A SRV record indicating that there is no LDAP server for the domain
# example.com
#srv-host=_ldap._tcp.example.com

# The following line shows how to make dnsmasq serve an arbitrary PTR
# record. This is useful for DNS-SD.
# The fields are <name>,<target>
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"

# Change the following lines to enable dnsmasq to serve TXT records.
# These are used for things like SPF and zeroconf.
# The fields are <name>,<text>,<text>...

#Example SPF.
#txt-record=example.com,"v=spf1 a -all"

#Example zeroconf
#txt-record=_http._tcp.example.com,name=value,paper=A4

# Provide an alias for a "local" DNS name. Note that this _only_ works
# for targets which are names from DHCP or /etc/hosts. Give host
# "bert" another name, bertrand
# The fields are <cname>,<target>
#cname=bertand,bert

里面没有一个配置项,与其 /var/etc/dnsmasg.conf 完全不一样。

OK,大致找到问题了。坏设备的 /etc/dnsmasg.conf 有了 /var/etc/dnsmasg.conf 一样的内容。所以,当 dnsmasq 加载完了 /etc/dnsmasg.conf 后再来加载 /var/etc/dnsmasg.conf 就出错了。
将 /etc/dnsmasg.conf 清空即可:

rm /etc/dnsmasg.conf
touch /etc/dnsmasg.conf

然后,再 /etc/init.d/dnsmasg start,就成功了。


那为什么坏的主机 /etc/dnsmasg.conf 有内容?而不是像好的设备那样全是注释? 我们去 OpenWrt工程中找答案。 dnsmasg 在工程的如下路径上:package/network/services/dnsmasq/ 目录为:

.
├── files
│   ├── dhcp.conf
│   ├── dnsmasq.conf
│   ├── dnsmasq.hotplug
│   └── dnsmasq.init
├── Makefile
└── patches
    ├── 001-Build-config-add-DNO_GMP-for-use-with-nettle-mini-gm.patch
    ├── 002-fix-race-on-interface-flaps.patch
    ├── 100-fix-dhcp-no-address-warning.patch
    └── 110-ipset-remove-old-kernel-support.patch

2 directories, 9 files

目录下的 files/dnsmasq.conf 文件在安装后就是 /etc/dnsmasg.conf 文件。打开看,其内容就与好的设备上的 /etc/dnsmasq.conf 文件一致。
如果一个纯净的系统固件,是不会出这个问题的。

那么有两种可能:

  • 由于脚本出错,致将 /var/etc/dnsmasg.conf 文件的内容写入到了 /etc/dnsmasg.conf 中

  • 是我们在进行 sysupgrade 过程中,出错的 /etc/dnsmasg.conf 文件被遗留下来了

验证的方法为:断电重启,看 /etc/dnsmasg.conf 是否会再次变成与 /var/etc/dnsmasg.conf 一致。 结果正常。

感谢你能够认真阅读完这篇文章,希望小编分享的“OpenWrt DNS问题排查的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/219970.html

(0)
上一篇 2022年1月2日
下一篇 2022年1月2日

相关推荐

发表回复

登录后才能评论