Как использовать Resolv::DNS::Resource::Generic

Я хотел бы лучше понять, как Resolv::DNS обрабатывает записи, которые не поддерживаются напрямую. Эти записи представлены классом Resolv::DNS::Resource::Generic, но я не смог найти документацию о том, как получить данные из этой записи.

В частности, моя зона будет содержать записи SSHFP и TLSA, и мне нужен способ получить эти данные.

1 ответ

Благодаря обратному инжинирингу я нашел ответ - задокументировал его здесь, чтобы другие могли его увидеть.

Обратите внимание, что это включает недокументированные функции модуля Resolv::DNS, и реализация может со временем измениться.

Записи ресурсов, которые модуль Resolv::DNS не понимает, представлены не через класс Generic, а через подкласс, имя которого представляет тип и класс ответа DNS - например, будет представлена ​​запись SSHFP (тип 44) как Resolv::DNS::Resource::Generic::Type44_Class1

Объект будет содержать метод "data", который дает вам доступ к RDATA записи в простом двоичном формате.

Таким образом, чтобы получить доступ к записи SSHFP, вот как ее получить:

def handle_sshfp(rr) do
   # the RDATA is a string but contains binary data
   data = rr.data.bytes
   algo = data[0].to_s
   fptype = data[1].to_s
   fp = data[2..-1].to_s
   hex = fp.map{|b| b.to_s(16).rr.rjust(2,'0') }.join(':')
   puts "The SSHFP record is: #{fptype} #{algo} #{hex}"
end

Resolv::DNS.open do |dns|
   all_records = dns.getresources('myfqdn.example.com', Resolv::DNS::Resource::IN::ANY ) rescue nil
   all_records.each do |rr|
      if rr.is_a? Resolv::DNS::Resource::Generic then
         classname = rr.class.name.split('::').last
         handle_sshfp(rr) if classname == "Type44_Class1"
      end
   end
end
Другие вопросы по тегам