DNS协议分析
DNS协议是用来进行域名与IP地址之间的转换的。当一个应用进程需要把域名解析为IP地址时,该应用进程就调用解析程序,把待解析的域名在DNS请求报文中,以UDP数据报方式发送给本地域名服务器。本地域名服务器在查找域名后,把对应的IP地址放在DNS应答报文中返回。若本地域名服务器不能回答该请求,则向其它域名服务器发送查询请求,直至找到能够回答该请求的域名服务器。
协议数据格式
根据RFC1035文档可知,DNS协议报文格式如下所示:
+---------------------+
| Header | 报文头
+---------------------+
| Question | 查询请求
+---------------------+
| Answer | 应答
+---------------------+
| Authority | 授权应答
+---------------------+
| Additional | 附加信息
+---------------------+
Header定义了报文是请求还是应答、错误码以及其它的一些标志位;
Question描述了查询的问题,包括查询类型(QTYPE)、查询类(QCLASS) 和查询的域名(QNAME);
Answer段包含回答问题的RRs;
Authority段包含授权域名服务器的RRs;
Additional段包含和请求相关的,但是不是必须回答的RRs。
其中,报文头的格式如下所示:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
其各个字段的解释如下所示:
• ID 16Bits 客户端设置,响应报文会原样带回,用于客户端区分不同的请求应答;
• QR 1Bits 区分是请求 (0 Question) 还是应答 (1 Response);
• Opcode 4Bits 设置查询的种类,响应报文会原样带回,可以为:0 标准查询 QUERY;1 反向查询 IQUERY;2 服务器状态查询 STATUS;3~15 保留;
• AA 1Bits 授权应答 Authoritative Answer,响应报文生效,用于标示服务器响应报文是否为授权服务器返回的结果,可能是在本地 Cache 的缓存;
• TC 1Bits 截断 Truncation,报文因为超过了允许的长度,导致被截断;
• RD 1Bits 用于请求中,期望使用递归查询;
• RA 1Bits 用于响应中,如果服务器支持递归查询则设置为 1 ,否则设置为 0 ;
• RCODE 4Bits 应答码 Response Code,会在响应报文中设置,其代表的含义如下:
0 没有错误;
1 报文格式错误(Format Error),服务器解析请求报文时报错;
2 服务器失败(Server Failure),因为服务器的原因导致没办法处理这个请求;
3 名字错误(Name Error),只对授权域名解析服务器有意义,解析的域名不存在;
4 没有实现(Not Implemented),域名服务器不支持查询类型;
5 拒绝(Refused),由于服务器设置的策略拒绝给出应答,通常是安全的配置;
6-15 保留值,暂未使用。
• QDCOUNT 无符号16位整数表示报文请求段中的问题记录数;
• ANCOUNT 无符号16位整数表示报文回答段中的回答记录数;
• NSCOUNT 无符号16位整数表示报文授权段中的授权记录数;
• ARCOUNT 无符号16位整数表示报文附加段中的附加记录数。
协议报文分析
只考虑到域名对应的IP地址是唯一的,不像百度(www.baidu.com)那样进行域名查询会应答多个IP地址,因此对于报文的分析就会比较简单一点。使用wireshark捕获DNS报文,其中DNS请求报文如下图所示:
DNS应答报文如下图所示:
由捕获的DNS请求报文和应答报文可知:
请求报文的ID由应答报文原样带回;
Flags字段应答报文为固定值(0x8180);
应答报文的Answer RRs = 1(域名对应的IP只有一个的情况),请求报文的Answer RRs = 0;
请求报文和应答报文的Questions、Authority RRs和Additional RRs字段是相同的;
请求报文和应答报文的Queries字段是相同的;
请求报文和应答报文都没有Authority段和Additional段,其中请求报文还没有Answers段;
应答报文的Answers段长度为16字节(域名对应的IP只有一个且对应IPv4版本的情况),具体分为以下几个部分:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
具体长度大小如下图所示:
由于本项目只需考虑域名对应一个IP地址,因此不需要考虑域名和数据的可变长度,所以其Answers段大小为16字节,其中:
• 域名(NAME):是记录中资源数据对应的Name,其格式与查询Name格式相同,经实验发现其一般为固定值(0xc0, 0x0c);
• 类型(TYPE):说明资源的类型码,通常为固定值(0x00, 0x01);
• 类域(CLASS):该字段与问题记录的查询类型字段相同,通常为固定值(0x00, 0x01);
• 生存时间(TTL):该字段是客户程序保留该资源记录的时间,大小为4bytes;
• 数据长度(RDLENGTH):该字段表示数据的长度,对于本项目为固定值(0x00, 0x04);
• 数据(RDATA):域名对应的IP地址,大小为4bytes;