コード例 #1
0
ファイル: utils.py プロジェクト: vinyldns/vinyldns
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
コード例 #2
0
ファイル: update_dns.02.py プロジェクト: jamescth/notes
def main():

    if (len(sys.argv) != 7):
        usage()
        return

    cmd = sys.argv[1]
    print "cmd", cmd

    hostname = sys.argv[2]
    print "hostname", hostname

    dns_ip = sys.argv[3]
    print "hostname", dns_ip

    domainname = sys.argv[4]
    print "Domain name", domainname

    ip = sys.argv[5]
    print "ip", ip

    prt = sys.argv[6]
    print "ip", prt

    # replace example with the domainname
    # replace host w/ the hostame
    update = dns.update.Update(domainname, keyring=keyring)
    update.replace(hostname, 300, prt, ip)

    # replace 10.0.0.1 with the dns server ip
    response = dns.query.tcp(update, dns_ip)

    print response
コード例 #3
0
def addREV(ipaddress, ttl, name):
    reversedomain = dns.reversename.from_address(str(ipaddress))
    reversedomain = str(reversedomain).rstrip('.')
    log.debug('[addREV] - reversedomain  %s' % reversedomain)
    authdomain = getrevzone_auth(str(reversedomain)).rstrip('.')
    log.debug('[addREV] - authdomain %s' % authdomain)
    label = stripptr(authdomain, reversedomain)
    log.debug('[addREV] - label %s' % label)
    name = name
    if name.endswith("."):
        return
    else:
        name = name + '.'
    log.debug('[addREV] - name %s' % name)
    check4TSIG = TSIGSecured(authdomain)
    if check4TSIG.isSecure(authdomain):
        key = str(check4TSIG.TSIG(authdomain))
        keyname = authdomain.replace(".", "_")
        keyring = dns.tsigkeyring.from_text({keyname: key})
        update = dns.update.Update(authdomain, keyring=keyring)
    else:
        update = dns.update.Update(authdomain)
    update.replace(label, monitor_ttl, dns.rdatatype.PTR, name)
    response = dns.query.tcp(update, monitor_nameserver)
    return response
コード例 #4
0
ファイル: dnsbl.py プロジェクト: srulikuk/private-dnsbl
def AddDNS(ip, rev_address, trap, host, sender, value='127.0.0.1'):
    print('Adding type A record "%s" for %s.%s :' %
          (value, rev_address, DNSBL_ZONE)),
    timestamp = int(time.time())
    date = datetime.datetime.fromtimestamp(
        timestamp, tz=pytz.utc).strftime('%Y-%m-%dZ%H:%M:%S')
    keyring = dns.tsigkeyring.from_text(RNDC_KEY)
    update = dns.update.Update(DNSBL_ZONE,
                               keyring=keyring,
                               keyalgorithm='hmac-md5.sig-alg.reg.int')
    update.replace(rev_address, 8600, 'A', value)
    update.replace(rev_address, 8600, 'TXT',
                   '"Address %s added at %d (%s)"' % (ip, timestamp, date))
    response = dns.query.tcp(update, DNS_HOSTNAME)
    if response.rcode() == dns.rcode.NOERROR:
        print('NOERROR, Adding to log file')
        # write to log file
        with open("/var/log/dnsbl_spamtrap.log", "a") as log:
            log.write(
                '{},IP-BANNED={},TRAP={},SENDER-HOST={},SENDER-EMAIL={}\n'.
                format(date, ip, trap, host, sender))
        return 0
    elif response.rcode() == dns.rcode.REFUSED:
        print('REFUSED')
        return 1
    else:
        print('Response: %s' % (response, ))
        return 2
コード例 #5
0
ファイル: paste.py プロジェクト: 5l1v3r1/dnsbin-1
    def on_post(self, req, resp):
        update = dns.update.Update(
            CONFIG.get('server', 'zone'),
            keyring=KEYRING,
            keyalgorithm=CONFIG.get('key', 'algo')
        )

        body = req.context['json']['data']
        LOGGER.info("Received %d byte long paste" % len(body))
        try:
            base64.b64decode(body.decode("ascii"))
        except Exception:
            raise falcon.HTTPBadRequest("Wrong encoding", "Your data is not base64 encoded !")

        uid = str(uuid.uuid4())
        i = 0
        for chunk in chunks(body, 255):
            i += 1
            LOGGER.info("Registering chunk %d of paste %s : %s" % (i, uid, chunk))
            update.replace("%d.%s" % (i, uid), 10, 'TXT', str(chunk))
            response = dns.query.tcp(update, CONFIG.get('server', 'address'))
        LOGGER.info("Registering chunk number of paste %s" % uid)
        update.replace("%s" % uid, 10, 'TXT', "%d" % i)
        response = dns.query.tcp(update, CONFIG.get('server', 'address'))
        req.context['result'] = {"paste": uid}
        LOGGER.info("Paste %s registered !" % uid)
コード例 #6
0
ファイル: utils.py プロジェクト: britneywright/vinyldns
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
コード例 #7
0
ファイル: ddns_updater.py プロジェクト: willnx/vlab_ipam_api
def update_a_record(hostname, ip, domain, domain_ip, keyring, algorithm):
    """Update the DNS record

    :Returns: None

    :param hostname: The name to give the DNS record
    :type hostname: String

    :param ip: The IP the hostname should map to
    :type ip: String

    :param domain: The FQDN of the vLab server
    :type domain: String

    :param domain_ip: The IPv4 address of the DNS server to send the udpate to
    :type domain_ip: String

    :param keyring: The dnssec creds required for making an update
    :type keyring: dns.tsigkeyring.from_text

    :type algorithm: The encryption method used for the keyring creds
    :type algorithm: String
    """
    update = dns.update.Update(domain, keyring=keyring, keyalgorithm=algorithm)
    update.replace(hostname, 300, 'a',
                   ip)  # 'a' means A-record, 300 is the TTL
    dns.query.udp(update, domain_ip)
