Example #1
0
    def test_all_servers_in_location(self):
        """Put master (as second server) to location and test if records
        changed properly
        """

        # master --> location paris
        self.master.run_command([
            'ipa', 'server-mod', self.master.hostname, '--location',
            self.LOC_PARIS])
        tasks.restart_named(self.master)

        servers_prague_loc = (
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (
            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
                self.master.domain.name).make_absolute())

        servers_paris_loc = (
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_paris_loc = (
            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
                self.master.domain.name).make_absolute())

        self._test_against_server(
            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)

        for ip in (self.replicas[1].ip, self.master.ip):
            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
Example #2
0
    def test_sign_root_zone(self):
        args = [
            "ipa", "dnszone-add", root_zone, "--dnssec", "true",
            "--skip-overlap-check",
        ]
        self.master.run_command(args)

        # make BIND happy: add the glue record and delegate zone
        args = [
            "ipa", "dnsrecord-add", root_zone, self.master.hostname,
            "--a-rec=" + self.master.ip
        ]
        self.master.run_command(args)
        args = [
            "ipa", "dnsrecord-add", root_zone, self.replicas[0].hostname,
            "--a-rec=" + self.replicas[0].ip
        ]
        self.master.run_command(args)
        time.sleep(10)  # sleep a bit until data are provided by bind-dyndb-ldap

        args = [
            "ipa", "dnsrecord-add", root_zone, self.master.domain.name,
            "--ns-rec=" + self.master.hostname
        ]
        self.master.run_command(args)
        tasks.restart_named(self.master, self.replicas[0])
        # test master
        assert wait_until_record_is_signed(
            self.master.ip, root_zone, self.log, timeout=100
        ), "Zone %s is not signed (master)" % root_zone

        # test replica
        assert wait_until_record_is_signed(
            self.replicas[0].ip, root_zone, self.log, timeout=300
        ), "Zone %s is not signed (replica)" % root_zone
