from decouple import config import datetime import logging import MySQLdb as m import dns.resolver def read_config(): zones_str = config('ZONES', default='example.com') zones = zones_str.split(',') dbhost = config('DB_HOST', 'localhost') dbport = int(config('DB_PORT', '3306')) dbdb = config('DB_DB', 'pdns') dbuser = config('DB_USER', 'test') dbpass = config('DB_PASS', 'testpass') master = config('DNS_MASTER', 'wile') return (zones,dbhost, dbport, dbuser, dbpass, dbdb, master) def main(): (zones, host, port, username, password, database, myname) = read_config() db = m.connect(host, username, password, database) for zone in zones: logging.debug(f"checking zone {zone}") # try to resolve dnskey.{zone} on all nameservers # dammit, my testserver is running on a weird port r = dns.resolver.Resolver() ns_str = config('NAMESERVERS', 'localhost:10053') nsarr = ns_str.split(',') expected = None for ns in nsarr: try: answer = r.resolve(qname=zone, rdtype='DNSKEY', tcp=False, search=ns) if not expected: expected = answer.rrset.to_text() expected = expected[expected.find('IN ')] else: answer_text = answer.rrset.to_text() answer_text = answer_text[answer_text.find('IN ')] if answer_text != expected: logging.debug(f"'{answer_text}' differs from '{expected}', bumping SOA record for {zone}") # I'm very confident this is more complicated than it needs to be... db.query(f"""SELECT id,content FROM records WHERE type='SOA' AND name='{zone}'""") result = db.store_result() row = result.fetch_row() (id,content) = row[0] carr = content.split() newdatestr = datetime.datetime.today().strftime("%Y%m%d01") if newdatestr[:8] == carr[2][:8]: count = int(carr[2][8:]) newcount = count + 1 newdatestr = f"{newdatestr[:8]}{newcount:02d}" carr[2] = newdatestr db.query(f"""UPDATE records SET content = '{' '.join(carr)}' WHERE id={id}""") db.commit() except: logging.error(f"{zone} has no DNSKEY") if __name__ == "__main__": logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', filename=config('LOG_FILENAME', './dnssec-fix.log'), level=config('LOG_LEVEL', 'DEBUG')) main()