我想更好地了解 Resolv::DNS 如何处理不直接支持的记录。这些记录由 Resolv::DNS::Resource::Generic 类表示,但我找不到有关如何从该记录中获取数据的文档。
具体来说,我的区域将包含 SSHFP 和 TLSA 记录,我需要一种方法来获取这些数据。
通过逆向工程,我找到了答案——在这里记录下来供其他人查看。
请注意,这涉及 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