Beispiel #1
0
def create_txt_record(
        domain_name, token,
        name_server_ip,
        keyring, keyalgorithm=dns.tsig.HMAC_MD5,
        ttl=300,
        sleep=5,
        timeout=10
        ):
    logger.info(' + Creating TXT record "%s" for the domain _acme-challenge.%s'
                % (token, domain_name))

    domain_list = ['_acme-challenge'] + domain_name.split('.')
    for i in range(1, len(domain_list)):
        update = dns.update.Update(
            '.'.join(domain_list[i:]),
            keyring=keyring,
            keyalgorithm=keyalgorithm)
        update.add('.'.join(domain_list[:i]), ttl, 'TXT', token)
        logger.debug(str(update))
        try:
            response = dns.query.udp(update, name_server_ip, timeout=timeout)
            rcode = response.rcode()
            logger.debug(" + Adding TXT record %s -> %s returned %s" % (
                '.'.join(domain_list[:i]),
                '.'.join(domain_list[i:]),
                dns.rcode.to_text(rcode)))
            if rcode is dns.rcode.NOERROR:
                break
        except DNSException as err:
            logger.debug("", exc_info=True)
            logger.error(err)

    # Wait for DNS record to propagate
    if (sleep < 0):
        return

    microsleep = min(1, sleep/3.)
    nameservers = query_NS_record('.'.join(domain_list))
    if not nameservers:
        nameservers = [name_server_ip]
    now = time.time()
    while (time.time() - now < sleep):
        try:
            if verify_record('.'.join(domain_list),
                             nameservers,
                             rtype='TXT',
                             rdata=token,
                             timeout=sleep,
                             invert=False):
                logger.info(" + TXT record successfully added!")
                return
        except Exception:
            logger.debug("", exc_info=True)
            logger.fatal(
                "Unable to check if TXT record was successfully inserted")
            sys.exit(1)
        time.sleep(microsleep)

    logger.fatal(" + TXT record not added.")
    sys.exit(1)
Beispiel #2
0
    def _submitDNS(self, entries):

        keys = entries.keys()
        keys.sort()

        update = dns.update.Update(
            self.zone,
            keyring=dns.tsigkeyring.from_text(self.tsig_key))

        update.delete(self.record, 'TXT')

        for k in keys:
            v = entries[k].replace(' ', '\ ')
            update.add(self.record, self.ttl, 'TXT', "%s=%s" % (k, v))

        #print update

        response = dns.query.tcp(update, self.dns_ip)

        #print response

        if response.rcode() != 0:
            raise ValueError("Unexpected Response Code: %s" % response)

        return str(response)
Beispiel #3
0
    def add_txt_record(self, record_name, record_content, record_ttl):
        """
        Add a TXT record using the supplied information.

        :param str record_name: The record name (typically beginning with '_acme-challenge.').
        :param str record_content: The record content (typically the challenge validation).
        :param int record_ttl: The record TTL (number of seconds that the record may be cached).
        :raises certbot.errors.PluginError: if an error occurs communicating with the DNS server
        """

        domain = self._find_domain(record_name)

        n = dns.name.from_text(record_name)
        o = dns.name.from_text(domain)
        rel = n.relativize(o)

        update = dns.update.Update(domain,
                                   keyring=self.keyring,
                                   keyalgorithm=self.algorithm)
        update.add(rel, record_ttl, dns.rdatatype.TXT, record_content)

        try:
            response = dns.query.tcp(update, self.server,
                                     self._default_timeout, self.port)
        except Exception as e:
            raise errors.PluginError(
                'Encountered error adding TXT record: {0}'.format(e))
        rcode = response.rcode()

        if rcode == dns.rcode.NOERROR:
            logger.debug('Successfully added TXT record %s', record_name)
        else:
            raise errors.PluginError(
                'Received response from server: {0}'.format(
                    dns.rcode.to_text(rcode)))
Beispiel #4
0
    def _manage_record(self, key=None, ttl=None, type=None,
                       zone=None, content=None, action=None):
        """ add or delete a given record
        """

        keyring = dns.tsigkeyring.from_text({
            zone: self.zone_list[zone]['key']
        })

        update = dns.update.Update(
                     zone + '.',
                     keyring=keyring,
                     keyalgorithm=self._select_algorithm(
                         self.zone_list[zone]['algorithm']
                     )
                 )

        if action == 'add':
            ttl = int(ttl)
            content = str(content)
            type = str(type)
            update.add(key, ttl, type, content)
        elif action == 'del':
            type = str(type)
            update.delete(key, type)
        else:
            raise WrongDnsUpdateMethod

        response = dns.query.tcp(update, self.zone_list[zone]['ip'])
Beispiel #5
0
    def add_txt_record(self, domain_name, record_name, record_content, record_ttl):
        """
        Add a TXT record using the supplied information.

        :param str domain: The domain to use to find the closest SOA.
        :param str record_name: The record name (typically beginning with '_acme-challenge.').
        :param str record_content: The record content (typically the challenge validation).
        :param int record_ttl: The record TTL (number of seconds that the record may be cached).
        :raises certbot.errors.PluginError: if an error occurs communicating with the DNS server
        """

        domain = self._find_domain(domain_name)

        n = dns.name.from_text(record_name)
        o = dns.name.from_text(domain)
        rel = n.relativize(o)

        update = dns.update.Update(
            domain,
            keyring=self.keyring,
            keyalgorithm=self.algorithm)
        update.add(rel, record_ttl, dns.rdatatype.TXT, record_content)

        try:
            response = dns.query.tcp(update, self.server)
        except Exception as e:
            raise errors.PluginError('Encountered error adding TXT record: {0}'
                                     .format(e))
        rcode = response.rcode()

        if rcode == dns.rcode.NOERROR:
            logger.debug('Successfully added TXT record')
        else:
            raise errors.PluginError('Received response from server: {0}'
                                     .format(dns.rcode.to_text(rcode)))
Beispiel #6
0
def is_dynupdate_enabled(domain: str, nameserver: str) -> bool:
    """
    Check if zone updating is enabled.

    :param domain: Name of the zone to transfer.
    :param nameserver: IPv4 or 6 to test.
    """
    newrecord = 'newrecord'

    try:
        update = dns.update.Update(domain)
        update.add(newrecord, 3600, dns.rdatatype.A, '10.10.10.10')
        response = dns.query.tcp(update, nameserver, timeout=5)

        result = True

        if response.rcode() > 0:
            show_close('Zone update not enabled on server',
                       details=dict(domain=domain, nameserver=nameserver))
            result = False
        else:
            show_open('Zone update enabled on server',
                      details=dict(domain=domain, nameserver=nameserver))
            result = True
    except dns.query.BadResponse:
        show_close('Zone update not enabled on server',
                   details=dict(domain=domain, nameserver=nameserver))
        result = False
    except (socket.error, dns.exception.Timeout) as exc:
        show_unknown('Could not connect',
                     details=dict(domain=domain,
                                  nameserver=nameserver,
                                  error=str(exc).replace(':', ',')))
        result = False
    return result
