在没有发送相关查询时对名称服务器的正确响应?
Proper response for a nameserver when no relevant query has been sent?
我有一个用 Python 编写的非常基本的名称服务器,它只使用 socket
和 dnslib
,主要用于 Let's Encrypt DNS-01 挑战响应,还有一些实验目的的A记录。
我的问题是,当查询到达服务器但它不包含服务器想要响应的相关数据时,名称服务器应该如何响应?
它应该忽略它吗?
我问这个问题是因为我一直在收到关于 ANY leth.cc
的查询,这些查询显然用于 DNS 放大攻击。在注意到这一点之前,我正在用一个空的答案部分来回复查询,现在我不会将任何东西发送回提供的地址。
我从
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
sock_dns.sendto(a.pack(), addr)
至
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
if len(a.rr) > 0:
sock_dns.sendto(a.pack(), addr)
这是可以接受的行为吗?
考虑到Patrick Mevzek的回答,我现在修改为
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
if not a.rr:
a.header.rcode = dnslib.RCODE.REFUSED
sock_dns.sendto(a.pack(), addr)
虽然这可能是对有效客户端的正确响应,但在正常操作下,对 leth.cc
的查询不应该到达服务器,因为除了我配置的 NS 记录之外,没有任何东西指向我的名称服务器在注册商DNS在线配置界面。这是他们的名称服务器,表明客户应该去向我的名称服务器询问他们无法回答的更具体查询的答案。
但是在 leth.cc
的查询到达我的服务器的情况下,这个查询很可能来自一个非常不寻常的来源。是否仍然可以使用 RCODE.REFUSED
来回答这些请求,或者请求是否可能以这种方式被欺骗,即 addr
包含不应联系的地址,以避免该地址的DDOS攻击?毕竟,这是一种放大攻击;那是反射的 DDOS 攻击吗?我不介意我的名称服务器受到 DDOS 攻击(那是我要解决的问题),我只是不希望它参与其中,以防万一。
此外,这不是解析名称服务器,如果找不到信息,它不会出去查询其他名称服务器。我不认为不回答不属于此名称服务器域的 qnames
的请求有什么不好。
忽略查询绝对不是您想要做的(在正常操作中),因为客户端随后会再次尝试,并在某个时候切换到另一个名称服务器,所以至少你给他们造成了延误,即使不是很糟糕的结果。
可能的 return 代码在 https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 中定义,大部分在 RFC 1035 中定义。
对于你的情况,我认为你有你需要的东西:REFUSED
它是这样定义的:
The name server refuses to
perform the specified operation for
policy reasons. For example, a name
server may not wish to provide the
information to the particular requester,
or a name server may not wish to perform a particular operation (e.g., zone
transfer) for particular data.
现在,您的名称服务器在某些域名上具有权威性。如果它收到其他人的查询,它应该说它对他们没有权威,这是 NXDOMAIN 或 RFC 1035 中定义的准确 RCODE 3:
Name Error - Meaningful only for
responses from an authoritative name
server, this code signifies that the
domain name referenced in the query does
not exist.
这是一个非常小的答案,因此您没有放大任何东西。您的服务器仍可能受到许多此类查询的影响,您可能决定实施速率限制(见下文)。确实,作为 UDP 的流量,您的服务器可能会回答受害者,而不是查询的真正来源,但不会放大,并且像世界上任何其他名称服务器一样也会这样做,因为这是所有基于 UDP 的协议的悲惨命运.
如果您回复查询的答案更大(例如,如果您尝试回复 ANY
,即使是您具有权威性的名称),DDOS 也会出现,就像这里的受害者一样收到大量流量,而攻击者几乎不需要发送给您。
此外,ANY
更像是一个(糟糕的)故障排除工具,用于递归名称服务器(如 "give me the current state of your cache for a specific label"),而不是权威名称服务器。目前有一些作品可以完全弃用它:https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/
现在你好像更多的是在讲操作问题,还有DDOS攻击。这是另一种情况,即使回复也可能代价高昂。目前的名称服务器为 "Response Rate Limiting" 实施了 RRL 机制,主要是通过降低回复率。
查看介绍此功能的 Bind 文章:https://kb.isc.org/article/AA-01000/0/A-Quick-Introduction-to-Response-Rate-Limiting.html
如果您担心自己的名称服务器会受到攻击,您可能希望为自己的名称服务器实现类似的功能。
我有一个用 Python 编写的非常基本的名称服务器,它只使用 socket
和 dnslib
,主要用于 Let's Encrypt DNS-01 挑战响应,还有一些实验目的的A记录。
我的问题是,当查询到达服务器但它不包含服务器想要响应的相关数据时,名称服务器应该如何响应?
它应该忽略它吗?
我问这个问题是因为我一直在收到关于 ANY leth.cc
的查询,这些查询显然用于 DNS 放大攻击。在注意到这一点之前,我正在用一个空的答案部分来回复查询,现在我不会将任何东西发送回提供的地址。
我从
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
sock_dns.sendto(a.pack(), addr)
至
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
if len(a.rr) > 0:
sock_dns.sendto(a.pack(), addr)
这是可以接受的行为吗?
考虑到Patrick Mevzek的回答,我现在修改为
data, addr = sock_dns.recvfrom(1024)
q = dnslib.DNSRecord.parse(data)
a = q.reply()
# add an answer if query is relevant
# a.add_answer(*dnslib.RR.fromZone(qname + " 30 IN TXT " + verification_code))
if not a.rr:
a.header.rcode = dnslib.RCODE.REFUSED
sock_dns.sendto(a.pack(), addr)
虽然这可能是对有效客户端的正确响应,但在正常操作下,对 leth.cc
的查询不应该到达服务器,因为除了我配置的 NS 记录之外,没有任何东西指向我的名称服务器在注册商DNS在线配置界面。这是他们的名称服务器,表明客户应该去向我的名称服务器询问他们无法回答的更具体查询的答案。
但是在 leth.cc
的查询到达我的服务器的情况下,这个查询很可能来自一个非常不寻常的来源。是否仍然可以使用 RCODE.REFUSED
来回答这些请求,或者请求是否可能以这种方式被欺骗,即 addr
包含不应联系的地址,以避免该地址的DDOS攻击?毕竟,这是一种放大攻击;那是反射的 DDOS 攻击吗?我不介意我的名称服务器受到 DDOS 攻击(那是我要解决的问题),我只是不希望它参与其中,以防万一。
此外,这不是解析名称服务器,如果找不到信息,它不会出去查询其他名称服务器。我不认为不回答不属于此名称服务器域的 qnames
的请求有什么不好。
忽略查询绝对不是您想要做的(在正常操作中),因为客户端随后会再次尝试,并在某个时候切换到另一个名称服务器,所以至少你给他们造成了延误,即使不是很糟糕的结果。
可能的 return 代码在 https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 中定义,大部分在 RFC 1035 中定义。
对于你的情况,我认为你有你需要的东西:REFUSED
它是这样定义的:
The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data.
现在,您的名称服务器在某些域名上具有权威性。如果它收到其他人的查询,它应该说它对他们没有权威,这是 NXDOMAIN 或 RFC 1035 中定义的准确 RCODE 3:
Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist.
这是一个非常小的答案,因此您没有放大任何东西。您的服务器仍可能受到许多此类查询的影响,您可能决定实施速率限制(见下文)。确实,作为 UDP 的流量,您的服务器可能会回答受害者,而不是查询的真正来源,但不会放大,并且像世界上任何其他名称服务器一样也会这样做,因为这是所有基于 UDP 的协议的悲惨命运.
如果您回复查询的答案更大(例如,如果您尝试回复 ANY
,即使是您具有权威性的名称),DDOS 也会出现,就像这里的受害者一样收到大量流量,而攻击者几乎不需要发送给您。
此外,ANY
更像是一个(糟糕的)故障排除工具,用于递归名称服务器(如 "give me the current state of your cache for a specific label"),而不是权威名称服务器。目前有一些作品可以完全弃用它:https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/
现在你好像更多的是在讲操作问题,还有DDOS攻击。这是另一种情况,即使回复也可能代价高昂。目前的名称服务器为 "Response Rate Limiting" 实施了 RRL 机制,主要是通过降低回复率。 查看介绍此功能的 Bind 文章:https://kb.isc.org/article/AA-01000/0/A-Quick-Introduction-to-Response-Rate-Limiting.html
如果您担心自己的名称服务器会受到攻击,您可能希望为自己的名称服务器实现类似的功能。