Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Knot DNS
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
21
Issues
21
List
Boards
Labels
Service Desk
Milestones
Merge Requests
16
Merge Requests
16
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Knot projects
Knot DNS
Commits
3fbf23de
Commit
3fbf23de
authored
Mar 28, 2017
by
Libor Peltan
Committed by
Daniel Salzman
May 29, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ksk rollover: parent DS check implemented +test
parent
b864bafe
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
464 additions
and
8 deletions
+464
-8
Knot.files
Knot.files
+1
-0
src/Makefile.am
src/Makefile.am
+1
-0
src/knot/conf/scheme.c
src/knot/conf/scheme.c
+3
-1
src/knot/conf/scheme.h
src/knot/conf/scheme.h
+3
-1
src/knot/dnssec/key-events.c
src/knot/dnssec/key-events.c
+21
-2
src/knot/dnssec/key-events.h
src/knot/dnssec/key-events.h
+4
-1
src/knot/dnssec/zone-sign.c
src/knot/dnssec/zone-sign.c
+9
-0
src/knot/dnssec/zone-sign.h
src/knot/dnssec/zone-sign.h
+2
-0
src/knot/events/events.c
src/knot/events/events.c
+2
-0
src/knot/events/events.h
src/knot/events/events.h
+1
-0
src/knot/events/handlers.h
src/knot/events/handlers.h
+2
-0
src/knot/events/handlers/key_rollover.c
src/knot/events/handlers/key_rollover.c
+1
-1
src/knot/events/handlers/parent_ds_query.c
src/knot/events/handlers/parent_ds_query.c
+227
-0
src/knot/modules/onlinesign/onlinesign.c
src/knot/modules/onlinesign/onlinesign.c
+1
-1
src/knot/nameserver/log.h
src/knot/nameserver/log.h
+3
-0
src/knot/zone/zone-load.c
src/knot/zone/zone-load.c
+6
-1
tests-extra/tests/dnssec/ksk_rollover/data/com.zone
tests-extra/tests/dnssec/ksk_rollover/data/com.zone
+6
-0
tests-extra/tests/dnssec/ksk_rollover/data/com.zone.1
tests-extra/tests/dnssec/ksk_rollover/data/com.zone.1
+7
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/data.mdb
tests-extra/tests/dnssec/ksk_rollover/data/keys/data.mdb
+0
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/301d3fc5392e83ea02312dc5bdc1a9f0b7937ddf.pem
...ta/keys/keys/301d3fc5392e83ea02312dc5bdc1a9f0b7937ddf.pem
+10
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/6abddc73bcb46c4e6078cf764290ac315fff03f0.pem
...ta/keys/keys/6abddc73bcb46c4e6078cf764290ac315fff03f0.pem
+10
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/7a3500c7feac3fd99f09a208a83b97f7455fa3e0.pem
...ta/keys/keys/7a3500c7feac3fd99f09a208a83b97f7455fa3e0.pem
+10
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/7e7492f7dcaf4d819a29eb30ad80c04f830d76cf.pem
...ta/keys/keys/7e7492f7dcaf4d819a29eb30ad80c04f830d76cf.pem
+10
-0
tests-extra/tests/dnssec/ksk_rollover/data/keys/lock.mdb
tests-extra/tests/dnssec/ksk_rollover/data/keys/lock.mdb
+0
-0
tests-extra/tests/dnssec/ksk_rollover/test.py
tests-extra/tests/dnssec/ksk_rollover/test.py
+103
-0
tests-extra/tools/dnstest/server.py
tests-extra/tools/dnstest/server.py
+21
-0
No files found.
Knot.files
View file @
3fbf23de
...
...
@@ -229,6 +229,7 @@ src/knot/events/handlers/nsec3resalt.c
src/knot/events/handlers/refresh.c
src/knot/events/handlers/update.c
src/knot/events/handlers/key_rollover.c
src/knot/events/handlers/parent_ds_query.c
src/knot/events/log.c
src/knot/events/log.h
src/knot/events/replan.c
...
...
src/Makefile.am
View file @
3fbf23de
...
...
@@ -289,6 +289,7 @@ libknotd_la_SOURCES = \
knot/events/handlers/refresh.c
\
knot/events/handlers/update.c
\
knot/events/handlers/key_rollover.c
\
knot/events/handlers/parent_ds_query.c
\
knot/events/log.c
\
knot/events/log.h
\
knot/events/replan.c
\
...
...
src/knot/conf/scheme.c
View file @
3fbf23de
...
...
@@ -203,6 +203,8 @@ static const yp_item_t desc_policy[] = {
{
C_NSEC3_SALT_LEN
,
YP_TINT
,
YP_VINT
=
{
0
,
UINT8_MAX
,
8
},
CONF_IO_FRLD_ZONES
},
{
C_NSEC3_SALT_LIFETIME
,
YP_TINT
,
YP_VINT
=
{
1
,
UINT32_MAX
,
DAYS
(
30
),
YP_STIME
},
CONF_IO_FRLD_ZONES
},
{
C_KSK_SUBMITTION_CHECK
,
YP_TREF
,
YP_VREF
=
{
C_RMT
},
YP_FMULTI
|
CONF_IO_FRLD_ZONES
,
{
check_ref
}
},
{
C_KSK_SUBMITTION_CHECK_INTERVAL
,
YP_TINT
,
YP_VINT
=
{
1
,
UINT32_MAX
,
HOURS
(
1
),
YP_STIME
},
CONF_IO_FRLD_ZONES
},
{
C_COMMENT
,
YP_TSTR
,
YP_VNONE
},
{
NULL
}
};
...
...
@@ -292,10 +294,10 @@ const yp_item_t conf_scheme[] = {
{
C_LOG
,
YP_TGRP
,
YP_VGRP
=
{
desc_log
},
YP_FMULTI
|
CONF_IO_FRLD_LOG
},
{
C_STATS
,
YP_TGRP
,
YP_VGRP
=
{
desc_stats
},
CONF_IO_FRLD_SRV
},
{
C_KEYSTORE
,
YP_TGRP
,
YP_VGRP
=
{
desc_keystore
},
YP_FMULTI
,
{
check_keystore
}
},
{
C_POLICY
,
YP_TGRP
,
YP_VGRP
=
{
desc_policy
},
YP_FMULTI
,
{
check_policy
}
},
{
C_KEY
,
YP_TGRP
,
YP_VGRP
=
{
desc_key
},
YP_FMULTI
,
{
check_key
}
},
{
C_ACL
,
YP_TGRP
,
YP_VGRP
=
{
desc_acl
},
YP_FMULTI
,
{
check_acl
}
},
{
C_RMT
,
YP_TGRP
,
YP_VGRP
=
{
desc_remote
},
YP_FMULTI
,
{
check_remote
}
},
{
C_POLICY
,
YP_TGRP
,
YP_VGRP
=
{
desc_policy
},
YP_FMULTI
,
{
check_policy
}
},
{
C_TPL
,
YP_TGRP
,
YP_VGRP
=
{
desc_template
},
YP_FMULTI
,
{
check_template
}
},
{
C_ZONE
,
YP_TGRP
,
YP_VGRP
=
{
desc_zone
},
YP_FMULTI
|
CONF_IO_FZONE
,
{
check_zone
}
},
{
C_INCL
,
YP_TSTR
,
YP_VNONE
,
CONF_IO_FDIFF_ZONES
|
CONF_IO_FRLD_ALL
,
{
include_file
}
},
...
...
src/knot/conf/scheme.h
View file @
3fbf23de
...
...
@@ -60,7 +60,10 @@
#define C_KASP_DB_MAPSIZE "\x0F""kasp-db-mapsize"
#define C_KEY "\x03""key"
#define C_KEYSTORE "\x08""keystore"
#define C_KSK_LIFETIME "\x0C""ksk-lifetime"
#define C_KSK_SIZE "\x08""ksk-size"
#define C_KSK_SUBMITTION_CHECK "\x14""ksk-submittion-check"
#define C_KSK_SUBMITTION_CHECK_INTERVAL "\x1D""ksk-submittion-check-interval"
#define C_LISTEN "\x06""listen"
#define C_LOG "\x03""log"
#define C_MANUAL "\x06""manual"
...
...
@@ -117,7 +120,6 @@
#define C_ZONE "\x04""zone"
#define C_ZONEFILE_SYNC "\x0D""zonefile-sync"
#define C_ZSK_LIFETIME "\x0C""zsk-lifetime"
#define C_KSK_LIFETIME "\x0C""ksk-lifetime"
#define C_ZSK_SIZE "\x08""zsk-size"
enum
{
...
...
src/knot/dnssec/key-events.c
View file @
3fbf23de
...
...
@@ -179,7 +179,7 @@ static roll_action next_action(kdnssec_ctx_t *ctx)
restype
=
SUBMIT
;
break
;
case
DNSSEC_KEY_STATE_READY
:
break
;
// TODO !!!
break
;
case
DNSSEC_KEY_STATE_ACTIVE
:
if
(
!
is_ksk_published
)
{
keytime
=
ksk_publish_time
(
key
->
timing
.
active
,
ctx
);
...
...
@@ -279,7 +279,7 @@ static int exec_remove_old_key(kdnssec_ctx_t *ctx, knot_kasp_key_t *key)
return
kdnssec_delete_key
(
ctx
,
key
);
}
int
knot_dnssec_key_rollover
(
kdnssec_ctx_t
*
ctx
,
bool
*
keys_changed
,
time_t
*
next_rollover
)
int
knot_dnssec_key_rollover
(
kdnssec_ctx_t
*
ctx
,
zone_t
*
zone
,
bool
*
keys_changed
,
time_t
*
next_rollover
)
{
if
(
ctx
->
policy
->
manual
)
{
return
KNOT_EOK
;
...
...
@@ -312,6 +312,11 @@ int knot_dnssec_key_rollover(kdnssec_ctx_t *ctx, bool *keys_changed, time_t *nex
break
;
case
SUBMIT
:
ret
=
submit_key
(
ctx
,
next
.
key
);
if
(
zone
==
NULL
)
{
return
KNOT_EINVAL
;
}
zone_events_schedule_now
(
zone
,
ZONE_EVENT_PARENT_DS_Q
);
// "now" it won't probably succeed, but it replans itself for proper interval
break
;
case
REPLACE
:
ret
=
exec_new_signatures
(
ctx
,
next
.
key
);
...
...
@@ -354,3 +359,17 @@ int knot_dnssec_ksk_submittion_confirm(kdnssec_ctx_t *ctx, uint16_t for_key)
}
return
KNOT_ENOENT
;
}
bool
zone_has_key_submittion
(
const
kdnssec_ctx_t
*
ctx
)
{
assert
(
ctx
->
zone
);
for
(
size_t
i
=
0
;
i
<
ctx
->
zone
->
num_keys
;
i
++
)
{
knot_kasp_key_t
*
key
=
&
ctx
->
zone
->
keys
[
i
];
if
(
dnssec_key_get_flags
(
key
->
key
)
==
DNSKEY_FLAGS_KSK
&&
get_key_state
(
key
,
ctx
->
now
)
==
DNSSEC_KEY_STATE_READY
)
{
return
true
;
}
}
return
false
;
}
src/knot/dnssec/key-events.h
View file @
3fbf23de
...
...
@@ -19,6 +19,7 @@
#include <time.h>
#include "knot/dnssec/context.h"
#include "knot/zone/zone.h"
/*!
* \brief Perform correct ZSK and KSK rollover action and plan next one.
...
...
@@ -37,6 +38,8 @@
*
* \return KNOT_E*
*/
int
knot_dnssec_key_rollover
(
kdnssec_ctx_t
*
ctx
,
bool
*
keys_changed
,
time_t
*
next_rollover
);
int
knot_dnssec_key_rollover
(
kdnssec_ctx_t
*
ctx
,
zone_t
*
zone
,
bool
*
keys_changed
,
time_t
*
next_rollover
);
int
knot_dnssec_ksk_submittion_confirm
(
kdnssec_ctx_t
*
ctx
,
uint16_t
for_key
);
bool
zone_has_key_submittion
(
const
kdnssec_ctx_t
*
ctx
);
src/knot/dnssec/zone-sign.c
View file @
3fbf23de
...
...
@@ -646,6 +646,15 @@ static bool cds_rdata_match(zone_key_t *key,
return
(
ret
==
KNOT_EOK
&&
res
==
0
);
}
bool
knot_match_key_ds
(
zone_key_t
*
key
,
const
knot_rdata_t
*
rdata
)
{
dnssec_binary_t
rdata_bin
=
{
.
data
=
knot_rdata_data
(
rdata
),
.
size
=
knot_rdata_rdlen
(
rdata
)
};
return
cds_rdata_match
(
key
,
&
rdata_bin
);
}
/*!
* \brief Check if DNSKEY/DS is present in public zone key set.
*/
...
...
src/knot/dnssec/zone-sign.h
View file @
3fbf23de
...
...
@@ -125,4 +125,6 @@ int knot_zone_sign_nsecs_in_changeset(const zone_keyset_t *zone_keys,
bool
knot_zone_sign_rr_should_be_signed
(
const
zone_node_t
*
node
,
const
knot_rrset_t
*
rrset
);
bool
knot_match_key_ds
(
zone_key_t
*
key
,
const
knot_rdata_t
*
rdata
);
/*! @} */
src/knot/events/events.c
View file @
3fbf23de
...
...
@@ -48,6 +48,7 @@ static const event_info_t EVENT_INFO[] = {
{
ZONE_EVENT_UTHAW
,
event_uthaw
,
"update thaw"
},
{
ZONE_EVENT_NSEC3RESALT
,
event_nsec3resalt
,
"NSEC3 resalt"
},
{
ZONE_EVENT_KEY_ROLLOVER
,
event_key_rollover
,
"KEY rollover"
},
{
ZONE_EVENT_PARENT_DS_Q
,
event_parent_ds_q
,
"parent DS query"
},
{
0
}
};
...
...
@@ -79,6 +80,7 @@ bool ufreeze_applies(zone_event_type_t type)
case
ZONE_EVENT_DNSSEC
:
case
ZONE_EVENT_NSEC3RESALT
:
case
ZONE_EVENT_KEY_ROLLOVER
:
case
ZONE_EVENT_PARENT_DS_Q
:
return
true
;
default:
return
false
;
...
...
src/knot/events/events.h
View file @
3fbf23de
...
...
@@ -41,6 +41,7 @@ typedef enum zone_event_type {
ZONE_EVENT_UTHAW
,
ZONE_EVENT_NSEC3RESALT
,
ZONE_EVENT_KEY_ROLLOVER
,
ZONE_EVENT_PARENT_DS_Q
,
// terminator
ZONE_EVENT_COUNT
,
}
zone_event_type_t
;
...
...
src/knot/events/handlers.h
View file @
3fbf23de
...
...
@@ -41,3 +41,5 @@ int event_uthaw(conf_t *conf, zone_t *zone);
int
event_nsec3resalt
(
conf_t
*
conf
,
zone_t
*
zone
);
/*! \brief ZSK rollover related actions (key creation, publishing, deleting...). */
int
event_key_rollover
(
conf_t
*
conf
,
zone_t
*
zone
);
/*! \brief When CDS/CDNSKEY published, look for matching DS */
int
event_parent_ds_q
(
conf_t
*
conf
,
zone_t
*
zone
);
src/knot/events/handlers/key_rollover.c
View file @
3fbf23de
...
...
@@ -29,7 +29,7 @@ int event_key_rollover(conf_t *conf, zone_t *zone)
return
ret
;
}
ret
=
knot_dnssec_key_rollover
(
&
kctx
,
&
keys_updated
,
&
next_rollover
);
ret
=
knot_dnssec_key_rollover
(
&
kctx
,
zone
,
&
keys_updated
,
&
next_rollover
);
kdnssec_ctx_deinit
(
&
kctx
);
if
(
next_rollover
)
{
...
...
src/knot/events/handlers/parent_ds_query.c
0 → 100644
View file @
3fbf23de
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include "knot/zone/zone.h"
#include "knot/common/log.h"
#include "knot/conf/conf.h"
#include "knot/dnssec/context.h"
#include "knot/dnssec/key-events.h"
#include "knot/dnssec/zone-keys.h"
#include "knot/dnssec/zone-sign.h" // match key and DS rdata
#include "knot/query/layer.h"
#include "knot/query/query.h"
#include "knot/query/requestor.h"
struct
ds_query_data
{
zone_t
*
zone
;
conf_t
*
conf
;
const
struct
sockaddr
*
remote
;
zone_key_t
*
key
;
bool
ds_ok
;
};
static
int
ds_query_begin
(
knot_layer_t
*
layer
,
void
*
params
)
{
layer
->
data
=
params
;
return
KNOT_STATE_PRODUCE
;
}
static
int
ds_query_produce
(
knot_layer_t
*
layer
,
knot_pkt_t
*
pkt
)
{
struct
ds_query_data
*
data
=
layer
->
data
;
query_init_pkt
(
pkt
);
int
r
=
knot_pkt_put_question
(
pkt
,
data
->
zone
->
name
,
KNOT_CLASS_IN
,
KNOT_RRTYPE_DS
);
if
(
r
!=
KNOT_EOK
)
{
return
KNOT_STATE_FAIL
;
}
return
KNOT_STATE_CONSUME
;
}
static
int
ds_query_consume
(
knot_layer_t
*
layer
,
knot_pkt_t
*
pkt
)
{
struct
ds_query_data
*
data
=
layer
->
data
;
if
(
knot_pkt_ext_rcode
(
pkt
)
!=
KNOT_RCODE_NOERROR
)
{
ns_log
(
LOG_WARNING
,
data
->
zone
->
name
,
LOG_OPERATION_PARENT
,
LOG_DIRECTION_OUT
,
data
->
remote
,
"failed (%s)"
,
knot_pkt_ext_rcode_name
(
pkt
));
return
KNOT_STATE_FAIL
;
}
const
knot_pktsection_t
*
answer
=
knot_pkt_section
(
pkt
,
KNOT_ANSWER
);
bool
match
=
false
;
for
(
size_t
j
=
0
;
j
<
answer
->
count
;
j
++
)
{
const
knot_rrset_t
*
rr
=
knot_pkt_rr
(
answer
,
j
);
if
(
!
rr
||
rr
->
type
!=
KNOT_RRTYPE_DS
||
rr
->
rrs
.
rr_count
!=
1
)
{
ns_log
(
LOG_WARNING
,
data
->
zone
->
name
,
LOG_OPERATION_PARENT
,
LOG_DIRECTION_OUT
,
data
->
remote
,
"malformed message"
);
return
KNOT_STATE_FAIL
;
}
if
(
knot_match_key_ds
(
data
->
key
,
knot_rdataset_at
(
&
rr
->
rrs
,
0
)))
{
match
=
true
;
break
;
}
}
ns_log
(
LOG_INFO
,
data
->
zone
->
name
,
LOG_OPERATION_PARENT
,
LOG_DIRECTION_OUT
,
data
->
remote
,
"KSK submittion attempt: %s"
,
(
match
?
"positive"
:
"negative"
));
if
(
match
)
data
->
ds_ok
=
true
;
return
KNOT_STATE_DONE
;
}
static
const
knot_layer_api_t
ds_query_api
=
{
.
begin
=
ds_query_begin
,
.
produce
=
ds_query_produce
,
.
consume
=
ds_query_consume
,
.
reset
=
NULL
,
.
finish
=
NULL
,
};
static
int
try_ds
(
conf_t
*
conf
,
zone_t
*
zone
,
const
conf_remote_t
*
parent
,
zone_key_t
*
key
)
{
// TODO: Abstract interface to issue DNS queries. This is almost copy-pasted.
assert
(
zone
);
assert
(
parent
);
struct
ds_query_data
data
=
{
.
zone
=
zone
,
.
conf
=
conf
,
.
remote
=
(
struct
sockaddr
*
)
&
parent
->
addr
,
.
key
=
key
,
.
ds_ok
=
false
,
};
struct
knot_requestor
requestor
;
knot_requestor_init
(
&
requestor
,
&
ds_query_api
,
&
data
,
NULL
);
knot_pkt_t
*
pkt
=
knot_pkt_new
(
NULL
,
KNOT_WIRE_MAX_PKTSIZE
,
NULL
);
if
(
!
pkt
)
{
knot_requestor_clear
(
&
requestor
);
return
KNOT_ENOMEM
;
}
const
struct
sockaddr
*
dst
=
(
struct
sockaddr
*
)
&
parent
->
addr
;
const
struct
sockaddr
*
src
=
(
struct
sockaddr
*
)
&
parent
->
via
;
struct
knot_request
*
req
=
knot_request_make
(
NULL
,
dst
,
src
,
pkt
,
&
parent
->
key
,
0
);
if
(
!
req
)
{
knot_request_free
(
req
,
NULL
);
knot_requestor_clear
(
&
requestor
);
return
KNOT_ENOMEM
;
}
int
timeout
=
conf
->
cache
.
srv_tcp_reply_timeout
*
1000
;
int
ret
=
knot_requestor_exec
(
&
requestor
,
req
,
timeout
);
knot_request_free
(
req
,
NULL
);
knot_requestor_clear
(
&
requestor
);
// alternative: we could put answer back through ctx instead of errcode
if
(
ret
==
KNOT_EOK
&&
!
data
.
ds_ok
)
{
ret
=
KNOT_ENORECORD
;
}
return
ret
;
}
static
bool
parents_have_ds
(
zone_t
*
zone
,
conf_t
*
conf
,
zone_key_t
*
key
)
{
conf_val_t
policy
=
conf_zone_get
(
conf
,
C_DNSSEC_POLICY
,
zone
->
name
);
uint8_t
*
policy_name
=
(
uint8_t
*
)
conf_str
(
&
policy
);
size_t
policy_name_len
=
strlen
((
const
char
*
)
policy_name
)
+
1
;
conf_val_t
parents
=
conf_rawid_get
(
conf
,
C_POLICY
,
C_KSK_SUBMITTION_CHECK
,
policy_name
,
policy_name_len
);
bool
success
=
false
;
while
(
parents
.
code
==
KNOT_EOK
)
{
success
=
false
;
conf_val_t
addr
=
conf_id_get
(
conf
,
C_RMT
,
C_ADDR
,
&
parents
);
size_t
addr_count
=
conf_val_count
(
&
addr
);
for
(
size_t
i
=
0
;
i
<
addr_count
;
i
++
)
{
conf_remote_t
parent
=
conf_remote
(
conf
,
&
parents
,
i
);
int
ret
=
try_ds
(
conf
,
zone
,
&
parent
,
key
);
if
(
ret
==
KNOT_EOK
)
{
success
=
true
;
break
;
}
}
if
(
!
success
)
{
// TODO dnssec warning, or not ?
}
conf_val_next
(
&
parents
);
}
return
success
;
}
int
event_parent_ds_q
(
conf_t
*
conf
,
zone_t
*
zone
)
{
conf_val_t
policy
=
conf_zone_get
(
conf
,
C_DNSSEC_POLICY
,
zone
->
name
);
kdnssec_ctx_t
ctx
=
{
0
};
int
ret
=
kdnssec_ctx_init
(
&
ctx
,
zone
->
name
,
&
policy
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
zone_keyset_t
keyset
=
{
0
};
ret
=
load_zone_keys
(
ctx
.
zone
,
ctx
.
keystore
,
false
,
ctx
.
now
,
&
keyset
);
if
(
ret
!=
KNOT_EOK
)
{
return
ret
;
}
for
(
size_t
i
=
0
;
i
<
keyset
.
count
;
i
++
)
{
zone_key_t
*
key
=
&
keyset
.
keys
[
i
];
if
(
dnssec_key_get_flags
(
key
->
key
)
==
DNSKEY_FLAGS_KSK
&&
key
->
is_ready
&&
!
key
->
is_active
)
{
if
(
parents_have_ds
(
zone
,
conf
,
key
))
{
ret
=
knot_dnssec_ksk_submittion_confirm
(
&
ctx
,
dnssec_key_get_keytag
(
key
->
key
));
// TODO get rid of keytag
}
else
{
ret
=
KNOT_ENOENT
;
}
}
}
if
(
ret
!=
KNOT_EOK
)
{
uint8_t
*
policy_name
=
(
uint8_t
*
)
conf_str
(
&
policy
);
size_t
policy_name_len
=
strlen
((
const
char
*
)
policy_name
)
+
1
;
conf_val_t
check_interval
=
conf_rawid_get
(
conf
,
C_POLICY
,
C_KSK_SUBMITTION_CHECK_INTERVAL
,
policy_name
,
policy_name_len
);
time_t
next_check
=
time
(
NULL
)
+
conf_int
(
&
check_interval
);
zone_events_schedule_at
(
zone
,
ZONE_EVENT_PARENT_DS_Q
,
next_check
);
}
else
{
zone_events_schedule_now
(
zone
,
ZONE_EVENT_DNSSEC
);
}
free_zone_keys
(
&
keyset
);
kdnssec_ctx_deinit
(
&
ctx
);
return
KNOT_EOK
;
// allways ok, if failure it has been rescheduled
}
src/knot/modules/onlinesign/onlinesign.c
View file @
3fbf23de
...
...
@@ -453,7 +453,7 @@ static int get_online_key(dnssec_key_t **key_ptr, knotd_mod_t *mod)
bool
ignore1
=
false
;
time_t
ignore2
=
0
;
r
=
knot_dnssec_key_rollover
(
&
kctx
,
&
ignore1
,
&
ignore2
);
r
=
knot_dnssec_key_rollover
(
&
kctx
,
NULL
,
&
ignore1
,
&
ignore2
);
if
(
r
!=
DNSSEC_EOK
)
{
goto
fail
;
}
...
...
src/knot/nameserver/log.h
View file @
3fbf23de
...
...
@@ -26,6 +26,7 @@ enum log_operation {
LOG_OPERATION_NOTIFY
,
LOG_OPERATION_REFRESH
,
LOG_OPERATION_UPDATE
,
LOG_OPERATION_PARENT
,
};
enum
log_direction
{
...
...
@@ -46,6 +47,8 @@ static inline const char *log_operation_name(enum log_operation operation)
return
"refresh"
;
case
LOG_OPERATION_UPDATE
:
return
"DDNS"
;
case
LOG_OPERATION_PARENT
:
return
"parent DS check"
;
default:
return
"?"
;
}
...
...
src/knot/zone/zone-load.c
View file @
3fbf23de
...
...
@@ -244,7 +244,12 @@ int zone_load_post(conf_t *conf, zone_t *zone, zone_contents_t *contents,
}
ignore1
=
false
;
ignore2
=
0
;
ret
=
knot_dnssec_key_rollover
(
&
kctx
,
&
ignore1
,
&
ignore2
);
ret
=
knot_dnssec_key_rollover
(
&
kctx
,
zone
,
&
ignore1
,
&
ignore2
);
if
(
zone_has_key_submittion
(
&
kctx
))
{
zone_events_schedule_now
(
zone
,
ZONE_EVENT_PARENT_DS_Q
);
}
kdnssec_ctx_deinit
(
&
kctx
);
if
(
ret
!=
KNOT_EOK
)
{
changeset_clear
(
&
change
);
...
...
tests-extra/tests/dnssec/ksk_rollover/data/com.zone
0 → 100644
View file @
3fbf23de
$ORIGIN com.
$TTL 1200
@ SOA ns admin 20110100 7 7 16 600
ns AAAA ::0
tests-extra/tests/dnssec/ksk_rollover/data/com.zone.1
0 → 100644
View file @
3fbf23de
$ORIGIN com.
$TTL 1200
@ SOA ns admin 20110101 25 25 80 600
ns AAAA ::0
example.com. 3600 DS 48031 7 2 19C30FF016E701DB8D9A600EEF5F29F3B5B5197AE78648AA8ED5308E341A7FFD
tests-extra/tests/dnssec/ksk_rollover/data/keys/data.mdb
0 → 100644
View file @
3fbf23de
File added
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/301d3fc5392e83ea02312dc5bdc1a9f0b7937ddf.pem
0 → 100644
View file @
3fbf23de
-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAsDQulN1onk4XnGGF
LhWmRudSBpBty4XbOyFBikeE9N3S1MMqzszuMbOeiXXdVwIcPgmDl5N1t3ClBJJg
SH++JQIDAQABAkAVegbDdkkuIm6WTPyipVjjA4bn7eq0B9i02FTYuebmwX7xg9rr
jcMRXEaA6yGqP62mvVWBNx91yaUvRji3RNqBAiEAxrljK01EgXdgE49l9SdV78Mf
A2e6con84vgbMb9B7S0CIQDi/Sj9WH1Q8DAqibaaM3mrUCHfOVBWeS2rdRbo4UJf
2QIhAI6PmkQLN1UFdYgyvDsF0BGj0dDYjhnzQdb1lFS41yu1AiEAtC0JvVfhWT7e
rNVVeb9EY8Sermb7KzjTFJdD0SUFH7kCIGvczpFwGty6p3MPatS2vc7A8Z8gvAe3
tE5uJQObc+Z+
-----END PRIVATE KEY-----
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/6abddc73bcb46c4e6078cf764290ac315fff03f0.pem
0 → 100644
View file @
3fbf23de
-----BEGIN PRIVATE KEY-----
MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAomNuj0gH5HYjdC0r
7i0mxtBp5rr9dzPPSUwS72ZCFPsq3b8sdfAh2cZsvGQgkYCPPZV0Zx+kUP3WyGFy
9xqiCQIDAQABAkA6KMKALpwlBurLwSHqu+EXc616JZ6CAtxKtCRT+ZvRR1GWcEJ6
O8TeIU4YjWK7N8CQcgmeCX5bKbAW/DxUdksBAiEAy3xujDpOidIhBbYwq/E6a3/Q
EnQ/FGfq6cw3hWI/4k0CIQDMS9ShKl/QouORUlW1zCKWIK/7sAHuncYx6E9pH7uE
rQIgRzrGg8XBSlNJBfPRs86ccZbrIhqZHi6GN9MpuEI9NJ0CIQCgNjuqpDN9x7AV
L+99YXgiKcI46/+n5F0gmGFmPHdvBQIgEQcjUUtC1+qDOlulSjvheIi/Al5c9SRs
AXhDSTXtN3A=
-----END PRIVATE KEY-----
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/7a3500c7feac3fd99f09a208a83b97f7455fa3e0.pem
0 → 100644
View file @
3fbf23de
-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAu9eosHX/Ag8J0r71
lT9tzQeWbEZRAOZY8w+zC4hqTvtAZeE9SsB+ppoNM8bvdaxLVQNIIKKqOxsteOZY
xMFicQIDAQABAkEAtXq84oeNsRqAXhjaQbB/T8gV31PsLNdfdq1jSTAprVVOmHSk
CfKq30FOdIXnlLum2kypxejpdHGocI1rqZLzBQIhAOoPNuh/k3NeEau2VZt9dENN
JL4ByVpMG2gMjiucHl57AiEAzXNc16CmvEfQ/i3JhEhbb1I8o7QGsOk9v8MP/DEz
pQMCIF8EcCjwaX6DKK9JpPUrd8A+l/TeqswSa2nQ9wIzLYzzAiEAzBl4+DV+rrjh
pEE0WpfPTe3yk+Z6ZzGuyFwt+ymd1qUCIBzE561e4uE5tyPB46ybM/029/GFa89z
0D1ZBKVF7AWi
-----END PRIVATE KEY-----
tests-extra/tests/dnssec/ksk_rollover/data/keys/keys/7e7492f7dcaf4d819a29eb30ad80c04f830d76cf.pem
0 → 100644
View file @
3fbf23de
-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA0u57CJSNnnkVPSqx
tX+LqlnAEkroE+zadaZACE/AvYh2sKP+ktZxOphEN5wNXjI+zsfQTyyKazcHaZOT
XFlSIQIDAQABAkAYjdRaqlhWA0hap3aqZx+OBAac2oVrlF3V5jV8AjSwm1T4gbDq
iV+ARxIgqP6bAVa+rVC1hUQVAjRGI6fioSgBAiEA3zFS9A6salJdprW4Hxoudn5Q
oEidH2+tVaFmtmgW5sECIQDx78ZOQi7bmQz/s6Zp0cqcdLRHyfVojqwL5vtvHX+j
YQIgPk/uAfdqyZBPVzDaw8wydqCTb/x16YXrVcHnBDwRUMECIQDesivie08wedga
Qp5Kx35tt4r+jarkfHdnWU1VwVxs4QIhAJnSVxhAiKBW+RXuW+sW8NTVvCSjOp8y
uEK+Tq88J7qx
-----END PRIVATE KEY-----
tests-extra/tests/dnssec/ksk_rollover/data/keys/lock.mdb
0 → 100644
View file @
3fbf23de
File added
tests-extra/tests/dnssec/ksk_rollover/test.py
0 → 100644
View file @
3fbf23de
#!/usr/bin/env python3
"""
Check if keytag conflict is correctly handled by Knot.
"""
import
collections
import
os
import
shutil
import
datetime
import
subprocess
from
subprocess
import
check_call
from
dnstest.utils
import
*
from
dnstest.keys
import
Keymgr
from
dnstest.test
import
Test
# check zone if keys are present and used for signing
def
check_zone5
(
server
,
min_dnskeys
,
min_rrsigs
,
min_cdnskeys
,
msg
):
dnskeys
=
server
.
dig
(
"example.com"
,
"DNSKEY"
)
found_dnskeys
=
dnskeys
.
count
(
"DNSKEY"
)
soa
=
server
.
dig
(
"example.com"
,
"DNSKEY"
,
dnssec
=
True
)
found_rrsigs
=
soa
.
count
(
"RRSIG"
)
cdnskey
=
server
.
dig
(
"example.com"
,
"CDNSKEY"
)
found_cdnskeys
=
cdnskey
.
count
(
"CDNSKEY"
)
check_log
(
"RRSIGs: %d (expected %d)"
%
(
found_rrsigs
,
min_rrsigs
));
check_log
(
"DNSKEYs: %d (expected %d)"
%
(
found_dnskeys
,
min_dnskeys
));
check_log
(
"CDNSKEYs: %d (expected %d)"
%
(
found_cdnskeys
,
min_cdnskeys
));
if
found_rrsigs
!=
min_rrsigs
:
set_err
(
"BAD RRSIG COUNT: "
+
msg
)
detail_log
(
"!RRSIGs not published and activated as expected: "
+
msg
)
if
found_dnskeys
!=
min_dnskeys
:
set_err
(
"BAD DNSKEY COUNT: "
+
msg
)
detail_log
(
"!DNSKEYs not published and activated as expected: "
+
msg
)
if
found_cdnskeys
!=
min_cdnskeys
:
set_err
(
"BAD CDNSKEY COUNT: "
+
msg
)
detail_log
(
"!CDNSKEYs not published and activated as expected: "
+
msg
)
detail_log
(
SEP
)
t
=
Test
()
parent
=
t
.
server
(
"knot"
)
parent_zone
=
t
.
zone
(
"com."
,
storage
=
"."
)
t
.
link
(
parent_zone
,
parent
)
child
=
t
.
server
(
"knot"
)
child_zone
=
t
.
zone
(
"example.com."
)
t
.
link
(
child_zone
,
child
)
child
.
dnssec
(
child_zone
).
enable
=
True
child
.
dnssec
(
child_zone
).
manual
=
False
child
.
dnssec
(
child_zone
).
zsk_lifetime
=
99999
child
.
dnssec
(
child_zone
).
ksk_lifetime
=
300
# this can be possibly left also infinity
child
.
dnssec
(
child_zone
).
propagation_delay
=
17
child
.
dnssec
(
child_zone
).
ksk_submittion_check
=
[
parent
]
child
.
dnssec
(
child_zone
).
ksk_submittion_check_interval
=
2
# install KASP db (one always enabled, one for testing)
shutil
.
copytree
(
os
.
path
.
join
(
t
.
data_dir
,
"keys"
),
child
.
keydir
)
# parameters
ZONE
=
"example.com."
KSK1
=
"7a3500c7feac3fd99f09a208a83b97f7455fa3e0"
KSK2
=
"7e7492f7dcaf4d819a29eb30ad80c04f830d76cf"
ZSK1
=
"6abddc73bcb46c4e6078cf764290ac315fff03f0"
ZSK2
=
"301d3fc5392e83ea02312dc5bdc1a9f0b7937ddf"
t
.
rel_sleep
(
0
)
# note that some of these paraneters will be immediately or later modified by automated key management
child
.
key_set
(
ZONE
,
KSK1
,
publish
=
"t-2y"
,
ready
=
"t-1y"
,
active
=
"t-1y"
,
retire
=
"t+10y"
,
remove
=
"t+20y"
)
# KSK1's retire and remove shall be reconfigured by Knot to soon as KSK2 takes place
child
.
key_set
(
ZONE
,
KSK2
,
publish
=
"t+0"
,
ready
=
"t+1h"
,
active
=
"t+10y"
,
retire
=
"t+11y"
,
remove
=
"t+12y"
)
child
.
key_set
(
ZONE
,
ZSK1
,
publish
=
"t-20"
,
ready
=
"t-10"
,
active
=
"t-10"
,
retire
=
"t+15y"
,
remove
=
"t+20y"
)
# ZSK1 simply valid for all the time
child
.
key_set
(
ZONE
,
ZSK2
,
publish
=
"t-2"
,
ready
=
"t+14y"
,
active
=
"t+14y"
,
retire
=
"t+31y"
,
remove
=
"t+36y"
)
# ZSK2 only reason: prevents Knot from publishing another ZSK
t
.
start
()
child
.
zone_wait
(
child_zone
)
check_zone5
(
child
,
4
,
1
,
0
,
"only first KSK"
)
t
.
rel_sleep
(
19
)
check_zone5
(
child
,
4
,
2
,
1
,
"new KSK ready"
)