Beispiel #7
0
def add_dns_record(new_hostname, domain, new_ipaddress):
    PRIMARY_DNS_SERVER_IP = '192.168.8.200'
    TTL = 300

    keyring = dns.tsigkeyring.from_text({
        "dynamic.vmware.haf.":
        "jn694IwJ9IP4i5yGtSdIZJTFeFpVEvK2wa78gHVX8PohLNBQVYQd+JyGNX8A3hju8WmsNVo1Oq58YS93HR4HIQ=="
    })

    logging.debug("DNS record A")
    ### Create A Record
    # Set the domain name with a trailing dot (to stop auto substitution of zone)
    dns_domain = '%s.' % (domain)
    # Prepare the payload for DNS record update in the given zone/domain (dns_domain)

    logging.debug(" {} ({})".format(new_hostname, new_ipaddress))
    update = dns.update.Update(zone=dns_domain,
                               keyname='dynamic.vmware.haf.',
                               keyring=keyring,
                               keyalgorithm=dns.tsig.HMAC_SHA512)
    # Inject the record details into the dns.update.Update class
    update.add(new_hostname, TTL, 'A', new_ipaddress)
    # Submit the new record to the DNS server to apply the update
    response = dns.query.tcp(update, PRIMARY_DNS_SERVER_IP, timeout=5)
    flags = dns.flags.to_text(response.flags)
    logging.debug(" A   DNS update response: {} {}".format(
        dns.rcode.to_text(response.rcode()), flags))
Beispiel #8
0
 def add_txt(self):
     try:
         update = dns.update.Update(self.get_domain_fqdn(), keyring=self.__keyring)
         update.add(self.__hostname, self.__ttl, 'TXT', self.__txt_value)
         return dns.query.tcp(update, self.__server_ip).rcode()
     except Exception, error:
         raise Exception("Error inserting DNS TXT Entry: %s" % (error))
Beispiel #9
0
    def _manage_record(self,
                       key=None,
                       ttl=None,
                       type=None,
                       zone=None,
                       content=None,
                       action=None):
        """ add or delete a given record
        """

        keyring = dns.tsigkeyring.from_text(
            {zone: self.zone_list[zone]['key']})

        update = dns.update.Update(zone + '.',
                                   keyring=keyring,
                                   keyalgorithm=self._select_algorithm(
                                       self.zone_list[zone]['algorithm']))

        if action == 'add':
            ttl = int(ttl)
            content = str(content)
            type = str(type)
            update.add(key, ttl, type, content)
        elif action == 'del':
            type = str(type)
            update.delete(key, type)
        else:
            raise WrongDnsUpdateMethod

        response = dns.query.tcp(update, self.zone_list[zone]['ip'])
Beispiel #10
0
def dns_do_command(zone, record_name, record_type, command, ttl=0, rdata=""):
    """
    Helper for dns add, update, delete
    """
    keyring = dns.tsigkeyring.from_text(
        {zone['connection']['keyName']: VinylDNSTestContext.dns_key})

    name_server, name_server_port = dns_server_port(zone)

    fqdn = record_name + "." + zone['name']

    print "updating " + fqdn + " to have data " + rdata

    update = dns.update.Update(zone['name'], keyring=keyring)
    if (command == 'add'):
        update.add(fqdn, ttl, record_type, rdata)
    elif (command == 'update'):
        update.replace(fqdn, ttl, record_type, rdata)
    elif (command == 'delete'):
        update.delete(fqdn, record_type)

    response = dns.query.udp(update,
                             name_server,
                             port=name_server_port,
                             ignore_unexpected=True)
    return response
Beispiel #11
0
    def _do_create_txt(dn):
        domain_list = dn.split('.')
        logger.info(' + Creating TXT record "%s" for the domain %s' %
                    (token, dn))

        for i in range(0, len(domain_list)):
            head = '.'.join(domain_list[:i])
            tail = '.'.join(domain_list[i:])
            update = dns.update.Update(tail,
                                       keyring=keyring,
                                       keyalgorithm=keyalgorithm)
            update.add(head, ttl, 'TXT', token)
            logger.debug(str(update))
            try:
                response = dns.query.udp(update,
                                         name_server_ip,
                                         timeout=timeout)
                rcode = response.rcode()
                logger.debug(" + Creating TXT record %s -> %s returned %s" %
                             (head, tail, dns.rcode.to_text(rcode)))
                if rcode is dns.rcode.NOERROR:
                    return dn
            except DNSException as err:
                logger.debug("", exc_info=True)
                logger.error("Error creating TXT record %s %s: %s" %
                             (head, tail, err))
Beispiel #12
0
def make_update(action, query):
    hostname = query.hostname.encode('ascii')
    D = dns.name.from_text(domain)
    H = dns.name.from_text(query.hostname)

    if H.is_subdomain(D):
        R = H.relativize(D)
    else:
        return "400 NOTAUTH %s\n" % H.to_text()

    keyring, algo = read_session_key("/etc/bind/keys/webapp.key")
    update = dns.update.Update(D, keyring=keyring, keyalgorithm=algo)
    if action == 'update':
       update.present(R, 'a')
       update.replace(R, 300, 'a', query.ip.encode('ascii'))
    elif action == 'delete':
       update.present(R, 'a')
       update.delete(R, 'a')
    elif action == 'add':
       update.absent(R, 'a')
       update.add(R, 300, 'a', query.ip.encode('ascii'))
    response = dns.query.tcp(update, '127.0.0.1')

    if response.rcode() == 0:
        return "NOERROR %s\n" % H.to_text()
    else:
        return "%s %s\n" % (dns.rcode.to_text(response.rcode()), H.to_text())
Beispiel #13
0
    def _update_record(self, identifier, rtype=None, name=None, content=None):
        if self._get_lexicon_option("ttl"):
            ttl = self._get_lexicon_option("ttl")
        else:
            ttl = 300
        if not identifier:
            rrset = self._list_records(rtype, name)
            if len(rrset) == 1:
                identifier = rrset[0]["id"]
            elif len(rrset) < 1:
                raise Exception(
                    "No records found matching type and name - won't update")
            else:
                raise Exception(
                    "Multiple records found matching type and name - won't update"
                )
        d_rtype, d_name, d_content = self._resolve_identifier(identifier)

        if not rtype:
            rtype = d_rtype
        if not name:
            name = d_name

        d_name = dns.name.from_text(d_name).relativize(
            dns.name.from_text(self.zone))
        name = dns.name.from_text(name).relativize(
            dns.name.from_text(self.zone))

        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.delete(d_name, d_rtype, d_content)
        update.add(name, ttl, rtype, content)
        self._run_query(update)
        return True
