dnsPython中的TXT记录

dnsPython中的TXT记录,dns,dnspython,Dns,Dnspython,我已经实现了一个简单的DNS服务器。 它只是用一个TXT记录来响应。我正在主持会议 脚本作为NS服务器,例如.com。NS服务器是x.y.z.k.它 当我发布以下内容时效果良好: $dig demo.example.com@x.y.z.k ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_4.1 <<>> demo.example.com @x.y.z.k ;; global options: printcmd

我已经实现了一个简单的DNS服务器。 它只是用一个TXT记录来响应。我正在主持会议 脚本作为NS服务器,例如.com。NS服务器是x.y.z.k.它 当我发布以下内容时效果良好:

$dig demo.example.com@x.y.z.k

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_4.1 <<>> demo.example.com @x.y.z.k
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10028
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;demo.example.com. IN A

;; ANSWER SECTION:
demo.example.com. 1000 IN TXT "test message"
你们知道怎么回事吗?有趣的是如果我改变 响应类型为CNAME,而不是TXT, 它很好用

def dns_响应(响应、q、数据类型):
rrset=dns.rrset.from_text(q.name,1000,
dns.rdataclass.IN,dns.rdatatype.TXT,“测试消息”)
响应应答追加(rrset)
返回响应
def dns_正常(响应,q,数据=无,消息=“”):
返回dns\u响应(resp=resp,q=q,数据类型='OK')
def dns_错误(响应,q):
返回dns\u响应(resp=resp,q=q,数据类型='Error')
def requestHandler(地址、消息):
resp=无
消息id=ord(消息[0])*256+ord(消息[1])
logging.debug('msg id='+str(message_id))
如果消息\u id在服务\u id中:
#请求已被接受,请删除此消息
logging.debug('我已经在为这个请求提供服务')
返回
服务\u id.append(消息\u id)
msg=dns.message.from_wire(消息)
op=msg.opcode()
如果op==0:
#标准和反向查询
qs=msg.question
如果len(qs)>0:
q=qs[0]
debug('请求为'+str(q))
如果q.rdtype==dns.rdatatype.A:
resp=std_qry(msg)
其他:
#未实施
#resp=std_qry(msg)
resp=作出响应(qry=msg,RCODE=4)
其他:
#未实施
resp=作出响应(qry=msg,RCODE=4)
如果分别:
s、 发送至(分别发送至_wire(),地址)
def标准(msg):
qs=msg.question
logging.debug(str(len(qs))+“问题”。)
答案=[]
nxdomain=False
对于qs中的q:
resp=作出响应(qry=msg)
logging.critical('Sending…'))
返回dns_ok(resp,q)
def作出响应(qry=None,id=None,RCODE=0):
如果qry为无,id为无:
引发异常,“错误使用make_响应”
如果qry为无:
resp=dns.message.message(id)
#QR=1
resp.flags |=dns.flags.QR
如果RCODE!=1:
引发异常,“错误使用make_响应”
其他:
resp=dns.message.make_响应(qry)
#resp.flags |=dns.flags.AA
resp.flags |=dns.flags.RA
相应集合码(rcode)
返回响应
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s、 setsockopt(socket.SOL_socket,socket.SO_REUSEADDR,1)
s、 绑定(“”,53))
debug('绑定到UDP端口53')
服务_id=[]
尽管如此:
logging.debug('等待请求')
消息,地址=s.recvfrom(1024)
logging.debug('为请求提供服务')
requestHandler(地址、消息)

我可以看到一些真正的错误,它们会阻止这项工作:

  • 您正在将
    TXT
    记录返回到
    a
    记录查询-这可能是显示停止符
  • 您应该返回
    AA
    标志(权威答案),而不是
    RA
  • 你的标题说在授权和附加部分有两个答案,但是没有
  • 一旦服务ID已实际送达,您就不会将其从列表中删除
  • 此外,还有一些与协议相关的问题需要解决:

  • 当被要求时,您需要能够返回
    NS
    记录和
    SOA
    记录,否则您的委派可能无法可靠地工作
  • 查询匹配应该使用整个(源IP、源端口、查询ID)元组,而不仅仅是(查询ID)
  • 如果问题名称位于正确的域中,但不在正确的子域中,则应返回
    NXDOMAIN
    (rcode=3)
  • 如果问题名称与正确的子域匹配,但记录类型错误,则应返回
    NOERROR
    (rcode=0),而不是
    NOTIMPL
  • 如果问题名称根本不是正确域的一部分,则应返回
    拒绝的
    (rcode=5)
  • ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_4.1 <<>> demo.example.com
    ;; global options:  printcmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 10905
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;demo.example.com. IN A
    
    ;; Query time: 5837 msec
    ;; SERVER: 172.16.1.1#53(172.16.1.1)
    ;; WHEN: Tue Jul 20 04:01:27 2010
    ;; MSG SIZE  rcvd: 75