#!/usr/bin/python import ldns import unbound from optparse import OptionParser import sys from datetime import datetime, timedelta def parse_rrsig_expire(expirestring): expires = datetime(int(expirestring[:4]), int(expirestring[4:6]), int(expirestring[6:8]), int(expirestring[8:10]), int(expirestring[10:12]), int(expirestring[12:14])) delta = expires - datetime.utcnow() return delta def check_dnssec_expire(resolver, name, warn, crit): s, result = resolver.resolve(name) if 0 != s: pass s, packet = ldns.ldns_wire2pkt(result.packet) rrsigs = packet.rr_list_by_type(unbound.RR_TYPE_RRSIG, ldns.LDNS_SECTION_ANSWER).rrs() for rrsig in rrsigs: delta = parse_rrsig_expire(str(rrsig.rrsig_expiration())) if delta < crit: print "CRIT (%s) %s" % (delta, name) elif delta < warn: print "WARN (%s) %s" % (delta, name) def main(): parser = OptionParser() parser.add_option("-n", "--name", action="append", type="string", dest="names", help="DNS Names to check") parser.add_option("-a", "--ancor", action="store", type="string", dest="ancor", default="/etc/unbound/root.key", help="DNSSEC root ancor") parser.add_option("-w", "--warning-days", action="store", type=int, dest="warn", default=5, help="minimum remaining validity in days before a warning is issued") parser.add_option("-c", "--critical-days", action="store", type=int, dest="crit", default=2, help="minimum remaining validity in days before a warning is issued") opts, _args = parser.parse_args() resolver = unbound.ub_ctx() resolver.add_ta_file(opts.ancor) for name in opts.names: check_dnssec_expire(resolver, name, timedelta(opts.warn), timedelta(opts.crit)) if __name__ == "__main__": main()