rrsets are encountered, there are then validated.
- enforce that signing is done by a parent domain (or same domain).
- adjust TTL downwards if rrset TTL bigger than signature allows.
+ - permissive mode feature, sets AD bit for secure, but bogus does
+ not give servfail (bogus is changed into indeterminate).
27 August 2007: Wouter
- do not garble the edns if a cache answer fails.
# potential bogus data in the additional section. All unsigned data
# in the additional section is removed from secure messages.
# val-clean-additional: yes
+
+ # Turn permissive mode on to permit bogus messages. Thus, messages
+ # for which security checks failed will be returned to clients,
+ # instead of SERVFAIL. It still performs the security checks, which
+ # result in interesting log files and possibly the AD bit in
+ # replies if the message is found secure. The default is off.
+ # val-permissive-mode: no
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
indeterminate or unchecked are not affected. Default is yes. Use this setting
to protect the users that rely on this validator for authentication from
protentially bad data in the additional section.
+.It \fBval-permissive-mode:\fR <yes or no>
+Instruct the validator to mark bogus messages as indeterminate. The security
+checks are performed, but if the result is bogus (failed security), the
+reply is not withheld from the client with SERVFAIL as usual. The client
+receives the bogus data. For messages that are found to be secure the AD bit
+is set in replies. Also logging is performed as for full validation.
+The default value is "no".
.El
.Ss Stub Zone Options
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000;
cfg->infra_cache_numlame = 1000;
- cfg->val_clean_additional = 1;
if(!(cfg->username = strdup(""))) goto error_exit;
if(!(cfg->chrootdir = strdup(""))) goto error_exit;
if(!(cfg->directory = strdup("/etc/unbound"))) goto error_exit;
cfg->trust_anchor_file_list = NULL;
cfg->trust_anchor_list = NULL;
cfg->val_date_override = 0;
+ cfg->val_clean_additional = 1;
+ cfg->val_permissive_mode = 0;
if(!(cfg->module_conf = strdup("iterator"))) goto error_exit;
return cfg;
error_exit:
int bogus_ttl;
/** should validator clean additional section for secure msgs */
int val_clean_additional;
+ /** should validator allow bogus messages to go through */
+ int val_permissive_mode;
/** daemonize, i.e. fork into the background. */
int do_daemonize;
val-override-date{COLON} { YDOUT; return VAR_VAL_OVERRIDE_DATE;}
val-bogus-ttl{COLON} { YDOUT; return VAR_BOGUS_TTL;}
val-clean-additional{COLON} { YDOUT; return VAR_VAL_CLEAN_ADDITIONAL;}
+val-permissive-mode{COLON} { YDOUT; return VAR_VAL_PERMISSIVE_MODE;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */
%token VAR_DO_NOT_QUERY_ADDRESS VAR_HIDE_IDENTITY VAR_HIDE_VERSION
%token VAR_IDENTITY VAR_VERSION VAR_HARDEN_GLUE VAR_MODULE_CONF
%token VAR_TRUST_ANCHOR_FILE VAR_TRUST_ANCHOR VAR_VAL_OVERRIDE_DATE
-%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL
+%token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_hide_version | server_identity | server_version |
server_harden_glue | server_module_conf | server_trust_anchor_file |
server_trust_anchor | server_val_override_date | server_bogus_ttl |
- server_val_clean_additional
+ server_val_clean_additional | server_val_permissive_mode
;
stubstart: VAR_STUB_ZONE
{
free($2);
}
;
-
+server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING
+ {
+ OUTYY(("P(server_val_permissive_mode:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->val_permissive_mode =
+ (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
stub_name: VAR_NAME STRING
{
OUTYY(("P(name:%s)\n", $2));
{
val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl;
val_env->clean_additional = cfg->val_clean_additional;
+ val_env->permissive_mode = cfg->val_permissive_mode;
if(!val_env->anchors)
val_env->anchors = anchors_create();
if(!val_env->anchors) {
val_init(struct module_env* env, int id)
{
struct val_env* val_env = (struct val_env*)calloc(1,
- sizeof(struct val_env));
+ sizeof(struct val_env));
if(!val_env) {
log_err("malloc failure");
return 0;
}
env->modinfo[id] = (void*)val_env;
env->need_to_validate = 1;
+ val_env->permissive_mode = 0;
if(!val_apply_cfg(val_env, env->cfg)) {
log_err("validator: could not apply configuration settings.");
return 0;
* endless bogus revalidation */
if(vq->orig_msg->rep->security == sec_status_bogus) {
vq->orig_msg->rep->ttl = time(0) + ve->bogus_ttl;
+ /* If we are in permissive mode, bogus gets indeterminate */
+ if(ve->permissive_mode)
+ vq->orig_msg->rep->security = sec_status_indeterminate;
}
/* store results in cache */
* secure messages.
*/
int clean_additional;
+
+ /**
+ * If set, the validator will not make messages bogus, instead
+ * indeterminate is issued, so that no clients receive SERVFAIL.
+ * This allows an operator to run validation 'shadow' without
+ * hurting responses to clients.
+ */
+ int permissive_mode;
};
/**