はじめに
何らかの原因でDNS情報をもらえない時に毎回思いついたものを「dig A XXXX.domain.co.jp」とかしていたので、まとめておいて一括で探そうよ。いつも検索しているものはなんだっけとかなるし。
コード
# coding:utf-8
@fqdn = ARGV[0]
if @fqdn.nil?
print "FQDN or is empty, please write like a \n"
print "\"ruby popular_record_search.rb sample.co.jp\"\n"
exit 1
end
def search(fqdn)
soa = {'soa' => [""]}
ns = {'ns' => [""]}
mx = {'mx' => ["", "mail.", "mx."]}
a = {'a' => ["", "www.", "ftp.", "mail.", "imap.", "pop.", "smtp.", "localhost."]}
txt = {'txt' => [""]}
records = [soa, ns, mx, a, txt]
records.each do |record|
record.each do |type, hosts|
puts ";; #{type} record"
hosts.each do |host|
answer = `dig #{type} #{host}#{@fqdn} +noall +answer |grep -v ^;`.sub("\n","")
unless answer == ""
puts answer
end
end
end
end
end
search(@fqdn)
exit 0
あまりに単純なんですが、それぞれのレコードごとに調べるホストをハッシュにしておいて、それらを配列にしてdigするっていうだけです。requireでそれ相応のものとかありそうですが、取り急ぎ感。
追記
指摘を頂いたので、resolv のライブラリを使った方法でちょっと書いてみた。入れ子が5段階でちょっとどうなのかなとか思うけれども。
# coding: utf-8
require 'resolv'
@domain = ARGV[0]
if @domain.nil?
print "DOMAIN or is empty, please write like a \n"
print "\"ruby popular_record_search.rb sample.co.jp\"\n"
exit 1
end
def search(fqdn)
resolv = Resolv::DNS.new(:nameserver =>['8.8.8.8'])
soa = {'SOA' => [""]}
ns = {'NS' => [""]}
mx = {'MX' => ["", "mail.", "mx."]}
a = {'A' => ["", "www.", "ftp.", "mail.", "imap.", "pop.", "smtp.", "localhost."]}
txt = {'TXT' => [""]}
records = [soa, ns, mx, a, txt]
records.each do |key|
key.each do |type, hosts|
puts "; #{type} RECORD"
hosts.each do |host|
fqdn = "#{host}#{@domain}"
case type
when 'SOA'
resolv.each_resource(fqdn, Resolv::DNS::Resource::IN::SOA) do |resource|
puts "TTL is #{resource.ttl}"
puts "#{fqdn}\tIN\t#{type}\t#{resource.mname}"
end
when 'NS'
resolv.each_resource(fqdn, Resolv::DNS::Resource::IN::NS) do |resource|
puts "#{fqdn}\tIN\t#{type}\t#{resource.name}"
end
when 'MX'
resolv.each_resource(fqdn, Resolv::DNS::Resource::IN::MX) do |resource|
puts "#{fqdn}\tIN\t#{type}\t#{resource.preference}\t#{resource.exchange}"
end
when 'A'
resolv.each_resource(fqdn, Resolv::DNS::Resource::IN::A) do |resource|
puts "#{fqdn}\tIN\t#{type}\t#{resource.address}"
end
when 'TXT'
resolv.each_resource(fqdn, Resolv::DNS::Resource::IN::TXT) do |resource|
puts "#{fqdn}\tIN\t#{type}\t#{resource.strings}"
end
end
end
end
end
end
search(@domain)
exit 0
なんとなくgoogleのDNSを仮指定しています。少し時間つかったのはresourceがどんなメソッドをもっているのかわからなかったので、.methodsで一覧見たりとか。表記は変わってしまったけど、一応名前解決はできるようになった。先の例はレコードが入っている列を抽出していただけだったけども、こっちはIP自体とかTTL自体とかをとれるので、いろいろ他の作業とかでも取り回しが良さそうでナイスです。
最後に
調べるホスト名で他も調べたほうが良いとか、よくあるホスト名とかしりたいです。このまま.zoneのファイルにするとかも場合によっては考えるか...です。あんまガンガン用途はなさそうですが。