Example #3
0
    def test_change_weight(self):
        """Change weight of master and test if records changed properly
        """

        new_weight = 2000

        self.master.run_command([
            'ipa', 'server-mod', self.master.hostname, '--service-weight',
            str(new_weight)
        ])

        # all servers must be restarted
        tasks.restart_named(self.master, self.replicas[0], self.replicas[1])

        servers_prague_loc = (
            (self.PRIO_LOW, new_weight, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (DNSName('{}._locations'.format(self.LOC_PRAGUE)) +
                             DNSName(self.master.domain.name).make_absolute())

        servers_paris_loc = (
            (self.PRIO_HIGH, new_weight, DNSName(self.master.hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_paris_loc = (DNSName('{}._locations'.format(self.LOC_PARIS)) +
                            DNSName(self.master.domain.name).make_absolute())

        self._test_against_server(self.replicas[0].ip, domain_prague_loc,
                                  servers_prague_loc)

        for ip in (self.replicas[1].ip, self.master.ip):
            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
Example #4
0
    def test_one_replica_in_location(self):
        """Put one replica to location and test if records changed properly
        """

        # create location prague, replica0 --> location prague
        self.master.run_command(['ipa', 'location-add', self.LOC_PRAGUE])
        self.master.run_command([
            'ipa', 'server-mod', self.replicas[0].hostname, '--location',
            self.LOC_PRAGUE
        ])
        tasks.restart_named(self.replicas[0])

        servers_without_loc = (
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_without_loc = DNSName(self.master.domain.name).make_absolute()

        servers_prague_loc = (
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (DNSName('{}._locations'.format(self.LOC_PRAGUE)) +
                             DNSName(self.master.domain.name).make_absolute())

        self._test_against_server(self.replicas[0].ip, domain_prague_loc,
                                  servers_prague_loc)

        for ip in (self.master.ip, self.replicas[1].ip):
            self._test_against_server(ip, domain_without_loc,
                                      servers_without_loc)
Example #5
0
    def test_all_servers_in_location(self):
        """Put master (as second server) to location and test if records
        changed properly
        """

        # master --> location paris
        self.master.run_command([
            'ipa', 'server-mod', self.master.hostname, '--location',
            self.LOC_PARIS])
        tasks.restart_named(self.master)

        servers_prague_loc = (
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (
            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
                self.master.domain.name).make_absolute())

        servers_paris_loc = (
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_paris_loc = (
            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
                self.master.domain.name).make_absolute())

        self._test_against_server(
            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)

        for ip in (self.replicas[1].ip, self.master.ip):
            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
Example #6
0
    def test_disable_reenable_signing_replica(self):

        dnskey_old = resolve_with_dnssec(self.replicas[0].ip, test_zone_repl,
                                         self.log, rtype="DNSKEY").rrset

        # disable DNSSEC signing of zone on replica
        args = [
            "ipa",
            "dnszone-mod", test_zone_repl,
            "--dnssec", "false",
        ]
        self.master.run_command(args)

        time.sleep(20)  # sleep a bit until LDAP changes are applied to DNS

        # test master
        assert not is_record_signed(
            self.master.ip, test_zone_repl, self.log
        ), "Zone %s is still signed (master)" % test_zone_repl

        # test replica
        assert not is_record_signed(
            self.replicas[0].ip, test_zone_repl, self.log
        ), "DNS zone %s is still signed (replica)" % test_zone_repl

        # reenable DNSSEC signing
        args = [
            "ipa",
            "dnszone-mod", test_zone_repl,
            "--dnssec", "true",
        ]
        self.master.run_command(args)

        tasks.restart_named(self.master, self.replicas[0])

        # test master
        assert wait_until_record_is_signed(
            self.master.ip, test_zone_repl, self.log, timeout=100
        ), "Zone %s is not signed (master)" % test_zone_repl

        # test replica
        assert wait_until_record_is_signed(
            self.replicas[0].ip, test_zone_repl, self.log, timeout=200
        ), "DNS zone %s is not signed (replica)" % test_zone_repl

        dnskey_new = resolve_with_dnssec(self.replicas[0].ip, test_zone_repl,
                                         self.log, rtype="DNSKEY").rrset
        assert dnskey_old != dnskey_new, "DNSKEY should be different"
Example #7
0
    def test_two_replicas_in_location(self):
        """Put second replica to location and test if records changed properly
        """

        # create location paris, replica1 --> location prague
        self.master.run_command(['ipa', 'location-add', self.LOC_PARIS])
        self.master.run_command([
            'ipa', 'server-mod', self.replicas[1].hostname, '--location',
            self.LOC_PARIS])
        tasks.restart_named(self.replicas[1])

        servers_without_loc = (
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_without_loc = DNSName(self.master.domain.name).make_absolute()

        servers_prague_loc = (
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (
            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
                self.master.domain.name).make_absolute())

        servers_paris_loc = (
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.master.hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_paris_loc = (
            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
                self.master.domain.name).make_absolute())

        self._test_against_server(
            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)

        self._test_against_server(
            self.replicas[1].ip, domain_paris_loc, servers_paris_loc)

        self._test_against_server(
            self.master.ip, domain_without_loc, servers_without_loc)
Example #8
0
    def test_if_zone_is_signed_master(self):
        # add zone with enabled DNSSEC signing on master
        args = [
            "ipa",
            "dnszone-add", test_zone,
            "--skip-overlap-check",
            "--dnssec", "true",
        ]
        self.master.run_command(args)

        tasks.restart_named(self.master, self.replicas[0])
        # test master
        assert wait_until_record_is_signed(
            self.master.ip, test_zone, self.log, timeout=100
        ), "Zone %s is not signed (master)" % test_zone

        # test replica
        assert wait_until_record_is_signed(
            self.replicas[0].ip, test_zone, self.log, timeout=200
        ), "DNS zone %s is not signed (replica)" % test_zone
Example #9
0
    def test_if_zone_is_signed_replica(self):
        # add zone with enabled DNSSEC signing on replica
        args = [
            "ipa",
            "dnszone-add", test_zone_repl,
            "--skip-overlap-check",
            "--dnssec", "true",
        ]
        self.replicas[0].run_command(args)

        tasks.restart_named(self.replicas[0])
        # test replica
        assert wait_until_record_is_signed(
            self.replicas[0].ip, test_zone_repl, self.log, timeout=300
        ), "Zone %s is not signed (replica)" % test_zone_repl

        # we do not need to wait, on master zones should be singed faster
        # than on replicas

        assert wait_until_record_is_signed(
            self.master.ip, test_zone_repl, self.log, timeout=5
        ), "DNS zone %s is not signed (master)" % test_zone
Example #10
0
    def test_change_weight(self):
        """Change weight of master and test if records changed properly
        """

        new_weight = 2000

        self.master.run_command([
            'ipa', 'server-mod', self.master.hostname, '--service-weight',
            str(new_weight)
        ])

        # all servers must be restarted
        tasks.restart_named(self.master, self.replicas[0], self.replicas[1])

        servers_prague_loc = (
            (self.PRIO_LOW, new_weight, DNSName(self.master.hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_prague_loc = (
            DNSName('{}._locations'.format(self.LOC_PRAGUE)) + DNSName(
                self.master.domain.name).make_absolute())

        servers_paris_loc = (
            (self.PRIO_HIGH, new_weight, DNSName(self.master.hostname)),
            (self.PRIO_LOW, self.WEIGHT, DNSName(self.replicas[0].hostname)),
            (self.PRIO_HIGH, self.WEIGHT, DNSName(self.replicas[1].hostname)),
        )
        domain_paris_loc = (
            DNSName('{}._locations'.format(self.LOC_PARIS)) + DNSName(
                self.master.domain.name).make_absolute())

        self._test_against_server(
            self.replicas[0].ip, domain_prague_loc, servers_prague_loc)

        for ip in (self.replicas[1].ip, self.master.ip):
            self._test_against_server(ip, domain_paris_loc, servers_paris_loc)
Example #11
0
    def test_migrate_dnssec_master(self):
        """Both master and replica have DNS installed"""
        backup_filename = "/var/lib/ipa/ipa-kasp.db.backup"
        replica_backup_filename = "/tmp/ipa-kasp.db.backup"

        # add test zone
        args = [
            "ipa", "dnszone-add", example_test_zone, "--dnssec", "true",
            "--skip-overlap-check",
        ]

        self.master.run_command(args)

        tasks.restart_named(self.master, self.replicas[0])
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.master.ip, example_test_zone, self.log, timeout=100
        ), "Zone %s is not signed (master)" % example_test_zone
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example_test_zone, self.log, timeout=200
        ), "Zone %s is not signed (replica)" % example_test_zone

        dnskey_old = resolve_with_dnssec(self.master.ip, example_test_zone,
                                         self.log, rtype="DNSKEY").rrset

        # migrate dnssec master to replica
        args = [
            "ipa-dns-install",
            "--disable-dnssec-master",
            "--forwarder", self.master.config.dns_forwarder,
            "--force",
            "-U",
        ]
        self.master.run_command(args)

        # move content of "ipa-kasp.db.backup" to replica
        kasp_db_backup = self.master.get_file_contents(backup_filename)
        self.replicas[0].put_file_contents(replica_backup_filename,
                                           kasp_db_backup)

        args = [
            "ipa-dns-install",
            "--dnssec-master",
            "--kasp-db", replica_backup_filename,
            "--forwarder", self.master.config.dns_forwarder,
            "-U",
        ]
        self.replicas[0].run_command(args)

        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.master.ip, example_test_zone, self.log, timeout=100
        ), "Zone %s is not signed after migration (master)" % example_test_zone
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example_test_zone, self.log, timeout=200
        ), "Zone %s is not signed after migration (replica)" % example_test_zone

        # test if dnskey are the same
        dnskey_new = resolve_with_dnssec(self.master.ip, example_test_zone,
                                         self.log, rtype="DNSKEY").rrset
        assert dnskey_old == dnskey_new, "DNSKEY should be the same"

        # add test zone
        args = [
            "ipa", "dnszone-add", example2_test_zone, "--dnssec", "true",
            "--skip-overlap-check",
        ]
        self.replicas[0].run_command(args)
        tasks.restart_named(self.master, self.replicas[0])
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example2_test_zone, self.log, timeout=100
        ), ("Zone %s is not signed after migration (replica - dnssec master)"
            % example2_test_zone)
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.master.ip, example2_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed after migration (master)"
            % example2_test_zone)

        # add new replica
        tasks.install_replica(self.master, self.replicas[1], setup_dns=True)

        # test if originial zones are signed on new replica
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[1].ip, example_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed (new replica)"
            % example_test_zone)
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[1].ip, example2_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed (new replica)"
            % example2_test_zone)

        # add new zone to new replica
        args = [
            "ipa", "dnszone-add", example3_test_zone, "--dnssec", "true",
            "--skip-overlap-check",
        ]
        self.replicas[1].run_command(args)
        tasks.restart_named(self.replicas[0], self.replicas[1])
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[1].ip, example3_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed (new replica)"
            % example3_test_zone)
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example3_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed (replica)"
            % example3_test_zone)
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.master.ip, example3_test_zone, self.log, timeout=200
        ), ("Zone %s is not signed (master)"
            % example3_test_zone)