Beispiel #14
0
 def post(self, request):
     """
     generate an update message for adding record.
     """
     if isinstance(request.DATA, list):
         for record in request.DATA:
             #RecordList.post(self, record)
             update = dns.update.Update(DOMAIN)
             rdname = str(record['name'])
             rdttl = int(record['ttl'])
             rdtype = str(record['type'])
             rdvalue = str(record['value'])
             update.add(rdname, rdttl, rdtype, rdvalue)
             try:
                 response = dns.query.tcp(update, DNS_SERVER)
                 log.info("ADD RDATA %s %d IN %s %s" % (rdname, rdttl, rdtype, rdvalue))
             except:
                 log.error("ADD RDATA FAIL.")                
     else:
         update = dns.update.Update(DOMAIN)
         rdname = str(request.DATA['name'])
         rdttl = int(request.DATA['ttl'])
         rdtype = str(request.DATA['type'])
         rdvalue = str(request.DATA['value'])
         update.add(rdname, rdttl, rdtype, rdvalue)
         try:
             dns.query.tcp(update, DNS_SERVER)
             log.info("ADD RDATA %s %d IN %s %s" % (rdname, rdttl, rdtype, rdvalue))
         except:
             log.error("ADD RDATA FAIL.")
     return Response() #RecordDetail.get()
Beispiel #15
0
def dns_do_command(zone, record_name, record_type, command, ttl=0, rdata=""):
    """
    Helper for dns add, update, delete
    """
    # Get the algorithm name from the DNS library (vinylDNS uses "-" in the name and dnspython uses "_")
    algo_name = getattr(dns.tsig,
                        VinylDNSTestContext.dns_key_algo.replace("-", "_"))
    keyring = dns.tsigkeyring.from_text({
        zone["connection"]["keyName"]: (algo_name, VinylDNSTestContext.dns_key)
    })

    (name_server, name_server_port) = dns_server_port(zone)
    fqdn = record_name + "." + zone["name"]
    update = dns.update.Update(zone["name"], keyring=keyring)

    if command == "add":
        update.add(fqdn, ttl, record_type, rdata)
    elif command == "update":
        update.replace(fqdn, ttl, record_type, rdata)
    elif command == "delete":
        update.delete(fqdn, record_type)

    response = dns.query.udp(update,
                             name_server,
                             port=name_server_port,
                             ignore_unexpected=True)
    return response
Beispiel #16
0
def _update_ns(name, addr):
    # name = name.replace('-', '')
    logger.info(f"updating forward zone {name}:{addr} ...")
    update = dns.update.Update("docker",
                               keyring=KEYRING,
                               keyalgorithm=ALGORITHM)
    update.delete(name, "A")
    update.add(name, 60, dns.rdatatype.A, str(addr))
    response = dns.query.tcp(update, DDNS_SERVER)
    if response.rcode() != 0:
        logger.error(f"Failed: {response}")

    rv = str(addr).split(".")
    rv.reverse()
    parts = ".".join(rv[:2])
    zone_name = ".".join(rv[2:]) + ".in-addr.arpa"
    logger.info(f"updating rev zone {zone_name} for {name}...")
    update = dns.update.Update(zone_name,
                               keyring=KEYRING,
                               keyalgorithm=ALGORITHM)
    update.delete(parts, "PTR")
    update.add(parts, 60, dns.rdatatype.PTR, str(name) + ".docker.")
    response = dns.query.tcp(update, DDNS_SERVER)
    if response.rcode() != 0:
        logger.error(f"Failed: {response}")
def addFWD(name,ttl,ipaddress):
	ipaddress = str(ipaddress)
	hostname = splitFQDN(name)[0]
	log.debug ('[addFWD] - hostname %s' % hostname)
	log.debug ('[addFWD] - domain %s' % splitFQDN(name)[1])
	domain = splitFQDN(name)[1]
	if domain.endswith("."):
		domain = domain.rstrip('.')
	check4TSIG = TSIGSecured(domain)
	if check4TSIG.isSecure(domain):
		key = str(check4TSIG.TSIG(domain))
		keyname = domain.replace(".","_")
		keyring = dns.tsigkeyring.from_text({keyname:key})
		update = dns.update.Update(splitFQDN(name)[1], keyring=keyring)
	else:
		update = dns.update.Update(splitFQDN(name)[1])
	address_type = enumIPtype(ipaddress)
        if address_type == 4:
		log.debug ('[addFWD] - IPv4')
		if monitor_replace == "False":
			update.add(hostname,monitor_ttl,dns.rdatatype.A, ipaddress)
		else:
			update.replace(hostname,monitor_ttl,dns.rdatatype.A, ipaddress)
	elif address_type == 6:
		log.debug ('[addFWD] - IPv6')

		if monitor_replace == "False":
			update.add(hostname,monitor_ttl,dns.rdatatype.AAAA, ipaddress)
		else:
			update.replace(hostname,monitor_ttl,dns.rdatatype.AAAA, ipaddress)
	response = dns.query.udp(update, monitor_nameserver)
	return response
Beispiel #18
0
    def add_dns_record(self, domain, txtvalue):
        zone, nameserverip = self._determine_zone_and_nameserverip(domain)
        update = dns.update.Update(zone,
                                   keyring=self.keyring,
                                   keyalgorithm=self.keyalgorithm)
        update.add(domain, self.dns_ttl, dns.rdatatype.TXT, txtvalue)
        print('Adding \'{} 60 IN TXT "{}"\' to {}'.format(
            domain, txtvalue, nameserverip))
        dns.query.tcp(update, nameserverip)

        verified = False
        retry = 0
        while self.dns_verify and not verified and retry < 5:
            request = dns.message.make_query(domain, dns.rdatatype.TXT)
            response = dns.query.tcp(request, nameserverip)
            for rrset in response.answer:
                for answer in rrset:
                    if answer.to_text().strip('"') == txtvalue:
                        verified = True
                        print('Verified \'{} 60 IN TXT "{}"\' on {}'.format(
                            domain, txtvalue, nameserverip))
                        break
            if not verified:
                time.sleep(1)
                retry += 1

        if not self.dns_verify or verified:
            return datetime.datetime.now() + datetime.timedelta(seconds=2 *
                                                                self.dns_ttl)
        else:
            raise ValueError(
                'Failed to verify \'{} 60 IN TXT "{}"\' on {}'.format(
                    domain, txtvalue, nameserverip))
Beispiel #19
0
    def delete(self, container_id):
        LOG.info("Deleting records for container: %s" % container_id)

        uuid_qname = dns.name.from_text(container_id, self._identity)
        identity_rrset = self._query(self._identity, dns.rdatatype.SRV)
        update = dns.update.Update(self._origin, keyring=self._keyring)

        for srv in identity_rrset.get(dns.rdatatype.SRV, []):
            if srv.target == uuid_qname:
                update.delete(self._identity, srv)

        uuid_rdata = self._query(uuid_qname, dns.rdatatype.CNAME, one_record=True)

        if not uuid_rdata:
            LOG.warn("No records found for container: %s" % container_id)
            return

        name_qname = uuid_rdata.target
        name_rrsets = self._query(name_qname, dns.rdatatype.ANY)
        name_rdata = name_rrsets[dns.rdatatype.A].items[0]

        service_name_rdata = name_rrsets[dns.rdatatype.SRV].items[0]
        service_rrsets = self._query(service_name_rdata.target, dns.rdatatype.A)
        service_rdata = service_rrsets.get(dns.rdatatype.A, [])

        update.delete(service_name_rdata.target, dns.rdatatype.A)
        update.delete(uuid_qname, dns.rdatatype.CNAME)
        update.delete(name_qname, dns.rdatatype.A)
        update.delete(name_qname, dns.rdatatype.SRV)

        for rdata in service_rdata:
            if rdata.address != name_rdata.address:
                update.add(service_name_rdata.target, self._ttl, rdata)

        self._update(update)