コード例 #8
0
    def update_zone(self):
        keyring = dns.tsigkeyring.from_text({
            self.key_name: self.key
            })

        update = dns.update.Update(self.domain, keyring=keyring)
        update.replace(self.host, 300, 'A', self.local_ip)

        try:
            response = dns.query.tcp(update, master_dns_server, timeout=10)
            logging.info(response)
        except EOFError as e:
            logging.error('Can not connect to DNS server, check your '
                          'connection, exiting')
            sys.exit(1)
        except dns.tsig.PeerBadKey as e:
            logging.error('Can not read authenticate with DNS server, '
                          'check credentials, exiting')
            logging.error(e)
            sys.exit(1)
        except dns.tsig.PeerBadTime as e:
            logging.error('Time on local sever is not in sync with time'
                          ' on the remote server, exiting')
            logging.error(e)
            sys.exit(1)
コード例 #9
0
    def _generate_update(self, zone):
        update = dns.update.Update(
            zone,
            keyring=self.keyring,
            keyalgorithm=self.keyalgorithm,
        )
        z = dns.zone.from_xfr(dns.query.xfr(self.server, zone))
        changed = False

        if self.ipv4addr:
            for name, ttl, rdata in z.iterate_rdatas('A'):
                if ttl != self.ttl:
                    continue

                if self.ipv4addr == IPv4Address(rdata.address):
                    continue

                update.replace(name, self.ttl, 'A', str(self.ipv4addr))
                changed = True

        if self.ipv6net:
            for name, ttl, rdata in z.iterate_rdatas('AAAA'):
                if ttl != self.ttl:
                    continue

                ipv6addr = self._relocate_ipv6_host(IPv6Address(rdata.address))
                if ipv6addr == IPv6Address(rdata.address):
                    continue

                update.replace(name, self.ttl, 'AAAA', str(ipv6addr))
                changed = True

        return update if changed else None
コード例 #10
0
def update_txt(
        nserver: str,
        key_name: str,
        secret: str,
        hmac_algo: str,
        zone: str,
        records: Mapping[str, str],
        ttl: int,
) -> None:
    """
    Upsert TXT records through TSIG authenticated dns update request.

    nserver: DNS server to send update to.
    key_name: Name of shared key
    secret: Shared secret (b64 string)
    hmac_algo: hmac algorithm to use for signing
    zone: DNS zone to update
    records: Map from domain names (fully qualified) to TXT record values.
    ttl: time to live
    """
    update = dns.update.Update(
        zone,
        keyring=dns.tsigkeyring.from_text({
            key_name: secret,
        }),
        keyalgorithm=dns.name.from_text(hmac_algo),
    )

    for fqdn, value in records.items():
        update.replace(strip_zone(fqdn, zone), ttl, 'txt', f'"{value}"')

    dns.query.tcp(update, nserver, timeout=10)
コード例 #11
0
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
コード例 #12
0
ファイル: docker-ddns.py プロジェクト: mbartsch/code
def dockerddns(action, event, dnsserver=config['dockerddns']['dnsserver'], ttl=60):
    update = dns.update.Update(config['dockerddns']['zonename'], keyring=keyring, keyname=config['dockerddns']['keyname'])
    if (action == 'start' and event['ip'] != '0.0.0.0' ):
        logging.debug('[%s] Updating dns %s , setting %s.%s to %s' % (event['name'], dnsserver, event['hostname'], config['dockerddns']['zonename'],event['ip']))
        update.replace(event['hostname'], ttl, 'A', event['ip'])
    elif (action == 'die' ):
        logging.debug('[%s] Removing entry for %s.%s in %s' % (event['name'], event['hostname'], config['dockerddns']['zonename'], dnsserver))
        update.delete(event['hostname'])
    try:
      response = dns.query.tcp(update, dnsserver, timeout=10)
    except (socket.error, dns.exception.Timeout):
      logging.debug('Timeout updating DNS')
      response = 'Timeout Socket'
      pass
    except dns.query.UnexpectedSource:
      logging.debug('Unexpected Source')
      response = 'UnexpectedSource'
      pass
    except dns.tsig.PeerBadKey:
      logging.debug('Bad Key for DNS, Check your config files')
      response = "BadKey"
      pass

    if response.rcode() != 0: 
      logging.error("[%s] Error Reported while updating %s (%s/%s)" % (event['name'],event['hostname'],dns.rcode.to_text(response.rcode()), response.rcode()))
コード例 #13
0
ファイル: domain-manager.py プロジェクト: arbu/lan-router
def domain_add(domain, ip):
    try:
        dns.resolver.query(domain + ".lan", "a")
    except dns.resolver.NXDOMAIN:
        update = dns.update.Update("lan")
        update.replace(domain, 300, "a", ip)
        dns.query.tcp(update, "127.0.0.1")
コード例 #14
0
ファイル: update.py プロジェクト: roninkenji/ddns.py
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())
コード例 #15
0
ファイル: update_dns.02.py プロジェクト: jamescth/notes
def main():

	if (len(sys.argv) != 7):
		usage()
		return

	cmd = sys.argv[1]
	print "cmd", cmd

	hostname = sys.argv[2]
	print "hostname", hostname

	dns_ip = sys.argv[3]
	print "hostname", dns_ip

	domainname = sys.argv[4]
	print "Domain name", domainname

	ip = sys.argv[5]
	print "ip", ip

	prt = sys.argv[6]
	print "ip", prt

	# replace example with the domainname
	# replace host w/ the hostame
	update = dns.update.Update(domainname, keyring=keyring)
	update.replace(hostname, 300, prt, ip)

	# replace 10.0.0.1 with the dns server ip
	response = dns.query.tcp(update, dns_ip)

	print response
コード例 #16
0
ファイル: domain-manager.py プロジェクト: arbu/lan-router
def domain_add(domain, ip):
	try:
		dns.resolver.query(domain + ".lan", "a")
	except dns.resolver.NXDOMAIN:
		update = dns.update.Update("lan")
		update.replace(domain, 300, "a", ip)
		dns.query.tcp(update, "127.0.0.1")
コード例 #17
0
def update_dns(zone, record, dns_update_host, new_ip, key):
  record = record.split('.')[0]             # we use just the non-fqdn record, not the full record.
  print "Updating zone [%s] record [%s] on dns host [%s] with new ip [%s]" % (zone, record, dns_update_host, new_ip)
  keyring = dns.tsigkeyring.from_text({zone : key})
  update = dns.update.Update(zone, keyring = keyring, keyname = zone, keyalgorithm = 'hmac-sha512')
  update.replace(record, 60, 'A', new_ip)
  response = dns.query.tcp(update, dns_update_host)
  sys.exit(0)
