diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l
index d352755342c464d35a1dce9742fda96e1991ae00..fc8785919628965355d6764b587722720ee828b6 100644
--- a/src/knot/conf/cf-lex.l
+++ b/src/knot/conf/cf-lex.l
@@ -124,7 +124,8 @@ rate-limit      { lval.t = yytext; return RATE_LIMIT; }
 rate-limit-size { lval.t = yytext; return RATE_LIMIT_SIZE; }
 rate-limit-slip { lval.t = yytext; return RATE_LIMIT_SLIP; }
 transfers       { lval.t = yytext; return TRANSFERS; }
-keydir          { lval.t = yytext; return KEYDIR; }
+dnssec-enable   { lval.t = yytext; return DNSSEC_ENABLE; }
+dnssec-keydir   { lval.t = yytext; return DNSSEC_KEYDIR; }
 
 interfaces      { lval.t = yytext; return INTERFACES; }
 address         { lval.t = yytext; return ADDRESS; }
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y
index 2f12b71fab1c667a636f93a92a2967045fddacfc..b81ae9b4e982bfc86f9426cd8ca5a13ad2762b4c 100644
--- a/src/knot/conf/cf-parse.y
+++ b/src/knot/conf/cf-parse.y
@@ -430,7 +430,8 @@ static int conf_mask(void* scanner, int nval, int prefixlen) {
 %token <tok> RATE_LIMIT_SIZE
 %token <tok> RATE_LIMIT_SLIP
 %token <tok> TRANSFERS
-%token <tok> KEYDIR
+%token <tok> DNSSEC_ENABLE
+%token <tok> DNSSEC_KEYDIR
 
 %token <tok> INTERFACES ADDRESS PORT
 %token <tok> IPA
@@ -872,7 +873,8 @@ zone:
 	   this_zone->notify_timeout = $3.i;
        }
    }
- | zone KEYDIR TEXT ';' { this_zone->keydir = $3.t; }
+ | zone DNSSEC_ENABLE BOOL ';' { this_zone->dnssec_enable =
+                                 $3.i ? CONF_BOOL_TRUE : CONF_BOOL_FALSE; }
  ;
 
 zones:
@@ -905,6 +907,9 @@ zones:
        }
  }
  | zones DBSYNC_TIMEOUT INTERVAL ';' { new_config->dbsync_timeout = $3.i; }
+ | zones DNSSEC_ENABLE BOOL ';' { new_config->dnssec_enable =
+                                  $3.i ? CONF_BOOL_TRUE : CONF_BOOL_FALSE; }
+ | zones DNSSEC_KEYDIR TEXT ';' { new_config->dnssec_keydir = $3.t; }
  ;
 
 log_prios_start: {
diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c
index 3dfe974c7aa89f0c5b3c82d25519ec10496b826f..f651f536c30cde44560c1469e36f8a4121de14c3 100644
--- a/src/knot/conf/conf.c
+++ b/src/knot/conf/conf.c
@@ -252,6 +252,11 @@ static int conf_process(conf_t *conf)
 	if (conf->xfers <= 0)
 		conf->xfers = CONFIG_XFERS;
 
+	/* Defaults for DNSSEC. */
+	if (conf->dnssec_enable == CONF_BOOL_DEFAULT) {
+		conf->dnssec_enable = CONF_BOOL_TRUE;
+	}
+
 	// Postprocess zones
 	int ret = KNOT_EOK;
 	node *n = 0;
@@ -334,6 +339,14 @@ static int conf_process(conf_t *conf)
 		}
 		memcpy(dpos + zname_len, dbext, strlen(dbext) + 1);
 		zone->ixfr_db = dest;
+
+		// DNSSEC
+		if (conf->dnssec_keydir == NULL) {
+			zone->dnssec_enable = CONF_BOOL_FALSE;
+		} else if (zone->dnssec_enable == CONF_BOOL_DEFAULT) {
+			zone->dnssec_enable = conf->dnssec_enable;
+		}
+		assert(zone->dnssec_enable != CONF_BOOL_DEFAULT);
 	}
 
 	/* Update UID and GID. */
@@ -532,6 +545,9 @@ conf_t *conf_new(const char* path)
 	c->build_diffs = 0; /* Disable by default. */
 	c->logs_count = -1;
 
