在Ruby中获取DNS TXT记录

13

我需要从 DNS 记录中获取 txt 字段。
是否有 Ruby API 可以做到这一点?

nslookup -q=txt xxxx.com
6个回答

24

尝试安装dnsruby gem。

该代码正在积极维护,并被用于一些重要的生产系统中。

require 'rubygems'
require 'dnsruby'
include Dnsruby

# Use the system configured nameservers to run a query
res = Dnsruby::Resolver.new
ret = res.query("google.com", Types.TXT)
print ret.answer

(该代码在MacOS X上测试-打印Google的SPF记录)

另请参见@Alex的答案,其更符合Ruby的习惯用语-Alex是 dnsruby 的作者。


链接无法使用。请使用此链接 - Penguin

22

不安装 gem 的情况下,可以使用 Ruby 标准库 Resolv::DNS 库:

require 'resolv'
txt = Resolv::DNS.open do |dns|
  records = dns.getresources("_dmarc.yahoo.com", Resolv::DNS::Resource::IN::TXT)
  records.empty? ? nil : records.map(&:data).join(" ")
end
#=> "v=DMARC1; p=reject; sp=none; pct=100; rua=mailto:dmarc-yahoo-rua@yahoo-inc.com, mailto:dmarc_y_rua@yahoo.com;"

getresources 返回一个请求的记录类名实例 (Resolv::DNS::Resource::IN::TXT) 数组。如果未找到 TXT 记录或主机名,则返回 nil;否则,我会映射记录、调用 data 获取值,然后将它们连接在一起。

通过将上面示例中的 TXT 替换为任何 DNS 记录类型 [TXT、NS、CNAME、MX 等],也可以查询。

TXT 记录是“非结构化”的,并用于主机名的增强数据,例如 SPF、DKIM、DMARC 配置。在实践中,可能只有一个 TXT 记录,但 RFC 没有说明可以有多少个。

阅读文档:http://www.ruby-doc.org/stdlib-2.1.1/libdoc/resolv/rdoc/index.html


很高兴看到有人提出了内置解决方案。谢谢! - siannopollo

9
require 'dnsruby'
Dnsruby::DNS.open {|dns|
  dns.each_resource("google.com", "TXT") {|rr| print rr}
    # or
  print dns.getresource("google.com", "TXT")}
}

3
Ruby提供了一个支持多线程的DNS解析库"Resolv"。Resolv可以在不阻塞整个Ruby解释器的情况下同时处理多个DNS请求。
获取DNS MX记录,请使用以下方法:
require "resolv"
    Resolv::DNS.open do |dns|
      ress = dns.getresources "infoir.com", Resolv::DNS::Resource::IN::MX
      p ress.map { |r| [r.exchange.to_s, r.preference] }
    end

获取DNS A记录

require "resolv"
    Resolv::DNS.open do |dns|
      ress = dns.getresources "infoir.com", Resolv::DNS::Resource::IN::A
      p ress.map { |r| [r.exchange.to_s, r.preference] }
    end

获取DNS TXT记录

require "resolv"
Resolv::DNS.open do |dns|
  ress = dns.getresources "infoir.com", Resolv::DNS::Resource::IN::TXT
  p ress.map { |r| [r.exchange.to_s, r.preference] }
end

2

尝试使用 Net::DNS gem。

这里有一个例子:

result = Net::DNS::Resolver.start("google.com", Net::DNS::TXT)
values = result.each_mx.map { |r| r.txt }
# "v=spf1 include:_spf.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all "

更详细的安装和使用说明可以在上面链接的Github页面找到。


我尝试使用Net::DNS::Resolver.start("waycoolblog.com", Net::DNS::TXT),但我无法获取txt字段的值。我应该如何正确使用它? - anusuya
我认为你使用得很正确,但它似乎出了问题,没有按照应该返回TXT记录。抱歉。 - Jakob Borg

-3

或者使用 system("nslookup -q=txt xxxx.com")


我在考虑不使用system(),因为它可能非常昂贵。 - anusuya
2
与 DNS 查找的成本相比,它不会很昂贵。 - nfm
这只适用于类Unix系统,而不适用于Windows或设备。对于大多数生产应用程序来说,这不是一个好的解决方案,但对于一次性脚本而言足够好用。@nfm:此方法将更加昂贵,因为您必须分叉进程、运行命令并仍然进行DNS查找。 - Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接