首页 > 解决方案 > application/dns-message 使用哪种编码?

问题描述

我正在编写 DNS-over-HTTPS 服务器,它应该解析自定义名称,而不仅仅是将它们代理到其他 DoH 服务器,如 Google 的。我无法正确解码请求的正文。

例如,我得到请求正文,即二进制格式,特别是在 Uint8 ArrayBuffer 类型的 javascript 中。我正在使用以下代码来获取数组的 ba​​se64 格式:

function _arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return btoa(binary);
}

结果我得到了这样的结果:

AAABAAABAAAAAAABCmFwbngtbWF0Y2gGZG90b21pA2NvbQAAAQABAAApEAAAAAAAAE4ADABKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

现在,根据RCF8484标准,这应该被解码为 base64url,但是当我这样解码时,我得到以下信息:

apnx-matchdotomicom)NJ

我还使用了这个“教程”作为参考,但它们也解码了类似格式的 blob,我得到了与以前类似的废话。

互联网上几乎没有关于此类信息的信息,如果有任何帮助,DoH 标准使用应用程序/dns-message 媒体类型作为正文。

如果有人对我做错了什么或如何编辑问题以使其更清楚有一些见解,请帮助我,欢呼:)

标签: javascripthttphttpsdnsdns-over-https

解决方案


如 RFC 中所述:

  1. “application/dns-message”媒体类型的定义

“application/dns-message”媒体类型的数据有效负载是 [RFC1035] 的第 4.2.1 节中定义的 DNS 在线格式的单个消息,它又指的是第 4.2.1 节中定义的完整有线格式该 RFC 的 4.1。

所以你得到的正是在正常 DNS over 53 案例中通过网络发送的内容。

我建议您使用一个 DNS 库,该库应该有一个from_wire或类似的方法,您可以向其提供此内容并取回一些结构化数据。

在 Python 中显示一个包含您提供的内容的示例:

In [1]: import base64

In [3]: import dns.message

In [5]: payload = 'AAABAAABAAAAAAABCmFwbngtbWF0Y2gGZG90b21pA2NvbQAAAQABAAApEAAAAAAAAE4ADABKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='

In [7]: raw = base64.b64decode(payload)

In [9]: msg = dns.message.from_wire(raw)

In [10]: print msg
id 0
opcode QUERY
rcode NOERROR
flags RD
edns 0
payload 4096
option Generic 12
;QUESTION
apnx-match.dotomi.com. IN A
;ANSWER
;AUTHORITY
;ADDITIONAL

A因此,您的消息是对名称记录类型的 DNS 查询apnx-match.dotomi.com.

还有关于:

我正在编写 DNS-over-HTTPS 服务器,它应该解析自定义名称,

如果您不这样做是为了学习(这是一个很好的目标),请注意已经有各种开源名称服务器软件可以执行 DOH,因此您无需重新发明它。例如:https ://blog.nlnetlabs.nl/dns-over-https-in-unbound/


推荐阅读