コード例 #18
0
 def test_TSIG(self):
     keyring = dns.tsigkeyring.from_text(
         {"keyname.": "NjHwPsMKjdN++dOfE5iAiQ=="})
     update = dns.update.Update("example.", keyring=keyring)
     update.replace("host.example.", 300, "A", "1.2.3.4")
     wire = update.to_wire()
     update2 = dns.message.from_wire(wire, keyring)
     self.assertEqual(update, update2)
コード例 #19
0
ファイル: test_update.py プロジェクト: zhutony/dnspython
 def test_TSIG(self):
     keyring = dns.tsigkeyring.from_text(
         {'keyname.': 'NjHwPsMKjdN++dOfE5iAiQ=='})
     update = dns.update.Update('example.', keyring=keyring)
     update.replace('host.example.', 300, 'A', '1.2.3.4')
     wire = update.to_wire()
     update2 = dns.message.from_wire(wire, keyring)
     self.assertEqual(update, update2)
コード例 #20
0
 def _update_record(self, qtype, fqdn, data, do_ptr):
     log.debug('DDNS update for record {}, fqdn: {}'.format(qtype, fqdn))
     origin, name = self._parse_name(fqdn)
     update = dns.update.Update(origin, keyring=self.keyring)
     update.replace(name, self.ttl, qtype, data)
     self._do_update(update)
     if do_ptr:
         self._update_ptr(fqdn, data)
コード例 #21
0
ファイル: dns.py プロジェクト: samuelchen/code-snippets
def ddns(dns_ip, domain, ip, tsigkey_name, tsigkey):

   keyring = dns.tsigkeyring.from_text({
       tsigkey_name : tsigkey
       })
   update = dns.update.Update('example.', keyring=keyring)
   update.replace(ip, 300, 'A', sys.argv[1])
   response = dns.query.tcp(update, dns_ip, timeout=10)
コード例 #22
0
    def modify_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring, keyalgorithm=self.algorithm)
        update.replace(self.module.params['record'],
                       self.module.params['ttl'],
                       self.module.params['type'],
                       self.module.params['value'])

        response = self.__do_update(update)
        return dns.message.Message.rcode(response)