Beispiel #20
0
    def _submitDNS(self, entries):

        keys = entries.keys()
        keys.sort()

        update = dns.update.Update(self.zone,
                                   keyring=dns.tsigkeyring.from_text(
                                       self.tsig_key))

        update.delete(self.record, 'TXT')

        for k in keys:
            v = entries[k].replace(' ', '\ ')
            update.add(self.record, self.ttl, 'TXT', "%s=%s" % (k, v))

        #print update

        response = dns.query.tcp(update, self.dns_ip)

        #print response

        if response.rcode() != 0:
            raise ValueError("Unexpected Response Code: %s" % response)

        return str(response)
Beispiel #21
0
    def dnsupdates(self, host, mac, addr):
        """
          determine and run needed DNS updates.
      """

        host_s = "%s-%s" % (host, self.suffix)
        fqdn = "%s.%s" % (host_s, self.domain)
        msgd("DNS check mac: %s asking for: %s" % (mac, addr))

        addr_si = dns_rev_host(addr)

        if (addr_si != 'AddrNotFound'):  # address already known.
            msgd("mac: %s asking for %s, rev is already %s" %
                 (mac, addr, addr_si))
            return

        if (addr in dns_fwd_addr("%s.%s" % (host, self.domain),
                                 self.dnsmaster)):
            msgd("mac: %s asking for %s, which it already has." %
                 (mac, host, addr))
            return

        if not (addr in dns_fwd_addr(fqdn, self.dnsmaster)):
            if (addr[0] == 'f') and (addr[1] in ['d', 'e', 'f']):
                msgd("ignoring link level address %s" % addr)
                return

            update = dns.update.Update(self.domain, keyring=self.dnskeyring)
            update.add(host_s, 300, 'aaaa', addr)
            response = dns.query.tcp(update, self.dnsmaster)
            if response.rcode() != 0:
                msge("forward registration of %s failed" % host)
                msge(response)
            else:
                msgi("fwd of %s for mac: %s as %s succeeded" %
                     (host_s, mac, addr))
        else:
            msgd("skipped fwd of %s for %s, already in DNS OK" % (host_s, mac))

        # fwd done, now check reverse...

        # FIXME: only works for 2 digit netmask /48, /64, etc...
        zone = str(dns.reversename.from_address(self.prefix[0:-4]))[0:63]
        pfx = int(self.prefix[-2:])
        rzone = "%s.ip6.arpa." % zone[-(pfx / 2) + 1:]

        msgd("mac: %s DNS Add rev %s -> %s" % (mac, addr, fqdn))

        update = dns.update.Update(rzone, keyring=self.dnskeyring)

        update.add(dns.reversename.from_address(addr), 300, 'ptr', fqdn)
        response = dns.query.tcp(update, self.dnsmaster)
        if response.rcode() != 0:
            msge("reverse registration of %s failed" % host)
            #msge( response )
        else:
            msgi("rev registration of %s-%s succeeded" % (host, self.suffix))

        return
Beispiel #22
0
 def update_ds(self, name, ds_set):
     update = self._init_update()
     name = dns.name.from_text(name)
     update.delete(name, dns.rdatatype.DS)
     for ds in ds_set:
         update.add(name, self._ttl, dns.rdatatype.DS, ds)
     response = dns.query.tcp(update, self._server, port=self._port)
     return response.rcode() == 0
Beispiel #23
0
 def add_address_to_update(self, update: dns.update.Update,
                           hostPart: dns.name.Name, ttl: int,
                           address: IPAddressUnion) -> None:
     assert isinstance(address, ipaddress.IPv6Address)
     update.add(
         hostPart, ttl,
         dns.rdtypes.IN.AAAA.AAAA(dns.rdataclass.IN, dns.rdatatype.AAAA,
                                  str(address)))
Beispiel #24
0
 def update_ds(self, name, ds_set):
     update = self._init_update()
     name = dns.name.from_text(name)
     update.delete(name, dns.rdatatype.DS)
     for ds in ds_set:
         update.add(name, self._ttl, dns.rdatatype.DS, ds)
     response = dns.query.tcp(update, self._server, port=self._port)
     return response.rcode() == 0
 def _add_record(self, qtype, fqdn, ip, do_ptr):
     log.debug('DDNS add for record {}, fqdn: {}'.format(qtype, fqdn))
     origin, name = self._parse_name(fqdn)
     update = dns.update.Update(origin, keyring=self.keyring)
     update.add(name, self.ttl, qtype, ip)
     self._do_update(update)
     if do_ptr:
         self._add_ptr(fqdn, ip)
 def UpdateDnsSrv(self, port, host, domain, dnsip):
     update = dns.update.Update(domain)
     update.add('_xmpp-server._tcp', 3600, 'SRV', '0 0 5269 ' + host)
     try:
         logging.debug('UpdateDnsSrv: writing to dns server')
         response = dns.query.tcp(update, dnsip)
     except:
         logging.info('Writing SRV failed')
         logging.exception('')
Beispiel #27
0
    def _perform_single(self, achall):
        response, validation = achall.response_and_validation()
        zone, record = self.zone_and_record(achall.domain, achall.validation_domain_name(achall.domain))

        update = dns.update.Update(zone, keyring=self.keyring, keyalgorithm=self.keyalgorithm)
        update.add(record, 300, 'TXT', validation.encode('ascii'))
        dns.query.tcp(update, self.conf('nameserver'))

        return response
def test_dns_unauth_update(Docker, resolver, zone):
    update = dns.update.Update(zone)
    update.add('test', 0, 'A', '10.0.0.1')
    response = dns.query.tcp(update, Docker.get_ip(), timeout=10)

    try:
        answers = resolver.query('test.%s' % zone, 'A')
    except dns.resolver.NXDOMAIN as err:
        assert err.message == "None of DNS query names exist: test.%s., test.%s." % (zone, zone)
 def UpdateDnsSrv(self,port,host,domain,dnsip):
     update=dns.update.Update(domain)
     update.add('_xmpp-server._tcp',3600,'SRV','0 0 5269 '+host)
     try:
         logging.debug('UpdateDnsSrv: writing to dns server')
         response = dns.query.tcp(update, dnsip)
     except:
         logging.info('Writing SRV failed')
         logging.exception('')
Beispiel #30
0
def add_dns(host, ip):
    if not ip or not DNS_KEY:
        return
    update = dns.update.Update(DNS_DOMAIN, keyring=keyring)
    if ip_address(ip).version == 6:
        update.add(host, 86400, 'AAAA', ip)
    else:
        update.add(host, 86400, 'A', ip)
    dns.query.tcp(update, DNS_SERVER)
