URL: https://github.com/freeipa/freeipa/pull/5780 Author: stanislavlevin Title: #5780: ipatests: dnssec: Add alternative approach for checking chain of trust Action: opened
PR body: """ drill is currently broken on F34. Fortunately, there are another tools for checking DNSSEC trust. One of them is `delv`: delv is a tool for sending DNS queries and validating the results, using the same internal resolver and validator logic as named. delv sends to a specified name server all queries needed to fetch and validate the requested data; this includes the original requested query, subsequent queries to follow CNAME or DNAME chains, queries for DNSKEY, and DS records to establish a chain of trust for DNSSEC validation. It does not perform iterative resolution, but simulates the behavior of a name server configured for DNSSEC validating and forwarding. - mark as XFAIL `test_chain_of_trust_drill` on F34 - conditionally skip `test_chain_of_trust_delv` (requires delv > 9.15.4 for `+yaml`) Related: https://pagure.io/freeipa/issue/8793 """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/5780/head:pr5780 git checkout pr5780
From 579269c90e60268ee08dabaf7d0f2e78fa87dc05 Mon Sep 17 00:00:00 2001 From: Stanislav Levin <s...@altlinux.org> Date: Wed, 19 May 2021 00:51:36 +0300 Subject: [PATCH 1/2] ipatests: dnssec: Add alternative approach for checking chain of trust drill is currently broken on F34. Fortunately, there are another tools for checking DNSSEC trust. One of them is `delv`: > delv is a tool for sending DNS queries and validating the results, using the same internal resolver and validator logic as named. delv sends to a specified name server all queries needed to fetch and validate the requested data; this includes the original requested query, subsequent queries to follow CNAME or DNAME chains, queries for DNSKEY, and DS records to establish a chain of trust for DNSSEC validation. It does not perform iterative resolution, but simulates the behavior of a name server configured for DNSSEC validating and forwarding. Related: https://pagure.io/freeipa/issue/8793 Signed-off-by: Stanislav Levin <s...@altlinux.org> --- ipatests/test_integration/test_dnssec.py | 115 ++++++++++++++++++++++- 1 file changed, 110 insertions(+), 5 deletions(-) diff --git a/ipatests/test_integration/test_dnssec.py b/ipatests/test_integration/test_dnssec.py index bae16120a7a..4e02a9b27d4 100644 --- a/ipatests/test_integration/test_dnssec.py +++ b/ipatests/test_integration/test_dnssec.py @@ -4,17 +4,23 @@ from __future__ import absolute_import +import base64 import logging import re import subprocess import time +import textwrap import dns.dnssec import dns.name +import pytest +import yaml from ipatests.test_integration.base import IntegrationTest from ipatests.pytest_ipa.integration import tasks from ipatests.pytest_ipa.integration.firewall import Firewall +from ipaplatform.tasks import tasks as platform_tasks +from ipaplatform.osinfo import osinfo from ipaplatform.paths import paths from ipapython.dnsutil import DNSResolver @@ -350,11 +356,7 @@ def test_sign_root_zone(self): self.replicas[0].ip, root_zone, timeout=300 ), "Zone %s is not signed (replica)" % root_zone - def test_chain_of_trust(self): - """ - Validate signed DNS records, using our own signed root zone - :return: - """ + def test_delegation(self): dnszone_add_dnssec(self.master, example_test_zone) # delegation @@ -419,6 +421,15 @@ def test_chain_of_trust(self): rtype="DS" ), "No DS record of '%s' returned from replica" % example_test_zone + @pytest.mark.xfail( + osinfo.id == "fedora" and osinfo.version_number == (34,), + reason="https://pagure.io/freeipa/issue/8793", + strict=True, + ) + def test_chain_of_trust_drill(self): + """ + Validate signed DNS records, using our own signed root zone + """ # extract DSKEY from root zone ans = resolve_with_dnssec(self.master.ip, root_zone, rtype="DNSKEY") @@ -462,6 +473,100 @@ def test_chain_of_trust(self): self.master.run_command(args) self.replicas[0].run_command(args) + def test_chain_of_trust_delv(self): + """ + Validate signed DNS records, using our own signed root zone + """ + INITIAL_KEY_FMT = '%s initial-key %d %d %d "%s";' + + # delv reports its version on stderr + delv_version = self.master.run_command( + ["delv", "-v"] + ).stderr_text.rstrip().replace("delv ", "") + assert delv_version + + delv_version_parsed = platform_tasks.parse_ipa_version(delv_version) + if delv_version_parsed < platform_tasks.parse_ipa_version("9.16"): + pytest.skip( + f"Requires delv >= 9.16(+yaml), installed: '{delv_version}'" + ) + + # extract DSKEY from root zone + ans = resolve_with_dnssec( + self.master.ip, root_zone, rtype="DNSKEY" + ) + dnskey_rrset = ans.response.get_rrset( + ans.response.answer, + dns.name.from_text(root_zone), + dns.rdataclass.IN, + dns.rdatatype.DNSKEY, + ) + assert dnskey_rrset, "No DNSKEY records received" + + # export trust keys for root zone + initial_keys = [] + for key_rdata in dnskey_rrset: + if key_rdata.flags != 257: + continue # it is not KSK + + initial_keys.append( + INITIAL_KEY_FMT % ( + root_zone, + key_rdata.flags, + key_rdata.protocol, + key_rdata.algorithm, + base64.b64encode(key_rdata.key).decode("utf-8"), + ) + ) + + assert initial_keys, "No KSK returned from the root zone" + + trust_anchors = textwrap.dedent( + """\ + trust-anchors {{ + {initial_key} + }}; + """ + ).format(initial_key="\n".join(initial_keys)) + logger.debug("Root zone trust-anchors: %s", trust_anchors) + + # set trusted anchor for our root zone + for host in [self.master, self.replicas[0]]: + host.put_file_contents(paths.DNSSEC_TRUSTED_KEY, trust_anchors) + + # verify signatures + args = [ + "delv", + "+yaml", + "+nosplit", + "+vtrace", + "@localhost", + example_test_zone, + "-a", + paths.DNSSEC_TRUSTED_KEY, + "SOA", + ] + + # delv puts trace info on stderr + for host in [self.master, self.replicas[0]]: + result = host.run_command(args) + yaml_data = yaml.safe_load(result.stdout_text) + + query_name_abs = dns.name.from_text(example_test_zone) + root_zone_name = dns.name.from_text(root_zone) + query_name_rel = query_name_abs.relativize( + root_zone_name + ).to_text() + assert yaml_data["query_name"] == query_name_rel + assert yaml_data["status"] == "success" + + assert len(yaml_data["records"]) == 1 + fully_validated = yaml_data["records"][0]["fully_validated"] + fully_validated.sort() + assert len(fully_validated) == 2 + assert f"{example_test_zone} 1 IN RRSIG SOA" in fully_validated[0] + assert f"{example_test_zone} 1 IN SOA" in fully_validated[1] + def test_servers_use_localhost_as_dns(self): # check that localhost is set as DNS server for host in [self.master, self.replicas[0]]: From 0014aa1e73c4d93e9aa833b9b686adbd2dd1dffc Mon Sep 17 00:00:00 2001 From: Stanislav Levin <s...@altlinux.org> Date: Wed, 19 May 2021 19:10:34 +0300 Subject: [PATCH 2/2] temp commit: Trigger DNSSEC tests on F33, F34 F32 is covered on Azure. Signed-off-by: Stanislav Levin <s...@altlinux.org> --- .freeipa-pr-ci.yaml | 2 +- ipatests/prci_definitions/temp_commit.yaml | 44 +++++++++++++++++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/.freeipa-pr-ci.yaml b/.freeipa-pr-ci.yaml index abcf8c5b634..80656690080 120000 --- a/.freeipa-pr-ci.yaml +++ b/.freeipa-pr-ci.yaml @@ -1 +1 @@ -ipatests/prci_definitions/gating.yaml \ No newline at end of file +ipatests/prci_definitions/temp_commit.yaml \ No newline at end of file diff --git a/ipatests/prci_definitions/temp_commit.yaml b/ipatests/prci_definitions/temp_commit.yaml index 26e4b0e58b9..606386b3e00 100644 --- a/ipatests/prci_definitions/temp_commit.yaml +++ b/ipatests/prci_definitions/temp_commit.yaml @@ -47,7 +47,7 @@ topologies: memory: 14500 jobs: - fedora-latest/build: + fedora-f33/build: requires: [] priority: 100 job: @@ -55,20 +55,46 @@ jobs: args: git_repo: '{git_repo}' git_refspec: '{git_refspec}' - template: &ci-master-latest + template: &ci-master-f33 name: freeipa/ci-master-f33 version: 0.0.8 timeout: 1800 topology: *build - fedora-latest/temp_commit: - requires: [fedora-latest/build] - priority: 50 + fedora-f33/test_dnssec_TestInstallDNSSECFirst: + requires: [fedora-f33/build] + priority: 100 + job: + class: RunPytest + args: + build_url: '{fedora-f33/build_url}' + test_suite: test_integration/test_dnssec.py::TestInstallDNSSECFirst + template: *ci-master-f33 + timeout: 3600 + topology: *master_1repl + + fedora-f34/build: + requires: [] + priority: 100 + job: + class: Build + args: + git_repo: '{git_repo}' + git_refspec: '{git_refspec}' + template: &ci-master-f34 + name: freeipa/ci-master-f34 + version: 0.0.3 + timeout: 1800 + topology: *build + + fedora-f34/test_dnssec_TestInstallDNSSECFirst: + requires: [fedora-f34/build] + priority: 100 job: class: RunPytest args: - build_url: '{fedora-latest/build_url}' - test_suite: test_integration/test_REPLACEME.py - template: *ci-master-latest + build_url: '{fedora-f33/build_url}' + test_suite: test_integration/test_dnssec.py::TestInstallDNSSECFirst + template: *ci-master-f34 timeout: 3600 - topology: *master_1repl_1client + topology: *master_1repl
_______________________________________________ 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 Do not reply to spam on the list, report it: https://pagure.io/fedora-infrastructure