Пример #1
0
def main():
    parser = argparse.ArgumentParser(
        description='Extract zonefiles from named.conf.')
    parser.add_argument('named_conf',
                        metavar='FILE',
                        type=str,
                        nargs=1,
                        help='the named.conf to parse')
    parser.add_argument('-w',
                        '--write',
                        metavar='DIR',
                        type=str,
                        help='Wwrite each extracted zonefile as its own file'
                        ' in DIR')
    parser.add_argument('-v',
                        '--verbose',
                        action='store_true',
                        help='verbose output')
    args = parser.parse_args()
    if args.verbose:
        LOG.setLevel(logging.INFO)
    else:
        LOG.setLevel(logging.WARNING)
    try:
        x = Extractor(args.named_conf[0])
        for zone in x.extract():
            if args.write is not None:
                zone.to_file(args.write)
            else:
                zone.to_stdout()
    except IOError as e:
        LOG.error(e)
Пример #2
0
    def deleteHost(self, host):
        """
        Delete host.

        @param host string: host
        """
        host = host.rstrip(".")
        map = self.map
        record = map.get(host)
        if not record:
            raise j.exceptions.RuntimeError("Invalid host name")

        for r in record:
            file = r["file"]
            old_ip = r["ip"]
            zone = dns.zone.from_file(file,
                                      os.path.basename(file),
                                      relativize=False)
            for k, v in zone.nodes.copy().items():
                if k.to_text() == "%s." % host:
                    zone.delete_node(k)
            # update version
            for k, v in zone.nodes.items():
                for ds in v.rdatasets:
                    if ds.rdtype == dns.rdatatype.SOA:
                        for item in ds.items:
                            item.serial += 1

            zone.to_file(file, relativize=False)
        self.restart()
Пример #3
0
    def updateHostIp(self, host, ip):
        """
        Update the IP of a host.

        @param host string: hostname
        @param ip   string: ip

        """
        map = self.map
        record = map.get(host)
        if not record:
            raise j.exceptions.RuntimeError("Invalid host name")

        for r in record:
            file = r["file"]
            old_ip = r["ip"]
            zone = dns.zone.from_file(file,
                                      os.path.basename(file),
                                      relativize=False)
            for k, v in zone.items():
                for dataset in v.rdatasets:
                    for item in dataset.items:
                        if hasattr(item, "address") and item.address == old_ip:
                            item.address = ip
                            zone.to_file(file)
        self.restart()
Пример #4
0
    def addRecord(self, domain, host, ip, klass, type, ttl):
        host = "%s." % host
        records  = [x for x in self.zones if x.domain == domain]
        if not records:
            raise RuntimeError("Invalid domain")
        
        record = records[0]
        file = record.file
        zone = dns.zone.from_file(file, os.path.basename(file),relativize=False)
        node = zone.get_node(host, create=True)
        
        if type == "A":
            t = dns.rdatatype.A
        
        if klass == "IN":
            k = dns.rdataclass.IN

        ds = node.get_rdataset(t, k, covers=dns.rdatatype.NONE, create=True)
        ds.ttl = ttl
        if type == "A" and klass == "IN":
            item = A(k, t, ip)
            ds.items.append(item)
        
        # update version
        for k, v in zone.nodes.iteritems():
            for ds in v.rdatasets:
                if ds.rdtype == dns.rdatatype.SOA:
                    for item in ds.items:
                        item.serial += 1
        
        zone.to_file(file, relativize=False)
        self.restart()
Пример #5
0
def zone_to_text(zone):
	after_tmp = tempfile.TemporaryFile(mode='w+t')
	zone.to_file(after_tmp, sorted=config.dnssec_order, relativize=config.relativize_zones)
	after_tmp.seek(0)
	after = after_tmp.read()
	after_tmp.close()
	return after
Пример #6
0
def modify_dns(new_IP):
    domain = "cap.com"
    zoneFile = "/etc/bind/zones/db.cap.com"

    zone = dns.zone.from_file(zoneFile, domain)

    change = "www"
    rdataset = zone.find_rdataset(change, rdtype='A')

    req_reload = False

    for rdata in rdataset:
        if rdata.address != new_IP:
            req_reload = True
            rdata.address = new_IP

    if req_reload:
        for (name, ttl, rdata) in zone.iterate_rdatas('SOA'):
            serial = rdata.serial + 1
            rdata.serial = serial

        zone.to_file(zoneFile)

        proc = Popen(["rndc", "reload", "cap.com"], stdout = PIPE, stderr = PIPE)
        out,err = proc.communicate()
        if err:
            print err
        else:
            pass
            #print "DNS zone modification complete"
    else:
        pass
Пример #7
0
    def addRecord(self, domain, host, ip, klass, type, ttl):
        host = "%s." % host
        records = [x for x in self.zones if x.domain == domain]
        if not records:
            raise RuntimeError("Invalid domain")

        record = records[0]
        file = record.file
        zone = dns.zone.from_file(file,
                                  os.path.basename(file),
                                  relativize=False)
        node = zone.get_node(host, create=True)

        if type == "A":
            t = dns.rdatatype.A

        if klass == "IN":
            k = dns.rdataclass.IN

        ds = node.get_rdataset(t, k, covers=dns.rdatatype.NONE, create=True)
        ds.ttl = ttl
        if type == "A" and klass == "IN":
            item = A(k, t, ip)
            ds.items.append(item)

        # update version
        for k, v in zone.nodes.iteritems():
            for ds in v.rdatasets:
                if ds.rdtype == dns.rdatatype.SOA:
                    for item in ds.items:
                        item.serial += 1

        zone.to_file(file, relativize=False)
        self.restart()
 def run(self):
     zone = dns.zone.from_xfr(dns.query.xfr(**self.config["query"]),
                              **self.config["zone"])
     if self.save:
         if not os.isdir("./dns-zones"):
             os.mkdir("./dns-zones/")
         zone.to_file(f"./dns-zones/{self.name}.txt", sorted=True)
     else:
         print(colored(zone.to_text().decode("ascii"), dark=True))