コード例 #23
0
def add_a_record(server, zone, key, name, address, 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.replace(name, ttl, 'a', address)
    response = dns.query.tcp(update, server)
    return response
コード例 #24
0
def add_a_record(server, zone, key, name, address, 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.replace(name, ttl, 'a', address)
    response = dns.query.tcp(update, server)
    return response
コード例 #25
0
 def create_ptr(self, ptr):
     if not isinstance(ptr, Ptr):
         raise ValueError("Argument must be of Ptr class.")
     update = dns.update.Update(ptr.get_ptr_zone(),
                                keyring=self.keyring,
                                keyalgorithm=HMAC_MD5)
     update.replace(ptr.get_ptr_zone_name(), 300, 'PTR', ptr.ptr)
     self.logger.debug("Updating %s" % self.dns_hostname)
     dns.query.tcp(update, self.dns_hostname)
コード例 #26
0
ファイル: dnsrecord.py プロジェクト: rubydhash/webradius
 def update_a(self):
     try:
         update = dns.update.Update(self.get_domain_fqdn(), keyring=self.__keyring)
         # Só realiza o update se tiver uma entrada TXT e o valor dela bater com o calculado pelo servidor
         update.present(self.__hostname, 'TXT', self.__txt_value)
         update.replace(self.__hostname, self.__ttl, 'A', self.__ip)
         return dns.query.tcp(update, self.__server_ip).rcode()
     except Exception, error:
         raise Exception("Error updating DNS A Entry: %s" % (error))
コード例 #27
0
def update(domain, host, ip):

    keyring = dns.tsigkeyring.from_text({'rndc-key': 'myRNDCkey=='})

    update = dns.update.Update('{0}.'.format(domain), keyring=keyring)
    update.replace(host, 300, 'A', ip)
    response = dns.query.tcp(update, '127.0.0.1', timeout=10)

    return "update with {0}\n".format(ip)
コード例 #28
0
def create_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.replace(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))

    logging.debug("DNS record PTR")
    ### Create reverse entry (PTR)
    # Neat function to generate a reverse entry
    reventry = dns.reversename.from_address(new_ipaddress)
    revzone = ''
    # Specify the reverse lookup zone based on the reverse IP address.
    # The labels[X:] property allows you to specify which octet to use.
    # e.g. 3: will apply the record to the 10.in-addr.arpa zone,
    # whereas 1: will apply it to the 72.23.10.in-addr.arpa zone
    revzone = b'.'.join(dns.name.from_text(str(reventry)).labels[1:])  #
    revzone = revzone.decode()

    # Prepare the payload for the DNS record update
    raction = dns.update.Update(zone=revzone,
                                keyname='dynamic.vmware.haf.',
                                keyring=keyring,
                                keyalgorithm=dns.tsig.HMAC_SHA512)

    # Although we are updating the reverse lookup zone,
    # the record needs to point back to the ‘test.example.com’ domain, not the 10.in-addr.arpa domain
    new_host_fqdn = '%s.%s' % (new_hostname, dns_domain)
    # Inject the updated record details into the the class, preparing for submission to the DNS server
    raction.replace(reventry, TTL, dns.rdatatype.PTR, new_host_fqdn)
    # submit the new record to the DNS server to apply the update
    response = dns.query.tcp(raction, PRIMARY_DNS_SERVER_IP, timeout=5)
    flags = dns.flags.to_text(response.flags)
    logging.debug(" PTR DNS update response: {} {}".format(
        dns.rcode.to_text(response.rcode()), flags))
コード例 #29
0
 def UpdateDnsA(self,host,ip,domain,type,dnsip):
     logging.debug('UpdateDnsA: '+host+' '+ip+' '+domain+' '+dnsip)
     update = dns.update.Update(domain)
     update.replace(host, 3600, type, ip)
     try:
         logging.debug('UpdateDnsA: writing to dns server')
         response = dns.query.tcp(update, dnsip)
     except:
         logging.info('Writing A record failed')
         logging.exception('')
コード例 #30
0
 def UpdateDnsA(self, host, ip, domain, type, dnsip):
     logging.debug('UpdateDnsA: ' + host + ' ' + ip + ' ' + domain + ' ' +
                   dnsip)
     update = dns.update.Update(domain)
     update.replace(host, 3600, type, ip)
     try:
         logging.debug('UpdateDnsA: writing to dns server')
         response = dns.query.tcp(update, dnsip)
     except:
         logging.info('Writing A record failed')
         logging.exception('')
コード例 #31
0
    def modify_record(self):
        update = dns.update.Update(self.zone,
                                   keyring=self.keyring,
                                   keyalgorithm=self.algorithm)
        update.replace(self.record, self.ttl, self.type, self.value)

        response = self.__do_update(update)
        if dns.message.Message.rcode(response) == 0:
            return True
        else:
            return False
コード例 #32
0
ファイル: dockerddns.py プロジェクト: mbartsch/docker-ddns
def dockerbind(action, event, config):
    """
    This will update a zone in a bind dns configured for dynamic updates
    """
    dnsserver = config['dnsserver']
    ttl = config['ttl']
    port = config['dnsport']
    update = dns.update.Update(config['zonename'],
                               keyring=config['keyring'],
                               keyname=config['keyname'])
    #logging.debug('EVENT: %s', event)
    try:
        if "srvrecords" in event:
            srvrecords = event["srvrecords"].split()
            for srv in srvrecords:
                values = srv.split("#")
                #print("%s %s\n" % (values, event['hostname']))

        if action == 'start' and event['ip'] != '0.0.0.0':
            update.replace(event['hostname'], ttl, 'A', event['ip'])
            if event['ipv6'] != '':
                update.replace(event['hostname'], ttl, 'AAAA', event['ipv6'])
                logging.info(
                    '[%s] Updating dns %s , setting %s.%s to %s and %s',
                    event['name'], dnsserver, event['hostname'],
                    config['zonename'], event['ip'], event['ipv6'])
            else:
                logging.info('[%s] Updating dns %s , setting %s.%s to %s',
                             event['name'], dnsserver, event['hostname'],
                             config['zonename'], event['ip'])

        elif action == 'die':
            logging.info('[%s] Removing entry for %s.%s in %s', event['name'],
                         event['hostname'], config['zonename'], dnsserver)
            update.delete(event['hostname'])

        response = dns.query.tcp(update, dnsserver, timeout=10, port=port)
        if response.rcode() != 0:
            logging.error("[%s] Error Reported while updating %s (%s/%s)",
                          event['name'], event['hostname'],
                          dns.rcode.to_text(response.rcode()),
                          response.rcode())
    except (socket.error, dns.exception.Timeout):
        logging.error('Timeout updating DNS')
        response = 'Timeout Socket'
    except dns.query.UnexpectedSource:
        logging.error('Unexpected Source')
        response = 'UnexpectedSource'
    except dns.exception.SyntaxError:
        logging.error('Missing parameters to update DNS')
    except dns.tsig.PeerBadKey:
        logging.error('Bad Key for DNS, Check your config files')
        response = "BadKey"
    return event
コード例 #33
0
ファイル: dnsrecord.py プロジェクト: rubydhash/webradius
 def update_rev(self):
     try:
         name = self.validate_rev_name()
         if not name:
             return None
         
         update = dns.update.Update(self.get_rev_domain_fqdn(), keyring=self.__keyring)
         update.replace(name, self.__ttl, 'PTR', self.get_fqdn())
         return dns.query.tcp(update, self.__server_ip).rcode()
     except Exception, error:
         raise Exception("Error updating DNS PTR Entry: %s" % (error))
コード例 #34
0
 def edit_record(self, domain_zone, domain_name, ttl, record_type,
                 record_value):
     update = dns.update.Update(domain_zone,
                                keyring=self.keyring,
                                keyalgorithm=self.sha_type)
     update.replace(domain_name, ttl, record_type, record_value)
     dns.query.tcp(update, self.name_server_addr)
     if self.search_record(domain_name + '.' + domain_zone, record_type):
         return {'code': 0, 'message': 'ok'}
     else:
         return {'code': '2', 'message': 'not edit'}
コード例 #35
0
ファイル: flib.py プロジェクト: thor-vath/foxtrot
    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
コード例 #36
0
    def modify_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.replace(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")
コード例 #37
0
    def update(self, domain="", hostIP=""):
        if domain == "":
            return False

        update = dns.update.Update('flashhold.com', keyring=self.keyring)
        if hostIP:
            update.replace(domain, 300, 'A', hostIP)
        else:
            update.replace(domain, 300, 'A', settings.DNS_HOST)

        response = dns.query.tcp(update, settings.DNS_HOST)
        print response
コード例 #38
0
ファイル: nsupdate.py プロジェクト: airstand/ansible-nsupdate
    def modify_record(self):
        update = dns.update.Update(self.zone, keyring=self.keyring)
        update.replace(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')
コード例 #39
0
ファイル: geo.py プロジェクト: tuciu/beastcraft-telemetry
def update_dns(coords=None, domain=None, key=None):
    if domain and key and coords:
        print('Update DNS: {0}'.format(coords))
        keyring = dns.tsigkeyring.from_text({
            domain : key
        })
        
        update = dns.update.Update(domain, keyring=keyring)
        update.replace('geo', 300, dns.rdatatype.TXT, '"%s"' % coords)
    
        return dns.query.tcp(update, 'localhost')
    else:
        return None
コード例 #40
0
ファイル: dnsupdate.py プロジェクト: jhzab/tools
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)
コード例 #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)
コード例 #42
0
ファイル: test_update.py プロジェクト: rthalley/dnspython
 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)
コード例 #43
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)
コード例 #44
0
ファイル: test_update.py プロジェクト: DaveDaCoda/dnspython
 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)
コード例 #45
0
ファイル: update-dyndns.py プロジェクト: wingel/dyndns
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)
コード例 #46
0
ファイル: test_update.py プロジェクト: zhutony/dnspython
 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)
コード例 #47
0
def add_reverse_record(fqdn, domain, ip_address, ttl, dns_server, key_file, key_name):
    """Add a reverse PTR record to the specific DNS server and zone."""
    reverse_fqdn = str(dns.reversename.from_address(ip_address))
    reverse_ip = re.search(r"([0-9]+).(.*).$", reverse_fqdn).group(1)
    reverse_domain = re.search(r"([0-9]+).(.*).$", reverse_fqdn).group(2)

    try:
        key_ring = keyutils.read_tsigkey(key_file, key_name)
    except:
        raise

    update = dns.update.Update(reverse_domain, keyring = key_ring)
    update.replace(reverse_ip, ttl, 'PTR', fqdn + ".")
    try:
        response = dns.query.tcp(update, dns_server)
    except Exception, err:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print "type: %s, obj: %s, tb: %s" % (exc_type, exc_obj, exc_tb)
        print "Unhandled exception in add_forward_record: %s" % err
        raise
