[dns-operations] Checking for signatures of a certain DNSKEY within a zone

Tony Finch dot at dotat.at
Tue Jul 6 16:00:46 UTC 2021


Klaus Darilion <klaus.mailinglists at pernau.at> wrote:
>
>   dig ... axfr | grep RRSIG | grep $KEYID
>
> This worked fine for long time but when having keys with the same keyid this
> obviously does not work anymore.

If it is one of your zones then your key management software should ensure
that all the key IDs are different, i.e. if there is an ID collision when
generating a key, throw it away and regenerate it. This is important for
verification performance (and, I would guess, less risk of encountering
bugs).

> So I want to change my code to additionally check if the signature can
> be verified with the respective public key. Are there any tools (bash,
> php ...)  which accepts single RRSIG RR and single DNSKEY RR and does
> the validation?

Each signature covers the entire RRset, so you need all the DNSKEY
records.

Dunno if there's an easier tool, but it's not too bad with Net::DNS.
I tried this out with ac.uk which is signed with both zsk and ksk, and
cam.ac.uk which is signed with just ksk.

        #!/usr/bin/perl

        use 5.10.0;

        use warnings;
        use strict;

        use Net::DNS;
        use Net::DNS::SEC;
        use Net::DNS::SEC::Keyset;

        my (@key, at sig);

        my $resolver = Net::DNS::Resolver->new();
        $resolver->dnssec(1);

        my $reply = $resolver->send(@ARGV, 'DNSKEY')
            or die $resolver->errorstring;

        for my $rr ($reply->answer) {
                push @sig, $rr if $rr->type eq 'RRSIG';
                push @key, $rr if $rr->type eq 'DNSKEY';
        }

        for my $rr (@key, @sig) {
                $rr->print;
        }

        die "no DNSKEY RRset found" unless @key;
        die "no RRSIG(DNSKEY) found" unless @sig;

        my $keyset = Net::DNS::SEC::Keyset->new(\@key, \@sig)
            or die Net::DNS::SEC::Keyset->keyset_err;

        for my $key (@key) {
                my $id = $key->keytag;
                my $ok = $keyset->verify($id);
                my $err = Net::DNS::SEC::Keyset->keyset_err;
                printf "key %d %s verify %s %s\n",
                    $id, $key->sep ? "ksk" : "zsk",
                    $ok ? "ok" : "fail", $err;
        }

Tony.
-- 
f.anthony.n.finch  <dot at dotat.at>  https://dotat.at/
the quest for freedom and justice can never end



More information about the dns-operations mailing list