Пример #9
0
def main():
    """
    Main function, typically invoked by the __name__ check.
    """
    description = 'Create and verify ZONEMD digest in zone files.'
    parser = argparse.ArgumentParser(description=description)
    parser.add_argument('--check', '-c', action='store_true',
                        help="check ZONEMD in zone file")
    parser.add_argument('--algorithm', '-a',
                        help="set algorithm to use (defaults to sha384)",
                        choices=(['sha384', 'sha512']),
                        default='sha384')
    parser.add_argument('--generic', '-g', action='store_true',
                        help="treat ZONEMD as an unknown type (RFC 3597)")
    parser.add_argument('--placeholder', '-p', action='store_true',
                        help='output a placeholder digest')
    parser.add_argument('--origin', '-o', type=str, default=".",
                        help="zone origin")
    parser.add_argument('filename', nargs='+')
    args = parser.parse_args()

    # pylint: disable=protected-access
    if args.generic:
        zonemd.ZONEMD_AS_GENERIC = True
    else:
        # Monkey-patch the dns.rdatatype module so we use the
        # presentation format.
        dns.rdatatype._by_value[zonemd.ZONEMD_RTYPE] = "ZONEMD"
        dns.rdatatype._by_text["ZONEMD"] = zonemd.ZONEMD_RTYPE
        dns.rdtypes.ANY.__all__.append("ZONEMD")
        mod_tuple = (dns.rdataclass.IN, zonemd.ZONEMD_RTYPE)
        dns.rdata._rdata_modules[mod_tuple] = zonemd

    exit_code = 0
    for filename in args.filename:
        zone = dns.zone.from_file(filename, check_origin=False,
                                  relativize=False, origin=args.origin)
        if args.check:
            okay, err = zonemd.validate_zonemd(zone)
            if okay:
                print(f"{filename} has a valid digest")
            else:
                print(f"{filename} does NOT have a valid digest: {err}")
                exit_code = 1
        else:
            zone_rr = zonemd.add_zonemd(zone, zonemd_algorithm=args.algorithm)
            if not args.placeholder:
                zone_rr = zonemd.update_zonemd(zone,
                                               zonemd_algorithm=args.algorithm)
            digest_hex = binascii.b2a_hex(zone_rr.digest).decode()
            zonemd_filename = filename + ".zonemd"
            with open(zonemd_filename, "w") as output_fp:
                zone.to_file(output_fp, relativize=False)
            print(f"Wrote ZONEMD digest {digest_hex} to {zonemd_filename}")

    sys.exit(exit_code)
Пример #10
0
	def dnszone (account):
   	
		zone_file = "/etc/bind/db.local"
	
		domain = "localhost"
  
		try:

			
			zone = dns.zone.from_file(zone_file, domain)

	
			for (name, ttl, rdata) in zone.iterate_rdatas(SOA):	

				print rdata

				serial = rdata.serial

				new_serial = datetime.now().strftime("%Y%m%d%H%M%S")

    				print "Changing SOA serial from %s to %s" % (serial, new_serial)
							
				rdata.serial = int(new_serial)						
				rdata.mname = dns.name.Name(("ns1", "codeless-hosting", "co", ""))

				
				

			print "Adding record of type A:", account.domain

			NS_add = "@"

			target = dns.name.Name(("ns1", "codeless-hosting", "co", ""))

			print "Adding record of type NS:", NS_add

			rdataset = zone.find_rdataset(NS_add, rdtype=NS, create=True)

			rdata = dns.rdtypes.ANY.NS.NS(IN, NS, target)

			rdataset.add(rdata, ttl=86400)	
				
			rdataset = zone.find_rdataset("www", rdtype=A, create=True)

			rdata = dns.rdtypes.IN.A.A(IN, A, address="192.168.1.30")

			rdataset.add(rdata, ttl=86400)
	     
			new_zone_file = "/etc/bind/zones/db.%s" % account.domain
			
			zone.to_file(new_zone_file)

		
		except DNSException, e:

			print e
Пример #11
0
def delete(hostname=None, UUID=None):
    if mongo.db.users.find_one({'token': UUID}):
        zonefile = '/etc/bind/db.example.com'
        zone = dns.zone.from_file(zonefile, os.path.basename(zonefile))
        zone.delete_rdataset(hostname, dns.rdatatype.A)
        # restart bind for changes to take effect
        subprocess.call(["sudo", "rndc", "reload"])
        zone.to_file(zonefile)
        mongo.db.users.update({'username': session['username']},
                              {'$pull': {
                                  'fqdns': hostname
                              }})
        return {"message": "A-record removed hostname {}".format(hostname)}
    else:
        return {"message": "not authorized"}
Пример #12
0
    def write_bind_zone_file(self, ip_list: list) -> None:
        zone_origin = f"rev.{self.domain}"
        zone = dns.zone.Zone(origin=zone_origin)

        zone = self._add_bind_common(zone)

        for ip in ip_list:
            zone = self._add_to_zone(
                zone,
                f"{ip.exploded.replace(':', '-')}.rev.{self.domain}.",
                "AAAA",
                ip.exploded,
            )

        zone.to_file(f"{self.config_folder}/{zone_origin}")