Beispiel #31
0
def add_to_dns(fqdn, ipadd):
    update = dns.update.Update(domain)
    update.add(fqdn, 300, 'A', ipadd)
    response = dns.query.tcp(update, dnsserver)
    response = str(response)
    if 'noerror' in response.lower():
        return ("Successful")
    else:
        return ("Unsuccessful")
def add_ns_record(server, zone, key, nameserver, ttl=300):

    # make input zones absolute
    #zone = zone + '.' if not zone.endswith('.')

    keyring = dns.tsigkeyring.from_text({'update-key': key})
    update = dns.update.Update(zone, keyring=keyring)
    update.add(zone, ttl, 'ns', nameserver)
    response = dns.query.tcp(update, server)
    return response
Beispiel #33
0
    def dnsupdates( self, host, mac, addr ):
      """
          determine and run needed DNS updates.
      """
  
      host_s= "%s-%s" % ( host, self.suffix )
      fqdn= "%s.%s" % ( host_s, self.domain)
      msgd( "DNS check mac: %s asking for: %s" % ( mac, addr ) )

      addr_si = dns_rev_host(addr)
  
      if ( addr_si != 'AddrNotFound' ) : # address already known.
           msgd( "mac: %s asking for %s, rev is already %s" % ( mac, addr, addr_si ) )
           return

      if ( addr in dns_fwd_addr( "%s.%s" % (host, self.domain) , self.dnsmaster)) :
           msgd( "mac: %s asking for %s, which it already has." % ( mac, host, addr ) )
           return

      if not ( addr in dns_fwd_addr(fqdn,self.dnsmaster) ) :
          if ( addr[0] == 'f' ) and ( addr[1] in [ 'd', 'e', 'f' ] ):
             msgd( "ignoring link level address %s" % addr )
             return

          update = dns.update.Update( self.domain, keyring=self.dnskeyring )
          update.add( host_s, 300, 'aaaa', addr )
          response = dns.query.tcp(update,self.dnsmaster)
          if response.rcode() != 0:
              msge( "forward registration of %s failed" % host )
              msge( response )
          else:
              msgi( "fwd of %s for mac: %s as %s succeeded" % ( host_s, mac, addr ) )
      else:
          msgd( "skipped fwd of %s for %s, already in DNS OK" % ( host_s, mac ) )
  
      # fwd done, now check reverse...
  
      # FIXME: only works for 2 digit netmask /48, /64, etc...
      zone = str(dns.reversename.from_address( self.prefix[0:-4] ))[0:63]
      pfx= int(self.prefix[-2:])
      rzone="%s.ip6.arpa." % zone[-(pfx/2)+1:]
  
      msgd( "mac: %s DNS Add rev %s -> %s" % ( mac, addr, fqdn ) )

      update = dns.update.Update( rzone, keyring=self.dnskeyring )
      
      update.add( dns.reversename.from_address(addr), 300, 'ptr', fqdn )
      response = dns.query.tcp(update,self.dnsmaster)
      if response.rcode() != 0:
          msge( "reverse registration of %s failed" % host )
          #msge( response )
      else:
          msgi( "rev registration of %s-%s succeeded" % ( host, self.suffix ))
  
      return
Beispiel #34
0
 def add_record(self, domain_zone, domain_name, ttl, record_type,
                record_value):
     if self.search_record(domain_name + '.' + domain_zone, record_type):
         return {'code': '1', 'message': 'record aleady exit'}
     else:
         update = dns.update.Update(domain_zone,
                                    keyring=self.keyring,
                                    keyalgorithm=self.sha_type)
         update.add(domain_name, ttl, record_type, record_value)
         dns.query.tcp(update, self.name_server_addr)
         return {'code': 0, 'message': 'ok'}
Beispiel #35
0
    def fx_agent_dynrec(self, operation, domain, nssrv, selector, ttl,
                        payload_b64, **tsig):
        """ Manage Agent Dynamic DNS Record: CRUD"""

        self.flogger.debug(
            "Accepted for record: {0}, {1}, {2}, {3}, {4}, {5}, {6}".format(
                operation, domain, nssrv, selector, ttl, payload_b64, tsig))

        keyring = dns.tsigkeyring.from_text(tsig)

        self.flogger.debug("DNS TSIG Keyring: " + str(keyring))
        update = dns.update.Update(domain,
                                   keyring=keyring,
                                   keyalgorithm=HMAC_SHA256)
        self.flogger.debug("DNS TXT Update: " + str(update))

        # Make DKIM record look normal
        dkim_record = '"v=DKIM1; h=sha256; k=rsa; t=y; s=email; p={0}"'.format(
            payload_b64)

        # From http://www.dnspython.org/docs/1.14.0/dns.update.Update-class.html#add
        if operation == 'add':
            self.flogger.debug("DNS: Adding TXT record")
            update.add(selector, ttl, dns.rdatatype.TXT, dkim_record)
        else:
            if operation == 'update':
                self.flogger.debug("DNS: Updating TXT record")
                update.replace(selector, ttl, dns.rdatatype.TXT, dkim_record)
            else:
                if operation == 'delete':
                    self.flogger.debug("DNS: Deleting TXT record")
                    update.delete(selector)
                else:
                    self.flogger.error("DNS: Invalid record action: " +
                                       operation)
                    raise ValueError(
                        "Operation must be one of <add|update|delete>")

        try:
            response = dns.query.tcp(update, nssrv, timeout=10)
            if response.rcode() == 0:
                self.flogger.debug("DynDNS: Update Successful")
                return True
            else:
                self.flogger.error("DynDNS: Update failed: code: {0}".format(
                    response.rcode()))
                self.flogger.error("Response: {0}".format(response))
                return False
        except dns.tsig.PeerBadKey as peerkey:
            self.flogger.error("DNS TSIG: Bad Peer key {0}".format(peerkey))
            return False
        except Exception as e:
            self.flogger.error("DNS: General Exception {0}".format(e))
            return False
Beispiel #36
0
    def _create_record(self, rtype, name, content):
        if self._get_lexicon_option("ttl"):
            ttl = self._get_lexicon_option("ttl")
        else:
            ttl = 300
        name = dns.name.from_text(name).relativize(
            dns.name.from_text(self.zone))

        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.add(name, ttl, rtype, content)
        self._run_query(update)
        return True
    def create_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.add(self.record, self.ttl, self.type, self.value)

        try:
            response = dns.query.tcp(update, self.server, timeout=10)
            if dns.message.Message.rcode(response) == 0:
                return True
            else:
                return False
        except:
            self.module.fail_json(msg="Connection to DNS server failed")
Beispiel #38
0
    def create_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.add(self.record, self.ttl, self.type, self.value)

        try:
            response = dns.query.tcp(update, self.server, timeout=10)
            if dns.message.Message.rcode(response) == 0:
                return True
            else:
                return False
        except:
            self.module.fail_json(msg='Connection to DNS server failed')
