summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xnagios-check-soas72
1 files changed, 72 insertions, 0 deletions
diff --git a/nagios-check-soas b/nagios-check-soas
new file mode 100755
index 0000000..8d6f6fb
--- /dev/null
+++ b/nagios-check-soas
@@ -0,0 +1,72 @@
+#!/usr/bin/ruby
+
+require 'resolv'
+require 'optparse'
+require 'yaml'
+
+NAGIOS_STATUS = { :OK => 0, :WARNING => 1, :CRITICAL => 2, :UNKNOWN => -1 };
+@verbose = 0;
+@additional_nameservers = []
+
+def show_help(parser, code=0, io=STDOUT)
+ program_name = File.basename($0, '.*')
+ io.puts "Usage: #{program_name} [options] <domainname>"
+ io.puts parser.summarize
+ exit(code)
+end
+ARGV.options do |opts|
+ opts.on_tail("-h", "--help" , "Display this help screen") { show_help(opts) }
+ opts.on("-v", "--verbose" , String, "Be verbose") { @verbose += 1 }
+ opts.on("-a", "--add=HOST" , String, "Also check SOA on <nameserver>") { |val| @additional_nameservers << val }
+ opts.parse!
+end
+show_help(ARGV.options, 1, STDERR) if ARGV.length == 0
+
+warnings = []
+oks = []
+
+dns = Resolv::DNS.new
+ARGV.each{ |domain|
+ serial = []
+ nameservers = dns.getresources(domain, Resolv::DNS::Resource::IN::NS)
+ nameservernames = nameservers.collect{ |ns| ns.name.to_s }
+ nameservernames = nameservernames.concat @additional_nameservers
+ nameservernames.each{ |nameserver|
+ puts "Testing nameserver #{nameserver} for #{domain}" if @verbose > 0
+ arecords = dns.getresources(nameserver, Resolv::DNS::Resource::IN::A)
+ warnings << "Nameserver #{nameserver} for #{domain} has #{arecords.length} A records" if arecords.length != 1
+ arecords.each{ |a|
+ puts " Nameserver #{nameserver} is at #{a.address}" if @verbose > 0
+ resolver = Resolv::DNS.new({:nameserver => a.address.to_s})
+ begin
+ soas = resolver.getresources(domain, Resolv::DNS::Resource::IN::SOA)
+ rescue SystemCallError => e
+ warnings << "Could not resolve #{domain} on #{nameserver}: #{e.message}"
+ else
+ warnings << "Nameserver #{nameserver} for #{domain} returns #{soas.length} SOAs" if soas.length != 1
+ soas.each{ |soa|
+ puts " Nameserver #{nameserver} returns serial #{soa.serial} for #{domain}" if @verbose > 0
+ serial << soa.serial unless serial.include? soa.serial
+ }
+ end
+ resolver.close
+ }
+ }
+ case serial.length
+ when 0
+ warnings << "Found no serials for #{domain}"
+ when 1
+ oks << "#{domain} is at #{serial.first}"
+ else
+ warnings << "Nameservers disagree on serials for #{domain}: found #{serial.join(', ')}" if serial.length != 1
+ end
+}
+dns.close
+
+if warnings.length > 0
+ warnings.each{ |w| puts w }
+ exit NAGIOS_STATUS[:WARNING]
+else
+ oks.each{ |w| puts w }
+ exit NAGIOS_STATUS[:OK]
+end