コード例 #48
0
ファイル: dnschange.py プロジェクト: curana/dynastie
	def publish(self):
		#
		# Replace the keyname and secret with appropriate values for your
		# configuration.
		#	
		keyring = dns.tsigkeyring.from_text({
		    'host-example.' : 'XXXXXXXXXXXXXXXXXXXXXX=='
		})

		#
		# Replace "example.com" with your domain, and "MY_HOSTNAME" with your hostname.
		#
		update = dns.update.Update('example.com', keyring=keyring)
		update.replace('MY_HOSTNAME', 300, 'A', self.myip)


		#
		# Replace "127.0.0.1" with the IP address of your master server.
		#
		response = dns.query.tcp(update, '127.0.0.1', timeout=10)
コード例 #49
0
ファイル: dnsrecords.py プロジェクト: ramsateesh/Axfr-ddns
    def updatedns_records(self):
        config = getconfig.Config()
        configParser = config.getConfig()
        dbcon = dbconn.DbConn()
        keyname = configParser['keyname']
        secretkey = configParser['secretkey']
        zone = configParser['zone']
        dnsServer = configParser['dnsserver']
        ddnsRecords = dbcon.getRecords()
        self.LOG.debug("keyname: {}, secretkey: {}, zone: {}, dnsserver: {}".format(keyname,secretkey,zone, dnsServer))
        for row in ddnsRecords:
            '''created_at          | updated_at          | data        | action | name                 | type | ttl'''
            '''vmname = row[4].split('.')[0]'''
            vmname = row[4][:len(row[4])-(len(zone)+1)]
            ip = row[2]
            recType = row[5]
            ttl = row[6]
            created = row[0]
            updated = row[1]
            action = row[3]
            if (action == 'UPDATE') or (action == 'CREATE'):
                try:
                    keyring = dns.tsigkeyring.from_text({keyname : secretkey})
                except:
                    raise

                update = dns.update.Update(zone, keyring=keyring)
                self.LOG.debug("vmname: {}, ip {}, record Type: {}".format(vmname, ip, recType))
                update.replace(vmname, 300, recType, ip)

                try:
                    response = dns.query.tcp(update, dnsServer)
                except dns.tsig.PeerBadKey:
                    self.LOG.exception ("The remote DNS server ns5.kcdc.att.com. did not accept the key passed.")
                    raise
                except Exception, err:
                    exc_type, exc_obj, exc_tb = sys.exc_info()
                    self.LOG.exception ("type: %s, obj: %s, tb: %s" % (exc_type, exc_obj, exc_tb))
                    self.LOG.exception ("Unhandled exception in add_forward_record: %s" % err)
                    raise
                self.LOG.debug("Forward Record Output: %s" % response)
コード例 #50
0
def add_forward_record(hostname, domain, ip_address, ttl, dns_server, key_file, key_name):
    """Add an A record to the specific DNS server
    with the provided hostname/IP/key information."""

    try:
        key_ring = keyutils.read_tsigkey(key_file, key_name)
    except:
        raise

    update = dns.update.Update(domain, keyring = key_ring)
    update.replace(hostname, ttl, 'A', ip_address)
    try:
        response = dns.query.tcp(update, dns_server)
    except dns.tsig.PeerBadKey:
        print "The remote DNS server %s did not accept the key passed." % dns_server
        raise
    except Exception, err:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        print "type: %s, obj: %s, tb: %s" % (exc_type, exc_obj, exc_tb)
        print "Unhandled exception in add_forward_record: %s" % err
        raise
コード例 #51
0
ファイル: dnsupdate.py プロジェクト: 19317362/mqttwarn
def plugin(srv, item):

    srv.logging.debug("*** MODULE=%s: service=%s, target=%s", __file__, item.service, item.target)

    if HAVE_DNS == False:
        return False

    config   = item.config

    dns_nameserver = config['dns_nameserver']
    dns_keyname    = config['dns_keyname']
    dns_keyblob    = config['dns_keyblob']

    try:
        zone, domain, ttl, rrtype = item.addrs
    except:
        srv.logging.error("Incorrect target configuration for {0}/{1}".format(item.service, item.target))
        return False

    text = item.message

    try:
        keyring = dns.tsigkeyring.from_text( { str(dns_keyname) : str(dns_keyblob) });

        update = dns.update.Update(zone,
            keyring = keyring,
            keyname = dns_keyname,
            keyalgorithm = 'hmac-sha256')   #FIXME configurable

        if rrtype.upper() == 'TXT':
            text = '"%s"' % text

        update.replace(domain, ttl, rrtype, text)
        response = dns.query.tcp(update, dns_nameserver, timeout=10)

        srv.logging.debug("DNS Update: {0}".format(dns.rcode.to_text(response.rcode())))
    except Exception, e:
        srv.logging.warning("Cannot notify to dnsupdate `%s': %s" % (dns_nameserver, str(e)))
        return False
コード例 #52
0
ファイル: flask-dyndns.py プロジェクト: blade2005/FlaskDyndns
def update():
    user_config = Config.users[request.authorization.username]

    hostname = request.args.get("hostname")
    if hostname not in user_config["hostnames"]:
        raise Exception("hostname %s not defined for user %s" % (hostname, request.authorization.username))

    myip = request.args.get("myip")
    if myip is None:
        raise Exception("parameter 'myip' is required.")
    try:
        ip = socket.inet_ntoa(socket.inet_aton(myip))
    except:
        raise Exception("invalid ip '" + myip + "' in get parameter 'myip'")

    keyring = dns.tsigkeyring.from_text(Config.keyring_data)
    update = dns.update.Update(
        user_config["domain"], keyring=keyring, keyname=Config.key_name, keyalgorithm=Config.key_algo
    )
    update.replace(str(hostname), 10, "A", ip)
    response = dns.query.tcp(update, Config.nameserver)
    return "ok"