Beispiel #39
0
def doUpdate(args):
    # Sanity check the data and get the action and record type
    action, _type = verify_input(my_input)
    ttl = is_valid_TTL(TimeToLive)
    # Get the hostname and the origin
    Origin, name = parse_name(Origin, my_input[1])
    # Validate and setup the Key
    keyring, keyalgo = get_key(KeyFile)
    # Start constructing the DDNS Query
    update = dns.update.Update(Origin, keyring=keyring,
                               keyalgorithm=getattr(dns.tsig, keyalgo))
    # Put the payload together.
    my_payload = ''  # Start with an empty payload.
    do_ptr = doPTR

    if _type == 'A' or _type == 'AAAA':
        my_payload = my_input[3]
        if doPTR == True:
            ptr_target = name.to_text() + '.' + Origin.to_text()
            ptr_origin, ptr_name = parse_name(None, genPTR(my_payload).to_text())
            ptr_update = dns.update.Update(ptr_origin, keyring=keyring)
    if action != 'del' and _type == 'CNAME' or _type == 'NS' or _type == 'TXT' or _type == 'PTR':
        my_payload = my_input[3]
        do_ptr = False
    elif type == 'SRV':
        my_payload = my_input[3] + ' ' + my_input[4] + ' ' + my_input[5] + ' ' + my_input[6]
        do_ptr = False
    elif type == 'MX':
        my_payload = my_input[3]+' '+my_input[4]
        do_ptr = False
    elif type == 'CNAME':
        do_ptr = False
    # Build the update
    if action == 'add':
        update.add(name, ttl, _type, my_payload)
        if do_ptr is True and _type:
            ptr_update.add(ptr_name, ttl, 'PTR', ptr_target)
    elif action == 'delete' or action == 'del':
        if my_payload != '':
            update.delete(name, _type, my_payload)
        else:
            update.delete(name)

        if do_ptr is True and (_type == 'A' or _type == 'AAAA'):
            ptr_update.delete(ptr_name, 'PTR', ptr_target)
        else:
            do_ptr = False
    elif action == 'update':
        update.replace(name, ttl, _type, my_payload)
        if doPTR is True:
            ptr_update.replace(ptr_name, ttl, 'PTR', ptr_target)
Beispiel #40
0
 def test_to_wire1(self): # type: () -> None
     update = dns.update.Update('example')
     update.id = 1
     update.present('foo')
     update.present('foo', 'a')
     update.present('bar', 'a', '10.0.0.5')
     update.absent('blaz2')
     update.absent('blaz2', 'a')
     update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
     update.add('bar', 300, 'a', '10.0.0.3')
     update.delete('bar', 'a', '10.0.0.4')
     update.delete('blaz', 'a')
     update.delete('blaz2')
     self.failUnless(update.to_wire() == goodwire)
Beispiel #41
0
 def test_to_wire2(self): # type: () -> None
     update = dns.update.Update('example')
     update.id = 1
     update.present('foo')
     update.present('foo', 'a')
     update.present('bar', 'a', '10.0.0.5')
     update.absent('blaz2')
     update.absent('blaz2', 'a')
     update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
     update.add('bar', 300, dns.rdata.from_text(1, 1, '10.0.0.3'))
     update.delete('bar', 'a', '10.0.0.4')
     update.delete('blaz', 'a')
     update.delete('blaz2')
     self.failUnless(update.to_wire() == goodwire)
Beispiel #42
0
 def test_to_wire3(self):  # type: () -> None
     update = dns.update.Update("example")
     update.id = 1
     update.present("foo")
     update.present("foo", "a")
     update.present("bar", "a", "10.0.0.5")
     update.absent("blaz2")
     update.absent("blaz2", "a")
     update.replace("foo", 300, "a", "10.0.0.1", "10.0.0.2")
     update.add("bar", dns.rdataset.from_text(1, 1, 300, "10.0.0.3"))
     update.delete("bar", "a", "10.0.0.4")
     update.delete("blaz", "a")
     update.delete("blaz2")
     self.assertEqual(update.to_wire(), goodwire)
Beispiel #43
0
def main():
    nameserver = sys.argv[1]
    zone = sys.argv[2]
    name = sys.argv[3]
    interface = sys.argv[4]
    keyfn = sys.argv[5]

    actual = []
    for d in ifaddresses(interface).setdefault(AF_INET, []):
        addr = d['addr']
        actual.append(addr)
    actual.sort()

    if not actual:
        print("no known addresses, giving up")
        return

    indns = []
    host = dns.name.from_text('%s.%s' % (name, zone))
    request = dns.message.make_query(host, dns.rdatatype.A)
    response = dns.query.tcp(request, nameserver)
    for entry in response.answer:
        for item in entry.items:
            indns.append(str(item))
    indns.sort()

    if actual == indns:
        if not force:
            return

        print("address not changed, updating anyway")

    else:
        print("IP address address for %s on %s.%s changed" % (
            interface, name, zone))

    print("actual: %s" % actual)
    print("in dns: %s" % indns)

    with open(keyfn) as f:
        key = f.readline().strip()

    keyring = dns.tsigkeyring.from_text({ zone + '.' : key })

    update = dns.update.Update(zone, keyring = keyring)
    update.replace(name, 300, 'A', actual[0])
    for a in actual[1:]:
        update.add(name, 300, 'A', a)

    response = dns.query.tcp(update, nameserver)
Beispiel #44
0
 def test_to_wire3(self):  # type: () -> None
     update = dns.update.Update('example')
     update.id = 1
     update.present('foo')
     update.present('foo', 'a')
     update.present('bar', 'a', '10.0.0.5')
     update.absent('blaz2')
     update.absent('blaz2', 'a')
     update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
     update.add('bar', dns.rdataset.from_text(1, 1, 300, '10.0.0.3'))
     update.delete('bar', 'a', '10.0.0.4')
     update.delete('blaz', 'a')
     update.delete('blaz2')
     self.assertEqual(update.to_wire(), goodwire)
Beispiel #45
0
 def test_to_wire3(self):
     update = dns.update.Update('example')
     update.id = 1
     update.present('foo')
     update.present('foo', 'a')
     update.present('bar', 'a', '10.0.0.5')
     update.absent('blaz2')
     update.absent('blaz2', 'a')
     update.replace('foo', 300, 'a', '10.0.0.1', '10.0.0.2')
     update.add('bar', dns.rdataset.from_text(1, 1, 300, '10.0.0.3'))
     update.delete('bar', 'a', '10.0.0.4')
     update.delete('blaz', 'a')
     update.delete('blaz2')
     self.failUnless(update.to_wire() == goodwire)
Beispiel #46
0
    def create_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring, keyalgorithm=self.algorithm)
        try:
            update.add(self.module.params['record'],
                       self.module.params['ttl'],
                       self.module.params['type'],
                       self.module.params['value'])
        except AttributeError:
            self.module.fail_json(msg='value needed when state=present')
        except dns.exception.SyntaxError:
            self.module.fail_json(msg='Invalid/malformed value')

        response = self.__do_update(update)
        return dns.message.Message.rcode(response)
