DNS协议介绍

惯例

首选name语法

DNS规范试图使构建的域名规则尽可能通用。这一想法的精髓是任何现有对象的名称经过尽量小的改变都能表示为域名。
但是在为对象分配域名时,谨慎的用户将选择即满足域名系统规则,又满足对象任何现有规则的名称,无论这些规则是公开出版的还是由现有程序暗示的。
如:当命名邮件域时,用于应当即满足本备忘录的规则,又满足RFC-822宏的规则。创建新的主机名时,应当遵守旧的HOSTS.TXT规则。这可避免当旧软件被转换为使用域名时出现问题
以下语法(BNF范式)将减少许多使用域名的应用程序(例如邮件,TELNET)的问题。

1
2
3
4
5
6
7
8
<domain> ::= <subdomain> | " "
<subdomain> ::= <label> | <subdomain>"." <label>
<label> ::= <letter> [[<ldh-str>] <let-dig>]
<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
<let-dig-hyp> ::= <let-dig> “-”
<let-dig> ::= <letter> | <digit>
<letter> ::= 52个字母字符A到Z中的任何一个(大写)和a到z中的小写
<digit> ::= 十个数字0到9中的任何一个

DNS报文格式

整个报文的格式如下,包括了五部分组成。

1
2
3
4
5
6
7
8
9
10
11
+---------------------+
| Header | 报文头
+---------------------+
| Question | 查询请求
+---------------------+
| Answer | 应答
+---------------------+
| Authority | 授权应答
+---------------------+
| Additional | 附加信息
+---------------------+

详细介绍如下。

  • Header 必选,定义了报文是请求还是应答、错误码以及其它的一些标志位;
  • Question 描述了查询的请求报文,包括查询类型(QTYPE)、查询类(QCLASS) 以及查询的域名(QNAME);

剩下的3个段包含相同的格式:一系列可能为空的资源记录(RR)。 Answer段包含回答问题的RR列表;Authority段包含授权域名服务器的RR列表; Additional段包含和请求相关的RR列表,但这些附件的RR不是必须回答的。

报文头(Header)

DNS的报文头由固定的12个字节构成。

1
2
3
4
5
6
7
8
9
10
11
12
13
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

字段介绍如下:

字段简写 字段长度 说明
ID 16 bits无符号整数 客户端设置,响应报文会原样带回,用于客户端区分不同的请求应答;
QR 1 bit 区分是请求还是应答
0 请求
1 应答
Opcode 4 bits 设置查询的种类,响应报文会原样带回.
0 标准查询 QUERY;
1 反向查询 IQUERY;
2 服务器状态查询 STATUS;
5 增量更新
3~15 保留;
AA 1bit 授权应答 AuthoritativeAnswer,响应报文生效,用于标示服务器响应报文是否为授权服务器返回的结果,可能是在本地 Cache 的缓存;
TC 1bit 截断 TrunCation,报文因为超过了允许的长度,导致被截断;
RD 1bit 用于请求报文,代表期望是否使用递归查询;
0 不使用递归查询
1 使用递归查询
RA 1bit 用于响应报文中,表示服务端是否支持递归查询
0 不支持递归
1 支持递归
RCODE 4 bits 应答码 ResponseCode,会在响应报文中设置。
0 没有错误;
1 报文格式错误(Format Error),服务器解析请求报文时报错
2 服务器失败(Server Failure),意思是服务器失败,也就是这个域名的权威服务器拒绝响应或者响应REFUSE,递归服务器返回Rcode值为2给CLIENT
3 名字错误(Name Error),对应的DNS应答状态为NXDOMAIN,意思是不存在的记录,也就是这个具体的域名在权威服务器中并不存在
4 没有实现(Not Implemented),域名服务器不支持查询类型
5 拒绝(Refused),由于服务器设置的策略拒绝给出应答,通常是安全的配置;也就是这个请求源IP不在服务的范围内
6-15 保留值,暂未使用。
QDCOUNT 16 bits 无符号整数 请求段中的RR
ANCOUNT 16 bits 无符号整数 应答段中的RR数,
NSCOUNT 16 bits 无符号整数 报文授权段中的授权RR
ARCOUNT 16 bits 无符号整数 报文附加段中的附加RR

查询请求(Question)

用来标识,查询的请求参数,同时需要在头中设置 QDCOUNT 这个字段。

1
2
3
4
5
6
7
8
9
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

字段含义如下:

