def syscmd_check_bind_domain(domain): if re.match(base.EREG_DOMAIN_NAME, domain) == None: return [False, "Domena %s neprosla eregem" % domain] (out, err, status) = base.shell_exec2( "/usr/sbin/named-compilezone -o /dev/null %s %s" % (domain, os.path.join(DNS_MASTER_ZONE_PATH, domain))) if status <> 0: return [True, out + err] else: return [True, 'OK']
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_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, )]
def sign_and_compile(domain, srcfile, dstfile, increment_serial=False): # find domain TTL and possibly update zone serial domain_ttl = None src_lock_fh = open(srcfile, 'r') flock(src_lock_fh, LOCK_SH) srcfh = open(srcfile, 'r+') serial_updated = False line = None while line == None or line != '': line = srcfh.readline() mymatch = re.match('@\s+([0-9]+)\s+IN\s+SOA\s.*$', line) if mymatch != None: domain_ttl = int(mymatch.group(1)) if not increment_serial: break 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() if increment_serial and not serial_updated: raise Exception('Unable to find zone serial') if domain_ttl == None: raise Exception('Unable to get domain TTL') config = ConfigParser.ConfigParser() config_file = os.path.join(DNSSEC_KEYS_LOCATION, domain, 'config.ini') try: config_fp = open(config_file) flock(config_fp, LOCK_SH) config.readfp(config_fp) config_fp.close() except: config.add_section(domain) config.set(domain, 'src_file', srcfile) config.set(domain, 'dst_file', dstfile) config.set(domain, 'zone_ttl', domain_ttl) domain_keys = check_zone_keys(domain, domain_ttl, config) tmpfile = tempfile.NamedTemporaryFile(delete=False) tmpfile.write(open(srcfile).read()) for keyid in domain_keys.keys(): tmpfile.write('$INCLUDE %s\n' % (domain_keys[keyid]['filename'])) tmpfile.close() # sign zone myworkdir = os.getcwd() os.chdir(os.path.join(DNSSEC_KEYS_LOCATION, domain)) (out, err, res) = base.shell_exec2( 'dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o %s -t %s' % (domain, tmpfile.name)) if res != 0: raise Exception('Unable to sign zone %s, Stdout: %s, Stderr: %s', (domain, out, err)) os.chdir(myworkdir) config.set(domain, 'last_signature', int(time.time())) if os.path.exists(config_file): config_fp = open(config_file, 'r+') else: config_fp = open(config_file, 'w') flock(config_fp, LOCK_EX) config_fp.seek(0) config_fp.truncate() config.write(config_fp) config_fp.close() if not os.path.exists(dstfile): open(dstfile, 'w').close() dst_lock_fh = open(dstfile, 'r') flock(dst_lock_fh, LOCK_EX) (out, err, res) = base.shell_exec2('named-compilezone -o ' + dstfile + ' ' + domain + ' ' + tmpfile.name + '.signed') os.unlink(tmpfile.name + '.signed') os.unlink(tmpfile.name) dst_lock_fh.close() src_lock_fh.close() return res == 0