def test_dns_auth_update(Docker, resolver, zone):
    update_keys = Docker.args['tsig_update']
    i = len(Docker.args.get('tsig_slave', [])) + 1
    for update_key in update_keys:
        keyring = dns.tsigkeyring.from_text({
            "key_%s" % i : update_key.split(':')[1]
        })
        update = dns.update.Update(zone, keyring=keyring, keyalgorithm=update_key.split(':')[0], keyname='key_%s' % i)
        update.add('test', 0, 'A', '10.0.0.1')
        response = dns.query.tcp(update, Docker.get_ip(), timeout=10)

        answers = resolver.query('test.%s' % zone, 'A')
        assert (answers[0].address == '10.0.0.1')
        i += 1
Beispiel #48
0
    def add(self, container_id, service, name, ip):
        LOG.info("Adding records for container: %s name: %s, ip: %s" % (container_id, name, ip))
        uuid_qname = dns.name.from_text(container_id, self._identity)
        service_qname = dns.name.from_text(service, self._origin)
        name_qname = dns.name.from_text(name, self._identity)

        update = dns.update.Update(self._origin, keyring=self._keyring)
        update.add(self._identity, self._ttl, dns.rdatatype.SRV, "10 10 0 %s" % uuid_qname)
        update.add(name_qname, self._ttl, dns.rdatatype.SRV, "10 10 0 %s" % service_qname)
        update.add(uuid_qname, self._ttl, dns.rdatatype.CNAME, str(name_qname))
        update.add(service_qname, self._ttl, dns.rdatatype.A, ip)
        update.add(name_qname, self._ttl, dns.rdatatype.A, ip)

        self._update(update)
Beispiel #49
0
 def update_dns_value(self, sqlobject, delete=False):
     """Update dns value
     if delete is true, delete value instead of adding"""
     self.create_keyring()
     domain = self.get_domain(sqlobject.t_domains_id)
     if not domain:
         if delete:
             # domain already deleted
             return True
         self.log.error('Cannot get domain for t_domains_id %s' % sqlobject.t_domains_id)
         return False
     if self.parse_inetlist(domain.masters):
         # this server is not master
         return True
     if not self.conf.bind_master:
         # this server is not master
         return True
     value = str(sqlobject.value).split('/')[0]
     update = dns.update.Update(str(domain.name), keyring=self.keyring,
                 keyalgorithm=str(self.conf.bind_secret_algorithm).lower())
     if delete:
         update.delete(str(sqlobject.key), str(sqlobject.type), value)
     else:
         if not self.check_record(sqlobject.key, sqlobject.type, sqlobject.value, domain.name):
             update.add(str(sqlobject.key), int(sqlobject.ttl),
                                             str(sqlobject.type), value)
         else:
             self.log.debug('Record %s %d IN %s %s already exists' % (
                                 str(sqlobject.key), int(sqlobject.ttl),
                                 str(sqlobject.type), value))
             return True
     try:
         response = dns.query.tcp(update, '127.0.0.1')
     except PeerBadKey or PeerBadSignature:
         self.log.error('Cannot update dns entry, secret invalid')
         return False
     if response.rcode() != 0:
         self.log.error('DNS update failed, got error %s on domain %s' % (
                         dns.rcode.to_text(response.rcode()), domain.name))
         return False
     if delete:
         self.log.info('Successfully deleted dns-record %s %d IN %s %s' % (
                                 str(sqlobject.key), int(sqlobject.ttl),
                                 str(sqlobject.type), value))
     else:
         self.log.info('Successfully added dns-record %s %d IN %s %s' % (
                                 str(sqlobject.key), int(sqlobject.ttl),
                                 str(sqlobject.type), value))
     return True
Beispiel #50
0
def _prepare_dns_updates(add_rrsets, delete_rrsets, my_zones):
    """Prepare a set of DNS updates for the specified rrset additions and deletions.
    
    One update will be created for each zone mentioned in the rrsets.  
    Constrints will be added to the DNS update message:
    
      * when deleting the record, ensure that it existed
      * when adding a record, ensure that it did not exist
      * when modifying (deleting and readding) a record, ensure that it existed
    
    Returns a dict mapping zone names to dnspython Update objects.
    """
    
    updates = {}
    
    for rrset in delete_rrsets:
        zone = _get_zone(rrset.name, my_zones)
        
        # Create a new update for this zone if necessary
        if zone not in updates:
            updates[zone] = dns.update.Update(zone, keyring=_create_keyring(zone))
        
        update = updates[zone]
        
        # Require the record exist before deleting it.
        update.present(rrset.name, *rrset.items)
        
        # Delete the record.
        update.delete(rrset.name, rrset)
        
    for rrset in add_rrsets:
        zone = _get_zone(rrset.name, my_zones)
        
        # Create a new update for this zone if necessary
        if zone not in updates:
            updates[zone] = dns.update.Update(zone, keyring=_create_keyring(zone))
        
        update = updates[zone]
        
        # For additions only, require that the record not exist before adding 
        # it.  We're processing each modification as a delete/add pair, so 
        # it will exist before the update (and we ensure this above).
        
        if rrset.name not in [delete.name for delete in delete_rrsets]:
            update.absent(rrset.name, rrset.rdtype)
        
        update.add(rrset.name, rrset)
    
    return updates
Beispiel #51
0
    def create_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring, keyalgorithm=self.algorithm)
        for entry in self.module.params['value']:
            try:
                update.add(self.module.params['record'],
                           self.module.params['ttl'],
                           self.module.params['type'],
                           entry)
            except AttributeError:
                self.module.fail_json(msg='value needed when state=present')
            except dns.exception.SyntaxError:
                self.module.fail_json(msg='Invalid/malformed value')

        response = self.__do_update(update)
        return dns.message.Message.rcode(response)
Beispiel #52
0
def dns_register_wildcard_cname(name):
	'''Creates a DNS wildcard CNAME entry '*.{name}' pointing to '{name}'
	'''

	assert name, 'Invalid parameters to DNS UPDATE: name={name}'.format(name=name)

	dns_params = _dns_init()
	cname = '*.{name}'.format(name=name)
	af, addr, port = [ dns_params.pop(attr) for attr in ('af', 'addr', 'port') ]

	print 'Registering DNS wildcard CNAME: {cname} -> {name}.{zone}'.format(cname=cname, name=name, zone=dns_params['zone'])

	update = dns.update.Update(**dns_params)
	#update = dns.update.Update(zone, keyring=keyring, keyname=zone, keyalgorithm=dns.tsig.HMAC_MD5)
	update.add(cname, 60, 'cname', name)
	response = dns.query.udp(update, where=addr, port=port, timeout=60, af=af)
Beispiel #53
0
    def _submitDNS(self, value):

        update = dns.update.Update(
            self.zone,
            keyring=dns.tsigkeyring.from_text(self.tsig_key))

        update.delete(self.record, self.type)
        update.add(self.record, self.ttl, self.type, "%s" % value)
        #print update

        response = dns.query.tcp(update, self.dns_ip)
        #print response

        #if response.rcode() != 0:
            #raise ValueError("Unexpected Response Code")

        return str(response)