コード例 #53
0
ファイル: views.py プロジェクト: yekeqiang/restful
def create_forward_zone_record(dns_server, zone_name, record_name, record_type, record_data, ttl, key_file):
    """ Parse passed elements and determine which records to create.

    Args:
      String dns_server
      String zone_name
      String record_name (just record name, not FQDN)
      String record_type (A, AAAA, etc)
      String record_data (IP address)
      Int ttl
      String key_name (from Key model)

    Return:
      Dict containing {description, output} from record creation
    issue #3: before add the forward record, u need validate if the record is exist,if not exist, return fail, if exist ,return              success,and add the record
    """
    KeyRing = getKey(key_file)
    update = dns.update.Update(zone_name, keyring = KeyRing)
    update.replace(record_name, ttl, record_type, record_data)
    response = dns.query.tcp(update, dns_server, timeout=10)
    rcode = response.rcode()
    return rcode
コード例 #54
0
ファイル: acme_tiny.py プロジェクト: nuxi/acme-tiny
def get_crt(account_key, csr, skip_check=False, log=LOGGER, CA=PROD_CA, contact=None,
            dns_zone_update_server=None, dns_zone_keyring=None, dns_zone=None, dns_update_algo=None):
    directory, acct_headers, alg, jwk, nonce = None, None, None, None, [None] # global variables

    # helper functions - base64 encode for jose spec
    def _b64(b):
        return base64.urlsafe_b64encode(b).decode('utf8').replace("=", "")

    # helper function - run external commands
    def _cmd(cmd_list, stdin=subprocess.PIPE, cmd_input=None, err_msg="Command Line Error"):
        proc = subprocess.Popen(cmd_list, stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
        out, err = proc.communicate(cmd_input)
        if proc.returncode != 0:
            raise IOError("{0}\n{1}".format(err_msg, err))
        return out

    # helper function - make request and automatically parse json response
    def _do_request(url, data=None, err_msg="Error", depth=0):
        try:
            resp = urlopen(Request(url, data=data, headers={"Content-Type": "application/jose+json", "User-Agent": "acme-tiny-dns"}))
            resp_data, code, headers = resp.read().decode("utf8"), resp.getcode(), resp.headers
        except IOError as e:
            resp_data = e.read().decode("utf8") if hasattr(e, "read") else str(e)
            code, headers = getattr(e, "code", None), {}
        nonce[0] = headers.get('Replay-Nonce', None)
        try:
            resp_data = json.loads(resp_data) # try to parse json results
        except ValueError:
            pass # ignore json parsing errors
        if depth < 100 and code == 400 and resp_data['type'] == "urn:ietf:params:acme:error:badNonce":
            raise IndexError(resp_data) # allow 100 retrys for bad nonces
        if code not in [200, 201, 204]:
            raise ValueError("{0}:\nUrl: {1}\nResponse Code: {2}\nResponse: {3}".format(err_msg, url, code, resp_data))
        return resp_data, code, headers

    # helper function - make signed requests
    def _send_signed_request(url, payload=None, err_msg="Error", depth=0):
        payload64 = _b64(json.dumps(payload).encode('utf8')) if payload is not None else ""
        if nonce[0] is None:
            _do_request(directory['newNonce'])
        protected = {"url": url, "alg": alg, "nonce": nonce[0]}
        protected.update({"jwk": jwk} if acct_headers is None else {"kid": acct_headers['Location']})
        protected64 = _b64(json.dumps(protected).encode('utf8'))
        protected_input = "{0}.{1}".format(protected64, payload64).encode('utf8')
        out = _cmd(["openssl", "dgst", "-sha256", "-sign", account_key], cmd_input=protected_input, err_msg="OpenSSL Error")
        data = json.dumps({"protected": protected64, "payload": payload64, "signature": _b64(out)})
        try:
            return _do_request(url, data=data.encode('utf8'), err_msg=err_msg, depth=depth)
        except IndexError: # retry bad nonces (they raise IndexError)
            return _send_signed_request(url, payload, err_msg, depth=(depth + 1))

    # helper function - poll until complete
    def _poll_until_not(url, pending_statuses, err_msg="Error", timeout=90):
        deadline = time.time() + timeout
        while True:
            result, _, _ = _send_signed_request(url, err_msg=err_msg)
            if time.time() < deadline and result['status'] in pending_statuses:
                time.sleep(2)
                continue
            return result

    # parse account key to get public key
    log.info("Parsing account key...")
    out = _cmd(["openssl", "rsa", "-in", account_key, "-noout", "-text"], err_msg="OpenSSL Error")
    pub_pattern = r"modulus:\n\s+00:([a-f0-9\:\s]+?)\npublicExponent: ([0-9]+)"
    pub_hex, pub_exp = re.search(pub_pattern, out.decode('utf8'), re.MULTILINE|re.DOTALL).groups()
    pub_exp = "{0:x}".format(int(pub_exp))
    pub_exp = "0{0}".format(pub_exp) if len(pub_exp) % 2 else pub_exp
    alg = "RS256"
    jwk = {
        "e": _b64(binascii.unhexlify(pub_exp.encode("utf-8"))),
        "kty": "RSA",
        "n": _b64(binascii.unhexlify(re.sub(r"(\s|:)", "", pub_hex).encode("utf-8"))),
    }
    accountkey_json = json.dumps(jwk, sort_keys=True, separators=(',', ':'))
    thumbprint = _b64(hashlib.sha256(accountkey_json.encode('utf8')).digest())

    # find domains
    log.info("Parsing CSR...")
    out = _cmd(["openssl", "req", "-in", csr, "-noout", "-text"], err_msg="Error loading {0}".format(csr))
    domains = set([])
    common_name = re.search(r"Subject:.*? CN\s?=\s?([^\s,;/]+)", out.decode('utf8'))
    if common_name is not None:
        domains.add(common_name.group(1))
    subject_alt_names = re.search(r"X509v3 Subject Alternative Name: \n +([^\n]+)\n", out.decode('utf8'), re.MULTILINE|re.DOTALL)
    if subject_alt_names is not None:
        for san in subject_alt_names.group(1).split(", "):
            if san.startswith("DNS:"):
                domains.add(san[4:])
    log.info("Found domains: {0}".format(", ".join(domains)))

    # get the ACME directory of urls
    log.info("Getting directory...")
    directory, _, _ = _do_request(CA, err_msg="Error getting directory")
    log.info("Directory found!")

    # create account, update contact details (if any), and set the global key identifier
    log.info("Registering account...")
    reg_payload = {"termsOfServiceAgreed": True}
    account, code, acct_headers = _send_signed_request(directory['newAccount'], reg_payload, "Error registering")
    log.info("{0}egistered: {1}".format("R" if code == 201 else "Already r", acct_headers['Location']))
    if contact is not None:
        account, _, _ = _send_signed_request(acct_headers['Location'], {"contact": contact}, "Error updating contact details")
        log.info("Updated contact details:\n{0}".format("\n".join(account['contact'])))

    # create a new order
    log.info("Creating new order...")
    order_payload = {"identifiers": [{"type": "dns", "value": d} for d in domains]}
    order, _, order_headers = _send_signed_request(directory['newOrder'], order_payload, "Error creating new order")
    log.info("Order created!")

    pending = []

    # get the authorizations that need to be completed
    for auth_url in order['authorizations']:
        authorization, _, _ = _send_signed_request(auth_url, err_msg="Error getting challenges")
        domain = authorization['identifier']['value']
        rdomain = '*.{0}'.format(domain) if authorization.get('wildcard', False) else domain
        if authorization['status'] == 'valid':
            log.info('Existing authorization for {0} is still valid!'.format(rdomain))
            continue
        types = [c['type'] for c in authorization['challenges']]
        if 'dns-01' not in types:
            raise IndexError('Challenge dns-01 is not allowed for {0}. Permitted challenges are: {1}'.format(rdomain, ', '.join(types)))
        log.info("Verifying {0} part 1...".format(rdomain))

        # find the dns-01 challenge and write the challenge file
        challenge = [c for c in authorization['challenges'] if c['type'] == "dns-01"][0]
        token = re.sub(r"[^A-Za-z0-9_\-]", "_", challenge['token'])
        keyauthorization = "{0}.{1}".format(token, thumbprint)
        record = _b64(hashlib.sha256(keyauthorization.encode('utf8')).digest())
        log.info('_acme-challenge.%s. 60 IN TXT %s' % (domain, record))
        zone = '_acme-challenge.'+domain
        if dns_zone:
            zone = dns_zone
            if isinstance(dns_zone, int):
                zone = '.'.join(('_acme-challenge.' + domain).split('.')[dns_zone:])
        pending.append((auth_url, authorization, challenge, domain, keyauthorization, rdomain, record, token, zone))

    if pending:
        if not dns_zone_update_server:
            log.info('Press enter to continue after updating DNS server')
            six.moves.input()
        else:
            log.debug('Performing DNS Zone Updates...')
            for authz in pending:
                auth_url, authorization, challenge, domain, keyauthorization, rdomain, record, token, zone = authz
                log.debug('Updating TXT record {0} in DNS zone {1}'.format('_acme-challenge.'+domain,zone))
                update = dns.update.Update(zone, keyring=dns_zone_keyring, keyalgorithm=dns_update_algo)
                update.replace('_acme-challenge.'+domain+'.', 60, 'TXT', str(record))
                response = dns.query.tcp(update, dns_zone_update_server, timeout=10)
                if response.rcode() != 0:
                    raise Exception("DNS zone update failed, aborting, query was: {0}".format(response))

    # verify each domain
    for authz in pending:
        auth_url, authorization, challenge, domain, keyauthorization, rdomain, record, token, zone = authz

        log.info("Verifying {0} part 2...".format(rdomain))

        if not skip_check:
            # check that the DNS record is in place
            addr = set()
            for x in dns.resolver.query(dns.resolver.zone_for_name(domain), 'NS'):
                addr = addr.union(map(str, dns.resolver.query(str(x), 'A', raise_on_no_answer=False)))
                addr = addr.union(map(str, dns.resolver.query(str(x), 'AAAA', raise_on_no_answer=False)))

            if not addr:
                raise ValueError("No DNS server for {0} was found".format(domain))

            qname = '_acme-challenge.{0}'.format(domain)
            valid = []
            for x in addr:
                req = dns.message.make_query(qname, 'TXT')
                try:
                    resp = dns.query.udp(req, x, timeout=30)
                except socket.error as e:
                    log.warn('Exception contacting {0}: {1}'.format(x, e))
                except dns.exception.DNSException as e:
                    log.warn('Exception contacting {0}: {1}'.format(x, e))
                else:
                    if resp.rcode() != dns.rcode.NOERROR:
                        raise ValueError("Query for {0} returned {1} on nameserver {2}".format(qname, dns.rcode.to_text(resp.rcode()), x))
                    else:
                        answer = resp.get_rrset(resp.answer, dns.name.from_text("{0}.".format(qname.rstrip(".")), None),
                                                dns.rdataclass.IN, dns.rdatatype.TXT)
                        if answer:
                            txt = list(map(lambda x: str(x)[1:-1], answer))
                            if record not in txt:
                                raise ValueError("{0} does not contain {1} on nameserver {2}".format(qname, record, x))
                            else:
                                valid.append(x)
                        else:
                            raise ValueError("Query for {0} returned an empty answer set on nameserver {1}".format(qname, x))

            if not valid:
                raise ValueError("No DNS server for {0} was reachable".format(qname))

        # say the challenge is done
        _send_signed_request(challenge['url'], {}, "Error submitting challenges: {0}".format(rdomain))

        # skip checking challenge state because it won't change if another challenge for this authorization has completed
        authorization = _poll_until_not(auth_url, ["pending"], "Error checking authorization status for {0}".format(rdomain))
        if authorization['status'] != "valid":
            errors = [c for c in authorization['challenges'] if c['status'] not in ('valid', 'pending') and 'error' in c]
            dns_error = [c for c in errors if c['type'] == 'dns-01']

            reason = dns_error[0] if dns_error else errors[0] if errors else None
            if reason is not None:
                raise ValueError("Challenge {0} failed (status: {1}) for {2}:\n{3}".format(reason['type'], reason['status'], rdomain,
                                 pprint.pformat(reason['error'])))
            else:
                raise ValueError("Authorization failed for {0}:\n{1}".format(rdomain, pprint.pformat(authorization)))
        log.info("{0} verified!".format(domain))

    # poll the order to monitor when it's ready
    order = _poll_until_not(order_headers['Location'], ["pending"], "Error checking order status")
    if order['status'] != "ready":
        raise ValueError("Order failed: {0}".format(order))

    # finalize the order with the csr
    log.info("Signing certificate...")
    csr_der = _cmd(["openssl", "req", "-in", csr, "-outform", "DER"], err_msg="DER Export Error")
    _send_signed_request(order['finalize'], {"csr": _b64(csr_der)}, "Error finalizing order")

    # poll the order to monitor when it's done
    order = _poll_until_not(order_headers['Location'], ["ready", "processing"], "Error checking order status")
    if order['status'] != "valid":
        raise ValueError("Order failed: {0}".format(order))

    # download the certificate
    certificate_pem, _, cert_headers = _send_signed_request(order['certificate'], err_msg="Certificate download failed")
    if cert_headers['Content-Type'] != "application/pem-certificate-chain":
        raise ValueError("Certifice received in unknown format: {0}".format(cert_headers['Content-Type']))

    # the spec recommends making sure that other types of PEM blocks don't exist in the response
    prefix = "-----BEGIN "
    suffix = "CERTIFICATE-----"
    for line in certificate_pem.splitlines():
        if line.startswith(prefix) and not line.endswith(suffix):
            raise ValueError("Unexpected PEM header in certificate: {0}".format(line))

    log.info("Certificate signed!")

    if pending:
        if not dns_zone_update_server:
            log.debug("You can now remove the _acme-challenge records from your DNS zone.")
        else:
            log.debug('Removing DNS records added for ACME challange...')
            for authz in pending:
                auth_url, authorization, challenge, domain, keyauthorization, rdomain, record, token, zone = authz
                log.debug('Removing TXT record {0} in DNS zone {1}'.format('_acme-challenge.'+domain,zone))
                update = dns.update.Update(zone, keyring=dns_zone_keyring, keyalgorithm=dns_update_algo)
                update.delete('_acme-challenge.'+domain+'.', 'TXT')
                response = dns.query.tcp(update, dns_zone_update_server, timeout=10)

    return certificate_pem
コード例 #55
0
ファイル: ddns.py プロジェクト: epic2005/homework
def dman(zone, name, ttl, type, rr, delete=False):
    if type == 'cname' and len(rr) == 1:
        update = dns.update.Update(name, keyring=keyring)
        update.replace('host', ttl, type, rr)
コード例 #56
0
ファイル: ddns.py プロジェクト: coolspiderghy/learning-python
#                /usr/local/sbin/ddns.py $IPADDR
#        fi
#
# in /etc/ifup-local.
#

import sys

import dns.update
import dns.query
import dns.tsigkeyring

#
# Replace the keyname and secret with appropriate values for your
# configuration.
#
keyring = dns.tsigkeyring.from_text({
    'keyname.': 'NjHwPsMKjdN++dOfE5iAiQ=='
})

#
# Replace "example." with your domain, and "host" with your hostname.
#
update = dns.update.Update('example.', keyring=keyring)
update.replace('host', 300, 'A', sys.argv[1])

#
# Replace "10.0.0.1" with the IP address of your master server.
#
response = dns.query.tcp(update, '10.0.0.1', timeout=10)
コード例 #57
0
def run(api, args, logger):
    global logf

    action = None
    if __name__ == "cobbler.modules.nsupdate_add_system_post":
        action = "replace"
    elif __name__ == "cobbler.modules.nsupdate_delete_system_pre":
        action = "delete"
    else:
        return 0

    settings = api.settings()

    if not str(settings.nsupdate_enabled).lower() in ["1", "yes", "y", "true"]:
        return 0

    # read our settings
    if str(settings.nsupdate_log) is not None:
        logf = open(str(settings.nsupdate_log), "a+")
        nslog(">> starting %s %s\n" % (__name__, args))

    if str(settings.nsupdate_tsig_key) is not None:
        keyring = dns.tsigkeyring.from_text({
            str(settings.nsupdate_tsig_key[0]): str(settings.nsupdate_tsig_key[1])
        })
    else:
        keyring = None

    if str(settings.nsupdate_tsig_algorithm) is not None:
        keyring_algo = str(settings.nsupdate_tsig_algorithm)
    else:
        keyring_algo = "HMAC-MD5.SIG-ALG.REG.INT"
#     nslog( " algo %s, key %s : %s \n" % (keyring_algo,str(settings.nsupdate_tsig_key[0]), str(settings.nsupdate_tsig_key[1])) )

    # get information about this system
    system = api.find_system(args[0])

    # process all interfaces and perform dynamic update for those with --dns-name
    for (name, interface) in system.interfaces.iteritems():
        host = interface["dns_name"]
        host_ip = interface["ip_address"]

        if not system.is_management_supported(cidr_ok=False):
            continue
        if not host:
            continue
        if host.find(".") == -1:
            continue

        domain = ".".join(host.split(".")[1:])    # get domain from host name
        host = host.split(".")[0]                   # strip domain

        nslog("processing interface %s : %s\n" % (name, interface))
        nslog("lookup for '%s' domain master nameserver... " % domain)

        # get master nameserver ip address
        answers = dns.resolver.query(domain + '.', dns.rdatatype.SOA)
        soa_mname = answers[0].mname
        soa_mname_ip = None

        for rrset in answers.response.additional:
            if rrset.name == soa_mname:
                soa_mname_ip = str(rrset.items[0].address)

        nslog("%s [%s]\n" % (soa_mname, soa_mname_ip))
        nslog("%s dns record for %s.%s [%s] .. " % (action, host, domain, host_ip))

        # try to update zone with new record
        update = dns.update.Update(domain + '.', keyring=keyring, keyalgorithm=keyring_algo)

        if action == "replace":
            update.replace(host, 3600, dns.rdatatype.A, host_ip)
            update.replace(host, 3600, dns.rdatatype.TXT, '"cobbler (date: %s)"' % (time.strftime("%c")))
        else:
            update.delete(host, dns.rdatatype.A, host_ip)
            update.delete(host, dns.rdatatype.TXT)

        try:
            response = dns.query.tcp(update, soa_mname_ip)
            rcode_txt = dns.rcode.to_text(response.rcode())
        except dns.tsig.PeerBadKey:
            nslog("failed (refused key)\n>> done\n")
            logf.close()

            raise CX("nsupdate failed, server '%s' refusing our key" % soa_mname)

        nslog('response code: %s\n' % rcode_txt)

        # notice user about update failure
        if response.rcode() != dns.rcode.NOERROR:
            nslog('>> done\n')
            logf.close()

            raise CX("nsupdate failed (response: %s, name: %s.%s, ip %s, name server %s)" % (rcode_txt, host, domain, host_ip, soa_mname))

    nslog('>> done\n')
    logf.close()
    return 0