From: Matthijs Mekking Date: Fri, 21 Jun 2019 08:30:05 +0000 (+0200) Subject: Also collect DNSSEC refresh signature statistics X-Git-Tag: v9.15.2~34^2~1 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=6f67546cd66e806643d495dd96b04aa983d8a58b;p=thirdparty%2Fbind9.git Also collect DNSSEC refresh signature statistics In addition to gather how many times signatures are created per key in a zone, also count how many of those signature creations are because of DNSSEC maintenance. These maintenance counters are incremented if a signature is refreshed (but the RRset did not changed), when the DNSKEY RRset is changed, and when that leads to additional RRset / RRSIG updates (for example SOA, NSEC). --- diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c index 3e3802fa76e..7d9be5d4897 100644 --- a/bin/named/statschannel.c +++ b/bin/named/statschannel.c @@ -1453,7 +1453,7 @@ dnssecsignstat_dump(dns_keytag_t tag, uint64_t val, void *arg) { xmlTextWriterPtr writer; int xmlrc; #endif -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C json_object *zoneobj, *obj; #endif @@ -1477,7 +1477,7 @@ dnssecsignstat_dump(dns_keytag_t tag, uint64_t val, void *arg) { #endif break; case isc_statsformat_json: -#ifdef HAVE_JSON +#ifdef HAVE_JSON_C zoneobj = (json_object *) dumparg->arg; obj = json_object_new_int64(val); if (obj == NULL) { @@ -1561,6 +1561,7 @@ zone_xmlrender(dns_zone_t *zone, void *arg) { isc_stats_t *gluecachestats; dns_stats_t *rcvquerystats; dns_stats_t *dnssecsignstats; + dns_stats_t *dnssecrefreshstats; uint64_t nsstat_values[ns_statscounter_max]; uint64_t gluecachestats_values[dns_gluecachestatscounter_max]; @@ -1588,8 +1589,8 @@ zone_xmlrender(dns_zone_t *zone, void *arg) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "type", - ISC_XMLCHAR "gluecache")); + ISC_XMLCHAR "type", + ISC_XMLCHAR "gluecache")); result = dump_counters(gluecachestats, isc_statsformat_xml, @@ -1628,8 +1629,8 @@ zone_xmlrender(dns_zone_t *zone, void *arg) { TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters")); TRY0(xmlTextWriterWriteAttribute(writer, - ISC_XMLCHAR "type", - ISC_XMLCHAR "dnssec")); + ISC_XMLCHAR "type", + ISC_XMLCHAR "dnssec-sign")); dumparg.result = ISC_R_SUCCESS; dns_dnssecsignstats_dump(dnssecsignstats, @@ -1639,7 +1640,27 @@ zone_xmlrender(dns_zone_t *zone, void *arg) { goto error; } - /* counters type="dnssec"*/ + /* counters type="dnssec-sign"*/ + TRY0(xmlTextWriterEndElement(writer)); + } + + dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone); + if (dnssecrefreshstats != NULL) { + TRY0(xmlTextWriterStartElement(writer, + ISC_XMLCHAR "counters")); + TRY0(xmlTextWriterWriteAttribute(writer, + ISC_XMLCHAR "type", + ISC_XMLCHAR "dnssec-refresh")); + + dumparg.result = ISC_R_SUCCESS; + dns_dnssecsignstats_dump(dnssecrefreshstats, + dnssecsignstat_dump, + &dumparg, 0); + if(dumparg.result != ISC_R_SUCCESS) { + goto error; + } + + /* counters type="dnssec-refresh"*/ TRY0(xmlTextWriterEndElement(writer)); } } @@ -2363,6 +2384,7 @@ zone_jsonrender(dns_zone_t *zone, void *arg) { isc_stats_t *gluecachestats; dns_stats_t *rcvquerystats; dns_stats_t *dnssecsignstats; + dns_stats_t *dnssecrefreshstats; uint64_t nsstat_values[ns_statscounter_max]; uint64_t gluecachestats_values[dns_gluecachestatscounter_max]; @@ -2458,11 +2480,39 @@ zone_jsonrender(dns_zone_t *zone, void *arg) { goto error; } - if (json_object_get_object(counters)->count != 0) + if (json_object_get_object(counters)->count != 0) { json_object_object_add(zoneobj, - "dnssec", counters); - else + "dnssec-sign", + counters); + } else { json_object_put(counters); + } + } + + dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone); + if (dnssecrefreshstats != NULL) { + stats_dumparg_t dumparg; + json_object *counters = json_object_new_object(); + CHECKMEM(counters); + + dumparg.type = isc_statsformat_json; + dumparg.arg = counters; + dumparg.result = ISC_R_SUCCESS; + dns_dnssecsignstats_dump(dnssecrefreshstats, + dnssecsignstat_dump, + &dumparg, 0); + if (dumparg.result != ISC_R_SUCCESS) { + json_object_put(counters); + goto error; + } + + if (json_object_get_object(counters)->count != 0) { + json_object_object_add(zoneobj, + "dnssec-refresh", + counters); + } else { + json_object_put(counters); + } } } diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 1495b12c94a..8f1da7ca8b4 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -905,6 +905,7 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, isc_stats_t *zoneqrystats; dns_stats_t *rcvquerystats; dns_stats_t *dnssecsignstats; + dns_stats_t *dnssecrefreshstats; dns_zonestat_level_t statlevel = dns_zonestat_none; int seconds; dns_zone_t *mayberaw = (raw != NULL) ? raw : zone; @@ -1190,15 +1191,18 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, zoneqrystats = NULL; rcvquerystats = NULL; dnssecsignstats = NULL; + dnssecrefreshstats = NULL; if (statlevel == dns_zonestat_full) { RETERR(isc_stats_create(mctx, &zoneqrystats, ns_statscounter_max)); RETERR(dns_rdatatypestats_create(mctx, &rcvquerystats)); RETERR(dns_dnssecsignstats_create(mctx, &dnssecsignstats)); + RETERR(dns_dnssecsignstats_create(mctx, &dnssecrefreshstats)); } dns_zone_setrequeststats(zone, zoneqrystats); dns_zone_setrcvquerystats(zone, rcvquerystats); dns_zone_setdnssecsignstats(zone, dnssecsignstats); + dns_zone_setdnssecrefreshstats(zone, dnssecrefreshstats); if (zoneqrystats != NULL) isc_stats_detach(&zoneqrystats); @@ -1210,6 +1214,10 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig, dns_stats_detach(&dnssecsignstats); } + if(dnssecrefreshstats != NULL) { + dns_stats_detach(&dnssecrefreshstats); + } + /* * Configure master functionality. This applies * to primary masters (type "master") and slaves diff --git a/bin/tests/system/statschannel/tests.sh b/bin/tests/system/statschannel/tests.sh index 2980337c554..a0147ec455e 100644 --- a/bin/tests/system/statschannel/tests.sh +++ b/bin/tests/system/statschannel/tests.sh @@ -281,7 +281,8 @@ n=`expr $n + 1` # Test dnssec sign statistics. zone="dnssec" -stat_prefix="dnskey sign operations" +sign_prefix="dnssec-sign operations" +refresh_prefix="dnssec-refresh operations" ksk_id=`cat ns2/$zone.ksk.id` zsk_id=`cat ns2/$zone.zsk.id` @@ -297,8 +298,10 @@ ret=0 # the SOA RRset before a competing RRset. This happens here and so the # SOA RRset is updated and resigned twice at startup, that explains the # additional zsk sign operation (11 instead of 10). -echo "${stat_prefix} ${zsk_id}: 11" > zones.expect -echo "${stat_prefix} ${ksk_id}: 1" >> zones.expect +echo "${refresh_prefix} ${zsk_id}: 11" > zones.expect +echo "${refresh_prefix} ${ksk_id}: 1" >> zones.expect +echo "${sign_prefix} ${zsk_id}: 11" >> zones.expect +echo "${sign_prefix} ${ksk_id}: 1" >> zones.expect cat zones.expect | sort > zones.expect.$n rm -f zones.expect # Fetch and check the dnssec sign statistics. @@ -325,8 +328,10 @@ echo update add $zone. 300 in txt "nsupdate added me" echo send ) | $NSUPDATE # This should trigger the resign of SOA, TXT and NSEC (+3 zsk). -echo "${stat_prefix} ${zsk_id}: 14" > zones.expect -echo "${stat_prefix} ${ksk_id}: 1" >> zones.expect +echo "${refresh_prefix} ${zsk_id}: 11" > zones.expect +echo "${refresh_prefix} ${ksk_id}: 1" >> zones.expect +echo "${sign_prefix} ${zsk_id}: 14" >> zones.expect +echo "${sign_prefix} ${ksk_id}: 1" >> zones.expect cat zones.expect | sort > zones.expect.$n rm -f zones.expect # Fetch and check the dnssec sign statistics. @@ -345,13 +350,16 @@ n=`expr $n + 1` # 3. Test sign operations of KSK. ret=0 +echo_i "fetch zone stats data after updating DNSKEY RRset ($n)" # Add a standby DNSKEY, this triggers resigning the DNSKEY RRset. zsk=$("$KEYGEN" -K ns2 -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone") $SETTIME -K ns2 -P now -A never $zsk.key > /dev/null loadkeys_on 2 $zone || ret=1 # This should trigger the resign of SOA (+1 zsk) and DNSKEY (+1 ksk). -echo "${stat_prefix} ${zsk_id}: 15" > zones.expect -echo "${stat_prefix} ${ksk_id}: 2" >> zones.expect +echo "${refresh_prefix} ${zsk_id}: 12" > zones.expect +echo "${refresh_prefix} ${ksk_id}: 2" >> zones.expect +echo "${sign_prefix} ${zsk_id}: 15" >> zones.expect +echo "${sign_prefix} ${ksk_id}: 2" >> zones.expect cat zones.expect | sort > zones.expect.$n rm -f zones.expect # Fetch and check the dnssec sign statistics. diff --git a/bin/tests/system/statschannel/zones-json.pl b/bin/tests/system/statschannel/zones-json.pl index f07e97e400d..deef35b0f15 100644 --- a/bin/tests/system/statschannel/zones-json.pl +++ b/bin/tests/system/statschannel/zones-json.pl @@ -23,8 +23,13 @@ close(INPUT); my $ref = decode_json($text); -my $dnssecsign = $ref->{views}->{_default}->{zones}[0]->{"dnssec"}; -my $type = "dnskey sign operations "; +my $dnssecsign = $ref->{views}->{_default}->{zones}[0]->{"dnssec-sign"}; +my $type = "dnssec-sign operations "; foreach $key (keys %{$dnssecsign}) { print $type . $key . ": ". $dnssecsign->{$key} ."\n"; } +my $dnssecrefresh = $ref->{views}->{_default}->{zones}[0]->{"dnssec-refresh"}; +my $type = "dnssec-refresh operations "; +foreach $key (keys %{$dnssecrefresh}) { + print $type . $key . ": ". $dnssecrefresh->{$key} ."\n"; +} diff --git a/bin/tests/system/statschannel/zones-xml.pl b/bin/tests/system/statschannel/zones-xml.pl index 3ccd5e4b968..f078b054bb8 100644 --- a/bin/tests/system/statschannel/zones-xml.pl +++ b/bin/tests/system/statschannel/zones-xml.pl @@ -25,13 +25,12 @@ foreach $group (@$counters) { my $type = $group->{type}; - if ($type eq "dnssec") { - my $prefix = "dnskey sign operations "; + if ($type eq "dnssec-sign" || $type eq "dnssec-refresh") { if (exists $group->{counter}->{name}) { - print $prefix . $group->{counter}->{name} . ": " . $group->{counter}->{content} . "\n"; + print $type . " operations " . $group->{counter}->{name} . ": " . $group->{counter}->{content} . "\n"; } else { foreach $key (keys %{$group->{counter}}) { - print $prefix . $key . ": ". $group->{counter}->{$key}->{content} ."\n"; + print $type . " operations " . $key . ": ". $group->{counter}->{$key}->{content} ."\n"; } } } diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index cd5cc698dde..33c1131f7fa 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1928,6 +1928,9 @@ dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats); void dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats); + +void +dns_zone_setdnssecrefreshstats(dns_zone_t *zone, dns_stats_t *stats); /*%< * Set additional statistics sets to zone. These are attached to the zone * but are not counted in the zone module; only the caller updates the @@ -1947,6 +1950,9 @@ dns_zone_getrcvquerystats(dns_zone_t *zone); dns_stats_t * dns_zone_getdnssecsignstats(dns_zone_t *zone); + +dns_stats_t * +dns_zone_getdnssecrefreshstats(dns_zone_t *zone); /*%< * Get the additional statistics for zone, if one is installed. * diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 10d4c132e77..b3936260c14 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -1141,6 +1141,7 @@ dns_zone_getchecknames dns_zone_getclass dns_zone_getdb dns_zone_getdbtype +dns_zone_getdnssecrefreshstats dns_zone_getdnssecsignstats dns_zone_getexpiretime dns_zone_getfile @@ -1242,6 +1243,7 @@ dns_zone_setclass dns_zone_setdb dns_zone_setdbtype dns_zone_setdialup +dns_zone_setdnssecrefreshstats dns_zone_setdnssecsignstats dns_zone_setfile dns_zone_setflag diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 15877bcdf48..d97491c61fc 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -327,6 +327,7 @@ struct dns_zone { isc_stats_t *requeststats; dns_stats_t *rcvquerystats; dns_stats_t *dnssecsignstats; + dns_stats_t *dnssecrefreshstats; uint32_t notifydelay; dns_isselffunc_t isself; void *isselfarg; @@ -1024,6 +1025,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->requeststats = NULL; zone->rcvquerystats = NULL; zone->dnssecsignstats = NULL; + zone->dnssecrefreshstats = NULL; zone->notifydelay = 5; zone->isself = NULL; zone->isselfarg = NULL; @@ -1200,6 +1202,9 @@ zone_free(dns_zone_t *zone) { if (zone->dnssecsignstats != NULL){ dns_stats_detach(&zone->dnssecsignstats); } + if (zone->dnssecrefreshstats != NULL){ + dns_stats_detach(&zone->dnssecrefreshstats); + } if (zone->db != NULL) { zone_detachdb(zone); } @@ -6523,7 +6528,8 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, { isc_result_t result; dns_dbnode_t *node = NULL; - dns_stats_t* dnssecsignstats = dns_zone_getdnssecsignstats(zone); + dns_stats_t* dnssecsignstats; + dns_stats_t* dnssecrefreshstats; dns_rdataset_t rdataset; dns_rdata_t sig_rdata = DNS_RDATA_INIT; unsigned char data[1024]; /* XXX */ @@ -6634,9 +6640,17 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, isc_buffer_init(&buffer, data, sizeof(data)); /* Update DNSSEC sign statistics. */ + dnssecsignstats = dns_zone_getdnssecsignstats(zone); + dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone); if (dnssecsignstats != NULL) { - dns_dnssecsignstats_increment(dnssecsignstats, - dst_key_id(keys[i])); + dns_dnssecsignstats_increment( + dns_zone_getdnssecsignstats(zone), + dst_key_id(keys[i])); + } + if (dnssecrefreshstats != NULL) { + dns_dnssecsignstats_increment( + dns_zone_getdnssecrefreshstats(zone), + dst_key_id(keys[i])); } } @@ -7023,7 +7037,8 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, dns_rdatasetiter_t *iterator = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; - dns_stats_t* dnssecsignstats = dns_zone_getdnssecsignstats(zone); + dns_stats_t* dnssecsignstats; + dns_stats_t* dnssecrefreshstats; isc_buffer_t buffer; unsigned char data[1024]; @@ -7128,9 +7143,17 @@ sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name, dns_rdata_reset(&rdata); /* Update DNSSEC sign statistics. */ + dnssecsignstats = dns_zone_getdnssecsignstats(zone); + dnssecrefreshstats = dns_zone_getdnssecrefreshstats(zone); if (dnssecsignstats != NULL) { - dns_dnssecsignstats_increment(dnssecsignstats, - dst_key_id(key)); + dns_dnssecsignstats_increment( + dns_zone_getdnssecsignstats(zone), + dst_key_id(key)); + } + if (dnssecrefreshstats != NULL) { + dns_dnssecsignstats_increment( + dns_zone_getdnssecrefreshstats(zone), + dst_key_id(key)); } (*signatures)--; @@ -17546,7 +17569,6 @@ dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) { void dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { - REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -17556,12 +17578,31 @@ dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) { UNLOCK_ZONE(zone); } +void +dns_zone_setdnssecrefreshstats(dns_zone_t *zone, dns_stats_t *stats) { + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + if (stats != NULL && zone->dnssecrefreshstats == NULL) { + dns_stats_attach(stats, &zone->dnssecrefreshstats); + } + UNLOCK_ZONE(zone); +} + dns_stats_t* dns_zone_getdnssecsignstats(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); + return (zone->dnssecsignstats); } +dns_stats_t* +dns_zone_getdnssecrefreshstats(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + + return (zone->dnssecrefreshstats); +} + isc_stats_t * dns_zone_getrequeststats(dns_zone_t *zone) { /*