application/dns-message 使用哪种编码?

Which encoding does application/dns-message use?

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

例如,我得到请求的主体,它是二进制格式的,具体是 javascript 中的 Uint8 ArrayBuffer 类型。我正在使用以下代码获取数组的 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);
}

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

AAABAAABAAAAAAABCmFwbngtbWF0Y2gGZG90b21pA2NvbQAAAQABAAApEAAAAAAAAE4ADABKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=

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

apnx-matchdotomicom)NJ

我也使用这个 "tutorial" 作为参考,但他们也解码了类似格式的 blob,我得到了与以前类似的废话。

互联网上关于此类内容的信息很少甚至没有,如果它有任何帮助,DoH 标准将 application/dns-message 媒体类型用于正文。

如果有人对我做错了什么或我如何编辑问题以使其更清楚有所了解,请帮助我,干杯:)

如 RFC 中所述:

  1. Definition of the "application/dns-message" Media Type

The data payload for the "application/dns-message" media type is a single message of the DNS on-the-wire format defined in Section 4.2.1 of [RFC1035], which in turn refers to the full wire format defined in Section 4.1 of that RFC.

所以您得到的正是正常 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

因此您的消息是对名称 apnx-match.dotomi.com.

上的 A 记录类型的 DNS 查询

另外关于:

I am writing DNS-over-HTTPS server which should resolve custom names,

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