64 lines
2.8 KiB
Python
64 lines
2.8 KiB
Python
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()
|