def run(self): """docstring for run""" if not self.active: return None if self.last_run != None and self.last_run > (time.time() - self.interval): return None self.last_run = time.time() for domain in os.listdir(DNSSEC_KEYS_LOCATION): if os.path.isdir(os.path.join(DNSSEC_KEYS_LOCATION, domain)): config = ConfigParser.ConfigParser({ 'src_file': os.path.join(DNS_MASTER_ZONE_PATH, domain), 'dst_file': os.path.join(DNS_COMPILED_ZONE_PATH, domain), 'in_keyroll': 'False', 'keyroll_timestamp': '0', 'zone_ttl': '3600', }) try: config_fp = open( os.path.join(DNSSEC_KEYS_LOCATION, domain, 'config.ini'), 'r') flock(config_fp, LOCK_SH) config.readfp(config_fp) config_fp.close() except: continue zonefile = config.get(domain, 'src_file') compiled_file = config.get(domain, 'dst_file') in_keyroll = config.getboolean(domain, 'in_keyroll') zone_ttl = config.getint(domain, 'zone_ttl') try: last_signature = config.getint(domain, 'last_signature') except: continue keyroll_timestamp = config.getint(domain, 'keyroll_timestamp') if keyroll_timestamp == 0: keyroll_timestamp = last_signature if (last_signature < (time.time() - DNSSEC_ZONE_REHASH)) or ( in_keyroll and zone_ttl != None and keyroll_timestamp < (time.time() - zone_ttl)): compile_result = sign_and_compile(domain, zonefile, compiled_file, increment_serial=True) if compile_result == True: base.shell_exec('rndc reload ' + domain)
def dns_compile_zonefile(base_domain, zonefile, zonefile_compiled): #### return True #### if dns_detect_dnssec(zonefile_compiled): #If there are DNSSEC records in zonefile, use prepared function compile_result = mydns_sign_and_compile(base_domain, zonefile, zonefile_compiled, True) #return dnssec_write else: #If no dnssec is used, just increase serial and compile zone. increment_serial = True serial_updated = False line = None srcfh = open(zonefile,'r+') flock(srcfh,LOCK_EX) while line == None or line != '': line = srcfh.readline() if increment_serial and not serial_updated: mymatch = re.match('^(\s+([0-9]{10})\s*;\s*serial\s*)$',line) if mymatch != None: old_serial = int(mymatch.group(2)) today_serial = int(datetime.date.today().strftime('%Y%m%d00')) new_serial = max(old_serial,today_serial)+1 line = line.replace(mymatch.group(2),str(new_serial)) filepos = srcfh.tell() srcfh.seek(filepos-len(line)) srcfh.write(line) serial_updated=True srcfh.close() #Compile zone (out, err, res) = base.shell_exec2('named-compilezone -o '+zonefile_compiled+' '+ base_domain +' '+zonefile) compile_result = res == 0 os.utime(zonefile_compiled, None) if compile_result == True: base.shell_exec('rndc reload '+base_domain) return [True, "ok" ] else: return [True, "Zone not loaded:\n"+str(out)+"\n\n"+str(err)]
def syscmd_update_reverse(data): ip, ip6, hostname = base.xml_cut(data, ['ip', 'ip6', 'hostname']) hostname = str(hostname) if re.match(base.EREG_IP, ip) == None: if ip != '': return [False, 'invalid ip'] else: updateip4 = False else: updateip4 = True if re.match(base.EREG_IP6, ip6) == None: if ip6 != '': return [False, 'invalid ip6'] else: updateip6 = False else: updateip6 = True if re.match(base.EREG_DOMAIN_NAME, hostname) == None: if hostname != '': return [False, 'invalid domain name'] if updateip4: ipbase = ip.split('.')[0:3] ipname = str(ip.split('.')[3]) ipbase.reverse() ipzone = '.'.join(ipbase) + '.in-addr.arpa' if updateip6: ls = os.listdir('/var/named/reverse') zonefiles = [] for file in ls: mymatch = re.search('^(.*).ip6.arpa', file) if mymatch != None: zonefiles.append((mymatch.group(1), file)) if updateip6: updateip6 = False ip6list = ip6.split(':') ip6hex = '' for item in ip6list: if item == '': item = '0' * (8 - len(ip6list) + 1) * 4 else: item = '0' * (4 - len(item)) + item ip6hex += item ip6listhex = list(ip6hex) ip6listhex.reverse() ip6text = '.'.join(ip6listhex) for zonefile in zonefiles: if ip6text[-1 * len(zonefile[0]):] == zonefile[0]: ip6zoneshort = zonefile[0] ip6zone = zonefile[1] ip6name = ip6text[:-len(zonefile[0]) - 1] updateip6 = True break ip4updated = False if updateip4: zonefile = '/etc/bind/reverse/' + ipzone ip4fh = open(zonefile, 'r+') flock(ip4fh, LOCK_EX) lines = ip4fh.readlines() for key in range(len(lines)): mymatch = re.match( '^' + re.escape(ipname) + '(\s+[0-9]+)?\s+IN\s+PTR\s+[a-zA-Z0-9\.\-]+\.$', lines[key].strip('\n')) if mymatch != None: lines[key] = ipname + mymatch.group( 1) + ' IN PTR ' + hostname + '.\n' ip4updated = True mymatch = re.match('^(\s+)([0-9]+)(\s+\;\s*serial)$', lines[key]) if mymatch != None: lines[key] = mymatch.group(1) + str( int(mymatch.group(2)) + 1) + mymatch.group(3) + '\n' if ip4updated: ip4fh.seek(0) lines = ip4fh.writelines(lines) ip4fh.truncate() ip4fh.close() if sign_and_compile(ipzone, zonefile, os.path.join(DNS_COMPILED_ZONE_PATH, ipzone)): base.shell_exec('rndc reload ' + ipzone) else: return [False, 'Unable to sign zone'] else: ip4fh.close() ip6updated = False if updateip6 == True: zonefile = '/etc/bind/reverse/' + ip6zone ip6fh = open(zonefile, 'r+') flock(ip6fh, LOCK_EX) lines = ip6fh.readlines() popkey = None for key in range(len(lines)): mymatch = re.match( '^' + re.escape(ip6name) + '\s+IN\s+PTR\s+[a-zA-Z0-9\.\-]*\.$', lines[key].strip('\n')) if mymatch != None: if hostname == '': popkey = key else: lines[key] = ip6name + ' IN PTR ' + hostname + '.\n' ip6updated = True mymatch = re.match('^(\s+)([0-9]+)(\s+\;\s*serial)$', lines[key]) if mymatch != None: lines[key] = mymatch.group(1) + str( int(mymatch.group(2)) + 1) + mymatch.group(3) + '\n' if popkey != None: lines.pop(popkey) if ip6updated != True and hostname != '': lines.append(ip6name + ' IN PTR ' + hostname + '.\n') ip6updated = True if ip6updated: ip6fh.seek(0) lines = ip6fh.writelines(lines) ip6fh.truncate() ip6fh.close() if sign_and_compile( ip6zoneshort + '.ip6.arpa', zonefile, os.path.join(DNS_COMPILED_ZONE_PATH, ip6zoneshort + '.ip6.arpa')): base.shell_exec('rndc reload ' + ip6zoneshort + '.ip6.arpa') else: return [False, 'Unable to sign zone'] base.shell_exec('rndc reload %s.ip6.arpa' % ip6zoneshort) else: ip6fh.close() return [True, 'reverse record updated']
def syscmd_domain_update_dns(data): trigger_file = '/var/lock/rndc-trigger.lock' lock_file = '/var/lock/rndc-reconfig.lock' dns = parseString(data) domain = dns.getElementsByTagName('domain')[0].childNodes[0].data dnssec = bool(int( dns.getElementsByTagName('dnssec')[0].childNodes[0].data)) if re.match(base.EREG_DOMAIN_NAME, domain) == None: return [False, "Domena %s neprosla eregem" % domain] if os.path.exists(DNS_MASTER_ZONE_PATH): zonefile = os.path.join(DNS_MASTER_ZONE_PATH, domain) compiled_file = os.path.join(DNS_COMPILED_ZONE_PATH, domain) # check original zone serial, increment if needed old_serial = 0 if os.path.exists(zonefile): for line in open(zonefile): mymatch = re.match('^(\s+([0-9]{10})\s*;\s*serial\s*)$', line) if mymatch != None: old_serial = int(mymatch.group(2)) break serial_checked = False f = open(zonefile, "w+") flock(f, LOCK_EX) for line in dns.getElementsByTagName( 'zone')[0].childNodes[0].data.split('\n'): if not serial_checked: mymatch = re.match('^(\s+([0-9]{10})\s*;\s*serial\s*)$', line) if mymatch != None: serial_checked = True new_serial = int(mymatch.group(2)) if new_serial <= old_serial: line = line.replace(str(new_serial), str(old_serial + 1)) f.write(line + '\n') f.close() # pokud je zonovy soubor j*z v teto vterine upraven, pockame 1 vterinu, aby bylo zajisteno, ze mtime souboru se zmeni. # bind odmita znovu reloadnout zonu, pokud se ji nezmenil mtime v celych cislech try: st = os.stat(compiled_file) if int(st.st_mtime) == int(time.time()): time.sleep(1) except: open(compiled_file, 'w').close() pass lock_fh = () if dnssec: compile_result = sign_and_compile(domain, zonefile, compiled_file) else: if not dnssec and os.path.exists( os.path.join(DNSSEC_KEYS_LOCATION, domain)): base.rmrf(os.path.join(DNSSEC_KEYS_LOCATION, domain)) dst_lock_fh = open(compiled_file, 'r') flock(dst_lock_fh, LOCK_EX) (out, err, res) = base.shell_exec2('named-compilezone -o ' + compiled_file + ' ' + domain + ' ' + zonefile) compile_result = res == 0 dst_lock_fh.close() os.utime(compiled_file, None) if compile_result == True: if update_master_config(domain): base.bind_restart_lock.acquire() base.trigger_update(base.bind_restart_data) base.bind_restart_lock.release() else: base.shell_exec('rndc reload ' + domain) return [True, "ok"] else: return [True, "Zone not loaded:\n" + str(out) + "\n\n" + str(err)] else: return [False, "adresar %s neexistuje" % (DNS_MASTER_ZONE_PATH, )]