Пример #13
0
def update_domain(domain, zonefile, secret):
    '''
    Updates the given domain with the new ACME secret.
    '''
    zone = dns.zone.from_file(zonefile, domain)

    # updata soa serial
    for (_, _, rdata) in zone.iterate_rdatas(SOA):
        rdata.serial += 1

    # update the acme challenge
    acme_record = zone.find_rdataset('_acme-challenge', rdtype=TXT)
    for rdata in acme_record:
        rdata.strings = [secret.encode("utf8")]

    zone.to_file(zonefile)
Пример #14
0
    def updateHostIp(self, host, ip):
        map = self.map
        record = map.get(host)
        if not record:
            raise RuntimeError("Invalid host name")

        for r in record:
            file = r['file']
            old_ip = r['ip']
            zone = dns.zone.from_file(file, os.path.basename(file),relativize=False)
            for k, v in zone.iteritems():
                for dataset in v.rdatasets:
                    for item in dataset.items:
                        if hasattr(item, 'address') and item.address == old_ip:
                            item.address = ip
                            zone.to_file(file)
        self.restart()
Пример #15
0
    def generate(self, domains: Iterable[str], filename: str):
        ttl = 3600
        origin = "rpz.local"

        def read_header():
            with open(filename, "r") as f:
                for line in f:
                    if not line.startswith("@"):
                        break
                    yield line

        try:
            # Read "header" only since it's expensive to parse everything.
            zone = dns.zone.from_text("\n".join(read_header()), origin=origin)
        except (dns.exception.DNSException, IOError):
            zone = dns.zone.Zone(origin)

        existing_soa_set = zone.get_rdataset("@", "SOA")
        zone.nodes.clear()

        soa_set = zone.find_rdataset("@", "SOA", create=True)
        if existing_soa_set is None:
            soa_set.ttl = 3600
            soa_set.add(
                dns.rdata.from_text("IN", "SOA",
                                    "@ hostmaster 0 86400 7200 2592000 86400"))
            logging.info("creating zone from scratch")
        else:
            soa_set.update(existing_soa_set)
            # Increment serial.
            serial = soa_set[0].serial + 1
            soa_set.add(soa_set[0].replace(serial=serial))
            logging.info("parsed existing header, new serial is %d", serial)

        in_ns = zone.find_rdataset("@", "NS", create=True)
        in_ns.ttl = ttl
        in_ns.add(dns.rdata.from_text("IN", "NS", "LOCALHOST."))

        in_cname_dot = dns.rdataset.from_text("IN", "CNAME", ttl, ".")
        for domain in domains:
            zone.find_node(domain, create=True).replace_rdataset(in_cname_dot)

        zone.to_file(filename, sorted=True)
        logging.info("block list has %d domains", len(zone.nodes) - 1)
Пример #16
0
    def write_ptr_zone_file(self, ip_list: list) -> None:
        """
        Function writes a BIND configuration file for the reverse DNS entry of the
        network
        """
        zone_origin = self._retrive_zone_origin(self.network)
        zone = dns.zone.Zone(origin=zone_origin)

        zone = self._add_bind_common(zone)

        for ip in ip_list:
            zone = self._add_to_zone(
                zone,
                f"{ip.reverse_pointer}.",
                "PTR",
                f"{ip.exploded.replace(':', '-')}.rev.{self.domain}.",
            )

        zone.to_file(f"{self.config_folder}/{zone_origin}")
Пример #17
0
    def updateHostIp(self, host, ip):
        map = self.map
        record = map.get(host)
        if not record:
            raise RuntimeError("Invalid host name")

        for r in record:
            file = r['file']
            old_ip = r['ip']
            zone = dns.zone.from_file(file,
                                      os.path.basename(file),
                                      relativize=False)
            for k, v in zone.iteritems():
                for dataset in v.rdatasets:
                    for item in dataset.items:
                        if hasattr(item, 'address') and item.address == old_ip:
                            item.address = ip
                            zone.to_file(file)
        self.restart()
Пример #18
0
    def _apply(self, plan):
        '''
        Arguments
        =========
        plan: octodns.provider.plan.Plan
        '''

        zone = dns.zone.Zone(plan.desired.name)

        soaset = dns.rdataset.Rdataset(dns.rdataclass.IN, dns.rdatatype.SOA)
        soaset.add(
            _create_rdata(dns.rdataclass.IN, dns.rdatatype.SOA, self.soa),
            self.soa_ttl)
        zone.replace_rdataset('@', soaset)

        for record in plan.desired.records:
            data = record.data
            name = record.name

            rdset = dns.rdataset.Rdataset(
                dns.rdataclass.IN, dns.rdatatype.from_text(record._type))

            if 'value' in data:
                rdset.add(_create_rdata(dns.rdataclass.IN,
                                        dns.rdatatype.from_text(record._type),
                                        data['value']),
                          ttl=int(data['ttl']))
            elif 'values' in data:
                for value in data['values']:
                    rdset.add(_create_rdata(
                        dns.rdataclass.IN,
                        dns.rdatatype.from_text(record._type), value),
                              ttl=int(data['ttl']))
            else:
                self.log.warning(
                    "neither value nor values found in {}".format(name))
                continue

            zone.replace_rdataset(name, rdset)

        zone.to_file(self.directory + '/' + plan.desired.name +
                     self.file_extension)