Beispiel #54
0
def update():
    if 'hostname' not in request.args:
        abort(400)
    if 'myip' not in request.args:
        abort(400)
    hostname = dns.name.from_text(request.args['hostname'])
    domain = dns.name.from_text(DOMAIN)
    particle = hostname.relativize(domain)
    if not hostname.is_subdomain(domain):
        return 'nohost'
    update = dns.update.Update(DOMAIN, keyring=KEYRING)
    update.delete(str(particle))
    update.add(str(particle), 600, 'a', str(request.args['myip']))
    response = dns.query.tcp(update, DNSHOST)
    if response.rcode() == 0:
        return "good "+str(request.args['myip'])
    else:
        return "dnserr"
Beispiel #55
0
def generate_update_from_diff(zonename, original_zone, updated_zone,
                              keyring, keyalgo, force_conflicts):
    update = dns.update.Update(zonename, keyring = keyring,
                               keyalgorithm = keyalgo)

    if (not force_conflicts):
        # Require the old SOA to still be present
        # (Essentially requires that the zone hasn't changed while editing)
        oldsoa = get_single_record(original_zone.iterate_rdatas(), 
                                   dns.rdatatype.SOA)
        update.present(oldsoa[0], oldsoa[2])

    added, removed = get_zone_diff(original_zone, updated_zone)

    for (name, ttl, rdata) in removed:
        update.delete(name, rdata)

    for (name, ttl, rdata) in added:
        update.add(name, ttl, rdata)

    return [update, len(added), len(removed)]
Beispiel #56
0
    def configure(self):
        cfg = self.ud.getSection('dnsupdate')
        for key in ('tsighost', 'tsigkey', 'host', 'domain', 'server'):
            if key not in cfg:
                return

        instanceid = self.id.getInstanceId()
        ipaddr = self.id.getPublicIPv4()

        template = True
        for key in ('prefix', 'domain', 'start'):
            if key not in cfg:
                template = False
                break

        if template:
            index = int(self.id.getAMILaunchIndex())
            start = int(cfg['start'])
            clusterid = '%02d' % (start + index)
            cfg['host'] = '%s%s' % (cfg['prefix'], clusterid)

        # Set keyring using TSIG variables from User Data
        keyring = dns.tsigkeyring.from_text({
            cfg['tsighost'] : cfg['tsigkey']
        })
        update = dns.update.Update(cfg['domain'], keyring=keyring)

        # Clear all TXT and A entries for domain
        update.delete(cfg['host'], 'a')
        dns.query.tcp(update, cfg['server'])
        update.delete(cfg['host'], 'txt')
        dns.query.tcp(update, cfg['server'])

        # Create A entry with public IP address
        update.add(cfg['host'], 300, 'a', ipaddr)
        dns.query.tcp(update, cfg['server'])

        # Create TXT entry with instanceID
        update.add(cfg['host'], 300, 'txt', instanceid)
        dns.query.tcp(update, cfg['server'])
Beispiel #57
0
def modify_zone_record(domain_name, domain_ip, key_file):
    """modify DNS zone record from dns server and return rcode.

    Args:
        String domain_name
        String domain_ip

    Returns:
        String rcode
    issue #1: when update the forward record, also need update the reserve record
    issue #2: before update the forward record, u need validate if the record is exist,if not exist, return fail, if exist ,return              success,and update the record
    """
    KeyRing = getKey(key_file)
    ttl = 3600
    record_type = "A"
    domain = dns.name.from_text(DOMAIN)
    update = dns.update.Update(DOMAIN, keyring = KeyRing)
    update.delete(str(domain_name))
    update.add(str(domain_name), ttl, record_type, str(domain_ip))
    response = dns.query.tcp(update, DNSHOST)
    rcode = response.rcode()
    return rcode
Beispiel #58
0
 def dns_push(self, logid, fqdn, v4_addrs = [], v6_addrs = [], cname = None):
     """
     Push a set of A and AAAA records to the DNS, but only if they've
     changed.
     """
     # check if there are any changes, sort the addresses first so that
     # scoring order changes do not cause cache misses
     v4_addrs = sorted(v4_addrs)
     v6_addrs = sorted(v6_addrs)
     if cname != None:
         cache_key = "CNAME " + cname
         v4_addrs = v6_addrs = []
     else:
         cache_key = ' '.join(v4_addrs) + ' ' + ' '.join(v6_addrs)
     
     if self.dns_update_cache.get(fqdn) == cache_key:
         #self.log.info("DNS push [%s]: %s - no changes", logid, fqdn)
         return
         
     self.dns_update_cache[fqdn] = cache_key
     
     # look up the zone file to update
     zone = self.dns_pick_zone(fqdn)
     if zone == None:
         self.log.info("DNS push [%s]: %s is not in a managed zone, not updating", logid, fqdn)
         return
     
     # add a dot to make sure bind doesn't add the zone name in the end
     fqdn = fqdn + '.'
     
     self.log.info("DNS pushing [%s]: %s: %s", logid, fqdn, cache_key)
     
     update = dns.update.Update(zone, keyring=self.dns_keyring, keyalgorithm="hmac-sha256")
     update.delete(fqdn)
     if cname != None:
         update.add(fqdn, self.dns_ttl, 'cname', cname + '.')
     else:
         for a in v4_addrs:
             update.add(fqdn, self.dns_ttl, 'a', a.encode('ascii'))
         for a in v6_addrs:
             update.add(fqdn, self.dns_ttl, 'aaaa', a.encode('ascii'))
     
     try:
         response = dns.query.tcp(update, self.dns_master)
     except socket.error as e:
         self.log.error("DNS push [%s]: update error, cannot connect to DNS master: %r", logid, e)
         return
     except dns.tsig.PeerBadKey as e:
         self.log.error("DNS push [%s]: update error, DNS master does not accept our key: %r", logid, e)
         return
     except Exception as e:
         self.log.error("DNS push [%s]: update error: %r", logid, e)
         return
         
     self.log.info("DNS push [%s]: Sent %s: %s - response: %s / %s", logid, zone, fqdn,
         dns.opcode.to_text(dns.opcode.from_flags(response.flags)),
         dns.rcode.to_text(dns.rcode.from_flags(response.flags, response.ednsflags))
         )
Beispiel #59
0
if __name__ == '__main__':
    options, args = parse_options()

    print options.remove, options.add
    if not (options.remove or options.add):
        print "figure out how to print usage"
        sys.exit(1)
 
    config = load_config(options.config)

    tsig =  config['domain']['tsig']
    domain_name = config['domain']['name']
    name_server = config['domain']['server']
    ttl = config['domain']['ttl']

    keyring = dns.tsigkeyring.from_text({
        "%s." % (domain_name) : tsig
    })
    
    update = dns.update.Update(domain_name, keyring=keyring)

    if options.remove:
        update.delete(options.name, 'A', options.ipaddress)
    elif options.add:
        update.add(options.name, ttl, 'A', options.ipaddress)
    try:
        response = dns.query.tcp(update, name_server)
    except Exception, e:
        print e