URL: https://github.com/freeipa/freeipa/pull/5189 Author: tiran Title: #5189: [Backport][ipa-4-8] Lookup ipa-ca record with NSS Action: opened
PR body: """ Manual backport of PR #5174 DNS data management now uses NSS's getaddrinfo() instead of direct DNS queries to resolve the ipa-ca record. This fixes missing ipa-ca records when the current hostname is not resolvable in DNS but has correct records in /etc/hosts. Reduce timeout to 15 seconds and tighten timeout loop. The changeset can speed up installation by almost 60 seconds. ipa-server-install without built-in DNS calls into DNS data management twice with a timeout of 30 seconds for each call. Fixes: https://pagure.io/freeipa/issue/8529 Related: https://pagure.io/freeipa/issue/8521 Related: https://pagure.io/freeipa/issue/8501 Signed-off-by: Christian Heimes <chei...@redhat.com> """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/5189/head:pr5189 git checkout pr5189
From 421cd426b84cadc560b4ce40616eedc8381a122f Mon Sep 17 00:00:00 2001 From: Christian Heimes <chei...@redhat.com> Date: Tue, 6 Oct 2020 13:12:41 +0200 Subject: [PATCH] Lookup ipa-ca record with NSS DNS data management now uses NSS's getaddrinfo() instead of direct DNS queries to resolve the ipa-ca record. This fixes missing ipa-ca records when the current hostname is not resolvable in DNS but has correct records in /etc/hosts. Reduce timeout to 15 seconds and tighten timeout loop. The changeset can speed up installation by almost 60 seconds. ipa-server-install without built-in DNS calls into DNS data management twice with a timeout of 30 seconds for each call. Fixes: https://pagure.io/freeipa/issue/8529 Related: https://pagure.io/freeipa/issue/8521 Related: https://pagure.io/freeipa/issue/8501 Signed-off-by: Christian Heimes <chei...@redhat.com> --- ipaserver/dns_data_management.py | 20 +++++++++------- ipaserver/install/installutils.py | 38 +++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/ipaserver/dns_data_management.py b/ipaserver/dns_data_management.py index 9ef2e6c384..aad00062a4 100644 --- a/ipaserver/dns_data_management.py +++ b/ipaserver/dns_data_management.py @@ -15,13 +15,13 @@ rdatatype, zone, ) -from dns.exception import DNSException from time import sleep, time from ipalib import errors from ipalib.dns import record_name_format -from ipapython.dnsutil import DNSName, resolve_rrsets +from ipapython.dnsutil import DNSName +from ipaserver.install import installutils if six.PY3: unicode=str @@ -55,7 +55,7 @@ (DNSName("_ntp._udp"), 123), ) -CA_RECORDS_DNS_TIMEOUT = 30 # timeout in seconds +CA_RECORDS_DNS_TIMEOUT = 15 # timeout in seconds class IPADomainIsNotManagedByIPAError(Exception): @@ -139,16 +139,20 @@ def __add_srv_records( def __add_ca_records_from_hostname(self, zone_obj, hostname): assert isinstance(hostname, DNSName) and hostname.is_absolute() r_name = DNSName('ipa-ca') + self.domain_abs - rrsets = [] + rrsets = None end_time = time() + CA_RECORDS_DNS_TIMEOUT - while time() < end_time: + while True: try: - rrsets = resolve_rrsets(hostname, (rdatatype.A, rdatatype.AAAA)) - except DNSException: # logging is done inside resolve_rrsets + # function logs errors + rrsets = installutils.resolve_rrsets_nss(hostname) + except OSError: + # also retry on EAI_AGAIN, EAI_FAIL pass if rrsets: break - sleep(5) + if time() >= end_time: + break + sleep(3) if not rrsets: logger.error('unable to resolve host name %s to IP address, ' diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index fbb0f8be0d..2036eacdc1 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -39,7 +39,7 @@ from configparser import ConfigParser as SafeConfigParser from configparser import NoOptionError -from dns import rdatatype +from dns import rrset, rdatatype, rdataclass from dns.exception import DNSException import ldap import six @@ -55,7 +55,7 @@ from ipalib import api, errors, x509 from ipalib.install import dnsforwarders from ipapython.dn import DN -from ipapython.dnsutil import resolve +from ipapython.dnsutil import DNSName, resolve from ipaserver.install import certs, service, sysupgrade from ipaplatform import services from ipaplatform.paths import paths @@ -492,6 +492,40 @@ def get_host_name(no_host_dns): verify_fqdn(hostname, no_host_dns) return hostname +def resolve_rrsets_nss(fqdn): + """Get list of dnspython RRsets from NSS""" + if not isinstance(fqdn, DNSName): + fqdn = DNSName.from_text(fqdn) + + ip_addresses = resolve_ip_addresses_nss(fqdn.to_text()) + + # split IP addresses into IPv4 and IPv6 + ipv4 = [] + ipv6 = [] + for ip_address in ip_addresses: + if ip_address.version == 4: + ipv4.append(str(ip_address)) + elif ip_address.version == 6: + ipv6.append(str(ip_address)) + + # construct an RRset for each address type. TTL is irrelevant + ttl = 3600 + rrs = [] + if ipv4: + rrs.append( + rrset.from_text_list( + fqdn, ttl, rdataclass.IN, rdatatype.A, ipv4 + ) + ) + if ipv6: + rrs.append( + rrset.from_text_list( + fqdn, ttl, rdataclass.IN, rdatatype.AAAA, ipv6 + ) + ) + return rrs + + def get_server_ip_address(host_name, unattended, setup_dns, ip_addresses): hostaddr = resolve_ip_addresses_nss(host_name) if hostaddr.intersection(
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org