简介
简单的介绍下mdns协议怎么配置跟使用
概念
MDNS,也即是Multicast DNS,在小范围内本地网络中使用。与DNS相似的接口,数据包结构,操作语义的协议- 优势:不需要有
DNS server。mDNS利用局域网的UDP组播,让每台加入网络中的设备,向网络组播发布自己的主机名与IP地址 - 使用
UDP连接,5353端口 - 组播地址:
224.0.0.251,fff02::fb - 只解析主机名带
.local后缀的地址 - 可以在零配置网络中给自己分配域名,设备给自身选择一个域名后,然后通过发送记录类型为
any的mDNS包来查询局域网内是否有同名,如果没有设备就会把这个名字作为自己的域名


配置
我们在树莓派上使用,目前有三种方案,umdns或者avahi或者mdnsd,我们选择avahi,需要打开的配置选项有
BR2_PACKAGE_AVAHI=y
BR2_PACKAGE_AVAHI_DAEMON=y
BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y
BR2_PACKAGE_AVAHI_DEFAULT_SERVICES=y
BR2_PACKAGE_NSS_MDNS=y
配置好后更新rootfs,就可以ps看到avahi-daemon: running [buildroot.local]在运行了,这个时候我们分配给自己的域名就是buildroot.local

PC机来ping一下

树莓派来ping我们的PC机,PC输入hostname获取我们的主机名


除了avahi,还有一个nss_mdns模块。主机上的/etc/nssswitch.conf文件,其中hosts一行,用来控制系统使用哪些服务来进行名称解析,以及顺序

files:优先查询/etc/hosts文件的数据mdns6_minimal:ipv6使用最小交互的mdns协议去查询域名mdns4_minimal:ipv4使用最小交互的mdns协议去查询域名[NOTFOUND=return]dns:从DNS服务器去查询域名,从/etc/resolv.conf获得dns服务器地址mdns4:ipv4使用完整的mdns协议去查询域名mdns6:ipv6使用完整的mdns协议去查询域名
avahi命令相关用法
查找服务
列出所有本地注册的服务
avahi-browse -a -r

比如图中的ssh服务,那我们在同个局域网内就可以ssh buildroot.local

同理还有http,ftp等等
简洁一点的命令还有
avahi-browse -a
avahi-browse -a -t


avahi-browse -a -r -t

修改局部域名
一般情况下,xxx.local中的xxx都是依据当前主机名字来的

如果想要修改,有两种方式,一种是利用avahi的命令,比如设置主机xxx为mdnstest
avahi-set-host-name mdnstest

另一种是修改/etc/avahi/avahi-daemon.conf文件,不过需要重启后才能生效

查找域名对应的IP
avahi-resolve -n DESKTOP-ED5M43N.local

可以看到解析后并没有存到邻居表中,说明avahi是不会更新IP对应的MAC地址到邻居表中的。我个人理解是,这东西就类似于DNS服务那样,你收到服务器回给你的解析包,但是你能说这个解析的地址对应的MAC地址就是回复你的服务器的MAC地址吗,不能这样整吧。
但是只要ping了后就能会存到邻居表中,应该是ping的时候会走到avahi解析的地方

strace跟踪了一下ping的过程,可以看到最后走到avahi中去获取解析到的地址,然后再去通过ipv6的RS协议(类似于ipv4中的ARP协议)得到DESKTOP-ED5M43N.local的MAC地址,更新了邻居表

抓包看了下,大概就是这个意思

记录
在上一步修改局部域名后,PC进行ping树莓派的两个不同的局部域名,都能ping的通,我猜测是,一个是可以缓存,一个是只要是局域网内没同名的,这个条目依旧可以用。具体的原理倒是没时间去细究了

支持ipv6
尝试ipv6的时候,发现ping -6不通,但是能解析

前面知道/etc/nsswitch.conf文件跟mdns域名解析有关,查看该文件可以看到,并没有支持ipv6

直接修改文件,增加ipv6配置
files mdns6_minimal mdns4_minimal [NOTFOUND=return] dns mdns4 mdns6

好了,成功ping通了

正如前面配置中提到的,/etc/nsswitch.conf文件会决定解析的优先顺序,mdns6_minimal排在前面后,后续都是以ipv6优先解析
工作流程以及简单的报文解析
mdns工作流程如下
- 查询阶段
- 设备A需要解析
bbbb.local的IP地址 - 设备A向
mdns组播地址224.0.0.251发送DNS查询请求
- 设备A需要解析
- 响应阶段
- 局域网内加入了这个组播地址的设备接收到这个查询请求
- 拥有
bbbb.local域名的设备B会识别查询,并向设备A发送包含bbbb.local的主机名的IP地址的响应
- 缓存和重复查询
- 设备A收到响应后,将该信息缓存,以便在短时间内再次查询时直接使用缓存数据,减少网络流量
- 如果没有设备响应,设备A可以定期重发查询请求,直到获得相应
这里用PC来ping我们的树莓派进行抓包实验(如果是树莓派来ping我们的PC,可能会抓不到查询的包,貌似PC启动后就会一直往组播地址发自己的域名)

抓包结果如下
- 包
382/383/384:PC(10.17.99.1 /fe80::4bd2:bf2:8235:e444)先发起ipv4跟ipv6的mdns的问询 - 包
385/387/388:树莓派(10.17.99.133 /fe80::da3a:ddff:fe8c:a416)响应了PC发出的请求

参考链接
问题
一开始碰到的是,PC能ping通树莓派,但是树莓派不行,排除了防火墙问题

但是树莓派进行解析PC的域名是可以获取到PC的地址的
avahi-resolve -n DESKTOP-ED5M43N.local

后面排查发现,原来是buildroot配置的时候没有配置BR2_PACKAGE_NSS_MDNS,导致/etc/nsswitch.conf文件中内容不对,如下,只有files dns,少了其他
