]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Check if the RRSIG jitter falls into mean+-2.5*stddev range
authorOndřej Surý <ondrej@sury.org>
Thu, 7 Nov 2019 13:54:24 +0000 (14:54 +0100)
committerOndřej Surý <ondrej@sury.org>
Fri, 8 Nov 2019 05:59:40 +0000 (06:59 +0100)
bin/tests/system/autosign/ns3/keygen.sh
bin/tests/system/autosign/tests.sh

index fd7a7224903c9cef4991c443801517cc82b315be..a60e852d30704864b3c4bf0b9fbfba7e89949dbf 100644 (file)
@@ -58,7 +58,7 @@ $DSFROMKEY $ksk.key > dsset-${zone}$TP
 setup jitter.nsec3.example
 cp $infile $zonefile
 count=1
-while [ $count -le 100 ]
+while [ $count -le 1000 ]
 do
     echo "label${count} IN TXT label${count}" >> $zonefile
     count=`expr $count + 1`
@@ -166,7 +166,7 @@ $DSFROMKEY $ksk.key > dsset-${zone}$TP
 setup oldsigs.example
 cp $infile $zonefile
 count=1
-while [ $count -le 100 ]
+while [ $count -le 1000 ]
 do
     echo "label${count} IN TXT label${count}" >> $zonefile
     count=`expr $count + 1`
index f64e8ba4c8ea33da498cfa9d2f64cfa0fa158655..21be51e37ed5309daffa99d0487dd24daf134bda 100755 (executable)
@@ -50,6 +50,11 @@ checkprivate () {
     return 1
 }
 
+freq() {
+       _file=$1
+       # remove first and last line that has incomplete set and skews the distribution
+       awk '$4 == "RRSIG" {print substr($9,1,8)}' < "$_file" | sort | uniq -c | sed '1d;$d'
+}
 # Check the signatures expiration times.  First check how many signatures
 # there are in total ($rrsigs).  Then see what the distribution of signature
 # expiration times is ($expiretimes).  Ignore the time part for a better
@@ -58,27 +63,49 @@ checkjitter () {
        _file=$1
        _ret=0
 
-       cat $_file | awk '$4 == "RRSIG" {print substr($9,1,8)}' | sort | uniq -c | cat_i
-       _rrsigs=$(cat $_file | awk '$4 == "RRSIG" {print $4}' | cat_i | wc -l)
-       _expiretimes=$(cat $_file | awk '$4 == "RRSIG" {print substr($9,1,8)}' | sort | uniq -c | awk '{print $1}')
+       if ! command -v bc >/dev/null 2>&1; then
+               echo_i "skip: bc not available"
+               return 0
+       fi
+
+       freq "$_file" | cat_i
+       _expiretimes=$(freq "$_file" | awk '{print $1}')
+
        _count=0
+       # Check if we have at least 8 days
+       for _num in $_expiretimes
+       do
+               _count=$((_count+1))
+       done
+       if [ "$_count" -lt 8 ]; then
+               echo_i "error: not enough categories"
+       fi
+
+       # Calculate mean
        _total=0
        for _num in $_expiretimes
        do
-               _total=$(($_total + $_num))
+               _total=$((_total+_num))
        done
-       # Make sure the total number of numbers matches the number of RRSIGs.
-       test $_total -eq $_rrsigs || _ret=1
-       # Calculate mean: The number of signatures divided over 8 days.
-       _mean=$(($_total / 8))
-       # We expect the number of signatures not to exceed twice the mean.
-       _limit=$(($_mean * 2))
-       # Add an additional margin.
-       _limit=$(($_limit + 10))
+       _mean=$(($_total / $_count))
+
+       # Calculate stddev
+       _stddev=0
+       for _num in $_expiretimes
+       do
+               _stddev=$(echo "$_stddev + (($_num - $_mean) * ($_num - $_mean))" | bc)
+       done
+       _stddev=$(echo "sqrt($_stddev/$_count)" | bc)
+
+       # We expect the number of signatures not to exceed the mean +- 2.5 * stddev.
+       _limit=$(((_stddev*25)/10))
+       _low=$((_mean-_limit))
+       _high=$((_mean+_limit))
        # Find outliers.
+       echo_i "checking whether all frequencies falls into <$_low;$_high> interval"
        for _num in $_expiretimes
        do
-               if [ $_num -gt $_limit ]; then
+               if [ $_num -gt $_high ] || [ $_num -lt $_low ]; then
                        echo_i "error: too many RRSIG records ($_num) with the same expiration time"
                        _ret=1
                fi