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

Reply via email to