字段名 长度 类型 说明
QNAME 最大255字节 标签字符串 域名被编码为一些labels序列,每个labels包含一个字节表示后续字符串长度,以及这个字符串,以0长度和空字符串来表示域名结束。注意这个字段可能为奇数字节,不需要进行边界填充对齐。
QTYPE 2字节 无符号整数 表示查询类型, 取值可以为任何可用的类型值,该字段的值包括对TYPE字段有效的所有代码,以及一些更通用的代码,这些代码可以匹配一种以上的RR, 以及通配码来表示所有的RR记录。
QCLASS 2 字节 无符号整数 表示查询的协议类,
0 保留
1 Internet (IN)
2 未使用
3 Chaos (CH)
4 Hesiod (HS)
5-253 未使用
254 QCLASS NONE
255 QCLASS * (ANY)

DNS RR介绍

DNS资源记录(Resource Record,简称RR)

DNS server 内的每一个域名都有自己的域文件(zone file),zone file 是由多个记录组成的,每一个记录就被称为资源记录(Resource Record,简称RR)。

RR 记录格式

所有的RR具有以下相同的格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

各个字段说明如下:

字段名 长度 类型 说明
NAME 最大255字节 标签字符串 不定长与之前QNAME相同,这里会使用省略字段
为了压缩消息总长度此内容可能会采用消息压缩方式存储。
TYPE 2字节 无符号整数 资源类型,是QTYPE的子集
CLASS 2字节 无符号整数 与之前的QCLASS相同
TTL 4字节 有符号整数 它指定在再次查询信息源之前可以缓存资源记录的时间间隔。零值被解释为表示RR仅可用于进行中的事务,不应缓存。例如,SOA记录始终以零TTL分发,以禁止缓存。零值也可以用于易失性数据。
RDLENGTH 2字节 无符号整数 后面跟随的RDATA的长度
RDATA 真实的数据内容

消息压缩

为了减小dns消息的大小,dns协议中针对域名采用了一种压缩方案,消除了消息中重复的域名。压缩方式为:使用2个字节的指针来指向消息中已经存在相同域名的位置。

1
2
3
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1 1| OFFSET |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

第一个字节的前2个bit为11时表示此域名采用的压缩格式,后面的OFFSET (14 bit) 是当前域名所在的位置相对于DNS消息开始的偏移量。
如:之前的header数组中出现过3www6google3com0,且处的位置为12,这里就可以用1100 000c 两个字节来代替3www6google3com0表示的16个字节

TYPE值说明

标准RR类型介绍