Example #12
0
    def test_chain_of_trust(self):
        """
        Validate signed DNS records, using our own signed root zone
        :return:
        """

        # add test zone
        args = [
            "ipa", "dnszone-add", example_test_zone, "--dnssec", "true",
            "--skip-overlap-check",
        ]

        self.master.run_command(args)

        # delegation
        args = [
            "ipa", "dnsrecord-add", root_zone, example_test_zone,
            "--ns-rec=" + self.master.hostname
        ]
        self.master.run_command(args)
        tasks.restart_named(self.master, self.replicas[0])
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.master.ip, example_test_zone, self.log, timeout=100
        ), "Zone %s is not signed (master)" % example_test_zone
        # wait until zone is signed
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example_test_zone, self.log, timeout=200
        ), "Zone %s is not signed (replica)" % example_test_zone

        # GET DNSKEY records from zone
        ans = resolve_with_dnssec(self.master.ip, example_test_zone, self.log,
                                  rtype="DNSKEY")
        dnskey_rrset = ans.response.get_rrset(
            ans.response.answer,
            dns.name.from_text(example_test_zone),
            dns.rdataclass.IN,
            dns.rdatatype.DNSKEY)
        assert dnskey_rrset, "No DNSKEY records received"

        self.log.debug("DNSKEY records returned: %s", dnskey_rrset.to_text())

        # generate DS records
        ds_records = []
        for key_rdata in dnskey_rrset:
            if key_rdata.flags != 257:
                continue  # it is not KSK
            ds_records.append(dns.dnssec.make_ds(example_test_zone, key_rdata,
                                                 'sha256'))
        assert ds_records, ("No KSK returned from the %s zone" %
                            example_test_zone)

        self.log.debug("DS records for %s created: %r", example_test_zone,
                       ds_records)

        # add DS records to root zone
        args = [
            "ipa", "dnsrecord-add", root_zone, example_test_zone,
            # DS record requires to coexists with NS
            "--ns-rec", self.master.hostname,
        ]
        for ds in ds_records:
            args.append("--ds-rec")
            args.append(ds.to_text())

        self.master.run_command(args)

        # wait until DS records it replicated
        assert wait_until_record_is_signed(
            self.replicas[0].ip, example_test_zone, self.log, timeout=100,
            rtype="DS"
        ), "No DS record of '%s' returned from replica" % example_test_zone

        # extract DSKEY from root zone
        ans = resolve_with_dnssec(self.master.ip, root_zone, self.log,
                                  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"

        self.log.debug("DNSKEY records returned: %s", dnskey_rrset.to_text())

        # export trust keys for root zone
        root_key_rdatas = []
        for key_rdata in dnskey_rrset:
            if key_rdata.flags != 257:
                continue  # it is not KSK
            root_key_rdatas.append(key_rdata)

        assert root_key_rdatas, "No KSK returned from the root zone"

        root_keys_rrset = dns.rrset.from_rdata_list(dnskey_rrset.name,
                                                    dnskey_rrset.ttl,
                                                    root_key_rdatas)
        self.log.debug("Root zone trusted key: %s", root_keys_rrset.to_text())

        # set trusted key for our root zone
        self.master.put_file_contents(paths.DNSSEC_TRUSTED_KEY,
                                      root_keys_rrset.to_text() + '\n')
        self.replicas[0].put_file_contents(paths.DNSSEC_TRUSTED_KEY,
                                           root_keys_rrset.to_text() + '\n')

        # verify signatures
        time.sleep(1)
        args = [
            "drill", "@localhost", "-k",
            paths.DNSSEC_TRUSTED_KEY, "-S",
            example_test_zone, "SOA"
        ]

        # test if signature chains are valid
        self.master.run_command(args)
        self.replicas[0].run_command(args)