mDNS与域名解析
文章目录
- mDNS与域名解析
- 1、mDNS介绍
- 1.1 组播 DNS 是如何工作的?
- 1.2 mDNS的优点
- 1.3 mDNS 的缺点和风险
- 2、软件准备
- 3、硬件准备
- 4、代码实现
在计算机网络中,多播 DNS (mDNS) 协议将主机名解析为不包含本地名称服务器的小型网络中的 IP 地址。 它是一种零配置服务,使用与单播域名系统 (DNS) 基本相同的编程接口、数据包格式和操作语义。
mDNS 是一种多播 UDP 服务,用于提供本地网络服务和主机发现。本文将详细介绍在ESP32中如何使用mDNS。
1、mDNS介绍
域名系统 (DNS) 可以被视为一个非常大的电话簿:用户可以在浏览器中输入网址,系统会确定正确的 IP 地址。 名称解析的工作原理是让自己的计算机查询适当的 DNS 服务器,该服务器存储每个主机名(即 Web 地址的列表)的列表,并为其分配正确的 IP 地址。 然而,多播 DNS 采用不同的路线。 经典 DNS 的替代方案如何运作?
1.1 组播 DNS 是如何工作的?
组播 DNS (mDNS) 是一种旨在帮助小型网络中的名称解析的协议。 为此,它采用了与众所周知的 DNS 不同的方法。 网络中的所有参与者都直接寻址,而不是查询名称服务器。 适当的客户端向网络发送多播,同时询问哪个网络参与者与主机名匹配。 多播是一种独特的通信形式,通过该形式将单个消息定向到一组接收者。 该组可以由例如整个网络或子网络组成。
这样,请求也会发送到拥有正在搜索的主机名的组参与者。 后者响应整个网络(也通过多播)。 所有参与者都会获知名称和 IP 地址之间的联系,并可以在其 mDNS 缓存中创建相应的条目。 只要此表示法有效,网络中就没有人需要请求主机名。
组播 DNS 会产生相对较大的流量,但会尝试节省活动的网络资源。 为此,发出请求的客户端会发送(根据当前缓存条目)他们认为正确的答复。 仅当该信息不再正确或条目即将过期时,收件人才需要回复。 其他参与者在收到回复之前就已收到通知。 通过该协议,可以减少网络内的流量。
一般来说,只有以 .local 结尾的主机名才可以使用多播 DNS。 这限制了本地网络上的这种形式的名称解析。 mDNS 不会处理具有其他*域 (TLD)(例如 .de 或 .com)的主机名。 因此,不能以这种方式解析网址。
注意:组播 DNS 于 2010 年代初开发,并在 RFC 6762 中进行了描述。
MDNS 是在 Zeroconf(零配置网络)的背景下开发的。 零配置网络背后的想法是计算机可以通过人类进行通信,而无需进行太多的事先调整。 多播 DNS 符合这些限制。 多播进程是 TCP/IP 的一部分,无需适当的配置也可以运行。
1.2 mDNS的优点
组播 DNS 专为小型网络而设计,旨在提高其用户友好性。 这个想法是用户可以毫无问题地连接秘密局域网中的设备。 由于所有设备都通过其 IP 地址相互交换信息,因此无需建立服务器或目录。 通过这种方式,可以快速、动态地导入其他设备。
mDNS 的一个流行实现是 Apple 的 Bonjour。 该服务主要旨在更轻松地将网络打印机连接到 PC 或 Mac。 由于设备通过其 IP 地址交换信息,因此用户不得独立配置连接。 除了Apple的服务之外,您现在还可以使用开源软件Avahi作为mDNS服务。 这使得无需事先执行配置即可连接不同的设备。 从 Windows 10 开始,mDNS 作为 Microsoft 操作系统的一部分提供。
1.3 mDNS 的缺点和风险
然而,简单的操作也伴随着一些缺点。 其中一个问题在于多播过程本身。 尽管该协议确实试图保持较低的网络流量,但所涉及的计算机必须不断监控网络并处理传入的消息。 这是处理能力的负担。
此外,主机名的分配也存在问题。 原则上,可以*地为每个设备分配一个名称,只要名称以“.local”结尾即可。 这可能(至少在理论上)导致两个网络参与者由相同的主机名表示。 mDNS 的开发人员有意识地没有针对此类场景实施解决方案。 一方面,他们认为这种情况很少见;另一方面,他们认为这种情况很少见。 另一方面,双重指定可能是故意的。
另一个问题是危险源。 在许多情况下,mDNS 是开放的。 这意味着它也会对外部查询(通过互联网)做出反应。 网络犯罪分子可以找到这些类型的开放服务并利用它们进行 DDoS 攻击。 然后,网络设备被滥用,以便通过查询轰炸目标服务器。 此外,还可以通过开放的多播 DNS 发现敏感数据。 例如,攻击者可以通过这种方式读取连接设备的 Mac 地址,并使用此信息进行进一步的攻击。
2、软件准备
- Arduino IDE
在前面的文章中,如何搭建ESP32的Arduino IDE开环境,主参考:
- ESP32-Arduino-开发实例-Arduino开发环境搭建
3、硬件准备
- ESP32开发板
4、代码实现
本次实例将使用到如下开源库:
- ESPAsyncWebServer
- AsyncTCP
示例代码如下:
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
AsyncWebServer server(80);
const char* ssid = "********"; // Your WiFi SSID
const char* password = "********"; // Your WiFi Password
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
if(!MDNS.begin("esp32")) {
Serial.println("mdns start failed");
while(true);
}
//("IP Address: ");
Serial.println("/");
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/text", "Hello,World");
});
server.begin();
}
void loop() {
delay(10);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
代码如何工作?
1)导入依赖库头文件:
#include <>
#include <>
#include <>
#include <>
#include <>
#include <>
- 1
- 2
- 3
- 4
- 5
- 6
2)创建服务器实例
AsyncWebServer server(80);
- 1
3)定义WiFi连接凭证
const char* ssid = "********"; // Your WiFi SSID
const char* password = "********"; // Your WiFi Password
- 1
- 2
4)在setup
函数中,
初始化串口:
Serial.begin(115200);
- 1
设置WiFi工作模式为STA模式:
WiFi.mode(WIFI_STA);
- 1
连接WiFi并等待连成完成:
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
- 1
- 2
- 3
- 4
- 5
启动mDNS:
if(!MDNS.begin("esp32")) {
Serial.println("mdns start failed");
while(true);
}
- 1
- 2
- 3
- 4
参数esp32
为需要解析的域名。
最后启动服务器:
//("IP Address: ");
Serial.println("/");
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/text", "Hello,World");
});
server.begin();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
5)在loop
函数中,调用delay
函数,延时10毫秒。这样做是为了避免看门狗任务超时。
void loop() {
delay(10);
}
- 1
- 2
- 3
在程序下载完成,WiFi连接完成后,在浏览器地址中输入:
/
即可访问。