Пример #19
0
def append(ip_adres=None, hostname=None, UUID=None):
    if mongo.db.users.find_one({'token': UUID}):
        zonefile = '/etc/bind/db.example.com'
        zone = dns.zone.from_file(zonefile, os.path.basename(zonefile))
        rdataset = zone.find_rdataset(hostname, dns.rdatatype.A, create=True)
        rdata = dns.rdtypes.IN.A.A(dns.rdataclass.IN, dns.rdatatype.A,
                                   ip_adres)
        rdataset.add(rdata, 86400)
        zone.to_file(zonefile)
        subprocess.call(["sudo", "rndc", "reload"])
        filter = {'username': session['username']}
        update = {"$push": {"fqdns": hostname}}
        mongo.db.users.update_one(filter, update)
        return {
            "message":
            "new A-record with ip {} and hostname {} inserted".format(
                ip_adres, hostname)
        }
    else:
        return {"message": "not authorized"}
Пример #20
0
def main():
    parser = argparse.ArgumentParser(description="Extract zonefiles from named.conf.")
    parser.add_argument("named_conf", metavar="FILE", type=str, nargs=1, help="the named.conf to parse")
    parser.add_argument(
        "-w", "--write", metavar="DIR", type=str, help="Wwrite each extracted zonefile as its own file" " in DIR"
    )
    parser.add_argument("-v", "--verbose", action="store_true", help="verbose output")
    args = parser.parse_args()
    if args.verbose:
        LOG.setLevel(logging.INFO)
    else:
        LOG.setLevel(logging.WARNING)
    try:
        x = Extractor(args.named_conf[0])
        for zone in x.extract():
            if args.write is not None:
                zone.to_file(args.write)
            else:
                zone.to_stdout()
    except IOError as e:
        LOG.error(e)
Пример #21
0
 def deleteHost(self, host):
     host = host.rstrip('.')
     map = self.map
     record = map.get(host)
     if not record:
         raise RuntimeError("Invalid host name")
     
     for r in record:
         file = r['file']
         old_ip = r['ip']
         zone = dns.zone.from_file(file, os.path.basename(file),relativize=False)
         for k, v in zone.nodes.copy().iteritems():
             if k.to_text() == "%s." % host:
                 zone.delete_node(k)
         # update version
         for k, v in zone.nodes.iteritems():
             for ds in v.rdatasets:
                 if ds.rdtype == dns.rdatatype.SOA:
                     for item in ds.items:
                         item.serial += 1
         
         zone.to_file(file, relativize=False)
     self.restart()
Пример #22
0
def main():
    parser = argparse.ArgumentParser(
        description='Extract zonefiles from named.conf.')
    parser.add_argument('named_conf', metavar='FILE', type=str, nargs=1,
                        help='the named.conf to parse')
    parser.add_argument('-w', '--write', metavar='DIR', type=str,
                        help='Wwrite each extracted zonefile as its own file'
                        ' in DIR')
    parser.add_argument('-v', '--verbose', action='store_true',
                        help='verbose output')
    args = parser.parse_args()
    if args.verbose:
        LOG.setLevel(logging.INFO)
    else:
        LOG.setLevel(logging.WARNING)
    try:
        x = Extractor(args.named_conf[0])
        for zone in x.extract():
            if args.write is not None:
                zone.to_file(args.write)
            else:
                zone.to_stdout()
    except IOError as e:
        LOG.error(e)
Пример #23
0
    if options.output_format == "dns":
        zone = zeroconf_to_zone(target_zone=options.target_zone,
                                target_ns=options.zone_xfr_from,
                                zeroconf_results=results,
                                locmap=eval(options.location_map),
                                priomap=eval(options.priority_map),
                                ttl=options.ttl)
    elif options.output_format == "json":
        zone = zeroconf_to_json(zeroconf_results=results)

    if not zone:
        sys.exit()

    if cgi_mode:
        print 'Content-Type: text/{format}' % options.output_format
        print

    if options.output_format == "dns":
        if options.output_rrset:
            zone.delete_node('@')
        zone.to_file(sys.stdout)
    elif options.output_format == "json":
        print zone

except:
    if cgi_mode:
        print 'Content-Type: text/plain'
        print
    raise
Пример #24
0
def writeZone(ctxt, zone, fp):
    fp.write(';; -*- coding: utf-8{config} -*-\n'.format(
        config=(('; dnssync-config: ' + ctxt.config) if ctxt.config else '')))
    fp.write('$ORIGIN {domain}\n'.format(domain=ctxt.domain))
    zone.to_file(fp, relativize=False)
Пример #25
0
    return dns.zone.from_text(zone_text, origin)

def update_serial(zone):
    soa = zone.get_rdataset('@', dns.rdatatype.SOA)[0]
    soa.serial += 1

def usage(code=0):
    print('Usage: update-zonefile.py zonefile origin')
    exit(code)

if len(sys.argv) != 3:
    usage(1)

zonefile = sys.argv[1]
origin = sys.argv[2]

zone = load_zone(zonefile, origin)
update_serial(zone)

domains = parse_lists(origin)

zone.to_file(zonefile)

with Path(zonefile).open('a') as f:
    for d in (sorted(domains)):
        f.write(d + ' IN CNAME drop.sinkhole.\n')
        if config['wildcard_block']:
            f.write('*.' + d + ' IN CNAME drop.sinkhole.\n')
            
