|
|
7e1b55 |
From 4fdab0c94c4e17e42e5f38a0e671bea39bcc9b74 Mon Sep 17 00:00:00 2001
|
|
|
7e1b55 |
From: Anuja More <amore@redhat.com>
|
|
|
7e1b55 |
Date: Mon, 9 Aug 2021 20:57:22 +0530
|
|
|
7e1b55 |
Subject: [PATCH] ipatests: Test unsecure nsupdate.
|
|
|
7e1b55 |
|
|
|
7e1b55 |
The test configures an external bind server on the ipa-server
|
|
|
7e1b55 |
(not the IPA-embedded DNS server) that allows unauthenticated nsupdates.
|
|
|
7e1b55 |
|
|
|
7e1b55 |
When the IPA client is registered using ipa-client-install,
|
|
|
7e1b55 |
DNS records are added for the client in the bind server using nsupdate.
|
|
|
7e1b55 |
The first try is using GSS-TIG but fails as expected, and the client
|
|
|
7e1b55 |
installer then tries with unauthenticated nsupdate.
|
|
|
7e1b55 |
|
|
|
7e1b55 |
Related : https://pagure.io/freeipa/issue/8402
|
|
|
7e1b55 |
|
|
|
7e1b55 |
Signed-off-by: Anuja More <amore@redhat.com>
|
|
|
7e1b55 |
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
|
|
|
7e1b55 |
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
|
|
|
7e1b55 |
---
|
|
|
7e1b55 |
.../test_installation_client.py | 118 ++++++++++++++++++
|
|
|
7e1b55 |
1 file changed, 118 insertions(+)
|
|
|
7e1b55 |
|
|
|
7e1b55 |
diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py
|
|
|
7e1b55 |
index fa59a5255..014b0f6ab 100644
|
|
|
7e1b55 |
--- a/ipatests/test_integration/test_installation_client.py
|
|
|
7e1b55 |
+++ b/ipatests/test_integration/test_installation_client.py
|
|
|
7e1b55 |
@@ -8,10 +8,15 @@ Module provides tests for various options of ipa-client-install.
|
|
|
7e1b55 |
|
|
|
7e1b55 |
from __future__ import absolute_import
|
|
|
7e1b55 |
|
|
|
7e1b55 |
+import pytest
|
|
|
7e1b55 |
+import re
|
|
|
7e1b55 |
import shlex
|
|
|
7e1b55 |
+import textwrap
|
|
|
7e1b55 |
|
|
|
7e1b55 |
+from ipaplatform.paths import paths
|
|
|
7e1b55 |
from ipatests.test_integration.base import IntegrationTest
|
|
|
7e1b55 |
from ipatests.pytest_ipa.integration import tasks
|
|
|
7e1b55 |
+from ipatests.pytest_ipa.integration.firewall import Firewall
|
|
|
7e1b55 |
|
|
|
7e1b55 |
|
|
|
7e1b55 |
class TestInstallClient(IntegrationTest):
|
|
|
7e1b55 |
@@ -70,3 +75,116 @@ class TestInstallClient(IntegrationTest):
|
|
|
7e1b55 |
extra_args=['--ssh-trust-dns'])
|
|
|
7e1b55 |
result = self.clients[0].run_command(['cat', '/etc/ssh/ssh_config'])
|
|
|
7e1b55 |
assert 'HostKeyAlgorithms' not in result.stdout_text
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+class TestClientInstallBind(IntegrationTest):
|
|
|
7e1b55 |
+ """
|
|
|
7e1b55 |
+ The test configures an external bind server on the ipa-server
|
|
|
7e1b55 |
+ (not the IPA-embedded DNS server) that allows unauthenticated nsupdates.
|
|
|
7e1b55 |
+ When the IPA client is registered using ipa-client-install,
|
|
|
7e1b55 |
+ DNS records are added for the client in the bind server using nsupdate.
|
|
|
7e1b55 |
+ The first try is using GSS-TIG but fails as expected, and the client
|
|
|
7e1b55 |
+ installer then tries with unauthenticated nsupdate.
|
|
|
7e1b55 |
+ """
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ num_clients = 1
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ @classmethod
|
|
|
7e1b55 |
+ def install(cls, mh):
|
|
|
7e1b55 |
+ cls.client = cls.clients[0]
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ @pytest.fixture
|
|
|
7e1b55 |
+ def setup_bindserver(self):
|
|
|
7e1b55 |
+ bindserver = self.master
|
|
|
7e1b55 |
+ named_conf_backup = tasks.FileBackup(self.master, paths.NAMED_CONF)
|
|
|
7e1b55 |
+ # create a zone in the BIND server that is identical to the IPA
|
|
|
7e1b55 |
+ add_zone = textwrap.dedent("""
|
|
|
7e1b55 |
+ zone "{domain}" IN {{ type master;
|
|
|
7e1b55 |
+ file "{domain}.db"; allow-query {{ any; }};
|
|
|
7e1b55 |
+ allow-update {{ any; }}; }};
|
|
|
7e1b55 |
+ """).format(domain=bindserver.domain.name)
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ namedcfg = bindserver.get_file_contents(
|
|
|
7e1b55 |
+ paths.NAMED_CONF, encoding='utf-8')
|
|
|
7e1b55 |
+ namedcfg += '\n' + add_zone
|
|
|
7e1b55 |
+ bindserver.put_file_contents(paths.NAMED_CONF, namedcfg)
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ def update_contents(path, pattern, replace):
|
|
|
7e1b55 |
+ contents = bindserver.get_file_contents(path, encoding='utf-8')
|
|
|
7e1b55 |
+ namedcfg_query = re.sub(pattern, replace, contents)
|
|
|
7e1b55 |
+ bindserver.put_file_contents(path, namedcfg_query)
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ update_contents(paths.NAMED_CONF, 'localhost;', 'any;')
|
|
|
7e1b55 |
+ update_contents(paths.NAMED_CONF, "listen-on port 53 { 127.0.0.1; };",
|
|
|
7e1b55 |
+ "#listen-on port 53 { 127.0.0.1; };")
|
|
|
7e1b55 |
+ update_contents(paths.NAMED_CONF, "listen-on-v6 port 53 { ::1; };",
|
|
|
7e1b55 |
+ "#listen-on-v6 port 53 { ::1; };")
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ add_records = textwrap.dedent("""
|
|
|
7e1b55 |
+ @ IN SOA {fqdn}. root.{domain}. (
|
|
|
7e1b55 |
+ 1001 ;Serial
|
|
|
7e1b55 |
+ 3H ;Refresh
|
|
|
7e1b55 |
+ 15M ;Retry
|
|
|
7e1b55 |
+ 1W ;Expire
|
|
|
7e1b55 |
+ 1D ;Minimum 1D
|
|
|
7e1b55 |
+ )
|
|
|
7e1b55 |
+ @ IN NS {fqdn}.
|
|
|
7e1b55 |
+ ns1 IN A {bindserverip}
|
|
|
7e1b55 |
+ _kerberos.{domain}. IN TXT {zoneupper}
|
|
|
7e1b55 |
+ {fqdn}. IN A {bindserverip}
|
|
|
7e1b55 |
+ ipa-ca.{domain}. IN A {bindserverip}
|
|
|
7e1b55 |
+ _kerberos-master._tcp.{domain}. IN SRV 0 100 88 {fqdn}.
|
|
|
7e1b55 |
+ _kerberos-master._udp.{domain}. IN SRV 0 100 88 {fqdn}.
|
|
|
7e1b55 |
+ _kerberos._tcp.{domain}. IN SRV 0 100 88 {fqdn}.
|
|
|
7e1b55 |
+ _kerberos._udp.{domain}. IN SRV 0 100 88 {fqdn}.
|
|
|
7e1b55 |
+ _kpasswd._tcp.{domain}. IN SRV 0 100 464 {fqdn}.
|
|
|
7e1b55 |
+ _kpasswd._udp.{domain}. IN SRV 0 100 464 {fqdn}.
|
|
|
7e1b55 |
+ _ldap._tcp.{domain}. IN SRV 0 100 389 {fqdn}.
|
|
|
7e1b55 |
+ """).format(
|
|
|
7e1b55 |
+ fqdn=bindserver.hostname,
|
|
|
7e1b55 |
+ domain=bindserver.domain.name,
|
|
|
7e1b55 |
+ bindserverip=bindserver.ip,
|
|
|
7e1b55 |
+ zoneupper=bindserver.domain.name.upper()
|
|
|
7e1b55 |
+ )
|
|
|
7e1b55 |
+ bindserverdb = "/var/named/{0}.db".format(bindserver.domain.name)
|
|
|
7e1b55 |
+ bindserver.put_file_contents(bindserverdb, add_records)
|
|
|
7e1b55 |
+ bindserver.run_command(['systemctl', 'start', 'named'])
|
|
|
7e1b55 |
+ Firewall(bindserver).enable_services(["dns"])
|
|
|
7e1b55 |
+ yield
|
|
|
7e1b55 |
+ named_conf_backup.restore()
|
|
|
7e1b55 |
+ bindserver.run_command(['rm', '-rf', bindserverdb])
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ def test_client_nsupdate(self, setup_bindserver):
|
|
|
7e1b55 |
+ """Test secure nsupdate failed, then try unsecure nsupdate..
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ Test to verify when bind is configured with dynamic update policy,
|
|
|
7e1b55 |
+ and during client-install 'nsupdate -g' fails then it should run with
|
|
|
7e1b55 |
+ second call using unauthenticated nsupdate.
|
|
|
7e1b55 |
+
|
|
|
7e1b55 |
+ Related : https://pagure.io/freeipa/issue/8402
|
|
|
7e1b55 |
+ """
|
|
|
7e1b55 |
+ # with pre-configured bind server, install ipa-server without dns.
|
|
|
7e1b55 |
+ tasks.install_master(self.master, setup_dns=False)
|
|
|
7e1b55 |
+ self.client.resolver.backup()
|
|
|
7e1b55 |
+ self.client.resolver.setup_resolver(
|
|
|
7e1b55 |
+ self.master.ip, self.master.domain.name)
|
|
|
7e1b55 |
+ try:
|
|
|
7e1b55 |
+ self.client.run_command(['ipa-client-install', '-U',
|
|
|
7e1b55 |
+ '--domain', self.client.domain.name,
|
|
|
7e1b55 |
+ '--realm', self.client.domain.realm,
|
|
|
7e1b55 |
+ '-p', self.client.config.admin_name,
|
|
|
7e1b55 |
+ '-w', self.client.config.admin_password,
|
|
|
7e1b55 |
+ '--server', self.master.hostname])
|
|
|
7e1b55 |
+ # call unauthenticated nsupdate if GSS-TSIG nsupdate failed.
|
|
|
7e1b55 |
+ str1 = "nsupdate (GSS-TSIG) failed"
|
|
|
7e1b55 |
+ str2 = "'/usr/bin/nsupdate', '/etc/ipa/.dns_update.txt'"
|
|
|
7e1b55 |
+ client_log = self.client.get_file_contents(
|
|
|
7e1b55 |
+ paths.IPACLIENT_INSTALL_LOG, encoding='utf-8'
|
|
|
7e1b55 |
+ )
|
|
|
7e1b55 |
+ assert str1 in client_log and str2 in client_log
|
|
|
7e1b55 |
+ dig_after = self.client.run_command(
|
|
|
7e1b55 |
+ ['dig', '@{0}'.format(self.master.ip), self.client.hostname,
|
|
|
7e1b55 |
+ '-t', 'SSHFP'])
|
|
|
7e1b55 |
+ assert "ANSWER: 0" not in dig_after.stdout_text.strip()
|
|
|
7e1b55 |
+ finally:
|
|
|
7e1b55 |
+ self.client.resolver.restore()
|
|
|
7e1b55 |
--
|
|
|
7e1b55 |
2.31.1
|
|
|
7e1b55 |
|