+	/* DNSSEC. */
+	c->dnssec_enable = true;
+
 	/* ACLs. */
 	c->ctl.acl = acl_new(ACL_DENY, "remote_ctl");
 	if (!c->ctl.acl) {
@@ -658,38 +674,25 @@ void conf_truncate(conf_t *conf, int unload_hooks)
 	conf->zones_count = 0;
 	init_list(&conf->zones);
 
-	if (conf->filename) {
-		free(conf->filename);
-		conf->filename = 0;
-	}
-	if (conf->identity) {
-		free(conf->identity);
-		conf->identity = 0;
-	}
-	if (conf->hostname) {
-		free(conf->hostname);
-		conf->hostname = 0;
-	}
-	if (conf->version) {
-		free(conf->version);
-		conf->version = 0;
-	}
-	if (conf->storage) {
-		free(conf->storage);
-		conf->storage = 0;
-	}
-	if (conf->rundir) {
-		free(conf->rundir);
-		conf->rundir = 0;
-	}
-	if (conf->pidfile) {
-		free(conf->pidfile);
-		conf->pidfile = 0;
-	}
-	if (conf->nsid) {
-		free(conf->nsid);
-		conf->nsid = 0;
-	}
+	conf->dnssec_enable = false;
+	free(conf->dnssec_keydir);
+	conf->dnssec_keydir = NULL;
+	free(conf->filename);
+	conf->filename = NULL;
+	free(conf->identity);
+	conf->identity = NULL;
+	free(conf->hostname);
+	conf->hostname = NULL;
+	free(conf->version);
+	conf->version = NULL;
+	free(conf->storage);
+	conf->storage = NULL;
+	free(conf->rundir);
+	conf->rundir = NULL;
+	free(conf->pidfile);
+	conf->pidfile = NULL;
+	free(conf->nsid);
+	conf->nsid = NULL;
 
 	/* Free remote control list. */
 	WALK_LIST_DELSAFE(n, nxt, conf->ctl.allow) {
@@ -884,7 +887,6 @@ void conf_free_zone(conf_zone_t *zone)
 	free(zone->name);
 	free(zone->file);
 	free(zone->ixfr_db);
-	free(zone->keydir);
 	free(zone);
 }
 
diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h
index 0e5542e2254c238abb7e63bb87451a44ba3f7629..f90ae2486da02aa60082455ed7c409971efcc8cb 100644
--- a/src/knot/conf/conf.h
+++ b/src/knot/conf/conf.h
@@ -54,6 +54,15 @@
 #define CONFIG_RRL_SIZE 393241 /*!< Htable default size. */
 #define CONFIG_XFERS 10
 
+/*!
+ * \brief Boolean with undefined default value.
+ */
+typedef enum {
+	CONF_BOOL_DEFAULT = 0,
+	CONF_BOOL_FALSE,
+	CONF_BOOL_TRUE,
+} conf_bool_t;
+
 /*!
  * \brief Configuration for the interface
  *
@@ -112,18 +121,18 @@ typedef struct conf_group_t {
  */
 typedef struct conf_zone_t {
 	node n;
-	char *name;               /*!< Zone name. */
-	uint16_t cls;             /*!< Zone class (IN or CH). */
-	char *file;               /*!< Path to a zone file. */
-	char *ixfr_db;            /*!< Path to a IXFR database file. */
-	char *keydir;             /*!< Path to key directory. */
-	size_t ixfr_fslimit;      /*!< File size limit for IXFR journal. */
-	int dbsync_timeout;       /*!< Interval between syncing to zonefile.*/
-	int enable_checks;        /*!< Semantic checks for parser.*/
-	int disable_any;          /*!< Disable ANY type queries for AA.*/
-	int notify_retries;       /*!< NOTIFY query retries. */
-	int notify_timeout;       /*!< Timeout for NOTIFY response (s). */
-	int build_diffs;          /*!< Calculate differences from changes. */
+	char *name;                /*!< Zone name. */
+	uint16_t cls;              /*!< Zone class (IN or CH). */
+	char *file;                /*!< Path to a zone file. */
+	char *ixfr_db;             /*!< Path to a IXFR database file. */
+	conf_bool_t dnssec_enable; /*!< DNSSEC: Online signing enabled. */
+	size_t ixfr_fslimit;       /*!< File size limit for IXFR journal. */
+	int dbsync_timeout;        /*!< Interval between syncing to zonefile.*/
+	int enable_checks;         /*!< Semantic checks for parser.*/
+	int disable_any;           /*!< Disable ANY type queries for AA.*/
+	int notify_retries;        /*!< NOTIFY query retries. */
+	int notify_timeout;        /*!< Timeout for NOTIFY response (s). */
+	int build_diffs;           /*!< Calculate differences from changes. */
 	struct {
 		list xfr_in;      /*!< Remotes accepted for for xfr-in.*/
 		list xfr_out;     /*!< Remotes accepted for xfr-out.*/
@@ -252,6 +261,8 @@ typedef struct conf_t {
 	size_t ixfr_fslimit; /*!< File size limit for IXFR journal. */
 	int build_diffs;     /*!< Calculate differences from changes. */
 	hattrie_t *names; /*!< Zone tree for duplicate checking. */
+	conf_bool_t dnssec_enable; /*!< DNSSEC: Online signing enabled. */
+	char *dnssec_keydir;       /*!< DNSSEC: Path to key directory. */
 
 	/*
 	 * Remote control interface.
diff --git a/src/knot/ctl/remote.c b/src/knot/ctl/remote.c
index 5122d2aeebd2966c6c7bfc529d18534ca33d159e..4a46311740d566483037c1a47a41b50cc2bb34f1 100644
--- a/src/knot/ctl/remote.c
+++ b/src/knot/ctl/remote.c
@@ -168,25 +168,23 @@ static int remote_zone_flush(server_t *s, const knot_zone_t *z)
 /*! \brief Sign zone callback. */
 static int remote_sign_zone(server_t *server, const knot_zone_t *zone)
 {
-	if (!server || !zone) {
+	if (!server || !zone)
 		return KNOT_EINVAL;
-	}
 
 	// generate NSEC records
 
 	knot_zone_create_nsec_chain(zone);
 
+//	zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
+//	const char *keydir = zd->conf->keydir;
+//
+//	if (!keydir) {
+//		log_server_info("no keys set for %s\n",
+//		                knot_dname_to_str(zone->name));
+//		return KNOT_EOK;
+//	}
+//	knot_zone_sign(zone, keydir);
 
-	zonedata_t *zd = (zonedata_t *)knot_zone_data(zone);
-	const char *keydir = zd->conf->keydir;
-
-	if (!keydir) {
-		log_server_info("no keys set for %s\n",
-		                knot_dname_to_str(zone->name));
-		return KNOT_EOK;
-	}
-
-	knot_zone_sign(zone, keydir);
 	return KNOT_EOK;
 }