print("Done")
Пример #26
0
def write_zone_to_file(zone_file, zone, absolute_names):
    zone.to_file(zone_file, sorted=True, relativize=(not absolute_names))
Пример #27
0
        new_serial = serial + 1
        print "Cambiando serial del SOA de %d a %d" % (serial, new_serial)
        rdata.serial = new_serial

    node_delete = "www2"
    print "Eliminando nodo", node_delete
    zone.delete_node(node_delete)

    A_change = "mail"
    new_IP = "192.168.2.100"
    print "Cambiando IPV4 del nodo", A_change, "al", new_IP
    rdataset = zone.find_rdataset(A_change, rdtype=A)
    for rdata in rdataset:
        rdata.address = new_IP

    rdataset = zone.find_rdataset("@", rdtype=NS)
    new_ttl = rdataset.ttl / 2
    print "Cambiando el TTL de todos los NS a", new_ttl
    rdataset.ttl = new_ttl

    A_add = "www3"
    print "Añadir nuevo nodo www3:", A_add
    rdataset = zone.find_rdataset(A_add, rdtype=A, create=True)
    rdata = dns.rdtypes.IN.A.A(IN, A, address="192.168.10.30")
    rdataset.add(rdata, ttl=86400)

    new_zone_file = "new.%s" % domain
    zone.to_file(new_zone_file)
except DNSException, e:
    print e.__class__, e
Пример #28
0
def cmd_export(args, r53):
    zone = _get_records(args, r53)
    print '$ORIGIN %s' % zone.origin.to_text()
    zone.to_file(sys.stdout, relativize=not args.full)
