Какую кодировку использует application/dns-message?
Я пишу сервер DNS-over-HTTPS, который должен разрешать пользовательские имена, а не просто проксировать их на какой-то другой сервер DoH, например, Google. У меня возникли проблемы с правильным расшифровкой текста запроса.
Например, я получаю тело запроса, то есть в двоичном формате, а именно в javascript в типе Uint8 ArrayBuffer. Я использую следующий код, чтобы получить формат массива base64:
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) Нью-Джерси
Я также использовал этот «учебник» в качестве справочника, но они также декодируют аналогично отформатированный blob, и я получаю такую же чушь, как и раньше.
Информации о чем-то подобном в Интернете очень мало или вообще нет, и если это может помочь, стандарт DoH использует тип носителя application / dns-message для тела.
Если у кого-то есть представление о том, что я делаю не так или как я могу отредактировать вопрос, чтобы сделать его более понятным, пожалуйста, помогите мне, ура :)
1 ответ
Как указано в RFC:
- Определение типа носителя "приложение / dns-сообщение"
Полезные данные для типа носителя «application / dns-message» - это одно сообщение в формате DNS on-the-wire, определенном в разделе 4.2.1 [RFC1035], который, в свою очередь, относится к полному проводному формату, определенному в разделе 4.1 этого 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
Итак, ваше сообщение представляет собой DNS-запрос для
A
тип записи по имени
apnx-match.dotomi.com.
Также о:
Я пишу сервер DNS-over-HTTPS, который должен разрешать пользовательские имена,
Если вы не делаете этого для обучения (что является прекрасной целью), обратите внимание, что уже существует различное программное обеспечение серверов имен с открытым исходным кодом, которое выполняет DOH, поэтому вам не нужно изобретать его заново. Например: https://blog.nlnetlabs.nl/dns-over-https-in-unbound/