类型 数值 RFC来源 描述 功能
A 1 RFC 1035 IP 地址记录 传回一个 32 比特的 IPv4 地址,最常用于映射主机名称到IP地址,但也用于 DNSBL(RFC 1101)等。
AAAA 28 RFC 3596 IPv6 IP 地址记录 传回一个 128 比特的 IPv6 地址,最常用于映射主机名称到 IP 地址。
AFSDB 18 RFC 1183 AFS文件系统 (Andrew File System)数据库核心的位置,于域名以外的 AFS 客户端常用来联系 AFS 核心。这个记录的子类型是被过时的DCE/DFS(DCE Distributed File System)所使用。
APL 42 RFC 3123 地址前缀列表 指定地址列表的范围,例如:CIDR 格式为各个类型的地址(试验性)。
CAA 257 RFC 6844 权威认证授权 DNS认证机构授权,限制主机/域的可接受的CA
CDNSKEY 60 RFC 7344 子关键记录 关键记录记录的子版本,用于转移到父级
CDS 59 RFC 7344 子委托签发者 委托签发者记录的子版本,用于转移到父级
CERT 37 RFC 4398 证书记录 存储 PKIX、SPKI、PGP等。
CNAME 5 RFC 1035 规范名称记录 一个主机名字的别名:域名系统将会继续尝试查找新的名字。
DHCID 49 RFC 4701 DHCP(动态主机设置协议)识别码 用于将 FQDN 选项结合至 DHCP。
DLV 32769 RFC 4431 DNSSEC(域名系统安全扩展)来源验证记录 为不在DNS委托者内发布DNSSEC的信任锚点,与 DS 记录使用相同的格式,RFC 5074介绍了如何使用这些记录。
DNAME 39 RFC 2672 代表名称 DNAME 会为名称和其子名称产生别名,与 CNAME 不同,在其标签别名不会重复。但与 CNAME 记录相同的是,DNS将会继续尝试查找新的名字。
DNSKEY 48 RFC 4034 DNS 关键记录 于DNSSEC内使用的关键记录,与 KEY 使用相同格式。
DS 43 RFC 4034 委托签发者 此记录用于鉴定DNSSEC已授权区域的签名密钥。
HIP 55 RFC 5205 主机鉴定协议 将端点标识符及IP 地址定位的分开的方法。
IPSECKEY 45 RFC 4025 IPSEC 密钥 与 IPSEC 同时使用的密钥记录。
KEY 25 RFC 2535RFC 2930 关键记录 只用于 SIG(0)(RFC 2931)及 TKEY(RFC 2930RFC 3455 否定其作为应用程序键及限制DNSSEC的使用。RFC 3755 指定了 DNSKEY 作为DNSSEC的代替。
LOC 29 RFC 1876 位置记录 将一个域名指定地理位置。
MX 15 RFC 1035 电邮交互记录 引导域名到该域名的邮件传输代理(MTA, Message Transfer Agents)列表。
NAPTR 35 RFC 3403 命名管理指针 允许基于正则表达式的域名重写使其能够作为 URI 、进一步域名查找等。
NS 2 RFC 1035 名称服务器记录 委托 DNS 域(DNS zone)使用已提供的权威域名服务器。
NSEC 47 RFC 4034 下一代安全记录 DNSSEC 的一部分; 用来验证一个未存在的服务器,使用与 NXT(已过时)记录的格式。
NSEC3 50 RFC 5155 NSEC 记录第三版 用作允许未经允许的区域行走以证明名称不存在性的 DNSSEC 扩展。
NSEC3PARAM 51 RFC 5155 NSEC3 参数 与 NSEC3 同时使用的参数记录。
OPENPGPKEY 61 RFC 7929 OpenPGP公钥记录 基于DNS的域名实体认证方法,用于使用OPENPGPKEY DNS资源记录在特定电子邮件地址的DNS中发布和定位OpenPGP公钥。
PTR 12 RFC 1035 指针记录 引导至一个规范名称(Canonical Name)。与 CNAME 记录不同,DNS“不会”进行进程,只会传回名称。最常用来运行反向 DNS 查找,其他用途包括引作DNS-SD。
RRSIG 46 RFC 4034 DNSSEC 证书 DNSSEC 安全记录集证书,与 SIG 记录使用相同的格式。
RP 17 RFC 1183 负责人 有关域名负责人的信息,电邮地址的 @ 通常写为 a
SIG 24 RFC 2535 证书 SIG(0)(RFC 2931)及 TKEY(RFC 2930)使用的证书。RFC 3755 designated RRSIG as the replacement for SIG for use within DNSSEC.
SOA 6 RFC 1035 权威记录的起始 指定有关DNS区域的权威性信息,包含主要名称服务器、域名管理员的电邮地址、域名的流水式编号、和几个有关刷新区域的定时器。
SPF 99 RFC 4408 SPF 记录 作为 SPF 协议的一部分,优先作为先前在 TXT 存储 SPF 数据的临时做法,使用与先前在 TXT 存储的格式。
SRV 33 RFC 2782 服务定位器 广义为服务定位记录,被新式协议使用而避免产生特定协议的记录,例如:MX 记录。
SSHFP 44 RFC 4255 SSH 公共密钥指纹 DNS 系统用来发布SSH公共密钥指纹的资源记录,以用作辅助验证服务器的真实性。
TA 32768 DNSSEC 信任当局 DNSSEC 一部分无签订 DNS 根目录的部署提案,,使用与 DS 记录相同的格式。
TKEY 249 RFC 2930 秘密密钥记录 为 TSIG 提供密钥材料的其中一类方法,that is 在公共密钥下加密的 accompanying KEY RR。
TSIG 250 RFC 2845 DNS 密钥交易验证协议 用以认证动态更新(Dynamic DNS)是来自合法的客户端,或与 DNSSEC 一样是验证回应是否来自合法的递归名称服务器。
TXT 16 RFC 1035 文本记录 最初是为任意可读的文本 DNS 记录。自1990年起,些记录更经常地带有机读数据,以 RFC 1464指定:opportunistic encryption、Sender Policy Framework(虽然这个临时使用的 TXT 记录在 SPF 记录推出后不被推荐)、DomainKeys、DNS-SD等。
URI 256 RFC 7553 统一资源标识符 可用于发布从主机名到URI的映射。
ZONEMD 63 RFC 8976 DNS 区域消息摘要 静态DNS 区域数据上提供加密消息摘要
SVCB 64 RFC 9460 服务绑定 为需要解析许多资源以访问域的客户端提高性能的 RR。2023年11月正式确定rfc9460
HTTPS 65 RFC 9460 专门针对http的svcb记录,为HTTP/HTTPS请求进行服务绑定 为需要解析许多资源以访问域的客户端提高性能的 RR。 2023年11月正式确定 rfc9460

其他或伪资源记录类型

类型 数值 RFC来源 描述 功能
* 255 RFC 1035 所有缓存的记录 传回所有服务器已知类型的记录。如果服务器未有任何关于名称的记录,该请求将被转发。而传回的记录未必完全完成,例如:当一个名称有 A 及 MX 类型的记录时,但服务器已缓存了 A 记录,就只有 A 记录会被传回。
AXFR 252 RFC 1035 全域转移 由主域名服务器转移整个区域文件至二级域名服务器。
IXFR 251 RFC 1995 增量区域转移 请求只有与先前流水式编号不同的特定区域的区域转移。此请求有机会被拒绝,如果权威服务器由于配置或缺乏必要的数据而无法履行请求,一个完整的(AXFR)会被发送以作回应。
OPT 41 RFC 2671 已被RFC 6891取代 选项(optinon) 这是一个“伪DNS 记录类型”,用于支持EDNS(0)。EDNS根据OPTION-CODE来确定传递的附加数据类型,从而决定传递的附加数据内容

已过时的RR类型

类型 数值 RFC来源 被淘汰RFC 描述
A6 38 RFC 2874 RFC 6563 Defined as part of early IPv6 but downgraded to experimental by RFC 3363; later downgraded to historic by RFC 6563.
APL 42 RFC 3123 Specify lists of address ranges, e.g. in CIDR format, for various address families. Experimental.
EID 31 N/A Defined by the Nimrod DNS internet draft, but never made it to RFC status. Not in current use by any notable application
GPOS 27 RFC 1712 A more limited early version of the LOC record
L32 105 RFC 6742 未被任何值得注意的应用程序使用并标记为“实验性”
L64 106 RFC 6742 未被任何值得注意的应用程序使用并标记为“实验性”
LP 107 RFC 6742 未被任何值得注意的应用程序使用并标记为“实验性”
MB 7 RFC 883 Not formally obsoleted. Unlikely to be ever adopted (RFC 2505). MB, MG, MR, and MINFO are records to publish subscriber mailing lists. MAILB is a query code which returns one of those records. The intent was for MB and MG to replace the SMTP VRFY and EXPN commands. MR was to replace the “551 User Not Local” SMTP error. Later, RFC 2505 recommended that both VRFY and EXPN be disabled, making MB and MG unnecessary. They were classified as experimental by RFC 1035.
MF 4 RFC 883 RFC 973 邮件目的地 (MD) 和邮件转发器 (MF) 记录;MAILA 不是实际的记录类型,而是返回 MF 和/或 MD 记录的查询类型。RFC 973 将这些记录替换为 MX 记录。
MG 8 RFC 883 没有正式过时。不太可能被采用(RFC 2505)。 MB、MG、MR 和 MINFO 是发布订阅者邮件列表的记录。MAILB 是一个查询代码,它返回这些记录之一。目的是让 MB 和 MG 替换SMTP VRFY 和 EXPN 命令。MR 是为了替换“551 User Not Local”SMTP 错误。后来,RFC 2505 建议禁用 VRFY 和 EXPN,使 MB 和 MG 变得不必要。它们被 RFC 1035 归类为实验性的。
NB 32 RFC 1002 Mistakes (from RFC 1002); the numbers are now assigned to NIMLOC and SRV.
NSAP-PTR 23 RFC 1706 Not in current use by any notable application
NXT 30 RFC 2065 RFC 3755 Part of the first version of DNSSEC (RFC 2065). NXT was obsoleted by DNSSEC updates (RFC 3755). At the same time, the domain of applicability for KEY and SIG was also limited to not include DNSSEC use.
PX 26 RFC 2163 Not in current use by any notable application
RP 17 RFC 1183 RP may be used for certain human-readable information regarding a different contact point for a specific host, subnet, or other domain level label separate than that used in the SOA record.
SIG 24 RFC 2065 RFC 3755 DNSSEC 第一个版本 (RFC 2065) 的一部分。NXT 已被 DNSSEC 更新 (RFC 3755) 淘汰。同时,KEY 和 SIG 的适用范围也仅限于不包括 DNSSEC 的使用。
X25 19 RFC 1183 Not in current use by any notable application
WKS 11 RFC 883, RFC 1035 Declared as “not to be relied upon” by RFC 1123 (more in RFC 1127). Record to describe well-known services supported by a host. Not used in practice. The current recommendation and practice is to determine whether a service is supported on an IP address by trying to connect to it. SMTP is even prohibited from using WKS records in MX processing.[14]
SINK 40 N/A Defined by the Kitchen Sink internet draft, but never made it to RFC status
NID 104 RFC 6742 Not in use by any notable application and marked as “experimental”
UINFO 100 N/A IANA reserved, no RFC documented them [1] and support was removed from BIND in the early 90s.
HINFO 13 RFC 883 Unobsoleted by RFC 8482. Currently used by Cloudflare in response to queries of the type ANY.[15] Record intended to provide information about host CPU type and operating system. It was intended to allow protocols to optimize processing when communicating with similar peers.
NINFO 56 N/A Used to provide status information about a zone. Requested for the IETF draft “The Zone Status (ZS) DNS Resource Record” in 2008. Expired without adoption.[19]
MR 9 RFC 883 没有正式过时。不太可能被采用(RFC 2505)。 MB、MG、MR 和 MINFO 是发布订阅者邮件列表的记录。MAILB 是一个查询代码,它返回这些记录之一。目的是让 MB 和 MG 替换SMTP VRFY 和 EXPN 命令。MR 是为了替换“551 User Not Local”SMTP 错误。后来,RFC 2505 建议禁用 VRFY 和 EXPN,使 MB 和 MG 变得不必要。它们被 RFC 1035 归类为实验性的。
MD 3 RFC 883 RFC 973 Mail destination (MD) and mail forwarder (MF) records; MAILA is not an actual record type, but a query type which returns MF and/or MD records. RFC 973 replaced these records with the MX record.
NSAP 22 RFC 1706 Not in current use by any notable application
NBSTAT 33 RFC 1002 错误(来自 RFC 1002);编号现在分配给 NIMLOC 和 SRV。
TALINK 58 N/A Defined by the DNSSEC Trust Anchor History Service internet draft, but never made it to RFC status
RKEY 57 N/A Used for encryption of NAPTR records. Requested for the IETF draft “The RKEY DNS Resource Record” in 2008. Expired without adoption.[20]
NIMLOC 32 N/A Nimrod DNS 互联网草案定义,但从未达到 RFC 状态。当前未由任何显着应用程序使用
ATMA 34 N/A Defined by The ATM Forum Committee.[16]
NULL 10 RFC 883 RFC 1035 Obsoleted by RFC 1035. RFC 883 defined “completion queries” (opcode 2 and maybe 3) which used this record. RFC 1035 later reassigned opcode 2 to be “status” and reserved opcode 3.
MINFO 14 RFC 883 没有正式过时。不太可能被采用(RFC 2505)。 MB、MG、MR 和 MINFO 是发布订阅者邮件列表的记录。MAILB 是一个查询代码,它返回这些记录之一。目的是让 MB 和 MG 替换SMTP VRFY 和 EXPN 命令。MR 是为了替换“551 User Not Local”SMTP 错误。后来,RFC 2505 建议禁用 VRFY 和 EXPN,使 MB 和 MG 变得不必要。它们被 RFC 1035 归类为实验性的。
UID 101 N/A IANA 保留,没有 RFC 记录它们[1]并且在 90 年代初从BIND中删除了支持。
DOA 259 N/A Defined by the DOA over DNS internet draft, but never made it to RFC status
ISDN 20 RFC 1183 Not in current use by any notable application
UNSPEC 103 N/A IANA 保留,没有 RFC 记录它们[1]并且在 90 年代初从BIND中删除了支持。
RT 21 RFC 1183 Not in current use by any notable application
MAILA 254 RFC 883 RFC 973 邮件目的地 (MD) 和邮件转发器 (MF) 记录;MAILA 不是实际的记录类型,而是返回 MF 和/或 MD 记录的查询类型。RFC 973 将这些记录替换为 MX 记录。
GID 102 N/A IANA 保留,没有 RFC 记录它们[1]并且在 90 年代初从BIND中删除了支持。
MAILB 253 RFC 883 没有正式过时。不太可能被采用(RFC 2505)。 MB、MG、MR 和 MINFO 是发布订阅者邮件列表的记录。MAILB 是一个查询代码,它返回这些记录之一。目的是让 MB 和 MG 替换SMTP VRFY 和 EXPN 命令。MR 是为了替换“551 User Not Local”SMTP 错误。后来,RFC 2505 建议禁用 VRFY 和 EXPN,使 MB 和 MG 变得不必要。它们被 RFC 1035 归类为实验性的。
KEY 25 RFC 2065 RFC 3755 DNSSEC 第一个版本 (RFC 2065) 的一部分。NXT 已被 DNSSEC 更新 (RFC 3755) 淘汰。同时,KEY 和 SIG 的适用范围也仅限于不包括 DNSSEC 的使用。
SPF 99 RFC 4408 RFC 7208 Specified as part of the Sender Policy Framework protocol as an alternative to storing SPF data in TXT records, using the same format. Support for it was discontinued in RFC 7208 due to widespread lack of support.[17][18]

RR格式详解

SRV

DNS SRV是DNS记录中一种,用来指定服务地址。与常见的A记录、cname不同的是,SRV中除了记录服务器的地址,还记录了服务的端口,并且可以设置每个服务地址的优先级和权重。访问服务的时候,本地的DNS resolver从DNS服务器查询到一个地址列表,根据优先级和权重,从中选取一个地址作为本次请求的目标地址。

应用场景

一个能够支持SRV的LDAP client可以通过查询域名,得知LDAP服务的IP地址和服务端口:

1
_ldap._tcp.example.com

这个域名的格式是rfc-2782中推荐的格式,_ldap表示LDAP服务,_tcp表示通过TCP协议访问LDAP服务。

SRV的记录格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ _Service._Proto.Name /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 33 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
_Service._Proto.Name 格式说明
标签名 说明
_Service 服务名称,前缀“_”是为防止与DNS Label(普通域名)冲突。
_Proto 服务使用的通信协议,_TCP、_UDP、其它标准协议或者自定义的协议。前缀“_”是为防止与DNS Label(普通域名)冲突
Name 提供服务的域名。
TTL/ CLASS及RDLENGTH 参考《RR记录格式》的标准含义
RDATA格式为:
1
2
3
4
5
6
7
8
9
10
11
12
13
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Priority |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Weight |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Port |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ Target /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
RDATA字段含义如下:
字段名 长度 类型 说明
Priority 2字节 无符号整形 该记录的优先级,数值越小表示优先级越高,范围0-65535。
Weight 2字节 无符号整形 该记录的权重,数值越高权重越高,范围0-65535。
Port 2字节 无符号整形 服务端口号,0-65535。
Target 标签字符串 目标主机对应的域名。 此域名必须有一个或多个地址记录(A或AAAA记录),此域名不能是别名(在 RFC 1034 或 RFC 2181 的意义上)。 建议并不强制要求在应答数据的附加数据部分返回此地址记录数据。 除非未来的标准允许,否则此名称不能使用标签压缩
“.” 代表该服务在此域中绝对不可用。

客户端查询到多条记录的时候,使用优先级最高的记录。

对相同优先级的记录,按照权重选择,记录的权重越高,被选择的可能性越高。

选择的时候,将所有记录的权重值累加,得到一个选择区间[0,sum],每个记录在[0,sum]中占据一段连续的、长度为自身权重值区间。然后生成一个[0,sum]中的随机数,随机数落在的区间所属的记录就是被选择的记录。

注意事项

  1. 在使用DNS SRV的时候,要注意DNS Client是否按照预期的方式处理收到的SRV记录。当前DNS SRV只能够负责提供服务地址列表,对这个列表如何解读,完全取决于Client的实现。

  2. rfc-1035中规定,通过UDP协议传输DNS响应时,UDP报文的负载不能超过512字节,在添加SRV记录的时候,要特别注意。(通过TCP传输时没有512字节的限制)

  3. 当一个服务地址有多个相同优先级的SRV记录的时候,Client会按照这些SRV的权重分配请求。下一次向服务发起的请求可能是发送到了另一个地址。

  4. 在通过SRV记录的权重来分配请求的时候,使用的是本地缓存的DNS记录,所以不能实时地感知到服务的地址列表变化。除非将TTL设置的非常短暂,但这样将会频繁地查询DNS服务器。

示例如下

EDNS( DNS扩展机制)

EDNS即Extension Mechanisms for DNS。最新定义在RFC 6891(替换了RFC2671)向DNS添加了扩展机制。EDNS在遵循已有的DNS报文格式的基础上增加一些字段,来支持更多的DNS请求业务,许多新的DNS使用和协议扩展依赖于这些扩展的存在。

需要注意的是,像DNS服务器这样一个大型且广泛应用的系统软件,新增加扩展协议的时候一定要考虑到向后兼容性(backward compatibility),即你增加了你这个特性的消息传输给未支持该特性的服务器时,后者依然能正确处理。

EDNS是DNS的逐跳( hop-by-hop )扩展。

EDNS0是第一个被广泛使用的EDNS协议版本。它提供了DNS消息的扩展格式,允许DNS协议支持更大的消息长度和更多的资源记录类型. EDNS(1)也是一种DNS协议扩展,用于增加DNS消息中的额外信息字段,与EDNS(0)相比,EDNS(1)的扩展性能更强

为什么要有EDNS?

RFC2671中指出EDNS被提出来的几个理由:

  • DNS协议头部的第二个16字节中都已经被用的差不多了,需要添加新的返回类型(RCODE)和标记(FLAGS)来支持其他需求;

  • 只为标示domain类型的标签分配了两位,现在已经用掉了两位(00标示字符串类型,11表示压缩类型),后面如果有更多的标签类型则无法支持;

  • 当初DNS协议中设计的用UDP包传输时包大小限制为512字节,现在很多主机已经具备重组大数据包的能力,所以要有一种机制来允许DNS请求方通知DNS服务器让其返回大包;

以后我们会看到,DNSSEC机制(DNS Security Extensions)ECS(edns-client-subnet)机制等都需要有EDNS的支持。

EDNS的内容是什么

怎样在DNS消息协议的基础上再增加一些字段呢?为了保持向后兼容性,更改已有的DNS协议格式是不可能的,所以只能在DNS协议的数据部分中做文章。

由此,EDNS中引入了一种新的伪资源记录 OPT(一种特殊的RR),之所以叫做伪资源记录是因为它不包含任何DNS数据,OPT RR不能被cache、不能被转发、不能被存储在zone文件中。OPT被放在DNS通信双方(requestor和responsor)DNS消息的Additional区域中。

OPT 伪RR介绍

OPT RR 有时称为meta RR一般存放在Additional区域中。其对应的RR TYPE值为41 。

线状数据格式表示

OPT RR遵循标准RR格式,但相关的含义会和标准的RR格式有些差别,每个字段定义如下:

1
2
3
4
5
6
7
8
9
10
+------------+--------------+------------------------------+
| Field Name | Field Type | Description |
+------------+--------------+------------------------------+
| NAME | domain name | MUST be 0 (root domain) | 固定为空
| TYPE | u_int16_t | OPT (41) | 固定为41(0x29)
| CLASS | u_int16_t | requestor's UDP payload size |
| TTL | u_int32_t | extended RCODE and flags | 扩展的DNS消息头部
| RDLEN | u_int16_t | length of all RDATA |
| RDATA | octet stream | {attribute,value} pairs | KV类型的可变部分
+------------+--------------+------------------------------+

TTL字段说明

原来的TTL字段被用来存储扩展消息头部中的RCODE和flags,它的格式如下:

1
2
3
4
5
6
              +0 (MSB)                            +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | EXTENDED-RCODE | VERSION |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | DO| Z |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

EXTENDED-RCODE
高位8个bit是扩展RCODE(返回状态码),这8个bit加上DNS头部的4bit总共有12bit(8bit在高位),这样就可以表示更多的返回类型;
Forms the upper 8 bits of extended 12-bit RCODE (together with the
4 bits defined in [RFC1035]. Note that EXTENDED-RCODE value 0
indicates that an unextended RCODE is in use (values 0 through
15).

VERSION
表示EDNS的版本(EDNS根据支持不同的扩展内容会有很多版本),
Indicates the implementation level of the setter. Full
conformance with this specification is indicated by version ‘0’.
Requestors are encouraged to set this to the lowest implemented
level capable of expressing a transaction, to minimise the
responder and network load of discovering the greatest common
implementation level between requestor and responder. A
requestor’s version numbering strategy MAY ideally be a run-time
configuration option.
If a responder does not implement the VERSION level of the
request, then it MUST respond with RCODE=BADVERS. All responses
MUST be limited in format to the VERSION level of the request, but
the VERSION of each response SHOULD be the highest implementation
level of the responder. In this way, a requestor will learn the
implementation level of a responder as a side effect of every
response, including error responses and including RCODE=BADVERS.

RDATA 字段说明

RDATA中可能包含零个或多个option。每个option必须视为一个位字段。每个option的格式如下:

1
2
3
4
5
6
7
8
9
10
              +0 (MSB)                            +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | OPTION-CODE |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | OPTION-LENGTH |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4: | |
/ OPTION-DATA /
/ /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

OPTION-CODE :由IANA分配,参考

OPTION-LENGTH: OPTION-DATA的长度

OPTION-DATA: OPTION-CODE对应的内容, 具体实现依赖于具体RFC定义,如ECS

EDNS 应用实现

ECS

ECS即ENS Client Subnet。 是EDNS(0)中的一个OPT,它允许递归 DNS 解析器为其代表进行DNS查询的主机或客户端指定子网。这通常旨在通过允许更好地使用基于 DNS 的负载平衡来在客户端计算机不一定靠近递归解析器时选择客户端附近的服务地址,从而帮助加快从内容传递网络传递数据的速度。

ECS 的详细内容可参考RFC7871

ECS option 数据格式

ECS基于设置OPT伪RR的RDATA来实现的。

1
2
3
4
5
6
7
8
9
10
11
12
             +0 (MSB)                            +1 (LSB)
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: | OPTION-CODE |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: | OPTION-LENGTH |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4: | FAMILY |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
6: | SOURCE PREFIX-LENGTH | SCOPE PREFIX-LENGTH |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
8: | ADDRESS... /
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  • OPTION-CODE: 长度为2个字节,固定为 8 (0x00 0x80)由 IANA 统一规定对应的编码序号。
  • OPTION-LENGTH:长度为2个字节,代表了后续的FAMILY、 SOURCE PREFIX-LENGTH 、SCOPE PREFIX-LENGTH 、ADDRESS等内容的总长度。
  • FAMILY:2个字节,标识ADDRESS的地址族,由IANA统一确定地址族编码序号,ipv4为1,ipv6为2
  • SOURCE PREFIX-LENGTH:1个字节,标识要查找的ADDRESS数据的最左边的有效位数即IP地址ADDRESS 宏的网络号的位数,ipv4最大32,ipv6最大128。在应答结果中返回请求时指定的网络号的位数
  • SCOPE PREFIX-LENGTH :在查询请求中固定为0;在应答数据中标识应答数据ADDRESS的最左边的有效位数即IP地址ADDRESS 的网络号的位数
  • ADDRESS:就是设置的SubNet的IP地址,依据上面的FAMILY

DNSSEC

DNSSEC( DNS Security Extensions) 即DNS安全扩展.DNSSEC是一种基于EDNS0的协议扩展,用于提供DNS域名解析的安全性和完整性。DNSSEC可以保护DNS查询和响应的完整性,防止DNS欺骗攻击和DNS污染攻击

什么是SOA?

SOA,即Start Of Authority,放在 zone file 中,用于描述这个 zone 负责的 name server,version number…等资料,以及当 slave server 要备份这个 zone 时的一些参数。

每个 zone file 中必须有且仅有一条 SOARR ,并在 zone file 中作为第一条资源记录保存。

举个栗子:

1
2
3
4
5
6
@ IN SOA lv3ns1.ffdns.net. webmaster.ffdns.net. (
2009092868 ; Serial
604800 ; Refresh
3600 ; Retry
2419200 ; Expire
3600 ) ; Minimum

第一行:@指代该 zone ; lv3ns1.ffdns.net.是该 zone 的授权主机;webmaster.ffdns.net.代表[webmaster@ffdns.net](mailto:webmaster@ffdns.net)`,即该 zone 的管理者信箱。

Serial:代表 zone file 的版本,每当 zone file 内容有变动,name server 管理者就应该增加这个号码,因为 slave 会将这个号码与其 copy 的那份比对以便决定是否要再 copy 一次(即进行 zone transfer )。

Refresh: slave server 每隔这段时间(秒),就去检查 master server 上的 serial number 。

Retry:当 slave server 无法和 master 进行 serial check 时,要每隔这段时间(秒) retry 一次。

Expire:当时间超过 Expire 所定的秒数而 slave server 都无法和 master 取得连络,那么 slave 会删除自己的这份 copy 。

Minimum:代表这个 zone file 中所有 record 的内定的 TTL 值,也就是其它的 DNS server cache 这笔 record 时,最长不应该超过这个时间。

名词解释

名词 解释
逐跳扩展 是一种网络协议设计中的扩展方式,它允许协议在数据包中添加自定义的扩展选项,而这些选项会在每一跳节点上进行处理和解析。
在逐跳扩展中,数据包会携带一个或多个扩展选项,这些选项在每一个跳的节点上被处理,然后转发到下一个节点。每一个节点只负责处理自己的扩展选项,而不影响其他选项或者原始数据包的内容。因此,逐跳扩展是一种比较灵活的扩展方式,能够让协议在不影响基本功能的情况下,添加额外的功能和特性。
逐跳扩展常常用于一些底层协议中,如IP协议、IPv6协议等。在这些协议中,逐跳扩展可以用来添加一些新的路由或者策略信息,或者用于网络诊断和测试等用途。另外,在一些应用层协议中,也可能会采用逐跳扩展,如DNS协议中的EDNS扩展就是一种基于逐跳扩展的设计。

参考

https://www.cnblogs.com/cobbliu/p/3188632.html

https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-11

https://www.iana.org/assignments/address-family-numbers/address-family-numbers.xhtml

https://asutorufa.github.io/posts/668530ca/

https://www.lijiaocn.com/%E6%8A%80%E5%B7%A7/2017/03/06/dns-srv.html
https://www.jianshu.com/p/27c3f95e7509


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!