Пример #29
0
class commands:
    def __init__(self, simplicify):
        self.config = simplicify.SimplicifyConfig

    def ls_SRV(self, service_name):
        """
        Note: This function retrieves all configured S
        Args:
            service_name:  The symbolic name of the desired service, as defined in Assigned
        Numbers [STD 2] or locally.  An underscore (_) is prepended to
        the service identifier to avoid collisions with DNS labels that
        occur in nature.

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully listed all service records with the specified service name ({})".format(
            service_name)

        try:
            response = dns.resolver.query(service_name, 'SRV')
        except:
            explanation = "An unknown error occurred listing records for the specified service ({})".format(
                service_name)
            status = 500
            return [1, status, explanation, ""]

        results_list = []
        for rdata in response:
            results_list.append(str(rdata.target).rstrip('.'))

        payload = results_list
        returns = [prog_status, http_status, explanation, payload]

        return returns

    def ls_A(self, dns_name):
        """
        Note: This function retrieves all configured S
        Args:
            service_name:  The symbolic name of the desired service, as defined in Assigned
        Numbers [STD 2] or locally.  An underscore (_) is prepended to
        the service identifier to avoid collisions with DNS labels that
        occur in nature.

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully listed all service records with the specified DNS name ({})".format(
            dns_name)

        try:
            response = dns.resolver.query(dns_name, 'A')
        except:
            explanation = "An unknown error occurred listing records for the specified DNS name ({})".format(
                dns_name)
            status = 500
            return [1, status, explanation, ""]

        results_list = []
        for rdata in response:
            results_list.append(str(rdata))

        payload = results_list
        returns = [prog_status, http_status, explanation, payload]

        return returns

    def create_A(self, record_name, ip_address):
        """
        Note: This function creates an A record on a bind9 DNS server
        Args:
            record_name:  FQDN for record

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully created specified A record ({})".format(
            record_name)

        domain = "simplicify.com"
        print "Getting zone object for domain", domain
        zone_file = "/etc/bind/zones/db.%s" % domain

        try:
            zone = dns.zone.from_file(zone_file, domain)
            print "Zone origin:", zone.origin
        except DNSException, e:
            print e.__class__, e

        rdataset = zone.find_rdataset(record_name, rdtype=A, create=True)
        rdata = dns.rdtypes.IN.A.A(IN, A, address=ip_address)
        rdataset.add(rdata, ttl=86400)
        new_zone_file = "new.db.%s" % domain

        try:
            zone.to_file(new_zone_file)
        except:
            explanation = "An unknown error occurred adding the specified A record ({})".format(
                dns_name)
            status = 500
            return [1, status, explanation, ""]

        payload = ""
        returns = {
            "prog_status": prog_status,
            "http_status": http_status,
            "explanation": explanation,
            "payload": payload
        }
        return returns
Пример #30
0
def generate_zone_file(origin):
    """Generates a zone file.
    
    Accepts the zone origin as string (no trailing dot).
     
    Returns the contents of a zone file that contains all the resource records
    associated with the domain with the provided origin.
    
    """
    Domain = cache.get_model('powerdns_manager', 'Domain')
    Record = cache.get_model('powerdns_manager', 'Record')
    
    the_domain = Domain.objects.get(name__exact=origin)
    the_rrs = Record.objects.filter(domain=the_domain).order_by('-type')
    
    # Generate the zone file
    
    origin = Name((origin.rstrip('.') + '.').split('.'))
    
    # Create an empty dns.zone object.
    # We set check_origin=False because the zone contains no records.
    zone = dns.zone.from_text('', origin=origin, relativize=False, check_origin=False)
    
    rdclass = dns.rdataclass._by_text.get('IN')
    
    for rr in the_rrs:
        
        # Add trailing dot to rr.name
        record_name = rr.name.rstrip('.') + '.'
        
        if rr.type == 'SOA':
            # Add SOA Resource Record
            
            # SOA content:  primary hostmaster serial refresh retry expire default_ttl
            bits = rr.content.split()
            # Primary nameserver of SOA record
            primary = bits[0].rstrip('.') + '.'
            mname = Name(primary.split('.'))
            # Responsible hostmaster from SOA record
            hostmaster = bits[1].rstrip('.') + '.'
            rname = Name(hostmaster.split('.'))
            
            rdtype = dns.rdatatype._by_text.get('SOA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SOA.SOA(rdclass, rdtype,
                mname = mname,
                rname = rname,
                serial = int(bits[2]),
                refresh = int(bits[3]),
                retry = int(bits[4]),
                expire = int(bits[5]),
                minimum = int(bits[6])
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'NS':
            # Add NS Resource Record
            rdtype = dns.rdatatype._by_text.get('NS')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.NS.NS(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'MX':
            # Add MX Resource Record
            rdtype = dns.rdatatype._by_text.get('MX')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.MX.MX(rdclass, rdtype,
                preference = int(rr.prio),
                exchange = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'TXT':
            # Add TXT Resource Record
            rdtype = dns.rdatatype._by_text.get('TXT')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.TXT.TXT(rdclass, rdtype,
                strings = rr.content.split(';')
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'CNAME':
            # Add CNAME Resource Record
            rdtype = dns.rdatatype._by_text.get('CNAME')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.CNAME.CNAME(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'A':
            # Add A Resource Record
            rdtype = dns.rdatatype._by_text.get('A')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.A.A(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'AAAA':
            # Add AAAA Resource Record
            rdtype = dns.rdatatype._by_text.get('AAAA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.AAAA.AAAA(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SPF':
            # Add SPF Resource Record
            rdtype = dns.rdatatype._by_text.get('SPF')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SPF.SPF(rdclass, rdtype,
                strings = rr.content.split(';')
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'PTR':
            # Add PTR Resource Record
            rdtype = dns.rdatatype._by_text.get('PTR')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.PTR.PTR(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SRV':
            # Add SRV Resource Record
            
            # weight port target
            weight, port, target = rr.content.split()
            
            rdtype = dns.rdatatype._by_text.get('SRV')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.SRV.SRV(rdclass, rdtype,
                priority = int(rr.prio),
                weight = int(weight),
                port = int(port),
                target = Name((target.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
            
    
    # Export text (from the source code of http://www.dnspython.org/docs/1.10.0/html/dns.zone.Zone-class.html#to_file)
    EOL = '\r\n'
    f = StringIO.StringIO()
    f.write('$ORIGIN %s%s' % (origin, EOL))
    zone.to_file(f, sorted=True, relativize=False, nl=EOL)
    data = f.getvalue()
    f.close()
    return data
Пример #31
0
def cmd_export(args, r53):
    zone = _get_records(args, r53)
    print '$ORIGIN %s' % zone.origin.to_text()
    zone.to_file(sys.stdout, relativize=not args.full)
Пример #32
0
def cmd_export(args):
    zone = _get_records(args)
    zone.to_file(sys.stdout)
Пример #33
0
        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully created specified SRV record (Service: {} Port: {} A Record: {})".format(service_name, service_port, A_record)

        domain = "simplicify.com"
        zone_file = "/etc/bind/zones/db.%s" % domain
        new_zone_file = "new.db.%s" % domain
        try:
            zone = dns.zone.from_file(zone_file, domain)
        except DNSException, e:
            print e.__class__, e
        n = dns.name.from_text(A_record)
        rdataset = zone.find_rdataset(service_name, rdtype='SRV', create=True)
        rdata = dns.rdtypes.IN.SRV.SRV(IN,SRV,0,0,service_port,target=n)
        rdataset.add(rdata, ttl=86400)
        print str(rdataset)
        print str(rdata)
        try:
            zone.to_file(new_zone_file)
        except:
                explanation = "An unknown error occurred adding the specified SRV record (Service: {} Port: {} A Record: {})".format(service_name, service_port, A_record)
                status = 500
                return [ 1, status, explanation, "" ]

        payload = ""
        returns = [ prog_status, http_status, explanation, payload ]

        return returns
Пример #34
0
    def main_process(self):
        """Main process editzone
        """
        def clean_up():
            if (tmp_file):
                os.unlink(tmp_file)

        tmp_file = ''
        # Get update session object
        error_str = ''
        try:
            update_session = DynDNSUpdate(settings['dns_server'],
                                    settings['dyndns_key_file'],
                                    settings['dyndns_key_name'],
                                    )
        except (socket.error, DynDNSCantReadKeyError, IOError) as exc:
            error_str = str(exc)
        # Process above error...
        if (error_str):
            log_error("%s" % error_str)
            sys.exit(os.EX_NOHOST)

        # Do AXFR to obtain current zone data
        msg = None
        try:
            (zone, dnskey_flag, nesc3param_flag) \
                = update_session.read_zone(self.zone_name)
        except NoSuchZoneOnServerError as exc:
            msg = str(exc)
        if msg:
            log_error(msg)
            sys.exit(os.EX_NOINPUT)
            
        # Only edit zone if not wrapping SOA serial number 
        if (not settings['wrap_serial'] and not settings['update_serial']
                and not settings['nsec3_seed'] and not settings['clear_nsec3']
                and not settings['clear_dnskey']):
            # Write zone out to a temporary file
            (fd, tmp_file) = tempfile.mkstemp(prefix=settings['process_name'] + '-',
                                    suffix='.zone')
            os.close(fd)
            zone.to_file(tmp_file)

            # Edit zone data
            old_stat = os.stat(tmp_file)
            editor = self._get_editor()
            try:
                output = check_call([editor, tmp_file])
            except CalledProcessError as exc:
                log_error("editor exited with '%s'." % exc.returncode)
                sys.exit(os.EX_SOFTWARE)
                
            new_stat = os.stat(tmp_file)
            if (not settings['force_update'] 
                    and old_stat[stat.ST_MTIME] == new_stat[stat.ST_MTIME]
                    and old_stat[stat.ST_SIZE] == new_stat[stat.ST_SIZE]
                    and old_stat[stat.ST_INO] == new_stat[stat.ST_INO]):
                log_info("File '%s' unchanged after editing - exiting." % tmp_file)
                clean_up()
                sys.exit(os.EX_OK)
     
            # Read in file and form zi structure
            zone = dns.zone.from_file(tmp_file, self.zone_name)
        # At the moment these values are just for the sake of it.
        zi = ZoneInstance(soa_refresh='5m', soa_retry='5m', soa_expire='7d', soa_minimum='600')
        for rdata in zone.iterate_rdatas():
            zi.add_rr(dnspython_to_rr(rdata))

        # Update Zone in DNS
        rcode, msg, soa_serial, *stuff = update_session.update_zone(
                            self.zone_name, zi, 
                            force_soa_serial_update=not(settings['no_serial']),
                            wrap_serial_next_time=settings['wrap_serial'],
                            nsec3_seed=settings['nsec3_seed'],
                            clear_nsec3=settings['clear_nsec3'],
                            clear_dnskey=settings['clear_dnskey']
                            )

        if rcode == RCODE_NOCHANGE:
            log_info(msg)
            sys.exit(os.EX_OK)

        # Delete temporary file
        clean_up()

        if rcode == RCODE_ERROR:
            log_warning(msg)
            sys.exit(os.EX_TEMPFAIL)
        elif rcode == RCODE_RESET:
            log_error(msg)
            sys.exit(os.EX_IOERR)
        elif rcode == RCODE_FATAL:
            log_error(msg)
            sys.exit(os.EX_IOERR)

        # Everything good - Lets GO!
        if (settings['verbose']):
            log_info(msg)
        else:
            log_debug(msg)
        sys.exit(os.EX_OK)
Пример #35
0
def generate_zone_file(origin):
    """Generates a zone file.
    
    Accepts the zone origin as string (no trailing dot).
     
    Returns the contents of a zone file that contains all the resource records
    associated with the domain with the provided origin.
    
    """
    Domain = get_model('powerdns_manager', 'Domain')
    Record = get_model('powerdns_manager', 'Record')
    
    the_domain = Domain.objects.get(name__exact=origin)
    the_rrs = Record.objects.filter(domain=the_domain).order_by('-type')
    
    # Generate the zone file
    
    origin = Name((origin.rstrip('.') + '.').split('.'))
    
    # Create an empty dns.zone object.
    # We set check_origin=False because the zone contains no records.
    zone = dns.zone.from_text('', origin=origin, relativize=False, check_origin=False)
    
    rdclass = dns.rdataclass._by_text.get('IN')
    
    for rr in the_rrs:
        
        # Add trailing dot to rr.name
        record_name = rr.name.rstrip('.') + '.'
        
        if rr.type == 'SOA':
            # Add SOA Resource Record
            
            # SOA content:  primary hostmaster serial refresh retry expire default_ttl
            bits = rr.content.split()
            # Primary nameserver of SOA record
            primary = bits[0].rstrip('.') + '.'
            mname = Name(primary.split('.'))
            # Responsible hostmaster from SOA record
            hostmaster = bits[1].rstrip('.') + '.'
            rname = Name(hostmaster.split('.'))
            
            rdtype = dns.rdatatype._by_text.get('SOA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SOA.SOA(rdclass, rdtype,
                mname = mname,
                rname = rname,
                serial = int(bits[2]),
                refresh = int(bits[3]),
                retry = int(bits[4]),
                expire = int(bits[5]),
                minimum = int(bits[6])
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'NS':
            # Add NS Resource Record
            rdtype = dns.rdatatype._by_text.get('NS')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.NS.NS(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'MX':
            # Add MX Resource Record
            rdtype = dns.rdatatype._by_text.get('MX')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.MX.MX(rdclass, rdtype,
                preference = int(rr.prio),
                exchange = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'TXT':
            # Add TXT Resource Record
            rdtype = dns.rdatatype._by_text.get('TXT')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.TXT.TXT(rdclass, rdtype,
                strings = [rr.content.strip('"')]
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'CNAME':
            # Add CNAME Resource Record
            rdtype = dns.rdatatype._by_text.get('CNAME')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.CNAME.CNAME(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'A':
            # Add A Resource Record
            rdtype = dns.rdatatype._by_text.get('A')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.A.A(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'AAAA':
            # Add AAAA Resource Record
            rdtype = dns.rdatatype._by_text.get('AAAA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.AAAA.AAAA(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SPF':
            # Add SPF Resource Record
            rdtype = dns.rdatatype._by_text.get('SPF')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SPF.SPF(rdclass, rdtype,
                strings = [rr.content.strip('"')]
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'PTR':
            # Add PTR Resource Record
            rdtype = dns.rdatatype._by_text.get('PTR')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.PTR.PTR(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SRV':
            # Add SRV Resource Record
            
            # weight port target
            weight, port, target = rr.content.split()
            
            rdtype = dns.rdatatype._by_text.get('SRV')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.SRV.SRV(rdclass, rdtype,
                priority = int(rr.prio),
                weight = int(weight),
                port = int(port),
                target = Name((target.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
            
    
    # Export text (from the source code of http://www.dnspython.org/docs/1.10.0/html/dns.zone.Zone-class.html#to_file)
    EOL = '\n'
    f = StringIO.StringIO()
    f.write('$ORIGIN %s%s' % (origin, EOL))
    zone.to_file(f, sorted=True, relativize=False, nl=EOL)
    data = f.getvalue()
    f.close()
    return data
Пример #36
0
def _check_zones(zone_list, add_rrsets, delete_rrsets):
    """Apply changes to zones and run named-checkzone.
    
    This function always returns None.  Its only effect is to raise an 
    exception if the updates cause named-checkzone to fail.
    
    This function will check to ensure that deleted records existed previously,
    and added records did not exist.  This duplicates the checks built into the
    DNS UPDATE message, but this is necessary because relying only on the DNS
    UPDATE constraints could mean that updates to one zone get processed but
    updates to another get rejected.  We want to try as hard as possible to make
    this all-or-nothing.
    """
    
    zones = {}
    
    # Acquire a copy of each zone.
    for zone in zone_list:
        axfr = dns.query.xfr(jinx_global_settings['DNS_NAMESERVER'], zone, relativize=False, port=int(jinx_global_settings['DNS_NAMESERVER_PORT']))
        zones[zone] = dns.zone.from_xfr(axfr, relativize=False)
    
    # Apply the updates.
    for rrset in delete_rrsets:
        zone = zones[_get_zone(rrset.name, zone_list)]
        
        new = _rrset_to_rdataset(rrset)
        existing = zone.get_rdataset(rrset.name, rrset.rdtype)
        
        # Are we deleting or modifying?  If an RRset with this name is in the 
        # add group, then it's actually a modification.
        if rrset.name in [r.name for r in add_rrsets]:
            action = "modify"
        else:
            action = "delete"
        
        if existing is None:
            raise JinxInvalidStateError("You are attempting to %s %s, but this record does not exist in DNS." %
                                        (action, _format_rrset_name(rrset)))
        elif not _rdatasets_are_equal(new, existing):
            raise JinxInvalidStateError("You are attempting to %s %s, but its value in DNS has changed since you constructed your update." %
                                        (action, _format_rrset_name(rrset)))
        
        zone.delete_rdataset(rrset.name, rrset.rdtype)
    
    for rrset in add_rrsets:
        zone = zones[_get_zone(rrset.name, zone_list)]
        
        if zone.get_rdataset(rrset.name, rrset.rdtype) is not None:
            raise JinxInvalidStateError("You are attempting to add %s, but this record already exists in DNS." % 
                                        _format_rrset_name(rrset))
        
        rdataset = _rrset_to_rdataset(rrset)
        zone.replace_rdataset(rrset.name, rdataset)
    
    for name, zone in zones.iteritems():
        zone_file = tempfile.NamedTemporaryFile()
        zone.to_file(zone_file, sorted=False, relativize=False)
        zone_file.flush()
        
        # Just flush, but don't close, the temp file, because Python temp files
        # are deleted once they're closed.
        
        try:
            checkzone = subprocess.Popen("/usr/sbin/named-checkzone -k fail -m fail -n fail -S ignore %s %s" % (name, zone_file.name),
                                         shell=True,
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE)
            checkzone.wait()
            
            if checkzone.returncode != 0:
                raise JinxInvalidRequestError("zone %s failed zone check:\n%s" % (name, checkzone.stdout.read()))
        except OSError, exception:
            # Perhaps I should wrap this in a JinxAPIServerError, but really,
            # if I just let it go up, the middleware will do that for me.
            
            raise 
Пример #37
0
    parser.add_argument('zonefile', help='path to zone file')
    parser.add_argument('origin', help='zone origin')
    args = parser.parse_args()

    os.chdir(os.path.dirname(os.path.realpath(__file__)))

    if not config['cache'].is_dir():
        config['cache'].mkdir(parents=True)

    zone = load_zone(args.zonefile, args.origin, args.raw_zone)
    update_serial(zone)

    domains = parse_lists(args.origin)

    tmpzonefile = Path(config['cache'], 'tempzone')
    zone.to_file(str(tmpzonefile))

    with tmpzonefile.open('a') as f:
        for d in (sorted(domains)):
            if d in config['domain_whitelist']:
                continue
            append_domain_to_zonefile(f, d)
            if config['wildcard_block']:
                append_domain_to_zonefile(f, '*.' + d)

    if args.no_bind:
        save_zone(tmpzonefile, args.zonefile, args.origin, args.raw_zone)
    else:
        if check_zone(args.origin, tmpzonefile):
            save_zone(tmpzonefile, args.zonefile, args.origin, args.raw_zone)
            reload_zone(args.origin)
Пример #38
0
#!/usr/bin/python
# bindnorm.py - "normalise" a bind zone file by expanding relative names.
# Tue Sep 23 10:03:35 SAST 2008

import dns.zone
import sys

if len(sys.argv)<2:
	sys.stderr.write("Usage: %s [zone fqdn]\n" % sys.argv[0])
	sys.stderr.write("Example: %s example.com < db.example.com > norm.db.example.com\n" % sys.argv[0])
	sys.exit(1)

zone = dns.zone.from_text(sys.stdin.read(), sys.argv[1], relativize=False, check_origin=False)
zone.to_file(sys.stdout, relativize=False)