Commit 6acf3269 authored by Michał Kępień's avatar Michał Kępień Committed by Evan Hunt

Apply raw zone deltas to yet unsigned secure zones

When inline signing is enabled for a zone without creating signing keys
for it, changes subsequently applied to the raw zone will not be
reflected in the secure zone due to the dns_update_signaturesinc() call
inside receive_secure_serial() failing.  Given that an inline zone will
be served (without any signatures) even with no associated signing keys
being present, keep applying raw zone deltas to the secure zone until
keys become available in an attempt to follow the principle of least
astonishment.
parent cfbc8e26
......@@ -10,6 +10,7 @@
rm -f */named.conf
rm -f */named.memstats
rm -f */named.run
rm -f */named.run.prev
rm -f */trusted.conf
rm -f ns1/K*
rm -f ns1/dsset-*
......@@ -23,6 +24,10 @@ rm -f ns2/inactiveksk.db
rm -f ns2/inactiveksk.db.jnl
rm -f ns2/inactivezsk.db
rm -f ns2/inactivezsk.db.jnl
rm -f ns2/nokeys.db
rm -f ns2/nokeys.db.jnl
rm -f ns2/removedkeys-secondary.db
rm -f ns2/removedkeys-secondary.db.jnl
rm -f ns2/retransfer.db
rm -f ns2/retransfer.db.jnl
rm -f ns2/retransfer3.db
......@@ -60,10 +65,22 @@ rm -f ns3/inactivezsk.bk
rm -f ns3/inactivezsk.bk.jnl
rm -f ns3/inactivezsk.bk.signed
rm -f ns3/inactivezsk.bk.signed.jnl
rm -f ns3/nokeys.bk
rm -f ns3/nokeys.bk.jnl
rm -f ns3/nokeys.bk.signed
rm -f ns3/nokeys.bk.signed.jnl
rm -f ns3/nsec3.db
rm -f ns3/nsec3.db.jnl
rm -f ns3/nsec3.db.signed
rm -f ns3/nsec3.db.signed.jnl
rm -f ns3/removedkeys-primary.db
rm -f ns3/removedkeys-primary.db.jnl
rm -f ns3/removedkeys-primary.db.signed
rm -f ns3/removedkeys-primary.db.signed.jnl
rm -f ns3/removedkeys-secondary.bk
rm -f ns3/removedkeys-secondary.bk.jnl
rm -f ns3/removedkeys-secondary.bk.signed
rm -f ns3/removedkeys-secondary.bk.signed.jnl
rm -f ns3/retransfer.bk
rm -f ns3/retransfer.bk.jnl
rm -f ns3/retransfer.bk.signed
......@@ -103,3 +120,4 @@ rm -f ns*/named.lock
rm -f dig.out.*
rm -f ns3/nzf-*
rm -f rndc.out.ns*
rm -rf ns3/removedkeys
......@@ -68,3 +68,15 @@ zone "inactivezsk" {
file "inactivezsk.db";
allow-update { any; };
};
zone "nokeys" {
type master;
file "nokeys.db";
allow-update { any; };
};
zone "removedkeys-secondary" {
type master;
file "removedkeys-secondary.db";
allow-update { any; };
};
......@@ -132,3 +132,28 @@ zone "inactivezsk" {
auto-dnssec maintain;
file "inactivezsk.bk";
};
zone "nokeys" {
type slave;
masters { 10.53.0.2; };
inline-signing yes;
auto-dnssec maintain;
file "nokeys.bk";
};
zone "removedkeys-primary" {
type master;
inline-signing yes;
auto-dnssec maintain;
allow-update { any; };
also-notify { 10.53.0.2; };
file "removedkeys-primary.db";
};
zone "removedkeys-secondary" {
type slave;
masters { 10.53.0.2; };
inline-signing yes;
auto-dnssec maintain;
file "removedkeys-secondary.bk";
};
......@@ -96,6 +96,18 @@ keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone`
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone -f KSK $zone`
$DSFROMKEY -T 1200 $keyname >> ../ns1/root.db
zone=removedkeys-primary
rm -f K${zone}.+*+*.key
rm -f K${zone}.+*+*.private
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
zone=removedkeys-secondary
rm -f K${zone}.+*+*.key
rm -f K${zone}.+*+*.private
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone`
keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
for s in a c d h k l m q z
do
zone=test-$s
......
......@@ -21,6 +21,8 @@ touch ns2/trusted.conf
cp ns2/bits.db.in ns2/bits.db
cp ns2/bits.db.in ns2/inactiveksk.db
cp ns2/bits.db.in ns2/inactivezsk.db
cp ns2/bits.db.in ns2/nokeys.db
cp ns2/bits.db.in ns2/removedkeys-secondary.db
cp ns2/bits.db.in ns2/retransfer.db
cp ns2/bits.db.in ns2/retransfer3.db
rm -f ns2/bits.db.jnl
......@@ -31,6 +33,9 @@ cp ns3/master.db.in ns3/updated.db
cp ns3/master.db.in ns3/expired.db
cp ns3/master.db.in ns3/nsec3.db
cp ns3/master.db.in ns3/externalkey.db
cp ns3/master.db.in ns3/removedkeys-primary.db
mkdir ns3/removedkeys
touch ns4/trusted.conf
cp ns4/noixfr.db.in ns4/noixfr.db
......
......@@ -1087,14 +1087,173 @@ grep "DNSKEY 8 1 [0-9]* [0-9]* [0-9]* ${kskid} " dig.out.ns3.test$n > /dev/null
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
# Wait until an update to the raw part of a given inline signed zone is fully
# processed. As waiting for a fixed amount of time is suboptimal and there is
# no single message that would signify both a successful modification and an
# error in a race-free manner, instead wait until either notifies are sent
# (which means the secure zone was modified) or a receive_secure_serial() error
# is logged (which means the zone was not modified and will not be modified any
# further in response to the relevant raw zone update).
wait_until_raw_zone_update_is_processed() {
zone="$1"
for i in 1 2 3 4 5 6 7 8 9 10
do
if nextpart ns3/named.run | egrep "zone ${zone}.*(sending notifies|receive_secure_serial)" > /dev/null; then
return
fi
sleep 1
done
}
n=`expr $n + 1`
echo_i "checking that changes to raw zone are applied to a previously unsigned secure zone ($n)"
ret=0
# Query for bar.nokeys/A and ensure the response is negative. As this zone
# does not have any signing keys set up, the response must be unsigned.
$DIG $DIGOPTS @10.53.0.3 bar.nokeys. A > dig.out.ns3.pre.test$n 2>&1 || ret=1
grep "status: NOERROR" dig.out.ns3.pre.test$n > /dev/null && ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null && ret=1
# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore
# log messages generated before the raw zone is updated.
nextpart ns3/named.run > /dev/null
# Add a record to the raw zone on the master.
$NSUPDATE << EOF || ret=1
zone nokeys.
server 10.53.0.2 ${PORT}
update add bar.nokeys. 0 A 127.0.0.1
send
EOF
wait_until_raw_zone_update_is_processed "nokeys"
# Query for bar.nokeys/A again and ensure the signer now returns a positive,
# yet still unsigned response.
$DIG $DIGOPTS @10.53.0.3 bar.nokeys. A > dig.out.ns3.post.test$n 2>&1
grep "status: NOERROR" dig.out.ns3.post.test$n > /dev/null || ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that changes to raw zone are not applied to a previously signed secure zone with no keys available (primary) ($n)"
ret=0
# Query for bar.removedkeys-primary/A and ensure the response is negative. As
# this zone has signing keys set up, the response must be signed.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A > dig.out.ns3.pre.test$n 2>&1 || ret=1
grep "status: NOERROR" dig.out.ns3.pre.test$n > /dev/null && ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null || ret=1
# Remove the signing keys for this zone.
mv -f ns3/Kremovedkeys-primary* ns3/removedkeys
# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore
# log messages generated before the raw zone is updated.
nextpart ns3/named.run > /dev/null
# Add a record to the raw zone on the master.
$NSUPDATE << EOF || ret=1
zone removedkeys-primary.
server 10.53.0.3 ${PORT}
update add bar.removedkeys-primary. 0 A 127.0.0.1
send
EOF
wait_until_raw_zone_update_is_processed "removedkeys-primary"
# Query for bar.removedkeys-primary/A again and ensure the signer still returns
# a negative, signed response.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A > dig.out.ns3.post.test$n 2>&1
grep "status: NOERROR" dig.out.ns3.post.test$n > /dev/null && ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that backlogged changes to raw zone are applied after keys become available (primary) ($n)"
ret=0
# Restore the signing keys for this zone.
mv ns3/removedkeys/Kremovedkeys-primary* ns3
$RNDCCMD 10.53.0.3 loadkeys removedkeys-primary > /dev/null 2>&1
# Determine what a SOA record with a bumped serial number should look like.
BUMPED_SOA=`sed -n 's/.*\(add removedkeys-primary.*IN.*SOA\)/\1/p;' ns3/named.run | tail -1 | awk '{$8 += 1; print $0}'`
# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore
# log messages generated before the raw zone is updated.
nextpart ns3/named.run > /dev/null
# Bump the SOA serial number of the raw zone.
$NSUPDATE << EOF || ret=1
zone removedkeys-primary.
server 10.53.0.3 ${PORT}
update del removedkeys-primary. SOA
update ${BUMPED_SOA}
send
EOF
wait_until_raw_zone_update_is_processed "removedkeys-primary"
# Query for bar.removedkeys-primary/A again and ensure the signer now returns a
# positive, signed response.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A > dig.out.ns3.test$n 2>&1
grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
grep "RRSIG" dig.out.ns3.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that changes to raw zone are not applied to a previously signed secure zone with no keys available (secondary) ($n)"
ret=0
# Query for bar.removedkeys-secondary/A and ensure the response is negative. As this
# zone does have signing keys set up, the response must be signed.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A > dig.out.ns3.pre.test$n 2>&1 || ret=1
grep "status: NOERROR" dig.out.ns3.pre.test$n > /dev/null && ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null || ret=1
# Remove the signing keys for this zone.
mv -f ns3/Kremovedkeys-secondary* ns3/removedkeys
# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore
# log messages generated before the raw zone is updated.
nextpart ns3/named.run > /dev/null
# Add a record to the raw zone on the master.
$NSUPDATE << EOF || ret=1
zone removedkeys-secondary.
server 10.53.0.2 ${PORT}
update add bar.removedkeys-secondary. 0 A 127.0.0.1
send
EOF
wait_until_raw_zone_update_is_processed "removedkeys-secondary"
# Query for bar.removedkeys-secondary/A again and ensure the signer still returns a
# negative, signed response.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A > dig.out.ns3.post.test$n 2>&1
grep "status: NOERROR" dig.out.ns3.post.test$n > /dev/null && ret=1
grep "RRSIG" dig.out.ns3.pre.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "checking that backlogged changes to raw zone are applied after keys become available (secondary) ($n)"
ret=0
# Restore the signing keys for this zone.
mv ns3/removedkeys/Kremovedkeys-secondary* ns3
$RNDCCMD 10.53.0.3 loadkeys removedkeys-secondary > /dev/null 2>&1
# Determine what a SOA record with a bumped serial number should look like.
BUMPED_SOA=`sed -n 's/.*\(add removedkeys-secondary.*IN.*SOA\)/\1/p;' ns2/named.run | tail -1 | awk '{$8 += 1; print $0}'`
# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore
# log messages generated before the raw zone is updated.
nextpart ns3/named.run > /dev/null
# Bump the SOA serial number of the raw zone on the master.
$NSUPDATE << EOF || ret=1
zone removedkeys-secondary.
server 10.53.0.2 ${PORT}
update del removedkeys-secondary. SOA
update ${BUMPED_SOA}
send
EOF
wait_until_raw_zone_update_is_processed "removedkeys-secondary"
# Query for bar.removedkeys-secondary/A again and ensure the signer now returns
# a positive, signed response.
$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A > dig.out.ns3.test$n 2>&1
grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
grep "RRSIG" dig.out.ns3.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that zonestatus reports 'type: master' for a inline master zone ($n)"
ret=0
$RNDCCMD 10.53.0.3 zonestatus master > rndc.out.ns3.test$n
grep "type: master" rndc.out.ns3.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "check that zonestatus reports 'type: slave' for a inline slave zone ($n)"
ret=0
......
......@@ -14230,8 +14230,17 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
fprintf(stderr, "looping on dns_update_signaturesinc\n");
return;
}
if (result != ISC_R_SUCCESS)
/*
* If something went wrong while trying to update the secure zone and
* the latter was already signed before, do not apply raw zone deltas
* to it as that would break existing DNSSEC signatures. However, if
* the secure zone was not yet signed (e.g. because no signing keys
* were created for it), commence applying raw zone deltas to it so
* that contents of the raw zone and the secure zone are kept in sync.
*/
if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
goto failure;
}
if (rjournal == NULL)
CHECK(dns_journal_open(zone->rss_raw->mctx,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment