mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-10-16 05:25:10 +02:00
Compare commits
96
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c96e26074 | ||
|
|
9ae988cea6 | ||
|
|
80957b6da3 | ||
|
|
d52d94c6db | ||
|
|
370a855f08 | ||
|
|
c7f44b99e3 | ||
|
|
9bbbca5de9 | ||
|
|
33ef79d433 | ||
|
|
eccfe3e1f5 | ||
|
|
adcbb6ced7 | ||
|
|
c678c696a1 | ||
|
|
313bceb983 | ||
|
|
6b2e96430e | ||
|
|
ceef84e022 | ||
|
|
95644c9309 | ||
|
|
cbdc138df7 | ||
|
|
392c1f0f54 | ||
|
|
69e188b5cf | ||
|
|
4e492725e1 | ||
|
|
49f2960089 | ||
|
|
94f04a77d9 | ||
|
|
fe8ef6e53d | ||
|
|
65113ac775 | ||
|
|
79024484a7 | ||
|
|
05e06fdcf5 | ||
|
|
df229db074 | ||
|
|
4f37d6489e | ||
|
|
ea1a5f35e4 | ||
|
|
dc38aacefc | ||
|
|
983c716feb | ||
|
|
83c712ca60 | ||
|
|
2c1a5203a5 | ||
|
|
778b50f113 | ||
|
|
d29ab10a34 | ||
|
|
63e6604b2a | ||
|
|
65ee2f2c39 | ||
|
|
c6c54f9de4 | ||
|
|
c7afaef10c | ||
|
|
9d1eb66f19 | ||
|
|
ef076c0e15 | ||
|
|
56cf526c68 | ||
|
|
4efbee08b5 | ||
|
|
db98a8b825 | ||
|
|
3ccb4c6c26 | ||
|
|
ff356b940b | ||
|
|
7926874669 | ||
|
|
575a6865be | ||
|
|
0572870592 | ||
|
|
0747d016e4 | ||
|
|
4a43aee99e | ||
|
|
a3171a1d48 | ||
|
|
f22e42f554 | ||
|
|
787d7a5952 | ||
|
|
0eba781ed3 | ||
|
|
df984d9c6f | ||
|
|
fed0fb42dd | ||
|
|
abd948f3d7 | ||
|
|
f7bb7f2a94 | ||
|
|
9bff0b94dd | ||
|
|
d2a719f606 | ||
|
|
b825bb668d | ||
|
|
8a6b3f088b | ||
|
|
86e8050352 | ||
|
|
c42c2cbbff | ||
|
|
7df2df0fc9 | ||
|
|
320aa64d18 | ||
|
|
3ba8ea321a | ||
|
|
42ba5ae4a2 | ||
|
|
732ad94729 | ||
|
|
84da2409b3 | ||
|
|
0b376cc42f | ||
|
|
b606c8273d | ||
|
|
4df2965459 | ||
|
|
65852bcbc4 | ||
|
|
4d15603a8c | ||
|
|
5617de6867 | ||
|
|
3576033b62 | ||
|
|
a664e8cec4 | ||
|
|
2360120562 | ||
|
|
9df75a842b | ||
|
|
7079f0b5aa | ||
|
|
33445be8df | ||
|
|
fba1c302ac | ||
|
|
ec4cf69eb7 | ||
|
|
d9a947f267 | ||
|
|
a98659791e | ||
|
|
5fff0f7e30 | ||
|
|
935634dcae | ||
|
|
b3f60db184 | ||
|
|
a9e6f6bc23 | ||
|
|
6b5f314a3a | ||
|
|
eac4eb3a9e | ||
|
|
0703a38243 | ||
|
|
4049885da2 | ||
|
|
a8d78b2083 | ||
|
|
285f93ff82 |
@@ -11,7 +11,7 @@ have any feedback, we would love to hear from you. Don’t hesitate to
|
||||
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
|
||||
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
You can learn more about Unbound by reading our
|
||||
[documentation](https://nlnetlabs.nl/documentation/unbound/).
|
||||
[documentation](https://unbound.docs.nlnetlabs.nl/).
|
||||
|
||||
## Compiling
|
||||
|
||||
@@ -33,7 +33,7 @@ support.
|
||||
|
||||
All of Unbound's configuration options are described in the man pages, which
|
||||
will be installed and are available on the Unbound
|
||||
[documentation page](https://nlnetlabs.nl/documentation/unbound/).
|
||||
[documentation page](https://unbound.docs.nlnetlabs.nl/).
|
||||
|
||||
An example configuration file is located in
|
||||
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
|
||||
|
||||
@@ -381,6 +381,9 @@
|
||||
/* Define to 1 if you have the <netinet/tcp.h> header file. */
|
||||
#undef HAVE_NETINET_TCP_H
|
||||
|
||||
/* Define to 1 if you have the <netioapi.h> header file. */
|
||||
#undef HAVE_NETIOAPI_H
|
||||
|
||||
/* Use libnettle for crypto */
|
||||
#undef HAVE_NETTLE
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.14.0.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.14.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -591,8 +591,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.14.0'
|
||||
PACKAGE_STRING='unbound 1.14.0'
|
||||
PACKAGE_VERSION='1.14.1'
|
||||
PACKAGE_STRING='unbound 1.14.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1466,7 +1466,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.14.0 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.14.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1531,7 +1531,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.14.0:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.14.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1773,7 +1773,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.14.0
|
||||
unbound configure 1.14.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2482,7 +2482,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.14.0, which was
|
||||
It was created by unbound $as_me 1.14.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2834,11 +2834,11 @@ UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=14
|
||||
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=14
|
||||
LIBUNBOUND_REVISION=15
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -2920,6 +2920,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.13.1 had 9:12:1
|
||||
# 1.13.2 had 9:13:1
|
||||
# 1.14.0 had 9:14:1
|
||||
# 1.14.1 had 9:15:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -14812,6 +14813,51 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_header in netioapi.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "netioapi.h" "ac_cv_header_netioapi_h" "$ac_includes_default
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UIO_H
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_netioapi_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_NETIOAPI_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
@@ -21840,7 +21886,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.14.0
|
||||
version=1.14.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -22359,7 +22405,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.14.0, which was
|
||||
This file was extended by unbound $as_me 1.14.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -22425,7 +22471,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.14.0
|
||||
unbound config.status 1.14.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+36
-2
@@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[14])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=14
|
||||
LIBUNBOUND_REVISION=15
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -100,6 +100,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.13.1 had 9:12:1
|
||||
# 1.13.2 had 9:13:1
|
||||
# 1.14.0 had 9:14:1
|
||||
# 1.14.1 had 9:15:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -412,6 +413,39 @@ AC_CHECK_HEADERS([net/if.h],,, [
|
||||
|
||||
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
|
||||
AC_CHECK_HEADERS([TargetConditionals.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([netioapi.h],,, [AC_INCLUDES_DEFAULT
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UIO_H
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_TCP_H
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index f426ac5f..147fbfa9 100644
|
||||
index 50f9224..09456f5 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -872,6 +872,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
@@ -970,6 +970,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is no.
|
||||
.TP
|
||||
@@ -17,14 +17,13 @@ index f426ac5f..147fbfa9 100644
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
|
||||
index aae934dd..55c55de0 100644
|
||||
index f093c1b..e55a224 100644
|
||||
--- a/iterator/iter_scrub.c
|
||||
+++ b/iterator/iter_scrub.c
|
||||
@@ -667,6 +667,32 @@ static int sanitize_nsec_is_overreach(struct rrset_parse* rrset,
|
||||
return 0;
|
||||
@@ -680,6 +680,32 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
|
||||
}
|
||||
|
||||
+/**
|
||||
/**
|
||||
+ * ASN: Lookup A records from rrset cache.
|
||||
+ * @param qinfo: the question originally asked.
|
||||
+ * @param env: module environment with config and cache.
|
||||
@@ -50,10 +49,11 @@ index aae934dd..55c55de0 100644
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
+/**
|
||||
* Given a response event, remove suspect RRsets from the response.
|
||||
* "Suspect" rrsets are potentially poison. Note that this routine expects
|
||||
@@ -686,6 +712,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
* the response to be in a "normalized" state -- that is, all "irrelevant"
|
||||
@@ -698,6 +724,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
|
||||
struct iter_env* ie)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ index aae934dd..55c55de0 100644
|
||||
int del_addi = 0; /* if additional-holding rrsets are deleted, we
|
||||
do not trust the normalized additional-A-AAAA any more */
|
||||
struct rrset_parse* rrset, *prev;
|
||||
@@ -721,6 +748,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
@@ -733,6 +760,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ index aae934dd..55c55de0 100644
|
||||
/* At this point, we brutally remove ALL rrsets that aren't
|
||||
* children of the originating zone. The idea here is that,
|
||||
* as far as we know, the server that we contacted is ONLY
|
||||
@@ -732,6 +766,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
@@ -744,6 +778,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset = msg->rrset_first;
|
||||
while(rrset) {
|
||||
|
||||
@@ -101,22 +101,22 @@ index aae934dd..55c55de0 100644
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
|
||||
index 7bc67da6..e10f547a 100644
|
||||
index 2482a1f..bd5ba24 100644
|
||||
--- a/iterator/iter_utils.c
|
||||
+++ b/iterator/iter_utils.c
|
||||
@@ -175,6 +175,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
}
|
||||
@@ -177,6 +177,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
|
||||
+ iter_env->aaaa_filter = cfg->aaaa_filter;
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 23b07ea9..ca29b48c 100644
|
||||
index 48238a2..34ba249 100644
|
||||
--- a/iterator/iterator.c
|
||||
+++ b/iterator/iterator.c
|
||||
@@ -2127,6 +2127,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
@@ -2184,6 +2184,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
|
||||
/**
|
||||
* This is the request event state where the request will be sent to one of
|
||||
@@ -2186,6 +2233,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -2243,6 +2290,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
if(!iq->dp) {
|
||||
@@ -3574,6 +3628,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -3688,6 +3742,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
/*
|
||||
* Return priming query results to interested super querystates.
|
||||
*
|
||||
@@ -3593,6 +3702,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
|
||||
@@ -3707,6 +3816,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
|
||||
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
|
||||
super->minfo[id])->state == DSNS_FIND_STATE)
|
||||
processDSNSResponse(qstate, id, super);
|
||||
@@ -256,7 +256,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
|
||||
error_supers(qstate, id, super);
|
||||
else if(qstate->is_priming)
|
||||
@@ -3630,6 +3742,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -3744,6 +3856,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
case INIT_REQUEST_3_STATE:
|
||||
cont = processInitRequest3(qstate, iq, id);
|
||||
break;
|
||||
@@ -266,7 +266,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
case QUERYTARGETS_STATE:
|
||||
cont = processQueryTargets(qstate, iq, ie, id);
|
||||
break;
|
||||
@@ -3961,6 +4076,8 @@ iter_state_to_string(enum iter_state state)
|
||||
@@ -4080,6 +4195,8 @@ iter_state_to_string(enum iter_state state)
|
||||
return "INIT REQUEST STATE (stage 2)";
|
||||
case INIT_REQUEST_3_STATE:
|
||||
return "INIT REQUEST STATE (stage 3)";
|
||||
@@ -275,7 +275,7 @@ index 23b07ea9..ca29b48c 100644
|
||||
case QUERYTARGETS_STATE :
|
||||
return "QUERY TARGETS STATE";
|
||||
case PRIME_RESP_STATE :
|
||||
@@ -3985,6 +4102,7 @@ iter_state_is_responsestate(enum iter_state s)
|
||||
@@ -4104,6 +4221,7 @@ iter_state_is_responsestate(enum iter_state s)
|
||||
case INIT_REQUEST_STATE :
|
||||
case INIT_REQUEST_2_STATE :
|
||||
case INIT_REQUEST_3_STATE :
|
||||
@@ -284,10 +284,10 @@ index 23b07ea9..ca29b48c 100644
|
||||
case COLLECT_CLASS_STATE :
|
||||
return 0;
|
||||
diff --git a/iterator/iterator.h b/iterator/iterator.h
|
||||
index 342ac207..731948d1 100644
|
||||
index a9e5856..ace68c6 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -135,6 +135,9 @@ struct iter_env {
|
||||
@@ -133,6 +133,9 @@ struct iter_env {
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
|
||||
@@ -297,11 +297,10 @@ index 342ac207..731948d1 100644
|
||||
/** lock on ratelimit counter */
|
||||
lock_basic_type queries_ratelimit_lock;
|
||||
/** number of queries that have been ratelimited */
|
||||
@@ -186,6 +189,14 @@ enum iter_state {
|
||||
*/
|
||||
@@ -188,6 +191,14 @@ enum iter_state {
|
||||
INIT_REQUEST_3_STATE,
|
||||
|
||||
+ /**
|
||||
/**
|
||||
+ * This state is responsible for intercepting AAAA queries,
|
||||
+ * and launch a A subquery on the same target, to populate the
|
||||
+ * cache with A records, so the AAAA filter scrubbing logic can
|
||||
@@ -309,10 +308,11 @@ index 342ac207..731948d1 100644
|
||||
+ */
|
||||
+ ASN_FETCH_A_FOR_AAAA_STATE,
|
||||
+
|
||||
/**
|
||||
+ /**
|
||||
* Each time a delegation point changes for a given query or a
|
||||
* query times out and/or wakes up, this state is (re)visited.
|
||||
@@ -375,6 +386,13 @@ struct iter_qstate {
|
||||
* This state is responsible for iterating through a list of
|
||||
@@ -376,6 +387,13 @@ struct iter_qstate {
|
||||
*/
|
||||
int refetch_glue;
|
||||
|
||||
@@ -327,10 +327,10 @@ index 342ac207..731948d1 100644
|
||||
struct outbound_list outlist;
|
||||
|
||||
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
|
||||
index f08b575d..47f1bb2e 100644
|
||||
index 03483ab..a8c30b5 100644
|
||||
--- a/pythonmod/interface.i
|
||||
+++ b/pythonmod/interface.i
|
||||
@@ -975,6 +975,7 @@ struct config_file {
|
||||
@@ -994,6 +994,7 @@ struct config_file {
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
@@ -339,10 +339,10 @@ index f08b575d..47f1bb2e 100644
|
||||
struct config_strlist* private_domain;
|
||||
size_t unwanted_threshold;
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 0ab8614a..729fb147 100644
|
||||
index 39050f5..326b0b9 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -218,6 +218,7 @@ config_create(void)
|
||||
@@ -231,6 +231,7 @@ config_create(void)
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->harden_algo_downgrade = 0;
|
||||
cfg->use_caps_bits_for_id = 0;
|
||||
@@ -351,10 +351,10 @@ index 0ab8614a..729fb147 100644
|
||||
cfg->private_address = NULL;
|
||||
cfg->private_domain = NULL;
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index e61257a3..dabaa7bb 100644
|
||||
index 18910be..bd59144 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -260,6 +260,8 @@ struct config_file {
|
||||
@@ -285,6 +285,8 @@ struct config_file {
|
||||
int harden_algo_downgrade;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
@@ -364,38 +364,38 @@ index e61257a3..dabaa7bb 100644
|
||||
struct config_strlist* caps_whitelist;
|
||||
/** strip away these private addrs from answers, no DNS Rebinding */
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index 79a0edca..4eaec678 100644
|
||||
index 71da924..b58b4b6 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -304,6 +304,7 @@ harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
|
||||
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
@@ -317,6 +317,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
|
||||
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
|
||||
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
|
||||
+aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) }
|
||||
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
|
||||
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
|
||||
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index 1d0e8658..f284dd43 100644
|
||||
index 1daf853..cd39618 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
||||
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
|
||||
+%token VAR_AAAA_FILTER
|
||||
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
||||
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||
@@ -233,6 +234,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
@@ -245,6 +246,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
||||
server_harden_referral_path | server_private_address |
|
||||
server_private_domain | server_extended_statistics |
|
||||
server_private_domain | server_extended_statistics |
|
||||
+ server_aaaa_filter |
|
||||
server_local_data_ptr | server_jostle_timeout |
|
||||
server_unwanted_reply_threshold | server_log_time_ascii |
|
||||
server_domain_insecure | server_val_sig_skew_min |
|
||||
@@ -1563,6 +1565,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
|
||||
server_local_data_ptr | server_jostle_timeout |
|
||||
server_unwanted_reply_threshold | server_log_time_ascii |
|
||||
server_domain_insecure | server_val_sig_skew_min |
|
||||
@@ -1742,6 +1744,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
|
||||
+121
-1
@@ -300,6 +300,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
*/
|
||||
if(fd != -1) {
|
||||
#ifdef HAVE_CHOWN
|
||||
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
|
||||
if (cfg->username && cfg->username[0] &&
|
||||
cfg_uid != (uid_t)-1) {
|
||||
if(chown(ip, cfg_uid, cfg_gid) == -1)
|
||||
@@ -307,7 +308,6 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
ip, strerror(errno));
|
||||
}
|
||||
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
|
||||
#else
|
||||
(void)cfg;
|
||||
#endif
|
||||
@@ -1285,6 +1285,62 @@ do_zone_remove(RES* ssl, struct local_zones* zones, char* arg)
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Enable or disable EDE (RFC 8914) responses in this local-zone */
|
||||
static int
|
||||
do_zone_enable_disable_ede(RES* ssl, struct local_zones* zones, char* arg,
|
||||
int enable)
|
||||
{
|
||||
uint8_t* name;
|
||||
int namelabels;
|
||||
size_t namelen;
|
||||
struct local_zone* z;
|
||||
|
||||
if(!parse_arg_name(ssl, arg, &name, &namelen, &namelabels)) {
|
||||
free(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
|
||||
if(!(z=local_zones_find(zones, name, namelen,
|
||||
namelabels, LDNS_RR_CLASS_IN))) {
|
||||
ssl_printf(ssl, "local-zone: %s not found\n", arg);
|
||||
free(name);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
}
|
||||
/* found local-zone in tree */
|
||||
lock_rw_wrlock(&z->lock);
|
||||
if (enable) {
|
||||
z->do_ede = 1;
|
||||
}
|
||||
else
|
||||
z->do_ede = 0;
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
||||
free(name);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Perform the do_zone_enable_ede command */
|
||||
static void
|
||||
do_zone_enable_ede(RES* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!(do_zone_enable_disable_ede(ssl, zones, arg, 1)))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Perform the do_zone_disable_ede command */
|
||||
static void
|
||||
do_zone_disable_ede(RES* ssl, struct local_zones* zones, char* arg)
|
||||
{
|
||||
if(!(do_zone_enable_disable_ede(ssl, zones, arg, 0)))
|
||||
return;
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Do the local_zones_remove command */
|
||||
static void
|
||||
do_zones_remove(RES* ssl, struct local_zones* zones)
|
||||
@@ -2992,6 +3048,60 @@ do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
|
||||
do_rpz_enable_disable(ssl, worker, arg, 0);
|
||||
}
|
||||
|
||||
/** enable/disable EDE (RFC 8914) responses this zone */
|
||||
static void
|
||||
do_rpz_do_ede_enable_disable(RES* ssl, struct worker* worker, char* arg, int enable) {
|
||||
size_t namelen;
|
||||
int namelabels;
|
||||
uint8_t *name = NULL;
|
||||
struct auth_zones *az = worker->env.auth_zones;
|
||||
struct auth_zone *z = NULL;
|
||||
if (!parse_arg_name(ssl, arg, &name, &namelen, &namelabels))
|
||||
return;
|
||||
|
||||
(void)ssl_printf(ssl, "NAME: %s", name);
|
||||
|
||||
if (az) {
|
||||
lock_rw_rdlock(&az->lock);
|
||||
z = auth_zone_find(az, name, namelen, LDNS_RR_CLASS_IN);
|
||||
if (z) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
}
|
||||
free(name);
|
||||
if (!z) {
|
||||
(void) ssl_printf(ssl, "error no auth-zone %s\n", arg);
|
||||
return;
|
||||
}
|
||||
if (!z->rpz) {
|
||||
(void) ssl_printf(ssl, "error auth-zone %s not RPZ\n", arg);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return;
|
||||
}
|
||||
if (enable) {
|
||||
rpz_do_ede_enable(z->rpz);
|
||||
} else {
|
||||
rpz_do_ede_disable(z->rpz);
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** do the rpz_enable command */
|
||||
static void
|
||||
do_rpz_do_ede_enable(RES* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
do_rpz_enable_disable(ssl, worker, arg, 1);
|
||||
}
|
||||
|
||||
/** do the rpz_disable command */
|
||||
static void
|
||||
do_rpz_do_ede_disable(RES* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
do_rpz_do_ede_enable_disable(ssl, worker, arg, 0);
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
static void
|
||||
distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd)
|
||||
@@ -3154,6 +3264,12 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
do_data_remove(ssl, worker->daemon->local_zones, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "local_datas_remove", 18)) {
|
||||
do_datas_remove(ssl, worker->daemon->local_zones);
|
||||
|
||||
} else if(cmdcmp(p, "local_zone_do_ede_enable", 24)) {
|
||||
do_zone_enable_ede(ssl, worker->daemon->local_zones, skipwhite(p+24));
|
||||
} else if(cmdcmp(p, "local_zone_do_ede_disable", 25)) {
|
||||
do_zone_disable_ede(ssl, worker->daemon->local_zones, skipwhite(p+25));
|
||||
|
||||
} else if(cmdcmp(p, "local_data", 10)) {
|
||||
do_data_add(ssl, worker->daemon->local_zones, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "local_datas", 11)) {
|
||||
@@ -3196,6 +3312,10 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
do_rpz_enable(ssl, worker, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "rpz_disable", 11)) {
|
||||
do_rpz_disable(ssl, worker, skipwhite(p+11));
|
||||
} else if(cmdcmp(p, "rpz_do_ede_enable", 17)) {
|
||||
do_rpz_do_ede_enable(ssl, worker, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "rpz_do_ede_disable", 18)) {
|
||||
do_rpz_do_ede_disable(ssl, worker, skipwhite(p+18));
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
}
|
||||
|
||||
+142
-5
@@ -484,6 +484,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
return 0;
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
if(worker->stats.extended) {
|
||||
@@ -499,6 +501,9 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
secure = 1;
|
||||
break;
|
||||
case sec_status_indeterminate:
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_DNSSEC_INDETERMINATE, "");
|
||||
/* fallthrough */
|
||||
case sec_status_insecure:
|
||||
default:
|
||||
/* not secure */
|
||||
@@ -654,6 +659,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
|
||||
worker->env.now_tv))
|
||||
goto bail_out;
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
@@ -1020,6 +1027,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
} else if(acl == refuse) {
|
||||
size_t opt_rr_mark;
|
||||
|
||||
log_addr(VERB_ALGO, "refused query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||
@@ -1029,15 +1038,124 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0; /* discard this */
|
||||
}
|
||||
sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
log_assert(LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
|
||||
|
||||
sldns_buffer_skip(c->buffer, LDNS_HEADER_SIZE); /* skip header */
|
||||
|
||||
if (!query_dname_len(c->buffer)) {
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
|
||||
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
|
||||
|
||||
/* check the qclass */
|
||||
if (sldns_buffer_read_u16(c->buffer) != LDNS_RR_CLASS_IN) {
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* check edns section is present */
|
||||
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1) {
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The OPT RR to be returned should come directly after
|
||||
* the query, so mark this spot.
|
||||
*/
|
||||
opt_rr_mark = sldns_buffer_position(c->buffer);
|
||||
|
||||
/* Skip through the RR records */
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
|
||||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
|
||||
if(!skip_pkt_rrs(c->buffer,
|
||||
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
|
||||
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Do we have a valid OPT RR here? If not return FORMERR */
|
||||
/* domain name must be the root of length 1. */
|
||||
if(pkt_dname_len(c->buffer) != 1) {
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
return 1;
|
||||
}
|
||||
if(sldns_buffer_remaining(c->buffer) < 2 ||
|
||||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
/* Write OPT RR directly after the query,
|
||||
* so without the (possibly skipped) Answer and NS RRs
|
||||
*/
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
|
||||
/* Check if OPT record can be written
|
||||
* 17 == root label (1) + RR type (2) + UDP Size (2)
|
||||
* + Fields (4) + rdata len (2) + EDE Option code (2)
|
||||
* + EDE Option length (2) + EDE info-code (2)
|
||||
*/
|
||||
if (sldns_buffer_available(c->buffer, 17) == 0) {
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
|
||||
|
||||
/* root label */
|
||||
sldns_buffer_write_u8(c->buffer, 0);
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
|
||||
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
|
||||
|
||||
/* write OPT Record TTL Field */
|
||||
sldns_buffer_write_u32(c->buffer, 0);
|
||||
|
||||
/* write rdata len: EDE option + length + info-code */
|
||||
sldns_buffer_write_u16(c->buffer, 6);
|
||||
|
||||
/* write OPTIONS; add EDE option code */
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
|
||||
|
||||
/* write single EDE option length (for just 1 info-code) */
|
||||
sldns_buffer_write_u16(c->buffer, 2);
|
||||
|
||||
/* write single EDE info-code */
|
||||
sldns_buffer_write_u16(c->buffer, LDNS_EDE_PROHIBITED);
|
||||
|
||||
sldns_buffer_flip(c->buffer);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -1382,12 +1500,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
* ACLs allow the snooping. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
acl != acl_allow_snoop ) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
|
||||
error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
@@ -1460,10 +1581,23 @@ lookup_cache:
|
||||
< *worker->env.now)
|
||||
leeway = 0;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
// @TODO test this
|
||||
// // stale answer?
|
||||
// if (worker->env.cfg->serve_expired &&
|
||||
// *worker->env.now >= ((struct reply_info*)e->data)->ttl) {
|
||||
// EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
|
||||
// worker->scratchpad, LDNS_EDE_STALE_ANSWER, "");
|
||||
// }
|
||||
|
||||
// add EDNS struct?
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway,
|
||||
(partial_rep || need_drop));
|
||||
|
||||
|
||||
|
||||
if(!partial_rep) {
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
@@ -1500,6 +1634,9 @@ lookup_cache:
|
||||
verbose(VERB_ALGO, "answer from the cache failed");
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
// @TODO Extended DNS Error Code 13 - Cached Error? place not clear
|
||||
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
if(answer_norec_from_cache(worker, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
|
||||
@@ -1,5 +1,66 @@
|
||||
7 January 2022: Wouter
|
||||
- Merge #600 from pemensik: Change file mode before changing file
|
||||
owner.
|
||||
|
||||
5 January 2022: Wouter
|
||||
- Fix for #596: fix that rpz return message is returned and not just
|
||||
the rcode from the iterator return path. This fixes signal unset RA
|
||||
after a CNAME.
|
||||
- Fix unit tests for rpz now that the AA flag returns successfully from
|
||||
the iterator loop.
|
||||
- Fix for #596: add unit test for nsdname trigger and signal unset RA.
|
||||
- Fix for #596: add unit test for nsip trigger and signal unset RA.
|
||||
- Fix #598: Fix unbound-checkconf fatal error: module conf
|
||||
'respip dns64 validator iterator' is not known to work.
|
||||
- Fix for #596: Fix rpz-signal-nxdomain-ra to work for clientip
|
||||
triggered operation.
|
||||
|
||||
4 January 2022: Wouter
|
||||
- Fix #596: unset the RA bit when a query is blocked by an unbound
|
||||
RPZ nxdomain reply. The option rpz-signal-nxdomain-ra allows to
|
||||
signal that a domain is externally blocked to clients when it
|
||||
is blocked with NXDOMAIN by unsetting RA.
|
||||
- Fix to add test for rpz-signal-nxdomain-ra.
|
||||
- Fix #596: only unset RA when NXDOMAIN is signalled.
|
||||
- Fix that RPZ does not set RD flag on replies, it should be copied
|
||||
from the query.
|
||||
|
||||
22 December 2021: George
|
||||
- contrib/aaaa-filter-iterator.patch file renewed diff content to
|
||||
apply cleanly to the current coderepo for the current code version.
|
||||
|
||||
20 December 2021: George
|
||||
- Fix #591: Unbound-anchor manpage links to non-existent license file.
|
||||
|
||||
13 December 2021: George
|
||||
- Add missing configure flags for optional features in the
|
||||
documentation.
|
||||
- Fix Unbound capitalization in the documentation.
|
||||
|
||||
13 December 2021: Wouter
|
||||
- Fix to pick up other class local zone information before unlock.
|
||||
|
||||
10 December 2021: George
|
||||
- Allow local-data for classes other than IN to inherit a configured
|
||||
local-zone's type if possible, instead of defaulting to type
|
||||
transparent as per the implicit rule.
|
||||
|
||||
10 December 2021: Wouter
|
||||
- Add code similar to fix for ldns for tab between strings, for
|
||||
consistency, the test case was not broken.
|
||||
|
||||
6 December 2021: Wouter
|
||||
- Merge PR #581 from fobser: Fix -Wmissing-prototypes and -Wshadow
|
||||
warnings in rpz.
|
||||
- Fix validator debug output about DS support, print correct algorithm.
|
||||
|
||||
3 December 2021: Wouter
|
||||
- Fix compile warning for if_nametoindex on windows 64bit.
|
||||
|
||||
1 December 2021: Wouter
|
||||
- configure is set to 1.14.0, and release branch.
|
||||
This was released as version 1.14.0 on 9 Dec 2021, with the doxygen
|
||||
fix below included. The main branch continues as 1.14.1.
|
||||
- Fix doc/unbound.doxygen to remove obsolete tag warning.
|
||||
|
||||
1 December 2021: George
|
||||
|
||||
+29
-21
@@ -82,13 +82,13 @@ server:
|
||||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
# outgoing-range: 4096
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# permit Unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# deny unbound the use this of port number or port range for
|
||||
# deny Unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# Use this to make sure Unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# If multiple outgoing-port-permit and outgoing-port-avoid options
|
||||
@@ -254,7 +254,7 @@ server:
|
||||
# use-systemd: no
|
||||
|
||||
# Detach from the terminal, run in background, "yes" or "no".
|
||||
# Set the value to "no" when unbound runs as systemd service.
|
||||
# Set the value to "no" when Unbound runs as systemd service.
|
||||
# do-daemonize: yes
|
||||
|
||||
# control which clients are allowed to make (recursive) queries
|
||||
@@ -307,7 +307,7 @@ server:
|
||||
# The pid file can be absolute and outside of the chroot, it is
|
||||
# written just prior to performing the chroot and dropping permissions.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/urandom (for entropy).
|
||||
# Additionally, Unbound may need to access /dev/urandom (for entropy).
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
@@ -517,7 +517,7 @@ server:
|
||||
# Use several entries, one per domain name, to track multiple zones.
|
||||
#
|
||||
# If you want to perform DNSSEC validation, run unbound-anchor before
|
||||
# you start unbound (i.e. in the system boot scripts).
|
||||
# you start Unbound (i.e. in the system boot scripts).
|
||||
# And then enable the auto-trust-anchor-file config item.
|
||||
# Please note usage of unbound-anchor root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see that file in the source).
|
||||
@@ -585,7 +585,7 @@ server:
|
||||
# val-permissive-mode: no
|
||||
|
||||
# Ignore the CD flag in incoming queries and refuse them bogus data.
|
||||
# Enable it if the only clients of unbound are legacy servers (w2008)
|
||||
# Enable it if the only clients of Unbound are legacy servers (w2008)
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: no
|
||||
|
||||
@@ -615,7 +615,7 @@ server:
|
||||
|
||||
# Return the original TTL as received from the upstream name server rather
|
||||
# than the decrementing TTL as stored in the cache. Enabling this feature
|
||||
# does not impact cache expiry, it only changes the TTL unbound embeds in
|
||||
# does not impact cache expiry, it only changes the TTL Unbound embeds in
|
||||
# responses to queries. Note that enabling this feature implicitly disables
|
||||
# enforcement of the configured minimum and maximum TTL.
|
||||
# serve-original-ttl: no
|
||||
@@ -709,9 +709,9 @@ server:
|
||||
# Add example.com into ipset
|
||||
# local-zone: "example.com" ipset
|
||||
|
||||
# If unbound is running service for the local host then it is useful
|
||||
# If Unbound is running service for the local host then it is useful
|
||||
# to perform lan-wide lookups to the upstream, and unblock the
|
||||
# long list of local-zones above. If this unbound is a dns server
|
||||
# long list of local-zones above. If this Unbound is a dns server
|
||||
# for a network of computers, disabled is better and stops information
|
||||
# leakage of local lan information.
|
||||
# unblock-lan-zones: no
|
||||
@@ -889,7 +889,7 @@ server:
|
||||
# the number of servers that will be used in the fast server selection.
|
||||
# fast-server-num: 3
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# Specific options for ipsecmod. Unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
# Enable or disable ipsecmod (it still needs to be defined in
|
||||
@@ -901,7 +901,7 @@ server:
|
||||
# listed in module-config (above).
|
||||
# ipsecmod-hook: "./my_executable"
|
||||
#
|
||||
# When enabled unbound will reply with SERVFAIL if the return value of
|
||||
# When enabled Unbound will reply with SERVFAIL if the return value of
|
||||
# the ipsecmod-hook is not 0.
|
||||
# ipsecmod-strict: no
|
||||
#
|
||||
@@ -966,10 +966,10 @@ remote-control:
|
||||
# For local sockets this option is ignored, and TLS is not used.
|
||||
# control-use-cert: "yes"
|
||||
|
||||
# unbound server key file.
|
||||
# Unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
# unbound server certificate file.
|
||||
# Unbound server certificate file.
|
||||
# server-cert-file: "@UNBOUND_RUN_DIR@/unbound_server.pem"
|
||||
|
||||
# unbound-control key file.
|
||||
@@ -1072,8 +1072,9 @@ remote-control:
|
||||
# local-zone: "example.com" refuse
|
||||
|
||||
# DNSCrypt
|
||||
# To enable, use --enable-dnscrypt to configure before compiling.
|
||||
# Caveats:
|
||||
# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper
|
||||
# 1. the keys/certs cannot be produced by Unbound. You can use dnscrypt-wrapper
|
||||
# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
|
||||
# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to
|
||||
# listen on `dnscrypt-port` with the follo0wing snippet:
|
||||
@@ -1092,7 +1093,9 @@ remote-control:
|
||||
# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert
|
||||
|
||||
# CacheDB
|
||||
# Enable external backend DB as auxiliary cache. Specify the backend name
|
||||
# External backend DB as auxiliary cache.
|
||||
# To enable, use --enable-cachedb to configure before compiling.
|
||||
# Specify the backend name
|
||||
# (default is "testframe", which has no use other than for debugging and
|
||||
# testing) and backend-specific options. The 'cachedb' module must be
|
||||
# included in module-config, just before the iterator module.
|
||||
@@ -1102,6 +1105,7 @@ remote-control:
|
||||
# secret-seed: "default"
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # (to enable, use --with-libhiredis to configure before compiling)
|
||||
# # redis server's IP address or host name
|
||||
# redis-server-host: 127.0.0.1
|
||||
# # redis server's TCP port
|
||||
@@ -1113,7 +1117,9 @@ remote-control:
|
||||
|
||||
# IPSet
|
||||
# Add specify domain into set via ipset.
|
||||
# Note: To enable ipset unbound needs to run as root user.
|
||||
# To enable:
|
||||
# o use --enable-ipset to configure before compiling;
|
||||
# o Unbound then needs to run as root user.
|
||||
# ipset:
|
||||
# # set name for ip v4 addresses
|
||||
# name-v4: "list-v4"
|
||||
@@ -1121,9 +1127,10 @@ remote-control:
|
||||
# name-v6: "list-v6"
|
||||
#
|
||||
|
||||
# Dnstap logging support, if compiled in. To enable, set the dnstap-enable
|
||||
# to yes and also some of dnstap-log-..-messages to yes. And select an
|
||||
# upstream log destination, by socket path, TCP or TLS destination.
|
||||
# Dnstap logging support, if compiled in by using --enable-dnstap to configure.
|
||||
# To enable, set the dnstap-enable to yes and also some of
|
||||
# dnstap-log-..-messages to yes. And select an upstream log destination, by
|
||||
# socket path, TCP or TLS destination.
|
||||
# dnstap:
|
||||
# dnstap-enable: no
|
||||
# # if set to yes frame streams will be used in bidirectional mode
|
||||
@@ -1136,7 +1143,7 @@ remote-control:
|
||||
# dnstap-tls: yes
|
||||
# # name for authenticating the upstream server. or "" disabled.
|
||||
# dnstap-tls-server-name: ""
|
||||
# # if "", it uses the cert bundle from the main unbound config.
|
||||
# # if "", it uses the cert bundle from the main Unbound config.
|
||||
# dnstap-tls-cert-bundle: ""
|
||||
# # key file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-key-file: ""
|
||||
@@ -1172,4 +1179,5 @@ remote-control:
|
||||
# rpz-cname-override: www.example.org
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "example policy"
|
||||
# rpz-signal-nxdomain-ra: no
|
||||
# tags: "example"
|
||||
|
||||
@@ -41,7 +41,7 @@ update certificate files.
|
||||
.P
|
||||
It tests if the root anchor file works, and if not, and an update is possible,
|
||||
attempts to update the root anchor using the root update certificate.
|
||||
It performs a https fetch of root-anchors.xml and checks the results (RFC7958),
|
||||
It performs a https fetch of root-anchors.xml and checks the results (RFC7958),
|
||||
if all checks are successful, it updates the root anchor file. Otherwise
|
||||
the root anchor file is unchanged. It performs RFC5011 tracking if the
|
||||
DNSSEC information available via the DNS makes that possible.
|
||||
@@ -159,7 +159,7 @@ Or something more suitable for your operational environment.
|
||||
The root keys and update certificate included in this tool
|
||||
are provided for convenience and under the terms of our
|
||||
license (see the LICENSE file in the source distribution or
|
||||
http://unbound.nlnetlabs.nl/svn/trunk/LICENSE) and might be stale or
|
||||
https://github.com/NLnetLabs/unbound/blob/master/LICENSE) and might be stale or
|
||||
not suitable to your purpose.
|
||||
.P
|
||||
By running "unbound\-anchor \-l" the keys and certificate that are
|
||||
@@ -185,5 +185,5 @@ Source for the root key information.
|
||||
.I https://data.iana.org/root\-anchors/root\-anchors.p7s
|
||||
Signature on the root key information.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
unbound\-checkconf
|
||||
\- Check unbound configuration file for errors.
|
||||
\- Check Unbound configuration file for errors.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-checkconf
|
||||
.RB [ \-h ]
|
||||
@@ -21,8 +21,8 @@ unbound\-checkconf
|
||||
.B Unbound\-checkconf
|
||||
checks the configuration file for the
|
||||
\fIunbound\fR(8)
|
||||
DNS resolver for syntax and other errors.
|
||||
The config file syntax is described in
|
||||
DNS resolver for syntax and other errors.
|
||||
The config file syntax is described in
|
||||
\fIunbound.conf\fR(5).
|
||||
.P
|
||||
The available options are:
|
||||
@@ -34,19 +34,19 @@ Show the version and commandline option help.
|
||||
Print full pathname, with chroot applied to it. Use with the \-o option.
|
||||
.TP
|
||||
.B \-o\fI option
|
||||
If given, after checking the config file the value of this option is
|
||||
If given, after checking the config file the value of this option is
|
||||
printed to stdout. For "" (disabled) options an empty line is printed.
|
||||
.TP
|
||||
.I cfgfile
|
||||
The config file to read with settings for unbound. It is checked.
|
||||
The config file to read with settings for Unbound. It is checked.
|
||||
If omitted, the config file at the default location is checked.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-checkconf program exits with status code 1 on error,
|
||||
The unbound\-checkconf program exits with status code 1 on error,
|
||||
0 for a correct config file.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
unbound configuration file.
|
||||
Unbound configuration file.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
+39
-39
@@ -14,15 +14,15 @@
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-control
|
||||
.RB [ \-hq ]
|
||||
.RB [ \-c
|
||||
.RB [ \-c
|
||||
.IR cfgfile ]
|
||||
.RB [ \-s
|
||||
.RB [ \-s
|
||||
.IR server ]
|
||||
.IR command
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-control
|
||||
performs remote administration on the \fIunbound\fR(8) DNS server.
|
||||
It reads the configuration file, contacts the unbound server over SSL
|
||||
It reads the configuration file, contacts the Unbound server over SSL
|
||||
sends the command and displays the result.
|
||||
.P
|
||||
The available options are:
|
||||
@@ -44,8 +44,8 @@ quiet, if the option is given it does not print anything if it works ok.
|
||||
There are several commands that the server understands.
|
||||
.TP
|
||||
.B start
|
||||
Start the server. Simply execs \fIunbound\fR(8). The unbound executable
|
||||
is searched for in the \fBPATH\fR set in the environment. It is started
|
||||
Start the server. Simply execs \fIunbound\fR(8). The Unbound executable
|
||||
is searched for in the \fBPATH\fR set in the environment. It is started
|
||||
with the config file specified using \fI\-c\fR or the default config file.
|
||||
.TP
|
||||
.B stop
|
||||
@@ -65,8 +65,8 @@ daemon release the file it is logging to. If you are using syslog it will
|
||||
attempt to close and open the syslog (which may not work if chrooted).
|
||||
.TP
|
||||
.B stats
|
||||
Print statistics. Resets the internal counters to zero, this can be
|
||||
controlled using the \fBstatistics\-cumulative\fR config statement.
|
||||
Print statistics. Resets the internal counters to zero, this can be
|
||||
controlled using the \fBstatistics\-cumulative\fR config statement.
|
||||
Statistics are printed with one [name]: [value] per line.
|
||||
.TP
|
||||
.B stats_noreset
|
||||
@@ -74,7 +74,7 @@ Peek at statistics. Prints them like the \fBstats\fR command does, but does not
|
||||
reset the internal counters to zero.
|
||||
.TP
|
||||
.B status
|
||||
Display server status. Exit code 3 if not running (the connection to the
|
||||
Display server status. Exit code 3 if not running (the connection to the
|
||||
port is refused), 1 on error, 0 if running.
|
||||
.TP
|
||||
.B local_zone \fIname\fR \fItype
|
||||
@@ -88,14 +88,14 @@ it. If the zone does not exist, the command succeeds.
|
||||
.B local_data \fIRR data...
|
||||
Add new local data, the given resource record. Like \fBlocal\-data\fR
|
||||
config statement, except for when no covering zone exists. In that case
|
||||
this remote control command creates a transparent zone with the same
|
||||
this remote control command creates a transparent zone with the same
|
||||
name as this record.
|
||||
.TP
|
||||
.B local_data_remove \fIname
|
||||
Remove all RR data from local name. If the name already has no items,
|
||||
nothing happens. Often results in NXDOMAIN for the name (in a static zone),
|
||||
but if the name has become an empty nonterminal (there is still data in
|
||||
domain names below the removed name), NOERROR nodata answers are the
|
||||
but if the name has become an empty nonterminal (there is still data in
|
||||
domain names below the removed name), NOERROR nodata answers are the
|
||||
result for that name.
|
||||
.TP
|
||||
.B local_zones
|
||||
@@ -125,22 +125,22 @@ in old or wrong data returned to clients. Loading data into the cache
|
||||
in this way is supported in order to aid with debugging.
|
||||
.TP
|
||||
.B lookup \fIname
|
||||
Print to stdout the name servers that would be used to look up the
|
||||
Print to stdout the name servers that would be used to look up the
|
||||
name specified.
|
||||
.TP
|
||||
.B flush \fIname
|
||||
Remove the name from the cache. Removes the types
|
||||
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV and NAPTR.
|
||||
Because that is fast to do. Other record types can be removed using
|
||||
.B flush_type
|
||||
or
|
||||
Because that is fast to do. Other record types can be removed using
|
||||
.B flush_type
|
||||
or
|
||||
.B flush_zone\fR.
|
||||
.TP
|
||||
.B flush_type \fIname\fR \fItype
|
||||
Remove the name, type information from the cache.
|
||||
.TP
|
||||
.B flush_zone \fIname
|
||||
Remove all information at or below the name from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
The entries are set to expired in the implementation of this command (so,
|
||||
@@ -187,7 +187,7 @@ therefore not flushed. The option must end with a ':' and whitespace
|
||||
must be between the option and the value. Some values may not have an
|
||||
effect if set this way, the new values are not written to the config file,
|
||||
not all options are supported. This is different from the set_option call
|
||||
in libunbound, where all values work because unbound has not been initialized.
|
||||
in libunbound, where all values work because Unbound has not been initialized.
|
||||
.IP
|
||||
The values that work are: statistics\-interval, statistics\-cumulative,
|
||||
do\-not\-query\-localhost, harden\-short\-bufsize, harden\-large\-queries,
|
||||
@@ -227,36 +227,36 @@ List the local data RRs in use. The resource records are printed.
|
||||
.TP
|
||||
.B insecure_add \fIzone
|
||||
Add a \fBdomain\-insecure\fR for the given zone, like the statement in unbound.conf.
|
||||
Adds to the running unbound without affecting the cache contents (which may
|
||||
Adds to the running Unbound without affecting the cache contents (which may
|
||||
still be bogus, use \fBflush_zone\fR to remove it), does not affect the config file.
|
||||
.TP
|
||||
.B insecure_remove \fIzone
|
||||
Removes domain\-insecure for the given zone.
|
||||
.TP
|
||||
.B forward_add \fR[\fI+i\fR] \fIzone addr ...
|
||||
Add a new forward zone to running unbound. With +i option also adds a
|
||||
Add a new forward zone to running Unbound. With +i option also adds a
|
||||
\fIdomain\-insecure\fR for the zone (so it can resolve insecurely if you have
|
||||
a DNSSEC root trust anchor configured for other names).
|
||||
The addr can be IP4, IP6 or nameserver names, like \fIforward-zone\fR config
|
||||
in unbound.conf.
|
||||
.TP
|
||||
.B forward_remove \fR[\fI+i\fR] \fIzone
|
||||
Remove a forward zone from running unbound. The +i also removes a
|
||||
Remove a forward zone from running Unbound. The +i also removes a
|
||||
\fIdomain\-insecure\fR for the zone.
|
||||
.TP
|
||||
.B stub_add \fR[\fI+ip\fR] \fIzone addr ...
|
||||
Add a new stub zone to running unbound. With +i option also adds a
|
||||
Add a new stub zone to running Unbound. With +i option also adds a
|
||||
\fIdomain\-insecure\fR for the zone. With +p the stub zone is set to prime,
|
||||
without it it is set to notprime. The addr can be IP4, IP6 or nameserver
|
||||
names, like the \fIstub-zone\fR config in unbound.conf.
|
||||
.TP
|
||||
.B stub_remove \fR[\fI+i\fR] \fIzone
|
||||
Remove a stub zone from running unbound. The +i also removes a
|
||||
Remove a stub zone from running Unbound. The +i also removes a
|
||||
\fIdomain\-insecure\fR for the zone.
|
||||
.TP
|
||||
.B forward \fR[\fIoff\fR | \fIaddr ...\fR ]
|
||||
Setup forwarding mode. Configures if the server should ask other upstream
|
||||
nameservers, should go to the internet root nameservers itself, or show
|
||||
nameservers, should go to the internet root nameservers itself, or show
|
||||
the current config. You could pass the nameservers after a DHCP update.
|
||||
.IP
|
||||
Without arguments the current list of addresses used to forward all queries
|
||||
@@ -296,7 +296,7 @@ status, indicating if the zone is expired and current serial number.
|
||||
Reload the auth zone from zonefile. The zonefile is read in overwriting
|
||||
the current contents of the zone in memory. This changes the auth zone
|
||||
contents itself, not the cache contents. Such cache contents exists if
|
||||
you set unbound to validate with for-upstream yes and that can be cleared
|
||||
you set Unbound to validate with for-upstream yes and that can be cleared
|
||||
with \fBflush_zone\fR \fIzone\fR.
|
||||
.TP
|
||||
.B auth_zone_transfer \fIzone\fR
|
||||
@@ -336,7 +336,7 @@ Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
The setup requires a self\-signed certificate and private keys for both
|
||||
The setup requires a self\-signed certificate and private keys for both
|
||||
the server and client. The script \fIunbound\-control\-setup\fR generates
|
||||
these in the default run directory, or with \-d in another directory.
|
||||
If you change the access control permissions on the key files you can decide
|
||||
@@ -350,7 +350,7 @@ If you have not configured
|
||||
a username in unbound.conf, the keys need read permission for the user
|
||||
credentials under which the daemon is started.
|
||||
The script preserves private keys present in the directory.
|
||||
After running the script as root, turn on \fBcontrol\-enable\fR in
|
||||
After running the script as root, turn on \fBcontrol\-enable\fR in
|
||||
\fIunbound.conf\fR.
|
||||
.SH "STATISTIC COUNTERS"
|
||||
The \fIstats\fR command shows a number of statistic counters.
|
||||
@@ -417,8 +417,8 @@ Average time it took to answer queries that needed recursive processing. Note th
|
||||
.TP
|
||||
.I threadX.recursion.time.median
|
||||
The median of the time it took to answer queries that needed recursive
|
||||
processing. The median means that 50% of the user queries were answered in
|
||||
less than this time. Because of big outliers (usually queries to non
|
||||
processing. The median means that 50% of the user queries were answered in
|
||||
less than this time. Because of big outliers (usually queries to non
|
||||
responsive servers), the average can be bigger than the median. This median
|
||||
has been calculated by interpolation from a histogram.
|
||||
.TP
|
||||
@@ -544,32 +544,32 @@ The total number of queries over all threads with query opcode QUERY.
|
||||
Also printed for other opcodes, UPDATE, ...
|
||||
.TP
|
||||
.I num.query.tcp
|
||||
Number of queries that were made using TCP towards the unbound server.
|
||||
Number of queries that were made using TCP towards the Unbound server.
|
||||
.TP
|
||||
.I num.query.tcpout
|
||||
Number of queries that the unbound server made using TCP outgoing towards
|
||||
Number of queries that the Unbound server made using TCP outgoing towards
|
||||
other servers.
|
||||
.TP
|
||||
.I num.query.tls
|
||||
Number of queries that were made using TLS towards the unbound server.
|
||||
Number of queries that were made using TLS towards the Unbound server.
|
||||
These are also counted in num.query.tcp, because TLS uses TCP.
|
||||
.TP
|
||||
.I num.query.tls.resume
|
||||
Number of TLS session resumptions, these are queries over TLS towards
|
||||
the unbound server where the client negotiated a TLS session resumption key.
|
||||
the Unbound server where the client negotiated a TLS session resumption key.
|
||||
.TP
|
||||
.I num.query.https
|
||||
Number of queries that were made using HTTPS towards the unbound server.
|
||||
Number of queries that were made using HTTPS towards the Unbound server.
|
||||
These are also counted in num.query.tcp and num.query.tls, because HTTPS
|
||||
uses TLS and TCP.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the unbound server.
|
||||
Number of queries that were made using IPv6 towards the Unbound server.
|
||||
.TP
|
||||
.I num.query.flags.RD
|
||||
The number of queries that had the RD flag set in the header.
|
||||
Also printed for flags QR, AA, TC, RA, Z, AD, CD.
|
||||
Note that queries with flags QR, AA or TC may have been rejected
|
||||
Note that queries with flags QR, AA or TC may have been rejected
|
||||
because of that.
|
||||
.TP
|
||||
.I num.query.edns.present
|
||||
@@ -603,7 +603,7 @@ These queries are also included in the num.answer.rcode.NOERROR number.
|
||||
Common for AAAA lookups when an A record exists, and no AAAA.
|
||||
.TP
|
||||
.I num.answer.secure
|
||||
Number of answers that were secure. The answer validated correctly.
|
||||
Number of answers that were secure. The answer validated correctly.
|
||||
The AD bit might have been set in some of these answers, where the client
|
||||
signalled (with DO or AD bit in the query) that they were ready to accept
|
||||
the AD bit in the answer.
|
||||
@@ -644,7 +644,7 @@ per delegation point, and their validation status.
|
||||
.I dnscrypt_shared_secret.cache.count
|
||||
The number of items in the shared secret cache. These are precomputed shared
|
||||
secrets for a given client public key/server secret key pair. Shared secrets
|
||||
are CPU intensive and this cache allows unbound to avoid recomputing the
|
||||
are CPU intensive and this cache allows Unbound to avoid recomputing the
|
||||
shared secret when multiple dnscrypt queries are sent from the same client.
|
||||
.TP
|
||||
.I dnscrypt_nonce.cache.count
|
||||
@@ -689,11 +689,11 @@ disabled, and cname\-override.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
unbound configuration file.
|
||||
Unbound configuration file.
|
||||
.TP
|
||||
.I @UNBOUND_RUN_DIR@
|
||||
directory with private keys (unbound_server.key and unbound_control.key) and
|
||||
self\-signed certificates (unbound_server.pem and unbound_control.pem).
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
.RB [ \-C
|
||||
.IR configfile ]
|
||||
.RB [ \-vdhr46D ]
|
||||
.RB [ \-c
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-t
|
||||
.IR type ]
|
||||
@@ -28,12 +28,12 @@
|
||||
.I hostname
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-host
|
||||
uses the unbound validating resolver to query for the hostname and display
|
||||
results. With the \fB\-v\fR option it displays validation
|
||||
uses the Unbound validating resolver to query for the hostname and display
|
||||
results. With the \fB\-v\fR option it displays validation
|
||||
status: secure, insecure, bogus (security failure).
|
||||
.P
|
||||
By default it reads no configuration file whatsoever. It attempts to reach
|
||||
the internet root servers. With \fB\-C\fR an unbound config file and with
|
||||
the internet root servers. With \fB\-C\fR an Unbound config file and with
|
||||
\fB\-r\fR resolv.conf can be read.
|
||||
.P
|
||||
The available options are:
|
||||
@@ -73,7 +73,7 @@ For example \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546
|
||||
.TP
|
||||
.B \-D
|
||||
Enables DNSSEC validation. Reads the root anchor from the default configured
|
||||
root anchor at the default location, \fI@UNBOUND_ROOTKEY_FILE@\fR.
|
||||
root anchor at the default location, \fI@UNBOUND_ROOTKEY_FILE@\fR.
|
||||
.TP
|
||||
.B \-f \fIkeyfile
|
||||
Reads keys from a file. Every line has a DS or DNSKEY record, in the format
|
||||
@@ -110,9 +110,9 @@ $ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325
|
||||
.P
|
||||
$ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" 192.0.2.153
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-host program exits with status code 1 on error,
|
||||
The unbound\-host program exits with status code 1 on error,
|
||||
0 on no error. The data may not be available on exit code 0, exit code 1
|
||||
means the lookup encountered a fatal error.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
|
||||
+2
-2
@@ -57,7 +57,7 @@ The available options are:
|
||||
Show the version number and commandline option help, and exit.
|
||||
.TP
|
||||
.B \-c\fI cfgfile
|
||||
Set the config file with settings for unbound to read instead of reading the
|
||||
Set the config file with settings for Unbound to read instead of reading the
|
||||
file at the default location, @ub_conf_file@. The syntax is
|
||||
described in \fIunbound.conf\fR(5).
|
||||
.TP
|
||||
@@ -70,7 +70,7 @@ or to syslog, but the log messages are printed to stderr all the time.
|
||||
.TP
|
||||
.B \-p
|
||||
Don't use a pidfile. This argument should only be used by supervision
|
||||
systems which can ensure that only one instance of unbound will run
|
||||
systems which can ensure that only one instance of Unbound will run
|
||||
concurrently.
|
||||
.TP
|
||||
.B \-v
|
||||
|
||||
+156
-90
@@ -30,7 +30,7 @@ can be used to check unbound.conf prior to usage.
|
||||
An example config file is shown below. Copy this to /etc/unbound/unbound.conf
|
||||
and start the server with:
|
||||
.P
|
||||
.nf
|
||||
.nfvalidator:val_inform_super
|
||||
$ unbound \-c /etc/unbound/unbound.conf
|
||||
.fi
|
||||
.P
|
||||
@@ -104,7 +104,7 @@ requestlist statistics are printed for every interval (but can be 0).
|
||||
This is because the median calculation requires data to be present.
|
||||
.TP
|
||||
.B statistics\-cumulative: \fI<yes or no>
|
||||
If enabled, statistics are cumulative since starting unbound, without clearing
|
||||
If enabled, statistics are cumulative since starting Unbound, without clearing
|
||||
the statistics counters after logging the statistics. Default is no.
|
||||
.TP
|
||||
.B extended\-statistics: \fI<yes or no>
|
||||
@@ -136,7 +136,7 @@ Same as interface: (for ease of compatibility with nsd.conf).
|
||||
Listen on all addresses on all (current and future) interfaces, detect the
|
||||
source interface on UDP queries and copy them to replies. This is a lot like
|
||||
ip\-transparent, but this option services all interfaces whilst with
|
||||
ip\-transparent you can select which (future) interfaces unbound provides
|
||||
ip\-transparent you can select which (future) interfaces Unbound provides
|
||||
service on. This feature is experimental, and needs support in your OS for
|
||||
particular socket options. Default value is no.
|
||||
.TP
|
||||
@@ -154,7 +154,7 @@ sent via a random outgoing interface to counter spoofing.
|
||||
If an IPv6 netblock is specified instead of an individual IPv6 address,
|
||||
outgoing UDP queries will use a randomised source address taken from the
|
||||
netblock to counter spoofing. Requires the IPv6 netblock to be routed to the
|
||||
host running unbound, and requires OS support for unprivileged non-local binds
|
||||
host running Unbound, and requires OS support for unprivileged non-local binds
|
||||
(currently only supported on Linux). Several netblocks may be specified with
|
||||
multiple
|
||||
.B outgoing\-interface:
|
||||
@@ -174,7 +174,7 @@ numbers need extra resources from the operating system. For performance a
|
||||
very large value is best, use libevent to make this possible.
|
||||
.TP
|
||||
.B outgoing\-port\-permit: \fI<port number or range>
|
||||
Permit unbound to open this port or range of ports for use to send queries.
|
||||
Permit Unbound to open this port or range of ports for use to send queries.
|
||||
A larger number of permitted outgoing ports increases resilience against
|
||||
spoofing attempts. Make sure these ports are not needed by other daemons.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
@@ -187,8 +187,8 @@ processing starts with the non IANA allocated ports above 1024 in the set
|
||||
of allowed ports.
|
||||
.TP
|
||||
.B outgoing\-port\-avoid: \fI<port number or range>
|
||||
Do not permit unbound to open this port or range of ports for use to send
|
||||
queries. Use this to make sure unbound does not grab a port that another
|
||||
Do not permit Unbound to open this port or range of ports for use to send
|
||||
queries. Use this to make sure Unbound does not grab a port that another
|
||||
daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
Give a port number or a range of the form "low\-high", without spaces.
|
||||
@@ -289,7 +289,7 @@ If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
space on UDP port 53 incoming queries. So that short spikes on busy
|
||||
servers do not drop packets (see counter in netstat \-su). Default is
|
||||
0 (use system value). Otherwise, the number of bytes to ask for, try
|
||||
"4m" on a busy server. The OS caps it at a maximum, on linux unbound
|
||||
"4m" on a busy server. The OS caps it at a maximum, on linux Unbound
|
||||
needs root permission to bypass the limit, or the admin can use sysctl
|
||||
net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf.
|
||||
On OpenBSD change header and recompile kernel. On Solaris ndd \-set
|
||||
@@ -302,7 +302,7 @@ in answer traffic, otherwise 'send: resource temporarily unavailable'
|
||||
can get logged, the buffer overrun is also visible by netstat \-su.
|
||||
Default is 0 (use system value). Specify the number of bytes to ask
|
||||
for, try "4m" on a very busy server. The OS caps it at a maximum, on
|
||||
linux unbound needs root permission to bypass the limit, or the admin
|
||||
linux Unbound needs root permission to bypass the limit, or the admin
|
||||
can use sysctl net.core.wmem_max. On BSD, Solaris changes are similar
|
||||
to so\-rcvbuf.
|
||||
.TP
|
||||
@@ -319,18 +319,18 @@ At extreme load it could be better to turn it off to distribute the queries
|
||||
evenly, reported for Linux systems (4.4.x).
|
||||
.TP
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where Unbound
|
||||
is listening for incoming traffic. Default no. Allows you to bind to
|
||||
non\-local interfaces. For example for non\-existent IP addresses that
|
||||
are going to exist later on, with host failover configuration. This is
|
||||
a lot like interface\-automatic, but that one services all interfaces
|
||||
and with this option you can select which (future) interfaces unbound
|
||||
provides service on. This option needs unbound to be started with root
|
||||
and with this option you can select which (future) interfaces Unbound
|
||||
provides service on. This option needs Unbound to be started with root
|
||||
permissions on some systems. The option uses IP_BINDANY on FreeBSD systems
|
||||
and SO_BINDANY on OpenBSD systems.
|
||||
.TP
|
||||
.B ip\-freebind: \fI<yes or no>
|
||||
If yes, then use IP_FREEBIND socket option on sockets where unbound
|
||||
If yes, then use IP_FREEBIND socket option on sockets where Unbound
|
||||
is listening to incoming traffic. Default no. Allows you to bind to
|
||||
IP addresses that are nonlocal or do not exist, like when the network
|
||||
interface or IP address is down. Exists only on Linux, where the similar
|
||||
@@ -560,7 +560,7 @@ service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B tls-session-ticket-keys: \fI<file>
|
||||
If not "", lists files with 80 bytes of random contents that are used to
|
||||
perform TLS session resumption for clients using the unbound server.
|
||||
perform TLS session resumption for clients using the Unbound server.
|
||||
These files contain the secret key for the TLS session tickets.
|
||||
First key use to encrypt and decrypt TLS session tickets.
|
||||
Other keys use to decrypt only. With this you can roll over to new keys,
|
||||
@@ -642,8 +642,8 @@ Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
.TP
|
||||
.B do\-daemonize: \fI<yes or no>
|
||||
Enable or disable whether the unbound server forks into the background as
|
||||
a daemon. Set the value to \fIno\fR when unbound runs as systemd service.
|
||||
Enable or disable whether the Unbound server forks into the background as
|
||||
a daemon. Set the value to \fIno\fR when Unbound runs as systemd service.
|
||||
Default is yes.
|
||||
.TP
|
||||
.B tcp\-connection\-limit: \fI<IP netblock> <limit>
|
||||
@@ -670,7 +670,7 @@ what almost all clients need). Nonrecursive queries are refused.
|
||||
.IP
|
||||
The \fIallow\fR action does allow nonrecursive queries to access the
|
||||
local\-data that is configured. The reason is that this does not involve
|
||||
the unbound server recursive lookup algorithm, and static data is served
|
||||
the Unbound server recursive lookup algorithm, and static data is served
|
||||
in the reply. This supports normal operations where nonrecursive queries
|
||||
are made for the authoritative data. For nonrecursive queries any replies
|
||||
from the dynamic cache are refused.
|
||||
@@ -742,7 +742,7 @@ to chroot and dropping permissions. This allows the pidfile to be
|
||||
Unbound is not able to remove the pidfile after termination when it is located
|
||||
outside of the chroot directory.
|
||||
.IP
|
||||
Additionally, unbound may need to access /dev/urandom (for entropy)
|
||||
Additionally, Unbound may need to access /dev/urandom (for entropy)
|
||||
from inside the chroot.
|
||||
.IP
|
||||
If given a chroot is done to the given directory. By default chroot is
|
||||
@@ -776,7 +776,7 @@ The logfile is reopened (for append) when the config file is reread, on
|
||||
SIGHUP.
|
||||
.TP
|
||||
.B use\-syslog: \fI<yes or no>
|
||||
Sets unbound to send log messages to the syslogd, using
|
||||
Sets Unbound to send log messages to the syslogd, using
|
||||
\fIsyslog\fR(3).
|
||||
The log facility LOG_DAEMON is used, with identity "unbound".
|
||||
The logfile setting is overridden when use\-syslog is turned on.
|
||||
@@ -786,7 +786,7 @@ The default is to log to syslog.
|
||||
If "" is given (default), then the name of the executable, usually "unbound"
|
||||
is used to report to the log. Enter a string to override it
|
||||
with that, which is useful on systems that run more than one instance of
|
||||
unbound, with different configurations, so that the logs can be easily
|
||||
Unbound, with different configurations, so that the logs can be easily
|
||||
distinguished against.
|
||||
.TP
|
||||
.B log\-time\-ascii: \fI<yes or no>
|
||||
@@ -874,12 +874,12 @@ with ascii_ prefix and then an ascii string.
|
||||
If enabled trustanchor.unbound queries are refused.
|
||||
.TP
|
||||
.B target\-fetch\-policy: \fI<"list of numbers">
|
||||
Set the target fetch policy used by unbound to determine if it should fetch
|
||||
Set the target fetch policy used by Unbound to determine if it should fetch
|
||||
nameserver target addresses opportunistically. The policy is described per
|
||||
dependency depth.
|
||||
.IP
|
||||
The number of values determines the maximum dependency depth
|
||||
that unbound will pursue in answering a query.
|
||||
that Unbound will pursue in answering a query.
|
||||
A value of \-1 means to fetch all targets opportunistically for that dependency
|
||||
depth. A value of 0 means to fetch on demand only. A positive value fetches
|
||||
that many targets opportunistically.
|
||||
@@ -1030,7 +1030,7 @@ a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
|
||||
.TP
|
||||
.B deny\-any: \fI<yes or no>
|
||||
If yes, deny queries of type ANY with an empty response. Default is no.
|
||||
If disabled, unbound responds with a short list of resource records if some
|
||||
If disabled, Unbound responds with a short list of resource records if some
|
||||
can be found in the cache and makes the upstream type ANY query if there
|
||||
are none.
|
||||
.TP
|
||||
@@ -1090,7 +1090,7 @@ File with trust anchor for one zone, which is tracked with RFC5011 probes.
|
||||
The probes are run several times per month, thus the machine must be online
|
||||
frequently. The initial file can be one with contents as described in
|
||||
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
|
||||
so the unbound user must have write permission. Write permission to the file,
|
||||
so the Unbound user must have write permission. Write permission to the file,
|
||||
but also to the directory it is in (to create a temporary file, which is
|
||||
necessary to deal with filesystem full events), it must also be inside the
|
||||
chroot (if that is used).
|
||||
@@ -1176,8 +1176,10 @@ the verbosity setting. Default is 0, off. At 1, for every user query
|
||||
that fails a line is printed to the logs. This way you can monitor what
|
||||
happens with validation. Use a diagnosis tool, such as dig or drill,
|
||||
to find out why validation is failing for these queries. At 2, not only
|
||||
the query that failed is printed but also the reason why unbound thought
|
||||
the query that failed is printed but also the reason why Unbound thought
|
||||
it was wrong and which server sent the faulty data.
|
||||
Enabling this influences the Extended DNS Errors (RFC 8914) messages, as
|
||||
the reason is added in the EDE message.
|
||||
.TP
|
||||
.B val\-permissive\-mode: \fI<yes or no>
|
||||
Instruct the validator to mark bogus messages as indeterminate. The security
|
||||
@@ -1188,15 +1190,15 @@ is set in replies. Also logging is performed as for full validation.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B ignore\-cd\-flag: \fI<yes or no>
|
||||
Instruct unbound to ignore the CD flag from clients and refuse to
|
||||
Instruct Unbound to ignore the CD flag from clients and refuse to
|
||||
return bogus answers to them. Thus, the CD (Checking Disabled) flag
|
||||
does not disable checking any more. This is useful if legacy (w2008)
|
||||
servers that set the CD flag but cannot validate DNSSEC themselves are
|
||||
the clients, and then unbound provides them with DNSSEC protection.
|
||||
the clients, and then Unbound provides them with DNSSEC protection.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B serve\-expired: \fI<yes or no>
|
||||
If enabled, unbound attempts to serve old responses from cache with a
|
||||
If enabled, Unbound attempts to serve old responses from cache with a
|
||||
TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the
|
||||
actual resolution to finish. The actual resolution answer ends up in the cache
|
||||
later on. Default is "no".
|
||||
@@ -1227,14 +1229,14 @@ RFC 8767 is 1800. Setting this to 0 will disable this
|
||||
behavior. Default is 0.
|
||||
.TP
|
||||
.B serve\-original\-ttl: \fI<yes or no>
|
||||
If enabled, unbound will always return the original TTL as received from
|
||||
If enabled, Unbound will always return the original TTL as received from
|
||||
the upstream name server rather than the decrementing TTL as
|
||||
stored in the cache. This feature may be useful if unbound serves as a
|
||||
front-end to a hidden authoritative name server. Enabling this feature does
|
||||
not impact cache expiry, it only changes the TTL unbound embeds in responses to
|
||||
stored in the cache. This feature may be useful if Unbound serves as a
|
||||
front-end to a hidden authoritative name server. Enabling this feature does
|
||||
not impact cache expiry, it only changes the TTL Unbound embeds in responses to
|
||||
queries. Note that enabling this feature implicitly disables enforcement of
|
||||
the configured minimum and maximum TTL, as it is assumed users who enable this
|
||||
feature do not want unbound to change the TTL obtained from an upstream server.
|
||||
the configured minimum and maximum TTL, as it is assumed users who enable this
|
||||
feature do not want Unbound to change the TTL obtained from an upstream server.
|
||||
Thus, the values set using \fBcache\-min\-ttl\fR and \fBcache\-max\-ttl\fR are
|
||||
ignored.
|
||||
Default is "no".
|
||||
@@ -1295,11 +1297,11 @@ or gigabytes (1024*1024 bytes in a megabyte).
|
||||
.TP
|
||||
.B unblock\-lan\-zones: \fI<yes or no>
|
||||
Default is disabled. If enabled, then for private address space,
|
||||
the reverse lookups are no longer filtered. This allows unbound when
|
||||
the reverse lookups are no longer filtered. This allows Unbound when
|
||||
running as dns service on a host where it provides service for that host,
|
||||
to put out all of the queries for the 'lan' upstream. When enabled,
|
||||
only localhost, 127.0.0.1 reverse and ::1 reverse zones are configured
|
||||
with default local zones. Disable the option when unbound is running
|
||||
with default local zones. Disable the option when Unbound is running
|
||||
as a (DHCP-) DNS network resolver for a group of machines, where such
|
||||
lookups should be filtered (RFC compliance), this also stops potential
|
||||
data leakage about the local network to the upstream DNS servers.
|
||||
@@ -1403,7 +1405,7 @@ Breaks out of that view and moves towards the global local zones for answer
|
||||
to the query. If the view first is no, it'll resolve normally. If view first
|
||||
is enabled, it'll break perform that step and check the global answers.
|
||||
For when the view has view specific overrides but some zone has to be
|
||||
answered from global local zone contents.
|
||||
answered from global local zone contents.
|
||||
.TP 10
|
||||
\h'5'\fInodefault\fR
|
||||
Used to turn off default contents for AS112 zones. The other types
|
||||
@@ -1562,6 +1564,60 @@ Use this localzone type, regardless the type configured for the local-zone
|
||||
(both tagged and untagged) and regardless the type configured using
|
||||
access\-control\-tag\-action.
|
||||
.TP 5
|
||||
.B ede\-local\-zones: \fI<yes or no>
|
||||
If enabled, all local zones will respond with Extended DNS Errors (RFC8914).
|
||||
This is the global setting for the configuration, but it can be overwritten by
|
||||
specifing setting 'local\-zone\-do\-ede' to "yes". By default this option
|
||||
is disabled.
|
||||
Note that the val\-log\-level influences the the reason for the error included
|
||||
in the EDE message.
|
||||
.TP 5
|
||||
.B local\-zone\-do\-ede: \fI<zone> <yes or no>
|
||||
If enabled, the responses from this local zone will include an Extended DNS
|
||||
Error (RFC8914). The type of error is dependent on the query. For example a
|
||||
query for a local-zone type "refuse" will result in EDE code 15 \- Blocked.
|
||||
By default this option is disabled.
|
||||
Note that the val\-log\-level influences the the reason for the error included
|
||||
in the EDE message.
|
||||
.TP 5
|
||||
.B local\-zone\-default\-ede: \fI<zone> <EDE code string or integer>
|
||||
If enabled, this zone will respond to requests resulting in an Extended DNS
|
||||
Error with the EDE code specified as input. This input can either be an integer
|
||||
corresponding to the EDE code number (e.g. 15 would be EDE Blocked), or a
|
||||
keyword from the following list corresponding to an EDE specified in RFC 8914.
|
||||
.TP 5
|
||||
EDE keywords:
|
||||
.nf
|
||||
\h'5'\fIother\fR
|
||||
\h'5'\fIunsupported-dnskey-algorithm\fR
|
||||
\h'5'\fIunsupported-ds-digest-type\fR
|
||||
\h'5'\fIstale-answer\fR
|
||||
\h'5'\fIforged\fR
|
||||
\h'5'\fIdnssec-indeterminate\fR
|
||||
\h'5'\fIdnssec-bogus\fR
|
||||
\h'5'\fIsignature-expired\fR
|
||||
\h'5'\fIsignature-not-yet-valid\fR
|
||||
\h'5'\fIdnskey-missing\fR
|
||||
\h'5'\fIrrsigs-missing\fR
|
||||
\h'5'\fIno-zone-key-bit-set\fR
|
||||
\h'5'\fInsec-missing\fR
|
||||
\h'5'\fIcached-error\fR
|
||||
\h'5'\fInot-ready\fR
|
||||
\h'5'\fIblocked\fR
|
||||
\h'5'\fIcensored\fR
|
||||
\h'5'\fIfiltered\fR
|
||||
\h'5'\fIprohibited\fR
|
||||
\h'5'\fIstale-nxdomain-answer\fR
|
||||
\h'5'\fInot-authoritative\fR
|
||||
\h'5'\fInot-supported\fR
|
||||
\h'5'\fIno-reachable-authority\fR
|
||||
\h'5'\fInetwork-error\fR
|
||||
\h'5'\fIinvalid-data\fR
|
||||
.fi
|
||||
.TP 5
|
||||
Note that the val\-log\-level influences the the reason for the error included
|
||||
in the EDE message.
|
||||
.TP 5
|
||||
.B response\-ip: \fI<IP-netblock> <action>
|
||||
This requires use of the "respip" module.
|
||||
.IP
|
||||
@@ -1647,7 +1703,7 @@ query names, but not spoofed reflection floods. Cached responses are not
|
||||
ratelimited by this setting. The zone of the query is determined by examining
|
||||
the nameservers for it, the zone name is used to keep track of the rate.
|
||||
For example, 1000 may be a suitable value to stop the server from being
|
||||
overloaded with random names, and keeps unbound from sending traffic to the
|
||||
overloaded with random names, and keeps Unbound from sending traffic to the
|
||||
nameservers for those zones.
|
||||
.TP 5
|
||||
.B ratelimit\-size: \fI<memory size>
|
||||
@@ -1714,7 +1770,7 @@ and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B outbound\-msg\-retry: \fI<number>
|
||||
The number of retries unbound will do in case of a non positive response is
|
||||
The number of retries Unbound will do in case of a non positive response is
|
||||
received. If a forward nameserver is used, this is the number of retries per
|
||||
forward nameserver in case of throwaway response.
|
||||
.TP 5
|
||||
@@ -1747,7 +1803,7 @@ In the
|
||||
.B remote\-control:
|
||||
clause are the declarations for the remote control facility. If this is
|
||||
enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
commands to the running Unbound server. The server uses these clauses
|
||||
to setup TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
@@ -1767,7 +1823,7 @@ the server for the change to take effect.
|
||||
.IP
|
||||
If you set it to an absolute path, a local socket is used. The local socket
|
||||
does not use the certificates and keys, so those files need not be present.
|
||||
To restrict access, unbound sets permissions on the file to the user and
|
||||
To restrict access, Unbound sets permissions on the file to the user and
|
||||
group that is configured, the access bits are set to allow the group members
|
||||
to access the control socket file. Put users that need to access the socket
|
||||
in the that group. To restrict access further, create a directory to put
|
||||
@@ -1787,12 +1843,12 @@ and the value of this option is ignored.
|
||||
.B server\-key\-file: \fI<private key file>
|
||||
Path to the server private key, by default unbound_server.key.
|
||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||
This file is used by the unbound server, but not by \fIunbound\-control\fR.
|
||||
This file is used by the Unbound server, but not by \fIunbound\-control\fR.
|
||||
.TP 5
|
||||
.B server\-cert\-file: \fI<certificate file.pem>
|
||||
Path to the server self signed certificate, by default unbound_server.pem.
|
||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||
This file is used by the unbound server, and also by \fIunbound\-control\fR.
|
||||
This file is used by the Unbound server, and also by \fIunbound\-control\fR.
|
||||
.TP 5
|
||||
.B control\-key\-file: \fI<private key file>
|
||||
Path to the control client private key, by default unbound_control.key.
|
||||
@@ -1810,24 +1866,24 @@ There may be multiple
|
||||
.B stub\-zone:
|
||||
clauses. Each with a name: and zero or more hostnames or IP addresses.
|
||||
For the stub zone this list of nameservers is used. Class IN is assumed.
|
||||
The servers should be authority servers, not recursors; unbound performs
|
||||
The servers should be authority servers, not recursors; Unbound performs
|
||||
the recursive processing itself for stub zones.
|
||||
.P
|
||||
The stub zone can be used to configure authoritative data to be used
|
||||
by the resolver that cannot be accessed using the public internet servers.
|
||||
This is useful for company\-local data or private zones. Setup an
|
||||
authoritative server on a different host (or different port). Enter a config
|
||||
entry for unbound with
|
||||
entry for Unbound with
|
||||
.B stub\-addr:
|
||||
<ip address of host[@port]>.
|
||||
The unbound resolver can then access the data, without referring to the
|
||||
The Unbound resolver can then access the data, without referring to the
|
||||
public internet for it.
|
||||
.P
|
||||
This setup allows DNSSEC signed zones to be served by that
|
||||
authoritative server, in which case a trusted key entry with the public key
|
||||
can be put in config, so that unbound can validate the data and set the AD
|
||||
can be put in config, so that Unbound can validate the data and set the AD
|
||||
bit on replies for the private zone (authoritative servers do not set the
|
||||
AD bit). This setup makes unbound capable of answering queries for the
|
||||
AD bit). This setup makes Unbound capable of answering queries for the
|
||||
private zone, and can even set the AD bit ('authentic'), but the AA
|
||||
('authoritative') bit is not set on these replies.
|
||||
.P
|
||||
@@ -1835,7 +1891,7 @@ Consider adding \fBserver:\fR statements for \fBdomain\-insecure:\fR and
|
||||
for \fBlocal\-zone:\fI name nodefault\fR for the zone if it is a locally
|
||||
served zone. The insecure clause stops DNSSEC from invalidating the
|
||||
zone. The local zone nodefault (or \fItransparent\fR) clause makes the
|
||||
(reverse\-) zone bypass unbound's filtering of RFC1918 zones.
|
||||
(reverse\-) zone bypass Unbound's filtering of RFC1918 zones.
|
||||
.TP
|
||||
.B name: \fI<domain name>
|
||||
Name of the stub zone. This is the full domain name of the zone.
|
||||
@@ -1884,10 +1940,10 @@ clauses. Each with a \fBname:\fR and zero or more hostnames or IP
|
||||
addresses. For the forward zone this list of nameservers is used to
|
||||
forward the queries to. The servers listed as \fBforward\-host:\fR and
|
||||
\fBforward\-addr:\fR have to handle further recursion for the query. Thus,
|
||||
those servers are not authority servers, but are (just like unbound is)
|
||||
recursive servers too; unbound does not perform recursion itself for the
|
||||
those servers are not authority servers, but are (just like Unbound is)
|
||||
recursive servers too; Unbound does not perform recursion itself for the
|
||||
forward zone, it lets the remote server do it. Class IN is assumed.
|
||||
CNAMEs are chased by unbound itself, asking the remote server for every
|
||||
CNAMEs are chased by Unbound itself, asking the remote server for every
|
||||
name in the indirection chain, to protect the local cache from illegal
|
||||
indirect referenced items.
|
||||
A forward\-zone entry with name "." and a forward\-addr target will
|
||||
@@ -1913,7 +1969,7 @@ name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, unbound will fall back to normal recursive resolution for this
|
||||
enabled, Unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified. The default is "no".
|
||||
.TP
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
@@ -1939,7 +1995,7 @@ have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone
|
||||
The authority zone with the name closest to the name looked up is used.
|
||||
Authority zones are processed after \fBlocal\-zones\fR and before
|
||||
cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner
|
||||
make unbound respond like an authority server. Authority zones are also
|
||||
make Unbound respond like an authority server. Authority zones are also
|
||||
processed after cache, just before going to the network to fetch
|
||||
information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used
|
||||
in this manner provide a local copy of an authority server that speeds up
|
||||
@@ -2000,25 +2056,25 @@ file is downloaded when notified. The primaries from primary: statements are
|
||||
allowed notify by default.
|
||||
.TP
|
||||
.B fallback\-enabled: \fI<yes or no>
|
||||
Default no. If enabled, unbound falls back to querying the internet as
|
||||
Default no. If enabled, Unbound falls back to querying the internet as
|
||||
a resolver for this zone when lookups fail. For example for DNSSEC
|
||||
validation failures.
|
||||
.TP
|
||||
.B for\-downstream: \fI<yes or no>
|
||||
Default yes. If enabled, unbound serves authority responses to
|
||||
downstream clients for this zone. This option makes unbound behave, for
|
||||
Default yes. If enabled, Unbound serves authority responses to
|
||||
downstream clients for this zone. This option makes Unbound behave, for
|
||||
the queries with names in this zone, like one of the authority servers for
|
||||
that zone. Turn it off if you want unbound to provide recursion for the
|
||||
that zone. Turn it off if you want Unbound to provide recursion for the
|
||||
zone but have a local copy of zone data. If for\-downstream is no and
|
||||
for\-upstream is yes, then unbound will DNSSEC validate the contents of the
|
||||
for\-upstream is yes, then Unbound will DNSSEC validate the contents of the
|
||||
zone before serving the zone contents to clients and store validation
|
||||
results in the cache.
|
||||
.TP
|
||||
.B for\-upstream: \fI<yes or no>
|
||||
Default yes. If enabled, unbound fetches data from this data collection
|
||||
Default yes. If enabled, Unbound fetches data from this data collection
|
||||
for answering recursion queries. Instead of sending queries over the internet
|
||||
to the authority servers for this zone, it'll fetch the data directly from
|
||||
the zone data. Turn it on when you want unbound to provide recursion for
|
||||
the zone data. Turn it on when you want Unbound to provide recursion for
|
||||
downstream clients, and use the zone data as a local copy to speed up lookups.
|
||||
.TP
|
||||
.B zonemd\-check: \fI<yes or no>
|
||||
@@ -2042,14 +2098,14 @@ a ZONEMD is always a failure, also for nonDNSSEC signed zones.
|
||||
.TP
|
||||
.B zonefile: \fI<filename>
|
||||
The filename where the zone is stored. If not given then no zonefile is used.
|
||||
If the file does not exist or is empty, unbound will attempt to fetch zone
|
||||
If the file does not exist or is empty, Unbound will attempt to fetch zone
|
||||
data (eg. from the primary servers).
|
||||
.SS "View Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
.B view:
|
||||
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
|
||||
\fBlocal\-data\fR elements. Views can also contain view\-first,
|
||||
\fBlocal\-data\fR elements. Views can also contain view\-first,
|
||||
response\-ip, response\-ip\-data and local\-data\-ptr elements.
|
||||
View can be mapped to requests by specifying the
|
||||
view name in an \fBaccess\-control\-view\fR element. Options from matching
|
||||
@@ -2142,9 +2198,9 @@ underneath the name given.
|
||||
The
|
||||
.B dnscrypt:
|
||||
clause gives the settings of the dnscrypt channel. While those options are
|
||||
available, they are only meaningful if unbound was compiled with
|
||||
available, they are only meaningful if Unbound was compiled with
|
||||
\fB\-\-enable\-dnscrypt\fR.
|
||||
Currently certificate and secret/public keys cannot be generated by unbound.
|
||||
Currently certificate and secret/public keys cannot be generated by Unbound.
|
||||
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/\
|
||||
dnscrypt-wrapper/blob/master/README.md#usage
|
||||
.TP
|
||||
@@ -2263,7 +2319,7 @@ of 0 is always accepted. Default is 0.
|
||||
.TP
|
||||
.B min\-client\-subnet\-ipv4: \fI<number>\fR
|
||||
Specifies the minimum prefix length of the IPv4 source mask we are willing to
|
||||
accept in queries. Shorter source masks result in REFUSED answers. Source mask
|
||||
accept in queries. Shorter source masks result in REFUSED answers. Source mask
|
||||
of 0 is always accepted. Default is 0.
|
||||
.TP
|
||||
.B max\-ecs\-tree\-size\-ipv4: \fI<number>\fR
|
||||
@@ -2276,12 +2332,13 @@ This number applies for each qname/qclass/qtype tuple. Defaults to 100.
|
||||
.SS "Opportunistic IPsec Support Module Options"
|
||||
.LP
|
||||
The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
|
||||
validator iterator" directive and be compiled into the daemon to be
|
||||
enabled. These settings go in the \fBserver:\fR section.
|
||||
validator iterator" directive and be compiled into Unbound by using
|
||||
\fB\-\-enable\-ipsecmod\fR to be enabled.
|
||||
These settings go in the \fBserver:\fR section.
|
||||
.LP
|
||||
When unbound receives an A/AAAA query that is not in the cache and finds a
|
||||
When Unbound receives an A/AAAA query that is not in the cache and finds a
|
||||
valid answer, it will withhold returning the answer and instead will generate
|
||||
an IPSECKEY subquery for the same domain name. If an answer was found, unbound
|
||||
an IPSECKEY subquery for the same domain name. If an answer was found, Unbound
|
||||
will call an external hook passing the following arguments:
|
||||
.TP 10
|
||||
\h'5'\fIQNAME\fR
|
||||
@@ -2310,19 +2367,19 @@ relevant for opportunistic IPsec.
|
||||
.B ipsecmod-enabled: \fI<yes or no>\fR
|
||||
Specifies whether the IPsec module is enabled or not. The IPsec module still
|
||||
needs to be defined in the \fBmodule\-config:\fR directive. This option
|
||||
facilitates turning on/off the module without restarting/reloading unbound.
|
||||
facilitates turning on/off the module without restarting/reloading Unbound.
|
||||
Defaults to yes.
|
||||
.TP
|
||||
.B ipsecmod\-hook: \fI<filename>\fR
|
||||
Specifies the external hook that unbound will call with \fIsystem\fR(3). The
|
||||
Specifies the external hook that Unbound will call with \fIsystem\fR(3). The
|
||||
file can be specified as an absolute/relative path. The file needs the proper
|
||||
permissions to be able to be executed by the same user that runs unbound. It
|
||||
permissions to be able to be executed by the same user that runs Unbound. It
|
||||
must be present when the IPsec module is defined in the \fBmodule\-config:\fR
|
||||
directive.
|
||||
.TP
|
||||
.B ipsecmod-strict: \fI<yes or no>\fR
|
||||
If enabled unbound requires the external hook to return a success value of 0.
|
||||
Failing to do so unbound will reply with SERVFAIL. The A/AAAA answer will also
|
||||
If enabled Unbound requires the external hook to return a success value of 0.
|
||||
Failing to do so Unbound will reply with SERVFAIL. The A/AAAA answer will also
|
||||
not be cached. Defaults to no.
|
||||
.TP
|
||||
.B ipsecmod\-max-ttl: \fI<seconds>\fR
|
||||
@@ -2330,7 +2387,7 @@ Time to live maximum for A/AAAA cached records after calling the external hook.
|
||||
Defaults to 3600.
|
||||
.TP
|
||||
.B ipsecmod-ignore-bogus: \fI<yes or no>\fR
|
||||
Specifies the behaviour of unbound when the IPSECKEY answer is bogus. If set
|
||||
Specifies the behaviour of Unbound when the IPSECKEY answer is bogus. If set
|
||||
to yes, the hook will be called and the A/AAAA answer will be returned to the
|
||||
client. If set to no, the hook will not be called and the answer to the
|
||||
A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no.
|
||||
@@ -2357,7 +2414,7 @@ If Unbound cannot even find an answer in the backend, it resolves the
|
||||
query as usual, and stores the answer in the backend.
|
||||
.P
|
||||
This module interacts with the \fBserve\-expired\-*\fR options and will reply
|
||||
with expired data if unbound is configured for that. Currently the use
|
||||
with expired data if Unbound is configured for that. Currently the use
|
||||
of \fBserve\-expired\-client\-timeout:\fR and
|
||||
\fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from
|
||||
the external cache as these will result in a reply with 0 TTL without trying to
|
||||
@@ -2436,16 +2493,17 @@ re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.TP
|
||||
.B redis-expire-records: \fI<yes or no>
|
||||
If Redis record expiration is enabled. If yes, unbound sets timeout for Redis
|
||||
If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
|
||||
records so that Redis can evict keys that have expired automatically. If
|
||||
unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
|
||||
Unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
|
||||
this option is internally reverted to "no". Redis SETEX support is required
|
||||
for this option (Redis >= 2.0.0).
|
||||
This option defaults to no.
|
||||
.SS DNSTAP Logging Options
|
||||
DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section.
|
||||
DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fR, is enabled
|
||||
in the \fBdnstap:\fR section.
|
||||
This starts an extra thread (when compiled with threading) that writes
|
||||
the log information to the destination. If unbound is compiled without
|
||||
the log information to the destination. If Unbound is compiled without
|
||||
threading it does not spawn a thread, but connects per-process to the
|
||||
destination.
|
||||
.TP
|
||||
@@ -2503,19 +2561,19 @@ Default is "".
|
||||
.TP
|
||||
.B dnstap-log-resolver-query-messages: \fI<yes or no>
|
||||
Enable to log resolver query messages. Default is no.
|
||||
These are messages from unbound to upstream servers.
|
||||
These are messages from Unbound to upstream servers.
|
||||
.TP
|
||||
.B dnstap-log-resolver-response-messages: \fI<yes or no>
|
||||
Enable to log resolver response messages. Default is no.
|
||||
These are replies from upstream servers to unbound.
|
||||
These are replies from upstream servers to Unbound.
|
||||
.TP
|
||||
.B dnstap-log-client-query-messages: \fI<yes or no>
|
||||
Enable to log client query messages. Default is no.
|
||||
These are client queries to unbound.
|
||||
These are client queries to Unbound.
|
||||
.TP
|
||||
.B dnstap-log-client-response-messages: \fI<yes or no>
|
||||
Enable to log client response messages. Default is no.
|
||||
These are responses from unbound to clients.
|
||||
These are responses from Unbound to clients.
|
||||
.TP
|
||||
.B dnstap-log-forwarder-query-messages: \fI<yes or no>
|
||||
Enable to log forwarder query messages. Default is no.
|
||||
@@ -2614,7 +2672,7 @@ allowed notify by default.
|
||||
.TP
|
||||
.B zonefile: \fI<filename>
|
||||
The filename where the zone is stored. If not given then no zonefile is used.
|
||||
If the file does not exist or is empty, unbound will attempt to fetch zone
|
||||
If the file does not exist or is empty, Unbound will attempt to fetch zone
|
||||
data (eg. from the primary servers).
|
||||
.TP
|
||||
.B rpz\-action\-override: \fI<action>
|
||||
@@ -2631,6 +2689,14 @@ Log all applied RPZ actions for this RPZ zone. Default is no.
|
||||
.B rpz\-log\-name: \fI<name>
|
||||
Specify a string to be part of the log line, for easy referencing.
|
||||
.TP
|
||||
.B rpz\-do\-ede: \fI<yes or no>
|
||||
Specify if this zone RPZ responds with Extended DNS Errors (RFC 8914). The
|
||||
default is no.
|
||||
.B rpz\-signal\-nxdomain\-ra: \fI<yes or no>
|
||||
Signal when a query is blocked by the RPZ with NXDOMAIN with an unset RA flag.
|
||||
This allows certain clients, like dnsmasq, to infer that the domain is
|
||||
externally blocked. Default is no.
|
||||
.TP
|
||||
.B tags: \fI<list of tags>
|
||||
Limit the policies from this RPZ clause to clients with a matching tag. Tags
|
||||
need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses
|
||||
@@ -2671,7 +2737,7 @@ server:
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @UNBOUND_RUN_DIR@
|
||||
default unbound working directory.
|
||||
default Unbound working directory.
|
||||
.TP
|
||||
.I @UNBOUND_CHROOT_DIR@
|
||||
default
|
||||
@@ -2679,13 +2745,13 @@ default
|
||||
location.
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
unbound configuration file.
|
||||
Unbound configuration file.
|
||||
.TP
|
||||
.I @UNBOUND_PIDFILE@
|
||||
default unbound pidfile with process ID of the running daemon.
|
||||
default Unbound pidfile with process ID of the running daemon.
|
||||
.TP
|
||||
.I unbound.log
|
||||
unbound log file. default is to log to
|
||||
Unbound log file. default is to log to
|
||||
\fIsyslog\fR(3).
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound\fR(8),
|
||||
|
||||
+2
-2
@@ -2534,7 +2534,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct dns_msg* forged_response = rpz_callback_from_iterator_module(qstate, iq);
|
||||
if(forged_response != NULL) {
|
||||
qstate->ext_state[id] = module_finished;
|
||||
qstate->return_rcode = FLAGS_GET_RCODE(forged_response->rep->flags);
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = forged_response;
|
||||
iq->response = forged_response;
|
||||
next_state(iq, FINISHED_STATE);
|
||||
@@ -3103,7 +3103,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
if(forged_response != NULL) {
|
||||
qstate->ext_state[id] = module_finished;
|
||||
qstate->return_rcode = FLAGS_GET_RCODE(forged_response->rep->flags);
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = forged_response;
|
||||
iq->response = forged_response;
|
||||
next_state(iq, FINISHED_STATE);
|
||||
|
||||
+369
-53
@@ -56,6 +56,44 @@
|
||||
* with 16 bytes for an A record, a 64K packet has about 4000 max */
|
||||
#define LOCALZONE_RRSET_COUNT_MAX 4096
|
||||
|
||||
/** print all RRsets in local zone */
|
||||
static void
|
||||
local_zone_out(struct local_zone* z)
|
||||
{
|
||||
struct local_data* d;
|
||||
struct local_rrset* p;
|
||||
RBTREE_FOR(d, struct local_data*, &z->data) {
|
||||
for(p = d->rrsets; p; p = p->next) {
|
||||
log_nametypeclass(NO_VERBOSE, "rrset", d->name,
|
||||
ntohs(p->rrset->rk.type),
|
||||
ntohs(p->rrset->rk.rrset_class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
local_zone_print(struct local_zone* z)
|
||||
{
|
||||
char buf[64];
|
||||
lock_rw_rdlock(&z->lock);
|
||||
snprintf(buf, sizeof(buf), "%s zone",
|
||||
local_zone_type2str(z->type));
|
||||
log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
|
||||
local_zone_out(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
|
||||
void local_zones_print(struct local_zones* zones)
|
||||
{
|
||||
struct local_zone* z;
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
local_zone_print(z);
|
||||
}
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
struct local_zones*
|
||||
local_zones_create(void)
|
||||
{
|
||||
@@ -156,6 +194,8 @@ local_zone_create(uint8_t* nm, size_t len, int labs,
|
||||
z->name = nm;
|
||||
z->namelen = len;
|
||||
z->namelabs = labs;
|
||||
z->do_ede = -1; /* do not set EDE (RFC8914) (0/1 is set) */
|
||||
z->default_ede = -1; /* do not overwrite EDE (RFC8914) codes */
|
||||
lock_rw_init(&z->lock);
|
||||
z->region = regional_create_nochunk(sizeof(struct regional));
|
||||
if(!z->region) {
|
||||
@@ -657,6 +697,177 @@ lz_enter_zone_tag(struct local_zones* zones, char* zname, uint8_t* list,
|
||||
return r;
|
||||
}
|
||||
|
||||
/** enter do-ede option into zone */
|
||||
static int
|
||||
lz_enter_respond_ede(struct local_zones* zones, char* zname, char* option)
|
||||
{
|
||||
uint8_t dname[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t dname_len = sizeof(dname);
|
||||
int dname_label_count;
|
||||
struct local_zone* z;
|
||||
|
||||
/* parse zone name */
|
||||
if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
|
||||
log_err("cannot parse zone name in local-zone-do-ede: %s",
|
||||
zname);
|
||||
return 0;
|
||||
}
|
||||
dname_label_count = dname_count_labels(dname);
|
||||
|
||||
/* find localzone entry */
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_find(zones, dname,
|
||||
dname_len, dname_label_count, LDNS_RR_CLASS_IN);
|
||||
if (!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
log_err("no local-zone for local-zone-do-ede: %s", zname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
if (z->do_ede != -1) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
log_err("duplicate local-zone-do-ede: %s", zname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* parse option and check that the global default is also negative */
|
||||
if ((strcmp(option, "no") == 0)) {
|
||||
z->do_ede = 0;
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
z->do_ede = 1; /* respond with EDEs in this local-zone */
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ede_string_to_sldns_ede_code(char* code)
|
||||
{
|
||||
if (strcmp("other", code) == 0)
|
||||
return LDNS_EDE_OTHER;
|
||||
else if (strcmp("unsupported_dnskey_algorithm", code) == 0)
|
||||
return LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
else if (strcmp("unsupported_ds_digest_type", code) == 0)
|
||||
return LDNS_EDE_UNSUPPORTED_DS_DIGEST;
|
||||
else if (strcmp("stale_answer", code) == 0)
|
||||
return LDNS_EDE_STALE_ANSWER;
|
||||
else if (strcmp("forged", code) == 0)
|
||||
return LDNS_EDE_FORGED_ANSWER;
|
||||
else if (strcmp("dnssec_indeterminate", code) == 0)
|
||||
return LDNS_EDE_DNSSEC_INDETERMINATE;
|
||||
else if (strcmp("dnssec_bogus", code) == 0)
|
||||
return LDNS_EDE_DNSSEC_BOGUS;
|
||||
else if (strcmp("signature_expired", code) == 0)
|
||||
return LDNS_EDE_SIGNATURE_EXPIRED;
|
||||
else if (strcmp("signature_not_yet_valid", code) == 0)
|
||||
return LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
else if (strcmp("dnskey_missing", code) == 0)
|
||||
return LDNS_EDE_DNSKEY_MISSING;
|
||||
else if (strcmp("rrsigs_missing", code) == 0)
|
||||
return LDNS_EDE_RRSIGS_MISSING;
|
||||
else if (strcmp("no_zone_key_bit_set", code) == 0)
|
||||
return LDNS_EDE_NO_ZONE_KEY_BIT_SET;
|
||||
else if (strcmp("nsec_missing", code) == 0)
|
||||
return LDNS_EDE_NSEC_MISSING;
|
||||
else if (strcmp("cached_error", code) == 0)
|
||||
return LDNS_EDE_CACHED_ERROR;
|
||||
else if (strcmp("not_ready", code) == 0)
|
||||
return LDNS_EDE_NOT_READY;
|
||||
else if (strcmp("blocked", code) == 0)
|
||||
return LDNS_EDE_BLOCKED;
|
||||
else if (strcmp("censored", code) == 0)
|
||||
return LDNS_EDE_CENSORED;
|
||||
else if (strcmp("filtered", code) == 0)
|
||||
return LDNS_EDE_FILTERED;
|
||||
else if (strcmp("prohibited", code) == 0)
|
||||
return LDNS_EDE_PROHIBITED;
|
||||
else if (strcmp("stale_nxdomain_answer", code) == 0)
|
||||
return LDNS_EDE_STALE_NXDOMAIN_ANSWER;
|
||||
else if (strcmp("not_authoritative", code) == 0)
|
||||
return LDNS_EDE_NOT_AUTHORITATIVE;
|
||||
else if (strcmp("not_supported", code) == 0)
|
||||
return LDNS_EDE_NOT_SUPPORTED;
|
||||
else if (strcmp("no_reachable_authority", code) == 0)
|
||||
return LDNS_EDE_NO_REACHABLE_AUTHORITY;
|
||||
else if (strcmp("network_error", code) == 0)
|
||||
return LDNS_EDE_NETWORK_ERROR;
|
||||
else if (strcmp("invalid_data", code) == 0)
|
||||
return LDNS_EDE_INVALID_DATA;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
lz_enter_default_ede_response(struct local_zones* zones, char* zname, char* code)
|
||||
{
|
||||
uint8_t dname[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t dname_len = sizeof(dname);
|
||||
int dname_label_count;
|
||||
struct local_zone* z;
|
||||
int default_ede;
|
||||
|
||||
/* parse zone name */
|
||||
if(sldns_str2wire_dname_buf(zname, dname, &dname_len) != 0) {
|
||||
log_err("cannot parse zone name in local-zone-default-ede: %s",
|
||||
zname);
|
||||
return 0;
|
||||
}
|
||||
dname_label_count = dname_count_labels(dname);
|
||||
|
||||
/* parse option in case of a textual string or integer value */
|
||||
if (atoi(code) != 0) {
|
||||
default_ede = (int) ede_string_to_sldns_ede_code(code);
|
||||
if (default_ede == -1) {
|
||||
log_err("incorect EDE code string found for "
|
||||
"local-zone-default-ede: %s", zname);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
int tmp = atoi(code);
|
||||
if (!(tmp >= 0 && tmp < 65635)) {
|
||||
log_err("incorrect EDE code integer value for"
|
||||
"local-zone-default-ede: %s", zname);
|
||||
return 0;
|
||||
}
|
||||
default_ede = tmp;
|
||||
}
|
||||
|
||||
/* find localzone entry */
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_find(zones, dname,
|
||||
dname_len, dname_label_count, LDNS_RR_CLASS_IN);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
log_err("no local-zone for local-zone-default-ede: %s", zname);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
if (z->default_ede) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
log_err("duplicate local-zone-default-ede: %s", zname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(z->default_ede >= 0)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
log_err("default-ede set for zone that does not have"
|
||||
"local-zone-do-ede enabled: %s", zname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
z->default_ede = default_ede; /* respond with EDEs in this local-zone */
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/** enter override into zone */
|
||||
static int
|
||||
lz_enter_override(struct local_zones* zones, char* zname, char* netblock,
|
||||
@@ -943,6 +1154,30 @@ lz_enter_overrides(struct local_zones* zones, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** parse local-zone-do-ede: statements */
|
||||
static int
|
||||
lz_enter_respond_ede_zones(struct local_zones* zones, struct config_file* cfg)
|
||||
{
|
||||
struct config_str2list* p;
|
||||
for(p = cfg->local_zone_do_ede; p; p = p->next) {
|
||||
if(!lz_enter_respond_ede(zones, p->str, p->str2))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** parse local_zone_default_ede: statements */
|
||||
static int
|
||||
lz_enter_default_ede_response_zones(struct local_zones* zones, struct config_file* cfg)
|
||||
{
|
||||
struct config_str2list* p;
|
||||
for(p = cfg->local_zone_default_ede; p; p = p->next) {
|
||||
if(!lz_enter_default_ede_response(zones, p->str, p->str2))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** setup parent pointers, so that a lookup can be done for closest match */
|
||||
static void
|
||||
init_parents(struct local_zones* zones)
|
||||
@@ -1010,6 +1245,38 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
|
||||
rr_type)) {
|
||||
/* Check if there is a zone that this could go
|
||||
* under but for different class; created zones are
|
||||
* always for LDNS_RR_CLASS_IN. Create the zone with
|
||||
* a different class but the same configured
|
||||
* local_zone_type. */
|
||||
struct local_zone* z = local_zones_lookup(zones,
|
||||
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
|
||||
if(z) {
|
||||
uint8_t* name = memdup(z->name, z->namelen);
|
||||
size_t znamelen = z->namelen;
|
||||
int znamelabs = z->namelabs;
|
||||
enum localzone_type ztype = z->type;
|
||||
lock_rw_unlock(&zones->lock);
|
||||
if(!name) {
|
||||
log_err("out of memory");
|
||||
free(rr_name);
|
||||
return 0;
|
||||
}
|
||||
if(!(
|
||||
#ifndef THREADS_DISABLED
|
||||
z =
|
||||
#endif
|
||||
lz_enter_zone_dname(zones, name,
|
||||
znamelen, znamelabs,
|
||||
ztype, rr_class))) {
|
||||
free(rr_name);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
free(rr_name);
|
||||
continue;
|
||||
}
|
||||
if(!have_name) {
|
||||
dclass = rr_class;
|
||||
nm = rr_name;
|
||||
@@ -1124,6 +1391,15 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
|
||||
if(!lz_enter_overrides(zones, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
/* enter EDE (RFC8914) response options for local zones */
|
||||
if(!lz_enter_respond_ede_zones(zones, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
/* enter default EDE (RFC8914) response options for local zones */
|
||||
if(!lz_enter_default_ede_response_zones(zones, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create implicit transparent zone from data. */
|
||||
if(!lz_setup_implicit(zones, cfg)) {
|
||||
return 0;
|
||||
@@ -1220,38 +1496,6 @@ local_zones_find_le(struct local_zones* zones,
|
||||
return (struct local_zone*)node;
|
||||
}
|
||||
|
||||
/** print all RRsets in local zone */
|
||||
static void
|
||||
local_zone_out(struct local_zone* z)
|
||||
{
|
||||
struct local_data* d;
|
||||
struct local_rrset* p;
|
||||
RBTREE_FOR(d, struct local_data*, &z->data) {
|
||||
for(p = d->rrsets; p; p = p->next) {
|
||||
log_nametypeclass(NO_VERBOSE, "rrset", d->name,
|
||||
ntohs(p->rrset->rk.type),
|
||||
ntohs(p->rrset->rk.rrset_class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void local_zones_print(struct local_zones* zones)
|
||||
{
|
||||
struct local_zone* z;
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
|
||||
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
|
||||
char buf[64];
|
||||
lock_rw_rdlock(&z->lock);
|
||||
snprintf(buf, sizeof(buf), "%s zone",
|
||||
local_zone_type2str(z->type));
|
||||
log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
|
||||
local_zone_out(z);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_rw_unlock(&zones->lock);
|
||||
}
|
||||
|
||||
/** encode answer consisting of 1 rrset */
|
||||
static int
|
||||
local_encode(struct query_info* qinfo, struct module_env* env,
|
||||
@@ -1286,11 +1530,65 @@ local_encode(struct query_info* qinfo, struct module_env* env,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** encode answer consisting of 1 rrset (with EDE code) */
|
||||
static int
|
||||
local_encode_ede(struct local_zone* zone, struct query_info* qinfo,
|
||||
struct module_env* env, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
struct ub_packed_rrset_key* rrset, int ansec, int rcode,
|
||||
sldns_ede_code ede_code, const char* ede_txt, int do_ede)
|
||||
{
|
||||
struct reply_info rep;
|
||||
uint16_t udpsize;
|
||||
|
||||
/* make answer with time=0 for fixed TTL values */
|
||||
memset(&rep, 0, sizeof(rep));
|
||||
rep.flags = (uint16_t)((BIT_QR | BIT_AA | BIT_RA) | rcode);
|
||||
rep.qdcount = 1;
|
||||
if(ansec)
|
||||
rep.an_numrrsets = 1;
|
||||
else rep.ns_numrrsets = 1;
|
||||
rep.rrset_count = 1;
|
||||
rep.rrsets = &rrset;
|
||||
udpsize = edns->udp_size;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
|
||||
repinfo, temp, env->now_tv)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
return 1;
|
||||
}
|
||||
/* check global and local-zone EDE settings */
|
||||
if (do_ede == 1 || /* local precedes global */
|
||||
(do_ede == -1 &&
|
||||
env->cfg->ede_local_zones == 1)){ /* global set, but local not */
|
||||
|
||||
if (zone != NULL && zone->default_ede != -1)
|
||||
ede_code = zone->default_ede;
|
||||
|
||||
edns_opt_list_append_ede(&edns->opt_list_out, temp, ede_code, ede_txt);
|
||||
}
|
||||
if(!reply_info_answer_encode(qinfo, &rep,
|
||||
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** encode local error answer */
|
||||
static void
|
||||
local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int rcode, int r)
|
||||
local_error_encode(struct local_zone* zone, struct query_info* qinfo,
|
||||
struct module_env* env, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
int rcode, int r, sldns_ede_code ede_code, const char* ede_txt,
|
||||
int do_ede)
|
||||
{
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -1300,6 +1598,16 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
|
||||
rcode, edns, repinfo, temp, env->now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
/* check global and local-zone ede settings */
|
||||
if (do_ede == 1 || /* local precedes global */
|
||||
(do_ede == -1 &&
|
||||
env->cfg->ede_local_zones == 1)){ /* global set, but local not */
|
||||
|
||||
if (zone != NULL && zone->default_ede != -1)
|
||||
ede_code = zone->default_ede;
|
||||
|
||||
edns_opt_list_append_ede(&edns->opt_list_out, temp, ede_code, ede_txt);
|
||||
}
|
||||
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
}
|
||||
@@ -1422,7 +1730,7 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int labs, struct local_data** ldp,
|
||||
enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
|
||||
size_t tag_datas_size, char** tagname, int num_tags)
|
||||
size_t tag_datas_size, char** tagname, int num_tags, int do_ede)
|
||||
{
|
||||
struct local_data key;
|
||||
struct local_data* ld;
|
||||
@@ -1495,9 +1803,11 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
|
||||
if(newtargetlen > LDNS_MAX_DOMAINLEN) {
|
||||
qinfo->local_alias = NULL;
|
||||
local_error_encode(qinfo, env, edns, repinfo,
|
||||
local_error_encode(z, qinfo, env, edns,repinfo,
|
||||
buf, temp, LDNS_RCODE_YXDOMAIN,
|
||||
(LDNS_RCODE_YXDOMAIN|BIT_AA));
|
||||
(LDNS_RCODE_YXDOMAIN|BIT_AA),
|
||||
LDNS_EDE_OTHER,
|
||||
"DNAME expansion became too large", do_ede);
|
||||
return 1;
|
||||
}
|
||||
memset(&qinfo->local_alias->rrset->entry, 0,
|
||||
@@ -1542,8 +1852,8 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1,
|
||||
LDNS_RCODE_NOERROR);
|
||||
}
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1,
|
||||
LDNS_RCODE_NOERROR);
|
||||
return local_encode_ede(z, qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1,
|
||||
LDNS_RCODE_NOERROR, LDNS_EDE_FORGED_ANSWER, "", do_ede);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1588,7 +1898,7 @@ int
|
||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
struct local_data* ld, enum localzone_type lz_type)
|
||||
struct local_data* ld, enum localzone_type lz_type, int do_ede)
|
||||
{
|
||||
if(lz_type == local_zone_deny ||
|
||||
lz_type == local_zone_always_deny ||
|
||||
@@ -1599,8 +1909,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_refuse
|
||||
|| lz_type == local_zone_always_refuse) {
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
|
||||
local_error_encode(z, qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA),
|
||||
LDNS_EDE_BLOCKED, "", do_ede);
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_static ||
|
||||
lz_type == local_zone_redirect ||
|
||||
@@ -1625,8 +1936,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
local_error_encode(z, qinfo, env, edns, repinfo, buf, temp,
|
||||
rcode, (rcode|BIT_AA), LDNS_EDE_BLOCKED, "", do_ede);
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_typetransparent
|
||||
|| lz_type == local_zone_always_transparent) {
|
||||
@@ -1664,15 +1975,17 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
d.rr_len = &rr_len;
|
||||
d.rr_data = &rr_datas;
|
||||
d.rr_ttl = &rr_ttl;
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
&lrr, 1, LDNS_RCODE_NOERROR);
|
||||
return local_encode_ede(z, qinfo, env, edns, repinfo, buf, temp,
|
||||
&lrr, 1, LDNS_RCODE_NOERROR, LDNS_EDE_FORGED_ANSWER, "", do_ede);
|
||||
} else {
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf,
|
||||
/* NODATA: No EDE needed */
|
||||
local_error_encode(z, qinfo, env, edns, repinfo, buf,
|
||||
temp, LDNS_RCODE_NOERROR,
|
||||
(LDNS_RCODE_NOERROR|BIT_AA));
|
||||
(LDNS_RCODE_NOERROR|BIT_AA), -1, NULL, 0);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* else lz_type == local_zone_transparent */
|
||||
|
||||
/* if the zone is transparent and the name exists, but the type
|
||||
@@ -1682,8 +1995,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
if(z != NULL && z->soa && z->soa_negative)
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa_negative, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
/* NODATA: No EDE needed */
|
||||
local_error_encode(z, qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA), -1, NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1846,13 +2160,15 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
&& lzt != local_zone_always_nodata
|
||||
&& lzt != local_zone_always_deny
|
||||
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
|
||||
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
||||
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags,
|
||||
z->do_ede)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
/* We should tell the caller that encode is deferred if we found
|
||||
* a local alias. */
|
||||
return !qinfo->local_alias;
|
||||
}
|
||||
r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
|
||||
r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld,
|
||||
lzt, z->do_ede);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r && !qinfo->local_alias; /* see above */
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "util/module.h"
|
||||
#include "services/view.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct packed_rrset_data;
|
||||
struct ub_packed_rrset_key;
|
||||
struct regional;
|
||||
@@ -164,6 +165,10 @@ struct local_zone {
|
||||
* artificial negative SOA rrset (TTL is the minimum of the TTL and the
|
||||
* SOA.MINIMUM). */
|
||||
struct ub_packed_rrset_key* soa_negative;
|
||||
/** should local_data result in EDE (RFC8914) code inclusion? */
|
||||
int do_ede;
|
||||
/** the default EDE (RFC8914) code for this zone */
|
||||
int default_ede;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -343,7 +348,8 @@ int
|
||||
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
|
||||
struct local_data* ld, enum localzone_type lz_type);
|
||||
struct local_data* ld, enum localzone_type lz_type,
|
||||
int do_ede);
|
||||
|
||||
/**
|
||||
* Parse the string into localzone type.
|
||||
@@ -608,7 +614,7 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int labs, struct local_data** ldp,
|
||||
enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
|
||||
size_t tag_datas_size, char** tagname, int num_tags);
|
||||
size_t tag_datas_size, char** tagname, int num_tags, int do_ede);
|
||||
|
||||
/**
|
||||
* Add RR to local zone.
|
||||
|
||||
@@ -1290,6 +1290,22 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
&r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
r->edns.opt_list_inplace_cb_out = NULL;
|
||||
}
|
||||
/* Send along EDE BOGUS EDNS0 option when answer is bogus */
|
||||
if(rcode == LDNS_RCODE_SERVFAIL &&
|
||||
m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
|
||||
char *reason = m->s.env->cfg->val_log_level >= 2
|
||||
? errinf_to_str_bogus(&m->s) : NULL;
|
||||
sldns_ede_code reason_bogus = rep->reason_bogus != LDNS_EDE_DNSSEC_BOGUS
|
||||
? rep->reason_bogus : errinf_to_reason_bogus(&m->s);
|
||||
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out, m->s.region,
|
||||
reason_bogus, reason);
|
||||
free(reason);
|
||||
}
|
||||
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
|
||||
r->qflags, &r->edns);
|
||||
m->reply_list = NULL;
|
||||
@@ -1313,6 +1329,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
|
||||
r->edns.opt_list_inplace_cb_out = NULL;
|
||||
/* internal server error (probably malloc failure) so no
|
||||
* EDE (RFC8914) needed */
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
&m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||
}
|
||||
|
||||
+60
-14
@@ -513,6 +513,13 @@ rpz_create(struct config_auth* p)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Respond with EDEs (RFC 8914) in this zone*/
|
||||
if (p->rpz_do_ede)
|
||||
r->do_ede = 1;
|
||||
else
|
||||
r->do_ede = 0;
|
||||
|
||||
|
||||
r->taglistlen = p->rpz_taglistlen;
|
||||
r->taglist = memdup(p->rpz_taglist, r->taglistlen);
|
||||
if(p->rpz_action_override) {
|
||||
@@ -542,6 +549,7 @@ rpz_create(struct config_auth* p)
|
||||
}
|
||||
}
|
||||
r->log = p->rpz_log;
|
||||
r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra;
|
||||
if(p->rpz_log_name) {
|
||||
if(!(r->log_name = strdup(p->rpz_log_name))) {
|
||||
log_err("malloc failure on RPZ log_name strdup");
|
||||
@@ -836,7 +844,7 @@ rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
|
||||
}
|
||||
|
||||
/* from localzone.c; difference is we don't have a dname */
|
||||
struct local_rrset*
|
||||
static struct local_rrset*
|
||||
rpz_clientip_new_rrset(struct regional* region,
|
||||
struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass)
|
||||
{
|
||||
@@ -1384,9 +1392,9 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
|
||||
if(dname) {
|
||||
dname_str(dname, dnamestr);
|
||||
} else if(addrnode) {
|
||||
char a[128];
|
||||
addr_to_str(&addrnode->addr, addrnode->addrlen, a, sizeof(a));
|
||||
snprintf(dnamestr, sizeof(dnamestr), "%s/%d", a, addrnode->net);
|
||||
char addrbuf[128];
|
||||
addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf));
|
||||
snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net);
|
||||
} else {
|
||||
dnamestr[0]=0;
|
||||
}
|
||||
@@ -1697,7 +1705,7 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
|
||||
if(msg == NULL) { return msg; }
|
||||
msg->qinfo = *qinfo;
|
||||
msg->rep = construct_reply_info_base(ms->region,
|
||||
LDNS_RCODE_NOERROR | BIT_RD | BIT_QR | BIT_AA | BIT_RA,
|
||||
LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
|
||||
1, /* qd */
|
||||
0, /* ttl */
|
||||
0, /* prettl */
|
||||
@@ -1715,14 +1723,18 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
|
||||
}
|
||||
|
||||
static inline struct dns_msg*
|
||||
rpz_synthesize_nxdomain(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
|
||||
rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
|
||||
struct query_info* qinfo, struct auth_zone* az)
|
||||
{
|
||||
struct dns_msg* msg = rpz_dns_msg_new(ms->region);
|
||||
uint16_t flags;
|
||||
if(msg == NULL) { return msg; }
|
||||
msg->qinfo = *qinfo;
|
||||
flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA;
|
||||
if(r->signal_nxdomain_ra)
|
||||
flags &= ~BIT_RA;
|
||||
msg->rep = construct_reply_info_base(ms->region,
|
||||
LDNS_RCODE_NXDOMAIN | BIT_RD | BIT_QR | BIT_AA | BIT_RA,
|
||||
flags,
|
||||
1, /* qd */
|
||||
0, /* ttl */
|
||||
0, /* prettl */
|
||||
@@ -1752,7 +1764,7 @@ rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qs
|
||||
if(msg == NULL) { return NULL; }
|
||||
|
||||
new_reply_info = construct_reply_info_base(ms->region,
|
||||
LDNS_RCODE_NOERROR | BIT_RD | BIT_QR | BIT_AA | BIT_RA,
|
||||
LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
|
||||
1, /* qd */
|
||||
0, /* ttl */
|
||||
0, /* prettl */
|
||||
@@ -1888,6 +1900,8 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
|
||||
{
|
||||
struct local_data* ld = NULL;
|
||||
int ret = 0;
|
||||
int do_ede = 0;
|
||||
|
||||
if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
|
||||
qinfo->local_alias = regional_alloc_zero(temp, sizeof(struct local_rrset));
|
||||
if(qinfo->local_alias == NULL) {
|
||||
@@ -1908,9 +1922,13 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check the rpz if we want to respond with EDE (RFC8914) */
|
||||
if (r->do_ede)
|
||||
do_ede = r->do_ede;
|
||||
|
||||
if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
|
||||
edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
|
||||
&ld, lzt, -1, NULL, 0, NULL, 0)) {
|
||||
&ld, lzt, -1, NULL, 0, NULL, 0, do_ede)) {
|
||||
if(r->log) {
|
||||
log_rpz_apply("qname", z->name, NULL,
|
||||
localzone_type_to_rpz_action(lzt), qinfo,
|
||||
@@ -1921,7 +1939,10 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
|
||||
}
|
||||
|
||||
ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
|
||||
0 /* no local data used */, lzt);
|
||||
0 /* no local data used */, lzt, do_ede);
|
||||
if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
|
||||
== LDNS_RCODE_NXDOMAIN)
|
||||
LDNS_RA_CLR(sldns_buffer_begin(buf));
|
||||
if(r->log) {
|
||||
log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt),
|
||||
qinfo, repinfo, NULL, r->log_name);
|
||||
@@ -1930,7 +1951,7 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct clientip_synthesized_rr*
|
||||
static struct clientip_synthesized_rr*
|
||||
rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is)
|
||||
{
|
||||
struct delegpt_addr* cursor;
|
||||
@@ -1947,7 +1968,7 @@ rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate*
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dns_msg*
|
||||
static struct dns_msg*
|
||||
rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
|
||||
struct clientip_synthesized_rr* raddr, struct auth_zone* az)
|
||||
{
|
||||
@@ -2006,7 +2027,7 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct dns_msg*
|
||||
static struct dns_msg*
|
||||
rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
|
||||
struct local_zone* z, struct matched_delegation_point const* match,
|
||||
struct auth_zone* az)
|
||||
@@ -2268,6 +2289,7 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
|
||||
enum rpz_action client_action;
|
||||
struct clientip_synthesized_rr* node = rpz_resolve_client_action_and_zone(
|
||||
az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
|
||||
int do_ede;
|
||||
|
||||
client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
|
||||
|
||||
@@ -2292,9 +2314,19 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
|
||||
(node?&node->node:NULL),
|
||||
client_action, qinfo, repinfo, NULL,
|
||||
(*r_out)->log_name);
|
||||
/* check the rpz zone if we want to respond with EDE (RFC8914) */
|
||||
if (*r_out && (*r_out)->do_ede)
|
||||
do_ede = (*r_out)->do_ede;
|
||||
else
|
||||
do_ede = 0;
|
||||
|
||||
local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns,
|
||||
repinfo, buf, temp, 0 /* no local data used */,
|
||||
rpz_action_to_localzone_type(client_action));
|
||||
rpz_action_to_localzone_type(client_action), do_ede);
|
||||
if(*r_out && (*r_out)->signal_nxdomain_ra &&
|
||||
LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
|
||||
== LDNS_RCODE_NXDOMAIN)
|
||||
LDNS_RA_CLR(sldns_buffer_begin(buf));
|
||||
}
|
||||
ret = 1;
|
||||
goto done;
|
||||
@@ -2380,3 +2412,17 @@ void rpz_disable(struct rpz* r)
|
||||
return;
|
||||
r->disabled = 1;
|
||||
}
|
||||
|
||||
void rpz_do_ede_enable(struct rpz* r)
|
||||
{
|
||||
if(!r)
|
||||
return;
|
||||
r->do_ede = 1;
|
||||
}
|
||||
|
||||
void rpz_do_ede_disable(struct rpz* r)
|
||||
{
|
||||
if(!r)
|
||||
return;
|
||||
r->do_ede = 0;
|
||||
}
|
||||
|
||||
@@ -123,8 +123,11 @@ struct rpz {
|
||||
struct ub_packed_rrset_key* cname_override;
|
||||
int log;
|
||||
char* log_name;
|
||||
/** signal NXDOMAIN blocked with unset RA flag */
|
||||
int signal_nxdomain_ra;
|
||||
struct regional* region;
|
||||
int disabled;
|
||||
int do_ede;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -259,4 +262,16 @@ void rpz_enable(struct rpz* r);
|
||||
*/
|
||||
void rpz_disable(struct rpz* r);
|
||||
|
||||
/**
|
||||
* Enable RPZ EDE (RFC 8914) responses
|
||||
* @param r: RPZ struct containing member to disable
|
||||
*/
|
||||
void rpz_do_ede_enable(struct rpz* r);
|
||||
|
||||
/**
|
||||
* Disable RPZ EDE (RFC 8914) responses
|
||||
* @param r: RPZ struct containing member to disable
|
||||
*/
|
||||
void rpz_do_ede_disable(struct rpz* r);
|
||||
|
||||
#endif /* SERVICES_RPZ_H */
|
||||
|
||||
@@ -97,18 +97,22 @@ extern "C" {
|
||||
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
|
||||
*/
|
||||
#define LDNS_QDCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
|
||||
#define LDNS_QDCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_QDCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the answer section */
|
||||
#define LDNS_ANCOUNT_OFF 6
|
||||
#define LDNS_ANCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
|
||||
#define LDNS_ANCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ANCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the authority section */
|
||||
#define LDNS_NSCOUNT_OFF 8
|
||||
#define LDNS_NSCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
|
||||
#define LDNS_NSCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_NSCOUNT_OFF, i))
|
||||
|
||||
/* Counter of the additional section */
|
||||
#define LDNS_ARCOUNT_OFF 10
|
||||
#define LDNS_ARCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
|
||||
#define LDNS_ARCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ARCOUNT_OFF, i))
|
||||
|
||||
/**
|
||||
* The sections of a packet
|
||||
|
||||
@@ -435,10 +435,41 @@ enum sldns_enum_edns_option
|
||||
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
|
||||
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
|
||||
LDNS_EDNS_PADDING = 12, /* RFC7830 */
|
||||
LDNS_EDNS_EDE = 15, /* RFC8914 */
|
||||
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
|
||||
};
|
||||
typedef enum sldns_enum_edns_option sldns_edns_option;
|
||||
|
||||
enum sldns_enum_ede_code
|
||||
{
|
||||
LDNS_EDE_OTHER = 0,
|
||||
LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
|
||||
LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
|
||||
LDNS_EDE_STALE_ANSWER = 3,
|
||||
LDNS_EDE_FORGED_ANSWER = 4,
|
||||
LDNS_EDE_DNSSEC_INDETERMINATE = 5,
|
||||
LDNS_EDE_DNSSEC_BOGUS = 6,
|
||||
LDNS_EDE_SIGNATURE_EXPIRED = 7,
|
||||
LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
|
||||
LDNS_EDE_DNSKEY_MISSING = 9,
|
||||
LDNS_EDE_RRSIGS_MISSING = 10,
|
||||
LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
|
||||
LDNS_EDE_NSEC_MISSING = 12,
|
||||
LDNS_EDE_CACHED_ERROR = 13,
|
||||
LDNS_EDE_NOT_READY = 14,
|
||||
LDNS_EDE_BLOCKED = 15,
|
||||
LDNS_EDE_CENSORED = 16,
|
||||
LDNS_EDE_FILTERED = 17,
|
||||
LDNS_EDE_PROHIBITED = 18,
|
||||
LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
|
||||
LDNS_EDE_NOT_AUTHORITATIVE = 20,
|
||||
LDNS_EDE_NOT_SUPPORTED = 21,
|
||||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||
LDNS_EDE_NETWORK_ERROR = 23,
|
||||
LDNS_EDE_INVALID_DATA = 24
|
||||
};
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
#define LDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
|
||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||
|
||||
+3
-2
@@ -543,9 +543,10 @@ sldns_parse_rdf_token(sldns_buffer* strbuf, char* token, size_t token_len,
|
||||
{
|
||||
size_t slen;
|
||||
|
||||
/* skip spaces */
|
||||
/* skip spaces and tabs */
|
||||
while(sldns_buffer_remaining(strbuf) > 0 && !*quoted &&
|
||||
*(sldns_buffer_current(strbuf)) == ' ') {
|
||||
(*(sldns_buffer_current(strbuf)) == ' ' ||
|
||||
*(sldns_buffer_current(strbuf)) == '\t')) {
|
||||
sldns_buffer_skip(strbuf, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -691,6 +691,8 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "dns64 iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip dns64 validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip dns64 iterator") != 0
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&& strcmp(cfg->module_conf, "python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip iterator") != 0
|
||||
|
||||
+82
-8
@@ -128,6 +128,8 @@ static void matchline(char* line, struct entry* e)
|
||||
e->match_answer = 1;
|
||||
} else if(str_keyword(&parse, "subdomain")) {
|
||||
e->match_subdomain = 1;
|
||||
} else if(str_keyword(&parse, "all_noedns")) {
|
||||
e->match_all_noedns = 1;
|
||||
} else if(str_keyword(&parse, "all")) {
|
||||
e->match_all = 1;
|
||||
} else if(str_keyword(&parse, "ttl")) {
|
||||
@@ -148,7 +150,15 @@ static void matchline(char* line, struct entry* e)
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((unsigned char)*parse))
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else if(str_keyword(&parse, "ede")) {
|
||||
e->match_ede = 1;
|
||||
if(*parse != '=' && *parse != ':')
|
||||
error("expected = or : in MATCH: %s", line);
|
||||
parse++;
|
||||
e->ede_info_code = (uint16_t)strtol(parse, (char**)&parse, 10);
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
} else {
|
||||
error("could not parse MATCH: '%s'", parse);
|
||||
@@ -266,11 +276,14 @@ static struct entry* new_entry(void)
|
||||
e->match_answer = 0;
|
||||
e->match_subdomain = 0;
|
||||
e->match_all = 0;
|
||||
e->match_all_noedns = 0;
|
||||
e->match_ttl = 0;
|
||||
e->match_do = 0;
|
||||
e->match_noedns = 0;
|
||||
e->match_serial = 0;
|
||||
e->ixfr_soa_serial = 0;
|
||||
e->match_ede = 0;
|
||||
e->ede_info_code = 0;
|
||||
e->match_transport = transport_any;
|
||||
e->reply_list = NULL;
|
||||
e->copy_id = 0;
|
||||
@@ -817,7 +830,7 @@ static uint32_t get_serial(uint8_t* p, size_t plen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** get ptr to EDNS OPT record (and remaining length); behind the type u16 */
|
||||
/** get ptr to EDNS OPT record (and remaining length); after the type u16 */
|
||||
static int
|
||||
pkt_find_edns_opt(uint8_t** p, size_t* plen)
|
||||
{
|
||||
@@ -884,6 +897,30 @@ get_do_flag(uint8_t* pkt, size_t len)
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
|
||||
}
|
||||
|
||||
/** return the EDNS EDE INFO-CODE if found, else -1 */
|
||||
static int
|
||||
get_ede_info_code(uint8_t* pkt, size_t len)
|
||||
{
|
||||
uint8_t *rdata;
|
||||
uint16_t rdlen, optlen;
|
||||
/* use arguments as temporary variables */
|
||||
if(!pkt_find_edns_opt(&pkt, &len)) return -1;
|
||||
if(len < 8) return -1; /* malformed */
|
||||
rdlen = sldns_read_uint16(pkt+6);
|
||||
rdata = pkt + 8;
|
||||
while(rdlen > 0) {
|
||||
if(rdlen < 4) return -1; /* malformed */
|
||||
if(sldns_read_uint16(rdata) == LDNS_EDNS_EDE) {
|
||||
if(rdlen < 6) return -1; /* malformed */
|
||||
return sldns_read_uint16(rdata+4);
|
||||
}
|
||||
optlen = sldns_read_uint16(rdata+2);
|
||||
rdlen -= optlen;
|
||||
rdata += 4 + optlen;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** zero TTLs in packet */
|
||||
static void
|
||||
zerottls(uint8_t* pkt, size_t pktlen)
|
||||
@@ -1201,7 +1238,7 @@ match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
|
||||
/* remove after answer section, (;; ANS, ;; AUTH, ;; ADD ..) */
|
||||
s = strstr(qcmpstr, ";; ANSWER SECTION");
|
||||
if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION");
|
||||
if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
|
||||
@@ -1292,10 +1329,28 @@ match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
|
||||
return r;
|
||||
}
|
||||
|
||||
/** ignore EDNS lines in the string by overwriting them with what's left or
|
||||
* zero out if at end of the string */
|
||||
static int
|
||||
ignore_edns_lines(char* str) {
|
||||
char* current = str, *edns = str, *n;
|
||||
size_t str_len = strlen(str);
|
||||
while((edns = strstr(edns, "; EDNS"))) {
|
||||
n = strchr(edns, '\n');
|
||||
if(!n) {
|
||||
/* EDNS at end of string; zero */
|
||||
*edns = 0;
|
||||
break;
|
||||
}
|
||||
memmove(edns, n+1, str_len-(n-str));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** match all of the packet */
|
||||
int
|
||||
match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
int noloc)
|
||||
int noloc, int noedns)
|
||||
{
|
||||
char* qstr, *pstr;
|
||||
uint8_t* qb = q, *pb = p;
|
||||
@@ -1313,6 +1368,11 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
qstr = sldns_wire2str_pkt(qb, qlen);
|
||||
pstr = sldns_wire2str_pkt(pb, plen);
|
||||
if(!qstr || !pstr) error("cannot pkt2string");
|
||||
/* should we ignore EDNS lines? */
|
||||
if(noedns) {
|
||||
ignore_edns_lines(qstr);
|
||||
ignore_edns_lines(pstr);
|
||||
}
|
||||
r = (strcmp(qstr, pstr) == 0);
|
||||
if(!r) {
|
||||
/* remove ;; MSG SIZE (at end of string) */
|
||||
@@ -1321,8 +1381,8 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
s = strstr(pstr, ";; MSG SIZE");
|
||||
if(s) *s=0;
|
||||
r = (strcmp(qstr, pstr) == 0);
|
||||
if(!r && !noloc) {
|
||||
/* we are going to fail see if it is because of EDNS */
|
||||
if(!r && !noloc && !noedns) {
|
||||
/* we are going to fail, see if the cause is EDNS */
|
||||
char* a = strstr(qstr, "; EDNS");
|
||||
char* b = strstr(pstr, "; EDNS");
|
||||
if( (a&&!b) || (b&&!a) ) {
|
||||
@@ -1434,7 +1494,7 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "comparepkt: ");
|
||||
reply = p->reply_list->reply_pkt;
|
||||
rlen = p->reply_list->reply_len;
|
||||
if(p->match_opcode && get_opcode(query_pkt, len) !=
|
||||
if(p->match_opcode && get_opcode(query_pkt, len) !=
|
||||
get_opcode(reply, rlen)) {
|
||||
verbose(3, "bad opcode\n");
|
||||
continue;
|
||||
@@ -1485,6 +1545,15 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "bad serial\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_ede) {
|
||||
int info_code = get_ede_info_code(query_pkt, len);
|
||||
if(info_code == -1 ||
|
||||
(uint16_t)info_code != p->ede_info_code) {
|
||||
verbose(3, "bad EDE INFO-CODE. Expected: %d, and got: %d\n",
|
||||
p->ede_info_code, info_code);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(p->match_do && !get_do_flag(query_pkt, len)) {
|
||||
verbose(3, "no DO bit set\n");
|
||||
continue;
|
||||
@@ -1502,8 +1571,13 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "bad transport\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_all_noedns && !match_all(query_pkt, len, reply,
|
||||
rlen, (int)p->match_ttl, 0, 1)) {
|
||||
verbose(3, "bad all_noedns match\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_all && !match_all(query_pkt, len, reply, rlen,
|
||||
(int)p->match_ttl, 0)) {
|
||||
(int)p->match_ttl, 0, 0)) {
|
||||
verbose(3, "bad allmatch\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
+35
-17
@@ -40,20 +40,25 @@ struct sldns_file_parse_state;
|
||||
ENTRY_BEGIN
|
||||
; first give MATCH lines, that say what queries are matched
|
||||
; by this entry.
|
||||
; 'opcode' makes the query match the opcode from the reply
|
||||
; if you leave it out, any opcode matches this entry.
|
||||
; 'qtype' makes the query match the qtype from the reply
|
||||
; 'qname' makes the query match the qname from the reply
|
||||
; 'subdomain' makes the query match subdomains of qname from the reply
|
||||
; 'serial=1023' makes the query match if ixfr serial is 1023.
|
||||
; 'opcode' makes the query match the opcode from the reply;
|
||||
; if you leave it out, any opcode matches this entry.
|
||||
; 'qtype' makes the query match the qtype from the reply.
|
||||
; 'qname' makes the query match the qname from the reply.
|
||||
; 'subdomain' makes the query match subdomains of qname from the reply.
|
||||
; 'serial=1023' makes the query match if ixfr serial is 1023.
|
||||
; 'all' has to match header byte for byte and all rrs in packet.
|
||||
; 'all_noedns' has to match header byte for byte and all rrs in packet;
|
||||
; ignoring EDNS.
|
||||
; 'ttl' used with all, rrs in packet must also have matching TTLs.
|
||||
; 'DO' will match only queries with DO bit set.
|
||||
; 'noedns' matches queries without EDNS OPT records.
|
||||
; 'rcode' makes the query match the rcode from the reply
|
||||
; 'question' makes the query match the question section
|
||||
; 'answer' makes the query match the answer section
|
||||
; 'rcode' makes the query match the rcode from the reply.
|
||||
; 'question' makes the query match the question section.
|
||||
; 'answer' makes the query match the answer section.
|
||||
; 'ednsdata' matches queries to HEX_EDNS section.
|
||||
; 'UDP' matches if the transport is UDP.
|
||||
; 'TCP' matches if the transport is TCP.
|
||||
; 'ede=2' makes the query match if the EDNS EDE info-code is 2.
|
||||
MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
|
||||
MATCH [UDP|TCP] DO
|
||||
MATCH ...
|
||||
@@ -72,6 +77,12 @@ struct sldns_file_parse_state;
|
||||
; 'sleep=10' sleeps for 10 seconds before giving the answer (TCP is open)
|
||||
ADJUST [sleep=<num>] ; sleep before giving any reply
|
||||
ADJUST [packet_sleep=<num>] ; sleep before this packet in sequence
|
||||
; 'copy_ednsdata_assume_clientsubnet' copies ednsdata to reply, assumes
|
||||
; it is clientsubnet and adjusts scopemask to match sourcemask.
|
||||
ADJUST copy_ednsdata_assume_clientsubnet
|
||||
; 'increment_ecs_scope' increments the ECS scope copied from the
|
||||
; sourcemask by one.
|
||||
ADJUST increment_ecs_scope
|
||||
SECTION QUESTION
|
||||
<RRs, one per line> ; the RRcount is determined automatically.
|
||||
SECTION ANSWER
|
||||
@@ -167,11 +178,11 @@ struct entry {
|
||||
/* match */
|
||||
/* How to match an incoming query with this canned reply */
|
||||
/** match query opcode with answer opcode */
|
||||
uint8_t match_opcode;
|
||||
uint8_t match_opcode;
|
||||
/** match qtype with answer qtype */
|
||||
uint8_t match_qtype;
|
||||
uint8_t match_qtype;
|
||||
/** match qname with answer qname */
|
||||
uint8_t match_qname;
|
||||
uint8_t match_qname;
|
||||
/** match rcode with answer rcode */
|
||||
uint8_t match_rcode;
|
||||
/** match question section */
|
||||
@@ -179,11 +190,15 @@ struct entry {
|
||||
/** match answer section */
|
||||
uint8_t match_answer;
|
||||
/** match qname as subdomain of answer qname */
|
||||
uint8_t match_subdomain;
|
||||
uint8_t match_subdomain;
|
||||
/** match SOA serial number, from auth section */
|
||||
uint8_t match_serial;
|
||||
uint8_t match_serial;
|
||||
/** match EDNS EDE info-code */
|
||||
uint8_t match_ede;
|
||||
/** match all of the packet */
|
||||
uint8_t match_all;
|
||||
/** match all of the packet; ignore EDNS */
|
||||
uint8_t match_all_noedns;
|
||||
/** match ttls in the packet */
|
||||
uint8_t match_ttl;
|
||||
/** match DO bit */
|
||||
@@ -193,9 +208,11 @@ struct entry {
|
||||
/** match edns data field given in hex */
|
||||
uint8_t match_ednsdata_raw;
|
||||
/** match query serial with this value. */
|
||||
uint32_t ixfr_soa_serial;
|
||||
uint32_t ixfr_soa_serial;
|
||||
/** match on UDP/TCP */
|
||||
enum transport_type match_transport;
|
||||
enum transport_type match_transport;
|
||||
/** match EDNS EDE info-code with this value. */
|
||||
uint16_t ede_info_code;
|
||||
|
||||
/** pre canned reply */
|
||||
struct reply_packet *reply_list;
|
||||
@@ -260,10 +277,11 @@ struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
|
||||
* @param mttl: if true, ttls must match, if false, ttls do not need to match
|
||||
* @param noloc: if true, rrs may be reordered in their packet-section.
|
||||
* rrs are then matches without location of the rr being important.
|
||||
* @param noedns: if true, edns is not compared, if false, edns must match.
|
||||
* @return true if matched.
|
||||
*/
|
||||
int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
|
||||
int noloc);
|
||||
int noloc, int noedns);
|
||||
|
||||
/**
|
||||
* copy & adjust packet, mallocs a copy.
|
||||
|
||||
@@ -137,7 +137,7 @@ test_buffers(sldns_buffer* pkt, sldns_buffer* out)
|
||||
/* compare packets */
|
||||
unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
|
||||
sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
|
||||
matches_nolocation));
|
||||
matches_nolocation, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -150,7 +150,7 @@ ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
Vendored
+1
-1
@@ -138,7 +138,7 @@ ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
Vendored
+1
-1
@@ -155,7 +155,7 @@ ENTRY_END
|
||||
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
Vendored
+1
-1
@@ -155,7 +155,7 @@ ENTRY_END
|
||||
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
Vendored
+2
-2
@@ -578,7 +578,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
@@ -595,7 +595,7 @@ ENTRY_END
|
||||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
|
||||
Vendored
+2
-2
@@ -560,7 +560,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
@@ -577,7 +577,7 @@ ENTRY_END
|
||||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.sub.example.com. IN A
|
||||
|
||||
Vendored
+2
-2
@@ -285,7 +285,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=7
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
@@ -304,7 +304,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ftp.example.com. IN A
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
rm -f K* piece1 base expired notyetincepted trust-anchors dnssec-failures.test.signed dnskey-failures.test.signed nsec-failures.test.signed rrsig-failures.test.signed
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
$ORIGIN dnskey-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
$ORIGIN dnssec-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
NS ns
|
||||
ns A 192.0.2.1
|
||||
notyetincepted TXT "Not yet incepted"
|
||||
expired TXT "Expired"
|
||||
sigsinvalid TXT "Signatures invalid"
|
||||
missingrrsigs TXT "Signatures missing"
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# create oudated zones
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnssec-failures.test`
|
||||
echo $CSK
|
||||
|
||||
echo ". IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d" | \
|
||||
cat $CSK.ds - > bogus/trust-anchors
|
||||
|
||||
ONEMONTHAGO=`date -d 'now - 1 month' +%Y%m%d`
|
||||
YESTERDAY=`date -d 'now - 2 days' +%Y%m%d`
|
||||
TOMORROW=`date -d 'now + 2 days' +%Y%m%d`
|
||||
ldns-signzone -i $YESTERDAY bogus/dnssec-failures.test $CSK -f - | \
|
||||
grep -v '^missingrrsigs\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
|
||||
sed 's/Signatures invalid/Signatures INVALID/g' | \
|
||||
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' | \
|
||||
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
|
||||
grep -v '^expired\.dnssec-failures\.test\..*IN.*TXT' | \
|
||||
grep -v '^expired\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' > base
|
||||
ldns-signzone -i $ONEMONTHAGO -e $YESTERDAY bogus/dnssec-failures.test $CSK -f - | \
|
||||
grep -v '[ ]NSEC[ ]' | \
|
||||
grep '^expired\.dnssec-failures\.test\..*IN.*TXT' > expired
|
||||
ldns-signzone -i $TOMORROW bogus/dnssec-failures.test $CSK -f - | \
|
||||
grep -v '[ ]NSEC[ ]' | \
|
||||
grep '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' > notyetincepted
|
||||
|
||||
cat base expired notyetincepted > bogus/dnssec-failures.test.signed
|
||||
|
||||
# create zone with DNSKEY missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnskey-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone bogus/dnskey-failures.test $CSK -f tmp.signed
|
||||
grep -v ' DNSKEY ' tmp.signed > bogus/dnskey-failures.test.signed
|
||||
|
||||
# create zone with NSEC missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom nsec-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone bogus/nsec-failures.test $CSK -f tmp.signed
|
||||
grep -v ' NSEC ' tmp.signed > bogus/nsec-failures.test.signed
|
||||
|
||||
# create zone with RRSIGs missing
|
||||
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom rrsig-failures.test`
|
||||
echo $CSK
|
||||
cat $CSK.ds >> bogus/trust-anchors
|
||||
|
||||
ldns-signzone bogus/rrsig-failures.test $CSK -f tmp.signed
|
||||
grep -v ' RRSIG ' tmp.signed > bogus/rrsig-failures.test.signed
|
||||
|
||||
# cleanup
|
||||
rm -f base expired notyetincepted tmp.signed $CSK.*
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
$ORIGIN nsec-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
$ORIGIN rrsig-failures.test.
|
||||
|
||||
@ SOA ns hostmaster (
|
||||
1 ; serial
|
||||
14400 ; refresh (4 hours)
|
||||
1800 ; retry (30 minutes)
|
||||
2419200 ; expire (4 weeks)
|
||||
300 ; minimum (5 minutes)
|
||||
)
|
||||
A 192.0.2.1
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
server:
|
||||
verbosity: 1
|
||||
use-syslog: no
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
local-zone: test nodefault
|
||||
port: @PORT2@
|
||||
|
||||
auth-zone:
|
||||
name: "dnssec-failures.test"
|
||||
zonefile: "bogus/dnssec-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "dnskey-failures.test"
|
||||
zonefile: "bogus/dnskey-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "nsec-failures.test"
|
||||
zonefile: "bogus/nsec-failures.test.signed"
|
||||
|
||||
auth-zone:
|
||||
name: "rrsig-failures.test"
|
||||
zonefile: "bogus/rrsig-failures.test.signed"
|
||||
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
server:
|
||||
verbosity: 2
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
directory: ""
|
||||
val-log-level: 2
|
||||
|
||||
# @TODO change this to local file
|
||||
#auto-trust-anchor-file: "/var/lib/unbound/root.key"
|
||||
trust-anchor-file: "bogus/trust-anchors"
|
||||
|
||||
module-config: "respip validator iterator"
|
||||
|
||||
access-control: 127.0.0.2/32 refuse
|
||||
|
||||
#ede-local-zones: yes
|
||||
|
||||
local-zone: hopsa.kidee. always_refuse
|
||||
#local-zone-do-ede: hopsa.kidee. yes
|
||||
local-data: "hopsa.kidee. TXT hela hola"
|
||||
|
||||
local-zone: nlnetlabs.nl transparent
|
||||
local-data: "hopsa.nlnetlabs.nl. TXT hela hola"
|
||||
|
||||
local-zone: uva.nl. always_null
|
||||
|
||||
local-zone: example.com redirect
|
||||
local-data: "example.com CNAME *.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa."
|
||||
|
||||
local-zone: test nodefault
|
||||
do-not-query-localhost: no
|
||||
|
||||
# @TODO add rpz?
|
||||
#rpz-do-ede: yes
|
||||
|
||||
forward-zone:
|
||||
name: "dnssec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "dnskey-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "nsec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
name: "rrsig-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: svcb
|
||||
Version: 1.0
|
||||
Description: Test Extended DNS Errors (rfc8914)
|
||||
CreationDate: Fri Aug 20 15:42:11 UTC 2021
|
||||
Maintainer: Tom Carpay
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre:
|
||||
Post:
|
||||
Test: ede.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
# #-- fwd_tcp.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT fwd_tcp.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < fwd_tcp.conf > ub.conf
|
||||
# start unbound in the background
|
||||
PRE="../.."
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
# #-- fwd_tcp.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT fwd_tcp.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# rewrite config file with created ports
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < fwd_tcp.conf > ub.conf
|
||||
|
||||
# start unbound in the background
|
||||
PRE="../.."
|
||||
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
Vendored
+203
@@ -0,0 +1,203 @@
|
||||
# #-- svcb.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
UNBOUND_PORT2=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "UNBOUND_PORT2=$UNBOUND_PORT2" >> .tpkg.var.test
|
||||
|
||||
# rewrite config file with created ports
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' < ede.conf > temp.conf
|
||||
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < temp.conf > ub.conf
|
||||
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < ede-auth.conf > ub2.conf
|
||||
|
||||
# create broken dnssec zone
|
||||
bogus/make-broken-zone.sh
|
||||
|
||||
# start unbound in the background
|
||||
PRE="../.."
|
||||
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
# start authoritative unbound in the background
|
||||
$PRE/unbound -d -c ub2.conf > unbound.log 2>&1 &
|
||||
UNBOUND_PID2=$!
|
||||
echo "UNBOUND_PID2=$UNBOUND_PID2" >> .tpkg.var.test
|
||||
|
||||
# @TODO did we fix this? -> we do not trigger this anymore
|
||||
# # query with bad edns keepalive
|
||||
# dig @127.0.0.1 -p $UNBOUND_PORT +tcp +ednsopt=11:010203 > keepalive.txt
|
||||
#
|
||||
# if ! grep -q "OPT=15: 00 00 71 75 65 72 79 20 77 69 74 68 20 62 61 64 20 65 64 6e 73 20 6b 65 65 70 61 6c 69 76 65" keepalive.txt
|
||||
# then
|
||||
# echo "Incorect bad edns keepalive output"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# refused nonrec (cache snoop) (Not Auth)
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT +norec > snoop.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 14" snoop.txt
|
||||
then
|
||||
echo "Incorect cache snoop output"
|
||||
cat snoop.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# local-zone always_refuse
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT qwerqwer.hopsa.kidee. TXT +dnssec > local_zone_refuse.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 0f" local_zone_refuse.txt
|
||||
then
|
||||
echo "query to qwerqwer.hopsa.kidee. should be EDE blocked"
|
||||
cat local_zone_refuse.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# DNAME expansion
|
||||
# @TODO do we have this?
|
||||
|
||||
|
||||
# RPZ DNAME expansion too long
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.qhqwer.qwer.qwer.h.example.com A > dname_expansion.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 00 44 4e 41 4d 45 20 65 78 70 61 6e 73 69 6f 6e 20 62 65 63 61 6d 65 20 74 6f 6f 20 6c 61 72 67 65" dname_expansion.txt
|
||||
then
|
||||
echo "No DNAME expansion for CNAME EDE message"
|
||||
cat dname_expansion.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# local-zone always_null gets EDE forged
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT uva.nl A > local_zone_always_null_forged.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 04" local_zone_always_null_forged.txt
|
||||
then
|
||||
echo "local-zone always_null must have EDE forged code"
|
||||
cat local_zone_always_null_forged.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# RPZ always_refuse
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT hopsa.kidee. A > local_zone_rpz_always_refuse.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 0f" local_zone_rpz_always_refuse.txt
|
||||
then
|
||||
echo "local-zone always_refuse must have EDE blocked code"
|
||||
cat local_zone_rpz_always_refuse.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# @TODO trigger mesh DNSSEC bogus
|
||||
|
||||
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT servfail.nl > servfail.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 07" servfail.txt
|
||||
then
|
||||
echo "query to servfail.nl should return EDE signature expired"
|
||||
cat servfail.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# local data forged answer
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT hopsa.nlnetlabs.nl TXT > local_data_forged.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 04" local_data_forged.txt
|
||||
then
|
||||
echo "query to hopsa.nlnetlabs.nl does not give EDE forged"
|
||||
cat local_data_forged.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ACL refused, EDE prohibited
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT -b 127.0.0.2 example.com > acl_refused.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 12" acl_refused.txt
|
||||
then
|
||||
echo "ACL refused does not give EDE prohibited"
|
||||
cat acl_refused.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# start authoritative unbound in the background
|
||||
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
|
||||
UNBOUND_PID2=$!
|
||||
echo "UNBOUND_PID2=$UNBOUND_PID2" >> .tpkg.var.test
|
||||
|
||||
# DNSSEC failure: key not incepted
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT notyetincepted.dnssec-failures.test. TXT +dnssec > sig_notyetincepted.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 08" sig_notyetincepted.txt
|
||||
then
|
||||
echo "Signature not yet valid does not return EDE Signature Not Yet Valid"
|
||||
cat sig_notyetincepted.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# DNSSEC failure: key expired
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT expired.dnssec-failures.test. TXT +dnssec > sig_expired.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 07" sig_expired.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE Signature expired"
|
||||
cat sig_expired.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# DNSSEC failure: missing rrsigs
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT missingrrsigs.dnssec-failures.test. TXT +dnssec > missingrrsigs.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 0a" missingrrsigs.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE RRSIGs missing"
|
||||
cat missingrrsigs.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with DNSKEY missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT dnskey-failures.test > dnskey-failure.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 09" dnskey-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE DNSKEY missing"
|
||||
cat dnskey-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with RRSIGs missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT rrsig-failures.test > rrsig-failure.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 0a" rrsig-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE RRSIGs missing"
|
||||
cat rrsig-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# signed zone with NSEC missing
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT abc.nsec-failures.test > nsec-failure.txt
|
||||
|
||||
if ! grep -q "OPT=15: 00 0c" nsec-failure.txt
|
||||
then
|
||||
echo "Expired signature does not return EDE NSEC missing"
|
||||
cat nsec-failure.txt
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# @TODO DNSSEC indeterminate
|
||||
|
||||
# @TODO touch other validator codepath: val_inform_super() -> touched by other .rpls!
|
||||
|
||||
# teardown
|
||||
kill_pid $UNBOUND_PID
|
||||
kill_pid $UNBOUND_PID2
|
||||
Vendored
+1
-5
@@ -47,14 +47,10 @@ STEP 1 QUERY
|
||||
STEP 10 CHECK_ANSWER
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP ednsdata
|
||||
MATCH TCP
|
||||
REPLY RD FORMERR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; Empty
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
|
||||
Vendored
+54
@@ -45,9 +45,32 @@ server:
|
||||
local-data: "b.c.implicit. A 20.30.45.50"
|
||||
local-data: "c.c.implicit. A 20.30.44.50"
|
||||
|
||||
; create implicit data in the ANY domain
|
||||
; this should inherit the local_zone_type of the already configured
|
||||
; zone 'refuse.top.' and not be transparent
|
||||
local-data: "refuse.top. ANY TXT implicit_non_transparent"
|
||||
|
||||
stub-zone:
|
||||
name: "refuse.top"
|
||||
stub-addr: 1.2.3.4
|
||||
|
||||
CONFIG_END
|
||||
SCENARIO_BEGIN Test local data queries
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
; This entry should never be queried
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.refuse.top. IN A
|
||||
SECTION ANSWER
|
||||
www.refuse.top. IN A 5.5.5.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; id.server.
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
@@ -390,4 +413,35 @@ SECTION ANSWER
|
||||
foo.null.top. IN AAAA ::0
|
||||
ENTRY_END
|
||||
|
||||
; refuse zone for implicit local-data with CLASS != IN
|
||||
STEP 64 QUERY
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
refuse.top. ANY TXT
|
||||
ENTRY_END
|
||||
STEP 65 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RA AA NOERROR
|
||||
SECTION QUESTION
|
||||
refuse.top. ANY TXT
|
||||
SECTION ANSWER
|
||||
refuse.top. ANY TXT implicit_non_transparent
|
||||
ENTRY_END
|
||||
|
||||
; refuse zone for implicit local-data with CLASS != IN
|
||||
STEP 66 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.refuse.top. ANY A
|
||||
ENTRY_END
|
||||
STEP 67 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RA RD AA REFUSED
|
||||
SECTION QUESTION
|
||||
www.refuse.top. ANY A
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+2
-2
@@ -138,7 +138,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 22 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
root-key-sentinel-not-ta-19036. IN A
|
||||
@@ -154,7 +154,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 33 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
root-key-sentinel-is-ta-20326. IN A
|
||||
|
||||
Vendored
+1
-1
@@ -348,7 +348,7 @@ ENTRY_END
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
REPLY QR AA RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
gotham.aa. IN A
|
||||
SECTION ANSWER
|
||||
|
||||
Vendored
+1
-1
@@ -348,7 +348,7 @@ ENTRY_END
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NXDOMAIN
|
||||
REPLY QR AA RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
gotham.aa. IN A
|
||||
SECTION ANSWER
|
||||
|
||||
Vendored
+254
@@ -0,0 +1,254 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
access-control: 192.0.0.0/8 allow
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
rpz-signal-nxdomain-ra: yes
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
$ORIGIN example.com.
|
||||
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
|
||||
1379078166 28800 7200 604800 7200 )
|
||||
3600 IN NS ns1.rpz.example.com.
|
||||
3600 IN NS ns2.rpz.example.com.
|
||||
$ORIGIN rpz.example.com.
|
||||
a.a CNAME .
|
||||
b.a CNAME .
|
||||
ns1.a.rpz-nsdname CNAME .
|
||||
24.0.0.0.192.rpz-nsip CNAME .
|
||||
24.0.3.0.192.rpz-client-ip CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "a."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test RPZ qname trigger and signal NXDOMAIN with unset RA.
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a. IN NS
|
||||
SECTION ANSWER
|
||||
a. IN NS ns.a.
|
||||
SECTION ADDITIONAL
|
||||
ns.a IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
a.a. IN TXT
|
||||
SECTION ANSWER
|
||||
a.a. IN TXT "upstream txt rr a.a."
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
b.a. IN TXT
|
||||
SECTION ANSWER
|
||||
b.a. IN TXT "upstream txt rr b.a."
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN CNAME b.a
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d.a. IN NS
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
d.a. IN NS ns1.a.
|
||||
SECTION ADDITIONAL
|
||||
ns1.a. IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e.a. IN NS
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
e.a. IN NS ns2.a.
|
||||
SECTION ADDITIONAL
|
||||
ns2.a. IN A 192.0.0.5
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
f.a. IN TXT
|
||||
SECTION ANSWER
|
||||
f.a. IN TXT "upstream txt rr f.a."
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 10.20.30.50
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d.a. IN NS
|
||||
SECTION ANSWER
|
||||
d.a. IN NS ns1.a.
|
||||
SECTION ADDITIONAL
|
||||
ns1.a. IN A 10.20.30.50
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d.d.a. IN TXT
|
||||
SECTION ANSWER
|
||||
d.d.a. IN TXT "upstream answer for d.d.a"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.0.0.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e.a. IN NS
|
||||
SECTION ANSWER
|
||||
e.a. IN NS ns2.a.
|
||||
SECTION ADDITIONAL
|
||||
ns2.a. IN A 192.0.0.5
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
e.e.a. IN TXT
|
||||
SECTION ANSWER
|
||||
e.e.a. IN TXT "upstream answer for e.e.a"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; qname trigger
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
a.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
a.a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; qname trigger after cname
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 21 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN CNAME b.a
|
||||
ENTRY_END
|
||||
|
||||
; nsdname trigger
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.d.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 31 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
d.d.a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; nsip trigger
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
e.e.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 41 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
e.e.a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; clientip trigger
|
||||
STEP 50 QUERY ADDRESS 192.0.3.1
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
f.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 51 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR AA RD NXDOMAIN
|
||||
SECTION QUESTION
|
||||
f.a. IN TXT
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+2
@@ -172,3 +172,5 @@ uri.arpa. 3600 IN ZONEMD 2018100702 1 1 ( 1291b78ddf7669b1a39d014
|
||||
root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 ( f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97 8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 )
|
||||
; from ldns issue #121, 0.10m was parsed as 0.01m.
|
||||
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.1m 0.1m 0.1m
|
||||
; from ldns issue #147, fix #148, tab between quoted strings.
|
||||
foo 12345 IN HINFO "hohum" "weirdo"
|
||||
|
||||
Vendored
+2
@@ -212,3 +212,5 @@ uri.arpa. 3600 IN ZONEMD 2018100702 1 1 1291B78DDF7669B1A39D014D87626B709B55774C
|
||||
root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 F1CA0CCD91BD5573D9F431C00EE0101B2545C97602BE0A978A3B11DBFC1C776D5B3E86AE3D973D6B5349BA7F04340F79
|
||||
03666F6F00001D00010000303900100011111182BD2D4D69530BD400988D20
|
||||
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.10m 0.10m 0.10m
|
||||
03666F6F00000D000100003039000D05686F68756D0677656972646F
|
||||
foo. 12345 IN HINFO "hohum" "weirdo"
|
||||
|
||||
Vendored
+1
-1
@@ -88,7 +88,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN AAAA
|
||||
|
||||
+1
-2
@@ -254,12 +254,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -253,13 +253,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-1
@@ -261,7 +261,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
foo.www.example.com. IN A
|
||||
|
||||
Vendored
+1
-3
@@ -256,13 +256,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-2
@@ -195,11 +195,10 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+2
-1
@@ -160,11 +160,12 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -154,13 +154,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -60,13 +60,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
_25._tcp.mail.nsecwc.nlnetlabs.nl. IN TLSA
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-1
@@ -153,7 +153,7 @@ ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
+1
-2
@@ -133,7 +133,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
a.c.x.w.example. IN A
|
||||
@@ -145,7 +145,6 @@ SECTION AUTHORITY
|
||||
; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
|
||||
; b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd ( gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
|
||||
; b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh 5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3 pOv0TSTyiTxIZg== )
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
+1
-3
@@ -127,13 +127,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=12
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ns1.example. IN MX
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
+1
-3
@@ -186,13 +186,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
ent.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -226,13 +226,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -58,13 +58,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
a.nsecwc.nlnetlabs.nl. IN TXT
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-3
@@ -154,13 +154,11 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=6
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
Vendored
+1
-1
@@ -223,7 +223,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub.example.com. IN A
|
||||
|
||||
Vendored
+1
-1
@@ -165,7 +165,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
MATCH all_noedns ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
+47
-2
@@ -373,6 +373,9 @@ config_create(void)
|
||||
cfg->ipset_name_v4 = NULL;
|
||||
cfg->ipset_name_v6 = NULL;
|
||||
#endif
|
||||
cfg->local_zone_do_ede = NULL;
|
||||
cfg->local_zone_default_ede = NULL;
|
||||
cfg->ede_local_zones = 0;
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
@@ -790,7 +793,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
}
|
||||
oi[cfg->num_out_ifs++] = d;
|
||||
cfg->out_ifs = oi;
|
||||
} else {
|
||||
} else S_YNO("ede-local-zones:", ede_local_zones)
|
||||
else {
|
||||
/* unknown or unsupported (from the set_option interface):
|
||||
* interface, outgoing-interface, access-control,
|
||||
* stub-zone, name, stub-addr, stub-host, stub-prime
|
||||
@@ -1239,6 +1243,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
#ifdef USE_IPSET
|
||||
else O_STR(opt, "name-v4", ipset_name_v4)
|
||||
else O_STR(opt, "name-v6", ipset_name_v6)
|
||||
else O_LS3(opt, "local-zone-do-ede", local_zone_do_ede)
|
||||
else O_LS3(opt, "local-zone-default-ede",local_zone_default_ede)
|
||||
#endif
|
||||
/* not here:
|
||||
* outgoing-permit, outgoing-avoid - have list of ports
|
||||
@@ -2545,6 +2551,7 @@ void errinf(struct module_qstate* qstate, const char* str)
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
p->reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
@@ -2552,7 +2559,34 @@ void errinf(struct module_qstate* qstate, const char* str)
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct config_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_ede(struct module_qstate* qstate,
|
||||
const char* str, sldns_ede_code reason_bogus)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
return;
|
||||
p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
p->reason_bogus = reason_bogus;
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct config_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
@@ -2603,6 +2637,17 @@ char* errinf_to_str_bogus(struct module_qstate* qstate)
|
||||
return p;
|
||||
}
|
||||
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
for(s=qstate->errinf; s; s=s->next) {
|
||||
if (s->reason_bogus != LDNS_EDE_DNSSEC_BOGUS) {
|
||||
return s->reason_bogus;
|
||||
}
|
||||
}
|
||||
return LDNS_EDE_DNSSEC_BOGUS;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#ifndef UTIL_CONFIG_FILE_H
|
||||
#define UTIL_CONFIG_FILE_H
|
||||
#include "sldns/rrdef.h"
|
||||
struct config_stub;
|
||||
struct config_auth;
|
||||
struct config_view;
|
||||
@@ -668,6 +669,13 @@ struct config_file {
|
||||
char* ipset_name_v4;
|
||||
char* ipset_name_v6;
|
||||
#endif
|
||||
|
||||
/** should a local_zone results inlude an EDE (RFC8914) code? */
|
||||
struct config_str2list* local_zone_do_ede;
|
||||
/** which EDE (RFC8914) should be the default */
|
||||
struct config_str2list* local_zone_default_ede;
|
||||
/** should the default for local_zone results inlude an EDE (RFC8914) code?*/
|
||||
int ede_local_zones;
|
||||
};
|
||||
|
||||
/** from cfg username, after daemonize setup performed */
|
||||
@@ -745,6 +753,10 @@ struct config_auth {
|
||||
/** Always reply with this CNAME target if the cname override action is
|
||||
* used */
|
||||
char* rpz_cname;
|
||||
/** Respond with EDEs (RFC 8914) for this zone */
|
||||
int rpz_do_ede;
|
||||
/** signal nxdomain block with unset RA */
|
||||
int rpz_signal_nxdomain_ra;
|
||||
/** Check ZONEMD records for this zone */
|
||||
int zonemd_check;
|
||||
/** Reject absence of ZONEMD records, zone must have one */
|
||||
@@ -786,6 +798,8 @@ struct config_strlist {
|
||||
struct config_strlist* next;
|
||||
/** config option string */
|
||||
char* str;
|
||||
/** EDE code companion to the error str */
|
||||
sldns_ede_code reason_bogus;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1235,6 +1249,8 @@ char* cfg_ptr_reverse(char* str);
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
void errinf_ede(struct module_qstate* qstate, const char* str,
|
||||
sldns_ede_code reason_bogus);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
@@ -1269,6 +1285,13 @@ void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
/**
|
||||
* Check the sldns_ede_code of the qstate.
|
||||
* @param qstate: query state.
|
||||
* @return LDNS_EDE_DNSSEC_BOGUS by default, or another sldns_ede_code
|
||||
* if this is set.
|
||||
*/
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For other servfails.
|
||||
|
||||
+2870
-2803
File diff suppressed because it is too large
Load Diff
@@ -347,6 +347,8 @@ rpz-action-override{COLON} { YDVAR(1, VAR_RPZ_ACTION_OVERRIDE) }
|
||||
rpz-cname-override{COLON} { YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) }
|
||||
rpz-log{COLON} { YDVAR(1, VAR_RPZ_LOG) }
|
||||
rpz-log-name{COLON} { YDVAR(1, VAR_RPZ_LOG_NAME) }
|
||||
rpz-do-ede{COLON} { YDVAR(1, VAR_RPZ_DO_EDE) }
|
||||
rpz-signal-nxdomain-ra{COLON} { YDVAR(1, VAR_RPZ_SIGNAL_NXDOMAIN_RA) }
|
||||
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
|
||||
master{COLON} { YDVAR(1, VAR_MASTER) }
|
||||
primary{COLON} { YDVAR(1, VAR_MASTER) }
|
||||
@@ -549,6 +551,9 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
local-zone-do-ede{COLON} { YDVAR(2, VAR_LOCAL_DATA_DO_EDE) }
|
||||
local-zone-default-ede{COLON} { YDVAR(2, VAR_LOCAL_ZONE_DEFAULT_EDE)}
|
||||
ede-local-zones{COLON} { YDVAR(1, VAR_EDE_LOCAL_ZONES) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
||||
+2020
-2587
File diff suppressed because it is too large
Load Diff
+31
-20
@@ -1,8 +1,8 @@
|
||||
/* A Bison parser, made by GNU Bison 3.6.4. */
|
||||
/* A Bison parser, made by GNU Bison 3.7.6. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
@@ -16,7 +16,7 @@
|
||||
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/>. */
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
@@ -364,18 +364,24 @@ extern int yydebug;
|
||||
VAR_RPZ_CNAME_OVERRIDE = 565, /* VAR_RPZ_CNAME_OVERRIDE */
|
||||
VAR_RPZ_LOG = 566, /* VAR_RPZ_LOG */
|
||||
VAR_RPZ_LOG_NAME = 567, /* VAR_RPZ_LOG_NAME */
|
||||
VAR_DYNLIB = 568, /* VAR_DYNLIB */
|
||||
VAR_DYNLIB_FILE = 569, /* VAR_DYNLIB_FILE */
|
||||
VAR_EDNS_CLIENT_STRING = 570, /* VAR_EDNS_CLIENT_STRING */
|
||||
VAR_EDNS_CLIENT_STRING_OPCODE = 571, /* VAR_EDNS_CLIENT_STRING_OPCODE */
|
||||
VAR_NSID = 572, /* VAR_NSID */
|
||||
VAR_ZONEMD_PERMISSIVE_MODE = 573, /* VAR_ZONEMD_PERMISSIVE_MODE */
|
||||
VAR_ZONEMD_CHECK = 574, /* VAR_ZONEMD_CHECK */
|
||||
VAR_ZONEMD_REJECT_ABSENCE = 575 /* VAR_ZONEMD_REJECT_ABSENCE */
|
||||
VAR_RPZ_DO_EDE = 568, /* VAR_RPZ_DO_EDE */
|
||||
VAR_DYNLIB = 569, /* VAR_DYNLIB */
|
||||
VAR_DYNLIB_FILE = 570, /* VAR_DYNLIB_FILE */
|
||||
VAR_EDNS_CLIENT_STRING = 571, /* VAR_EDNS_CLIENT_STRING */
|
||||
VAR_EDNS_CLIENT_STRING_OPCODE = 572, /* VAR_EDNS_CLIENT_STRING_OPCODE */
|
||||
VAR_NSID = 573, /* VAR_NSID */
|
||||
VAR_ZONEMD_PERMISSIVE_MODE = 574, /* VAR_ZONEMD_PERMISSIVE_MODE */
|
||||
VAR_ZONEMD_CHECK = 575, /* VAR_ZONEMD_CHECK */
|
||||
VAR_ZONEMD_REJECT_ABSENCE = 576, /* VAR_ZONEMD_REJECT_ABSENCE */
|
||||
VAR_LOCAL_DATA_DO_EDE = 577, /* VAR_LOCAL_DATA_DO_EDE */
|
||||
VAR_LOCAL_ZONE_DEFAULT_EDE = 578, /* VAR_LOCAL_ZONE_DEFAULT_EDE */
|
||||
VAR_EDE_LOCAL_ZONES = 579, /* VAR_EDE_LOCAL_ZONES */
|
||||
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 580 /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
|
||||
};
|
||||
typedef enum yytokentype yytoken_kind_t;
|
||||
#endif
|
||||
/* Token kinds. */
|
||||
#define YYEMPTY -2
|
||||
#define YYEOF 0
|
||||
#define YYerror 256
|
||||
#define YYUNDEF 257
|
||||
@@ -689,14 +695,19 @@ extern int yydebug;
|
||||
#define VAR_RPZ_CNAME_OVERRIDE 565
|
||||
#define VAR_RPZ_LOG 566
|
||||
#define VAR_RPZ_LOG_NAME 567
|
||||
#define VAR_DYNLIB 568
|
||||
#define VAR_DYNLIB_FILE 569
|
||||
#define VAR_EDNS_CLIENT_STRING 570
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 571
|
||||
#define VAR_NSID 572
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 573
|
||||
#define VAR_ZONEMD_CHECK 574
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 575
|
||||
#define VAR_RPZ_DO_EDE 568
|
||||
#define VAR_DYNLIB 569
|
||||
#define VAR_DYNLIB_FILE 570
|
||||
#define VAR_EDNS_CLIENT_STRING 571
|
||||
#define VAR_EDNS_CLIENT_STRING_OPCODE 572
|
||||
#define VAR_NSID 573
|
||||
#define VAR_ZONEMD_PERMISSIVE_MODE 574
|
||||
#define VAR_ZONEMD_CHECK 575
|
||||
#define VAR_ZONEMD_REJECT_ABSENCE 576
|
||||
#define VAR_LOCAL_DATA_DO_EDE 577
|
||||
#define VAR_LOCAL_ZONE_DEFAULT_EDE 578
|
||||
#define VAR_EDE_LOCAL_ZONES 579
|
||||
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 580
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
@@ -706,7 +717,7 @@ union YYSTYPE
|
||||
|
||||
char* str;
|
||||
|
||||
#line 710 "util/configparser.h"
|
||||
#line 721 "util/configparser.h"
|
||||
|
||||
};
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
||||
+85
-3
@@ -183,10 +183,12 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
|
||||
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
|
||||
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
|
||||
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
|
||||
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME VAR_RPZ_DO_EDE
|
||||
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
|
||||
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
|
||||
%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
|
||||
%token VAR_LOCAL_DATA_DO_EDE VAR_LOCAL_ZONE_DEFAULT_EDE VAR_EDE_LOCAL_ZONES
|
||||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -308,7 +310,9 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_tls_use_sni | server_edns_client_string |
|
||||
server_edns_client_string_opcode | server_nsid |
|
||||
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
server_local_zone_do_ede | server_local_zone_default_ede |
|
||||
server_ede_local_zones
|
||||
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
@@ -455,6 +459,26 @@ rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG
|
||||
cfg_parser->cfg->auths->rpz_log_name = $2;
|
||||
}
|
||||
;
|
||||
rpz_signal_nxdomain_ra: VAR_RPZ_SIGNAL_NXDOMAIN_RA STRING_ARG
|
||||
{
|
||||
OUTYY(("P(rpz_signal_nxdomain_ra:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->auths->rpz_signal_nxdomain_ra = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
rpz_do_ede: VAR_RPZ_DO_EDE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(rpz_do_ede:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->auths->rpz_do_ede =
|
||||
(strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
rpzstart: VAR_RPZ
|
||||
{
|
||||
@@ -478,7 +502,7 @@ contents_rpz: contents_rpz content_rpz
|
||||
| ;
|
||||
content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
|
||||
auth_allow_notify | rpz_action_override | rpz_cname_override |
|
||||
rpz_log | rpz_log_name
|
||||
rpz_log | rpz_log_name | rpz_do_ede | rpz_signal_nxdomain_ra
|
||||
;
|
||||
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
||||
{
|
||||
@@ -2206,6 +2230,64 @@ server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG
|
||||
}
|
||||
}
|
||||
;
|
||||
server_local_zone_do_ede: VAR_LOCAL_DATA_DO_EDE STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_local_zone_do_ede:%s %s)\n", $2, $3));
|
||||
if(strcmp($3, "yes") != 0 && strcmp($3, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
if(!cfg_str2list_insert(&cfg_parser->cfg->local_zone_do_ede,
|
||||
$2, $3)) {
|
||||
yyerror("out of memory adding local-zone-do-ede");
|
||||
}
|
||||
}
|
||||
;
|
||||
server_local_zone_default_ede: VAR_LOCAL_ZONE_DEFAULT_EDE STRING_ARG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_local_zone_default_ede:%s %s)\n", $2, $3));
|
||||
if (!(strcmp($3, "other") == 0) &&
|
||||
!(strcmp($3, "unsupported-dnskey-algorithm") == 0) &&
|
||||
!(strcmp($3, "unsupported-ds-digest-type") == 0) &&
|
||||
!(strcmp($3, "stale-answer") == 0) &&
|
||||
!(strcmp($3, "forged") == 0) &&
|
||||
!(strcmp($3, "dnssec-indeterminate") == 0) &&
|
||||
!(strcmp($3, "dnssec-bogus") == 0) &&
|
||||
!(strcmp($3, "signature-expired") == 0) &&
|
||||
!(strcmp($3, "signature-not-yet-valid") == 0) &&
|
||||
!(strcmp($3, "dnskey-missing") == 0) &&
|
||||
!(strcmp($3, "rrsigs-missing") == 0) &&
|
||||
!(strcmp($3, "no-zone-key-bit-set") == 0) &&
|
||||
!(strcmp($3, "nsec-missing") == 0) &&
|
||||
!(strcmp($3, "cached-error") == 0) &&
|
||||
!(strcmp($3, "not-ready") == 0) &&
|
||||
!(strcmp($3, "blocked") == 0) &&
|
||||
!(strcmp($3, "censored") == 0) &&
|
||||
!(strcmp($3, "filtered") == 0) &&
|
||||
!(strcmp($3, "prohibited") == 0) &&
|
||||
!(strcmp($3, "stale-nxdomain-answer") == 0) &&
|
||||
!(strcmp($3, "not-authoritative") == 0) &&
|
||||
!(strcmp($3, "not-supported") == 0) &&
|
||||
!(strcmp($3, "no-reachable-authority") == 0) &&
|
||||
!(strcmp($3, "network-error") == 0) &&
|
||||
!(strcmp($3, "invalid-data") == 0) &&
|
||||
!(atoi($3) == 0))
|
||||
yyerror("expected default-ede keyword or integer"
|
||||
"refering to the respecive ede code");
|
||||
if(!cfg_str2list_insert(&cfg_parser->cfg->local_zone_default_ede,
|
||||
$2, $3)) {
|
||||
yyerror("out of memory adding local-zone-default-ede");
|
||||
}
|
||||
}
|
||||
;
|
||||
server_ede_local_zones: VAR_EDE_LOCAL_ZONES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ede_local_zones:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ede_local_zones =
|
||||
(strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_minimal_responses:%s)\n", $2));
|
||||
|
||||
@@ -1157,7 +1157,7 @@ skip_pkt_rr(sldns_buffer* pkt)
|
||||
}
|
||||
|
||||
/** skip RRs from packet */
|
||||
static int
|
||||
int
|
||||
skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -293,6 +293,14 @@ int parse_packet(struct sldns_buffer* pkt, struct msg_parse* msg,
|
||||
int parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
struct edns_data* edns, struct regional* region);
|
||||
|
||||
/**
|
||||
* Skip RRs from packet
|
||||
* @param pkt:the packet. position at start must be right after the query
|
||||
* section. At end, right after EDNS data or no movement if failed.
|
||||
* @param num: Limit of the number of records we want to parse.
|
||||
* @return: 0 on success, 1 on failure*/
|
||||
int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
||||
|
||||
/**
|
||||
* If EDNS data follows a query section, extract it and initialize edns struct.
|
||||
* @param pkt: the packet. position at start must be right after the query
|
||||
|
||||
@@ -117,6 +117,7 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
rep->ar_numrrsets = ar;
|
||||
rep->rrset_count = total;
|
||||
rep->security = sec;
|
||||
rep->reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
rep->authoritative = 0;
|
||||
/* array starts after the refs */
|
||||
if(region)
|
||||
@@ -989,6 +990,35 @@ parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region,
|
||||
return rep;
|
||||
}
|
||||
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt)
|
||||
{
|
||||
struct edns_option** prevp;
|
||||
struct edns_option* opt;
|
||||
size_t txt_len = txt ? strlen(txt) : 0;
|
||||
|
||||
/* allocate new element */
|
||||
opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
|
||||
if(!opt)
|
||||
return 0;
|
||||
opt->next = NULL;
|
||||
opt->opt_code = LDNS_EDNS_EDE;
|
||||
opt->opt_len = txt_len + sizeof(uint16_t);
|
||||
opt->opt_data = regional_alloc(region, txt_len + sizeof(uint16_t));
|
||||
if(!opt->opt_data)
|
||||
return 0;
|
||||
sldns_write_uint16(opt->opt_data, (uint16_t)code);
|
||||
if (txt_len)
|
||||
memmove(opt->opt_data + 2, txt, txt_len);
|
||||
|
||||
/* append at end of list */
|
||||
prevp = list;
|
||||
while(*prevp != NULL)
|
||||
prevp = &((*prevp)->next);
|
||||
*prevp = opt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region)
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#define UTIL_DATA_MSGREPLY_H
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct sldns_buffer;
|
||||
struct comm_reply;
|
||||
struct alloc_cache;
|
||||
@@ -167,6 +168,11 @@ struct reply_info {
|
||||
*/
|
||||
enum sec_status security;
|
||||
|
||||
/**
|
||||
* EDE (rfc8914) code with reason for DNSSEC bogus status.
|
||||
*/
|
||||
sldns_ede_code reason_bogus;
|
||||
|
||||
/**
|
||||
* Number of RRsets in each section.
|
||||
* The answer section. Add up the RRs in every RRset to calculate
|
||||
@@ -530,6 +536,35 @@ void log_query_info(enum verbosity_value v, const char* str,
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region);
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param LIST: the edns option list to append the edns option to.
|
||||
* @param REGION: region to allocate the new edns option.
|
||||
* @param CODE: the EDE code.
|
||||
* @param TXT: Additional text for the option
|
||||
*/
|
||||
#define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT) \
|
||||
do { \
|
||||
struct { \
|
||||
uint16_t code; \
|
||||
char text[sizeof(TXT) - 1]; \
|
||||
} ede = { htons(CODE), TXT }; \
|
||||
edns_opt_list_append((LIST), LDNS_EDNS_EDE, \
|
||||
sizeof(uint16_t) + sizeof(TXT) - 1, \
|
||||
(void *)&ede, (REGION)); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param list: the edns option list to append the edns option to.
|
||||
* @param region: region to allocate the new edns option.
|
||||
* @param code: the EDE code.
|
||||
* @param txt: Additional text for the option
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt);
|
||||
|
||||
/**
|
||||
* Remove any option found on the edns option list that matches the code.
|
||||
* @param list: the list of edns options.
|
||||
|
||||
@@ -44,6 +44,9 @@
|
||||
#ifdef HAVE_NET_IF_H
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETIOAPI_H
|
||||
#include <netioapi.h>
|
||||
#endif
|
||||
#include "util/net_help.h"
|
||||
#include "util/log.h"
|
||||
#include "util/data/dname.h"
|
||||
|
||||
+110
-11
@@ -530,6 +530,24 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return dnskeyset_verify_rrset_ede(
|
||||
env, ve, rrset, dnskey, sigalg, reason, NULL, section, qstate);
|
||||
}
|
||||
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
@@ -543,6 +561,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -551,12 +571,15 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(algo_needs_num_missing(&needs) == 0) {
|
||||
verbose(VERB_QUERY, "zone has no known algorithms");
|
||||
*reason = "zone has no known algorithms";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
return sec_status_insecure;
|
||||
}
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
|
||||
dnskey, i, &sortree, reason, section, qstate);
|
||||
dnskey, i, &sortree, reason, reason_bogus,
|
||||
section, qstate);
|
||||
/* see which algorithm has been fixed up */
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg)
|
||||
@@ -599,6 +622,25 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return dnskey_verify_rrset_ede(env, ve, rrset, dnskey, dnskey_idx,
|
||||
reason, NULL, section, qstate);
|
||||
}
|
||||
|
||||
static enum sec_status
|
||||
dnskey_verify_rrset_sig_ede(struct regional* region, sldns_buffer* buf,
|
||||
struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
enum sec_status
|
||||
dnskey_verify_rrset_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num, numchecked = 0;
|
||||
@@ -612,6 +654,8 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
@@ -620,10 +664,10 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
tag != rrset_get_sig_keytag(rrset, i))
|
||||
continue;
|
||||
buf_canon = 0;
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
sec = dnskey_verify_rrset_sig_ede(env->scratch,
|
||||
env->scratch_buffer, ve, *env->now, rrset,
|
||||
dnskey, dnskey_idx, i, &sortree, &buf_canon, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
numchecked ++;
|
||||
@@ -633,12 +677,13 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* find matching keys and check them */
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
@@ -649,6 +694,8 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
int buf_canon = 0;
|
||||
verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
|
||||
if(!dnskey_algo_id_is_supported(algo)) {
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
verbose(VERB_QUERY, "verify sig: unknown algorithm");
|
||||
return sec_status_insecure;
|
||||
}
|
||||
@@ -661,14 +708,17 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
numchecked ++;
|
||||
|
||||
/* see if key verifies */
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
sec = dnskey_verify_rrset_sig_ede(env->scratch,
|
||||
env->scratch_buffer, ve, now, rrset, dnskey, i,
|
||||
sig_idx, sortree, &buf_canon, reason, section, qstate);
|
||||
sig_idx, sortree, &buf_canon, reason, reason_bogus,
|
||||
section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
*reason = "signatures from unknown keys";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
verbose(VERB_QUERY, "verify: could not find appropriate key");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
@@ -1361,8 +1411,8 @@ subtract_1982(uint32_t a, uint32_t b)
|
||||
|
||||
/** check rrsig dates */
|
||||
static int
|
||||
check_dates(struct val_env* ve, uint32_t unow,
|
||||
uint8_t* expi_p, uint8_t* incep_p, char** reason)
|
||||
check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p,
|
||||
uint8_t* incep_p, char** reason, sldns_ede_code *reason_bogus)
|
||||
{
|
||||
/* read out the dates */
|
||||
uint32_t expi, incep, now;
|
||||
@@ -1386,6 +1436,14 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: inception after expiration, "
|
||||
"signature bad", expi, incep, now);
|
||||
*reason = "signature inception after expiration";
|
||||
if (reason_bogus){
|
||||
/* from RFC8914 on Signature Not Yet Valid: The resolver
|
||||
* attempted to perform DNSSEC validation, but no
|
||||
* signatures are presently valid and at least some are
|
||||
* not yet valid. */
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if(compare_1982(incep, now) > 0) {
|
||||
@@ -1397,6 +1455,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature bad, current time is"
|
||||
" before inception date", expi, incep, now);
|
||||
*reason = "signature before inception date";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature inception "
|
||||
@@ -1410,6 +1470,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature expired", expi,
|
||||
incep, now);
|
||||
*reason = "signature expired";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_EXPIRED;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature expiration "
|
||||
@@ -1475,6 +1537,20 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon, char** reason,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
return dnskey_verify_rrset_sig_ede(region, buf, ve, now, rrset, dnskey,
|
||||
dnskey_idx, sig_idx, sortree, buf_canon, reason, NULL,
|
||||
section, qstate);
|
||||
}
|
||||
|
||||
static enum sec_status
|
||||
dnskey_verify_rrset_sig_ede(struct regional* region, sldns_buffer* buf,
|
||||
struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
uint8_t* sig; /* RRSIG rdata */
|
||||
@@ -1492,12 +1568,16 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(siglen < 2+20) {
|
||||
verbose(VERB_QUERY, "verify: signature too short");
|
||||
*reason = "signature too short";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) {
|
||||
verbose(VERB_QUERY, "verify: dnskey without ZSK flag");
|
||||
*reason = "dnskey without ZSK flag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -1505,6 +1585,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */
|
||||
verbose(VERB_QUERY, "verify: dnskey has wrong key protocol");
|
||||
*reason = "dnskey has wrong protocolnumber";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -1514,17 +1596,23 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(!signer_len) {
|
||||
verbose(VERB_QUERY, "verify: malformed signer name");
|
||||
*reason = "signer name malformed";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name invalid */
|
||||
}
|
||||
if(!dname_subdomain_c(rrset->rk.dname, signer)) {
|
||||
verbose(VERB_QUERY, "verify: signer name is off-tree");
|
||||
*reason = "signer name off-tree";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name offtree */
|
||||
}
|
||||
sigblock = (unsigned char*)signer+signer_len;
|
||||
if(siglen < 2+18+signer_len+1) {
|
||||
verbose(VERB_QUERY, "verify: too short, no signature data");
|
||||
*reason = "signature too short, no signature data";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* sig rdf is < 1 byte */
|
||||
}
|
||||
sigblock_len = (unsigned int)(siglen - 2 - 18 - signer_len);
|
||||
@@ -1537,6 +1625,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
log_nametypeclass(VERB_QUERY, "the key name is",
|
||||
dnskey->rk.dname, 0, 0);
|
||||
*reason = "signer name mismatches key name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -1545,18 +1635,24 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(memcmp(sig+2, &rrset->rk.type, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong type covered");
|
||||
*reason = "signature covers wrong type";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
/* verify keytag and sig algo (possibly again) */
|
||||
if((int)sig[2+2] != dnskey_get_algo(dnskey, dnskey_idx)) {
|
||||
verbose(VERB_QUERY, "verify: wrong algorithm");
|
||||
*reason = "signature has wrong algorithm";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
ktag = htons(dnskey_calc_keytag(dnskey, dnskey_idx));
|
||||
if(memcmp(sig+2+16, &ktag, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong keytag");
|
||||
*reason = "signature has wrong keytag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -1564,6 +1660,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) {
|
||||
verbose(VERB_QUERY, "verify: labelcount out of range");
|
||||
*reason = "signature labelcount out of range";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -1598,7 +1696,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* verify inception, expiration dates
|
||||
* Do this last so that if you ignore expired-sigs the
|
||||
* rest is sure to be OK. */
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12, reason)) {
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12,
|
||||
reason, reason_bogus)) {
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#define VALIDATOR_VAL_SIGCRYPT_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct module_env;
|
||||
struct module_qstate;
|
||||
@@ -266,6 +267,12 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
enum sec_status dnskeyset_verify_rrset_ede(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
|
||||
/**
|
||||
* verify rrset against one specific dnskey (from rrset)
|
||||
@@ -285,6 +292,13 @@ enum sec_status dnskey_verify_rrset(struct module_env* env,
|
||||
struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
enum sec_status
|
||||
dnskey_verify_rrset_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* verify rrset, with dnskey rrset, for a specific rrsig in rrset
|
||||
* @param env: module environment, scratch space is used.
|
||||
@@ -306,6 +320,7 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* verify rrset, with specific dnskey(from set), for a specific rrsig
|
||||
|
||||
+103
-27
@@ -332,11 +332,11 @@ rrset_get_ttl(struct ub_packed_rrset_key* rrset)
|
||||
return d->ttl;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
static enum sec_status
|
||||
val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
@@ -358,8 +358,8 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
|
||||
section, qstate);
|
||||
sec = dnskeyset_verify_rrset_ede(env, ve, rrset, keys, sigalg, reason,
|
||||
reason_bogus, section, qstate);
|
||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||
regional_free_all(env->scratch);
|
||||
|
||||
@@ -393,6 +393,16 @@ enum sec_status
|
||||
val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
||||
char** reason, sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
return val_verify_rrset_entry_ede(
|
||||
env, ve, rrset, kkey, reason, NULL, section, qstate);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
val_verify_rrset_entry_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* temporary dnskey rrset-key */
|
||||
struct ub_packed_rrset_key dnskey;
|
||||
@@ -406,16 +416,28 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
dnskey.entry.key = &dnskey;
|
||||
dnskey.entry.data = kd->rrset_data;
|
||||
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
return sec;
|
||||
}
|
||||
|
||||
/** verify that a DS RR hashes to a key and that key signs the set */
|
||||
#if 0
|
||||
static enum sec_status
|
||||
verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return verify_dnskeys_with_ds_rr_ede( env, ve, dnskey_rrset, ds_rrset,
|
||||
ds_idx, reason, NULL, qstate);
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum sec_status
|
||||
verify_dnskeys_with_ds_rr_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
|
||||
@@ -450,8 +472,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/* Otherwise, we have a match! Make sure that the DNSKEY
|
||||
* verifies *with this key* */
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
dnskey_rrset, i, reason, LDNS_SECTION_ANSWER, qstate);
|
||||
sec = dnskey_verify_rrset_ede(env, ve, dnskey_rrset, dnskey_rrset,
|
||||
i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
return sec;
|
||||
}
|
||||
@@ -488,11 +510,26 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset)
|
||||
return digest_algo;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
/**
|
||||
* This function (without EDE (RFC 8914)) is currently only used in
|
||||
* authzone, after a zone-transfer. This does not invoke a query-response
|
||||
* so we can leave this wrapper in-place.
|
||||
*/
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return val_verify_DNSKEY_with_DS_ede(env, ve, dnskey_rrset, ds_rrset,
|
||||
sigalg, reason, NULL, qstate);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_DS_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this DS rrset to be
|
||||
* equivalent to no DS rrset. */
|
||||
@@ -528,8 +565,8 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
continue;
|
||||
}
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ds_rrset, i, reason, qstate);
|
||||
sec = verify_dnskeys_with_ds_rr_ede(env, ve, dnskey_rrset,
|
||||
ds_rrset, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@@ -560,7 +597,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
if(!has_useful_ds) {
|
||||
verbose(VERB_ALGO, "No usable DS records were found -- "
|
||||
"treating as insecure.");
|
||||
return sec_status_insecure;
|
||||
return sec_status_insecure;
|
||||
}
|
||||
/* If any were understandable, then it is bad. */
|
||||
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
|
||||
@@ -571,15 +608,26 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
struct key_entry_key*
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return val_verify_new_DNSKEYs_ede(region, env, ve,dnskey_rrset, ds_rrset,
|
||||
downprot, reason, NULL, qstate);
|
||||
}
|
||||
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs_ede(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason, qstate);
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS_ede(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
||||
reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
@@ -597,12 +645,23 @@ val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
return val_verify_DNSKEY_with_TA_ede(env, ve, dnskey_rrset, ta_ds,
|
||||
ta_dnskey, sigalg, reason, NULL, qstate);
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_TA_ede(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this anchor to be
|
||||
* equivalent to no anchor. */
|
||||
@@ -617,6 +676,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match DS RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match DS RRset by name";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
if(ta_dnskey && (dnskey_rrset->rk.dname_len != ta_dnskey->rk.dname_len
|
||||
@@ -625,6 +686,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match anchor RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match anchor RRset by name";
|
||||
if (reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@@ -647,8 +710,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
ds_get_digest_algo(ta_ds, i) != digest_algo)
|
||||
continue;
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ta_ds, i, reason, qstate);
|
||||
sec = verify_dnskeys_with_ds_rr_ede(env, ve, dnskey_rrset,
|
||||
ta_ds, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@@ -721,26 +784,39 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, struct module_qstate* qstate)
|
||||
{
|
||||
return val_verify_rrset_entry_ede(region, env, ve, dnskey_rrset,
|
||||
ta_ds_rrset, ta_dnskey_rrset,downprot, reason, NULL, qstate);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct key_entry_key*
|
||||
val_verify_new_DNSKEYs_with_ta_ede(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA_ede(env, ve,
|
||||
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
|
||||
downprot?sigalg:NULL, reason, qstate);
|
||||
downprot?sigalg:NULL, reason, reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
return key_entry_create_rrset(region,
|
||||
dnskey_rrset->rk.dname, dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class), dnskey_rrset,
|
||||
downprot?sigalg:NULL, *env->now);
|
||||
} else if(sec == sec_status_insecure) {
|
||||
return key_entry_create_null(region, dnskey_rrset->rk.dname,
|
||||
dnskey_rrset->rk.dname_len,
|
||||
dnskey_rrset->rk.dname_len,
|
||||
ntohs(dnskey_rrset->rk.rrset_class),
|
||||
rrset_get_ttl(dnskey_rrset), *env->now);
|
||||
}
|
||||
@@ -749,7 +825,7 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||
BOGUS_KEY_TTL, *env->now);
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
|
||||
{
|
||||
size_t i;
|
||||
@@ -767,15 +843,15 @@ val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
|
||||
sldns_lookup_table *lt;
|
||||
char herr[64], aerr[64];
|
||||
lt = sldns_lookup_by_id(sldns_hashes,
|
||||
(int)ds_get_digest_algo(ds_rrset, i));
|
||||
(int)ds_get_digest_algo(ds_rrset, 0));
|
||||
if(lt) snprintf(herr, sizeof(herr), "%s", lt->name);
|
||||
else snprintf(herr, sizeof(herr), "%d",
|
||||
(int)ds_get_digest_algo(ds_rrset, i));
|
||||
(int)ds_get_digest_algo(ds_rrset, 0));
|
||||
lt = sldns_lookup_by_id(sldns_algorithms,
|
||||
(int)ds_get_key_algo(ds_rrset, i));
|
||||
(int)ds_get_key_algo(ds_rrset, 0));
|
||||
if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name);
|
||||
else snprintf(aerr, sizeof(aerr), "%d",
|
||||
(int)ds_get_key_algo(ds_rrset, i));
|
||||
(int)ds_get_key_algo(ds_rrset, 0));
|
||||
verbose(VERB_ALGO, "DS unsupported, hash %s %s, "
|
||||
"key algorithm %s %s", herr,
|
||||
(ds_digest_algo_is_supported(ds_rrset, 0)?
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#define VALIDATOR_VAL_UTILS_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct query_info;
|
||||
struct reply_info;
|
||||
struct val_env;
|
||||
@@ -113,6 +114,7 @@ void val_find_signer(enum val_classification subtype,
|
||||
struct query_info* qinf, struct reply_info* rep,
|
||||
size_t cname_skip, uint8_t** signer_name, size_t* signer_len);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Verify RRset with keys
|
||||
* @param env: module environment (scratch buffer)
|
||||
@@ -130,6 +132,7 @@ enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Verify RRset with keys from a keyset.
|
||||
@@ -147,6 +150,12 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
struct key_entry_key* kkey, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
enum sec_status val_verify_rrset_entry_ede(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
||||
* returns a sec_status instead of a key_entry.
|
||||
@@ -168,6 +177,11 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
enum sec_status val_verify_DNSKEY_with_DS_ede(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
|
||||
* but for a trust anchor.
|
||||
@@ -191,6 +205,12 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
enum sec_status val_verify_DNSKEY_with_TA_ede(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
|
||||
* match the DNSKEY keys.
|
||||
@@ -221,6 +241,11 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
struct key_entry_key* val_verify_new_DNSKEYs_ede(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify rrset with trust anchor: DS and DNSKEY rrset.
|
||||
@@ -252,6 +277,13 @@ struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset,
|
||||
int downprot, char** reason, struct module_qstate* qstate);
|
||||
|
||||
struct key_entry_key* val_verify_new_DNSKEYs_with_ta_ede(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Determine if DS rrset is usable for validator or not.
|
||||
* Returns true if the algorithms for key and DShash are supported,
|
||||
|
||||
+51
-26
@@ -592,6 +592,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
enum sec_status sec;
|
||||
int dname_seen = 0;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
/* validate the ANSWER section */
|
||||
for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
@@ -612,8 +613,8 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
}
|
||||
|
||||
/* Verify the answer rrset */
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
LDNS_SECTION_ANSWER, qstate);
|
||||
sec = val_verify_rrset_entry_ede(env, ve, s, key_entry, &reason,
|
||||
&reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
/* If the (answer) rrset failed to validate, then this
|
||||
* message is BAD. */
|
||||
if(sec != sec_status_secure) {
|
||||
@@ -627,6 +628,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
errinf(qstate, "for DNAME");
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
chase_reply->reason_bogus = reason_bogus;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -642,8 +644,8 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
for(i=chase_reply->an_numrrsets; i<chase_reply->an_numrrsets+
|
||||
chase_reply->ns_numrrsets; i++) {
|
||||
s = chase_reply->rrsets[i];
|
||||
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
|
||||
LDNS_SECTION_AUTHORITY, qstate);
|
||||
sec = val_verify_rrset_entry_ede(env, ve, s, key_entry, &reason,
|
||||
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
/* If anything in the authority section fails to be secure,
|
||||
* we have a bad message. */
|
||||
if(sec != sec_status_secure) {
|
||||
@@ -654,6 +656,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
errinf_rrset(qstate, s);
|
||||
chase_reply->security = sec_status_bogus;
|
||||
chase_reply->reason_bogus = reason_bogus;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -669,6 +672,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct module_env* env,
|
||||
/* only validate rrs that have signatures with the key */
|
||||
/* leave others unchecked, those get removed later on too */
|
||||
val_find_rrset_signer(s, &sname, &slen);
|
||||
|
||||
if(sname && query_dname_compare(sname, key_entry->name)==0)
|
||||
(void)val_verify_rrset_entry(env, ve, s, key_entry,
|
||||
&reason, LDNS_SECTION_ADDITIONAL, qstate);
|
||||
@@ -1557,6 +1561,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
verbose(VERB_QUERY, "unsigned parent zone denies"
|
||||
" trust anchor, indeterminate");
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_DNSSEC_INDETERMINATE;
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@@ -1588,6 +1593,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(vq->key_entry == NULL && anchor == NULL) {
|
||||
/*response isn't under a trust anchor, so we cannot validate.*/
|
||||
vq->chase_reply->security = sec_status_indeterminate;
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_DNSSEC_INDETERMINATE;
|
||||
/* go to finished state to cache this result */
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
@@ -1635,7 +1641,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
} else if(key_entry_isbad(vq->key_entry)) {
|
||||
/* key is bad, chain is bad, reply is bogus */
|
||||
errinf_dname(qstate, "key for validation", vq->key_entry->name);
|
||||
errinf(qstate, "is marked as invalid");
|
||||
errinf_ede(qstate, "is marked as invalid", LDNS_EDE_DNSSEC_BOGUS);
|
||||
if(key_entry_get_reason(vq->key_entry)) {
|
||||
errinf(qstate, "because of a previous");
|
||||
errinf(qstate, key_entry_get_reason(vq->key_entry));
|
||||
@@ -1643,6 +1649,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* no retries, stop bothering the authority until timeout */
|
||||
vq->restart_count = ve->max_restart;
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@@ -1713,9 +1720,10 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
|
||||
vq->empty_DS_name) == 0) {
|
||||
/* do not query for empty_DS_name again */
|
||||
verbose(VERB_ALGO, "Cannot retrieve DS for signature");
|
||||
errinf(qstate, "no signatures");
|
||||
errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
vq->state = VAL_FINISHED_STATE;
|
||||
return 1;
|
||||
}
|
||||
@@ -1848,7 +1856,9 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
"of trust to keys for", vq->key_entry->name,
|
||||
LDNS_RR_TYPE_DNSKEY, vq->key_entry->key_class);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
errinf(qstate, "while building chain of trust");
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
errinf_ede(qstate, "while building chain of trust",
|
||||
LDNS_EDE_DNSKEY_MISSING);
|
||||
if(vq->restart_count >= ve->max_restart)
|
||||
key_cache_insert(ve->kcache, vq->key_entry, qstate);
|
||||
return 1;
|
||||
@@ -1861,9 +1871,10 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
"signer name", &vq->qchase);
|
||||
verbose(VERB_DETAIL, "Could not establish validation of "
|
||||
"INSECURE status of unsigned response.");
|
||||
errinf(qstate, "no signatures");
|
||||
errinf_ede(qstate, "no signatures", LDNS_EDE_RRSIGS_MISSING);
|
||||
errinf_origin(qstate, qstate->reply_origin);
|
||||
vq->chase_reply->security = sec_status_bogus;
|
||||
vq->chase_reply->reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return 1;
|
||||
}
|
||||
subtype = val_classify_response(qstate->query_flags, &qstate->qinfo,
|
||||
@@ -2001,17 +2012,21 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
vq->orig_msg->rep, vq->rrset_skip);
|
||||
|
||||
/* store overall validation result in orig_msg */
|
||||
if(vq->rrset_skip == 0)
|
||||
if(vq->rrset_skip == 0) {
|
||||
vq->orig_msg->rep->security = vq->chase_reply->security;
|
||||
else if(subtype != VAL_CLASS_REFERRAL ||
|
||||
vq->orig_msg->rep->reason_bogus = vq->chase_reply->reason_bogus;
|
||||
} else if(subtype != VAL_CLASS_REFERRAL ||
|
||||
vq->rrset_skip < vq->orig_msg->rep->an_numrrsets +
|
||||
vq->orig_msg->rep->ns_numrrsets) {
|
||||
/* ignore sec status of additional section if a referral
|
||||
* type message skips there and
|
||||
* use the lowest security status as end result. */
|
||||
if(vq->chase_reply->security < vq->orig_msg->rep->security)
|
||||
if(vq->chase_reply->security < vq->orig_msg->rep->security) {
|
||||
vq->orig_msg->rep->security =
|
||||
vq->chase_reply->security;
|
||||
vq->orig_msg->rep->reason_bogus =
|
||||
vq->chase_reply->reason_bogus;
|
||||
}
|
||||
}
|
||||
|
||||
if(subtype == VAL_CLASS_REFERRAL) {
|
||||
@@ -2304,6 +2319,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct key_entry_key* kkey = NULL;
|
||||
enum sec_status sec = sec_status_unchecked;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
int downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||
|
||||
if(!dnskey_rrset) {
|
||||
@@ -2311,7 +2327,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
"could not fetch DNSKEY rrset",
|
||||
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
errinf(qstate, "no DNSKEY rrset");
|
||||
errinf_ede(qstate, "no DNSKEY rrset", LDNS_EDE_DNSKEY_MISSING);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
*qstate->env->now);
|
||||
@@ -2325,9 +2341,9 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
return kkey;
|
||||
}
|
||||
/* attempt to verify with trust anchor DS and DNSKEY */
|
||||
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
|
||||
kkey = val_verify_new_DNSKEYs_with_ta_ede(qstate->region, qstate->env, ve,
|
||||
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
|
||||
&reason, qstate);
|
||||
&reason, &reason_bogus, qstate);
|
||||
if(!kkey) {
|
||||
log_err("out of memory: verifying prime TA");
|
||||
return NULL;
|
||||
@@ -2346,7 +2362,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
|
||||
/* NOTE: in this case, we should probably reject the trust
|
||||
* anchor for longer, perhaps forever. */
|
||||
if(qstate->env->cfg->harden_dnssec_stripped) {
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
kkey = key_entry_create_bad(qstate->region, ta->name,
|
||||
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
|
||||
*qstate->env->now);
|
||||
@@ -2389,6 +2405,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
{
|
||||
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
enum val_classification subtype;
|
||||
if(rcode != LDNS_RCODE_NOERROR) {
|
||||
char rc[16];
|
||||
@@ -2397,7 +2414,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* errors here pretty much break validation */
|
||||
verbose(VERB_DETAIL, "DS response was error, thus bogus");
|
||||
errinf(qstate, rc);
|
||||
errinf(qstate, "no DS");
|
||||
errinf_ede(qstate, "no DS", reason_bogus);
|
||||
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@@ -2411,17 +2429,17 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(!ds) {
|
||||
log_warn("internal error: POSITIVE DS response was "
|
||||
"missing DS.");
|
||||
errinf(qstate, "no DS record");
|
||||
errinf_ede(qstate, "no DS record", reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
/* Verify only returns BOGUS or SECURE. If the rrset is
|
||||
* bogus, then we are done. */
|
||||
sec = val_verify_rrset_entry(qstate->env, ve, ds,
|
||||
vq->key_entry, &reason, LDNS_SECTION_ANSWER, qstate);
|
||||
sec = val_verify_rrset_entry_ede(qstate->env, ve, ds,
|
||||
vq->key_entry, &reason, &reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec != sec_status_secure) {
|
||||
verbose(VERB_DETAIL, "DS rrset in DS response did "
|
||||
"not verify");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@@ -2430,6 +2448,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
if(!val_dsset_isusable(ds)) {
|
||||
/* If they aren't usable, then we treat it like
|
||||
* there was no DS. */
|
||||
|
||||
// @TODO add EDE Unsupported DS Digest Type
|
||||
|
||||
*ke = key_entry_create_null(qstate->region,
|
||||
qinfo->qname, qinfo->qname_len, qinfo->qclass,
|
||||
ub_packed_rrset_ttl(ds), *qstate->env->now);
|
||||
@@ -2452,7 +2473,7 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* make sure there are NSECs or NSEC3s with signatures */
|
||||
if(!val_has_signed_nsecs(msg->rep, &reason)) {
|
||||
verbose(VERB_ALGO, "no NSECs: %s", reason);
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, LDNS_EDE_NSEC_MISSING);
|
||||
goto return_bogus;
|
||||
}
|
||||
|
||||
@@ -2676,7 +2697,7 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
* @param origin: the origin of msg.
|
||||
*/
|
||||
static void
|
||||
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
|
||||
struct sock_list* origin)
|
||||
{
|
||||
@@ -2685,6 +2706,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
struct ub_packed_rrset_key* dnskey = NULL;
|
||||
int downprot;
|
||||
char* reason = NULL;
|
||||
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
|
||||
if(rcode == LDNS_RCODE_NOERROR)
|
||||
dnskey = reply_find_answer_rrset(qinfo, msg->rep);
|
||||
@@ -2693,6 +2715,9 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
/* bad response */
|
||||
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
|
||||
"DNSKEY query.");
|
||||
|
||||
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
|
||||
if(vq->restart_count < ve->max_restart) {
|
||||
val_blacklist(&vq->chain_blacklist, qstate->region,
|
||||
origin, 1);
|
||||
@@ -2707,7 +2732,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
log_err("alloc failure in missing dnskey response");
|
||||
/* key_entry is NULL for failure in Validate */
|
||||
}
|
||||
errinf(qstate, "No DNSKEY record");
|
||||
errinf_ede(qstate, "No DNSKEY record", reason_bogus);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
vq->state = VAL_VALIDATE_STATE;
|
||||
@@ -2720,8 +2745,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
return;
|
||||
}
|
||||
downprot = qstate->env->cfg->harden_algo_downgrade;
|
||||
vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env,
|
||||
ve, dnskey, vq->ds_rrset, downprot, &reason, qstate);
|
||||
vq->key_entry = val_verify_new_DNSKEYs_ede(qstate->region, qstate->env,
|
||||
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, qstate);
|
||||
|
||||
if(!vq->key_entry) {
|
||||
log_err("out of memory in verify new DNSKEYs");
|
||||
@@ -2742,7 +2767,7 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
}
|
||||
verbose(VERB_DETAIL, "Did not match a DS to a DNSKEY, "
|
||||
"thus bogus.");
|
||||
errinf(qstate, reason);
|
||||
errinf_ede(qstate, reason, reason_bogus);
|
||||
errinf_origin(qstate, origin);
|
||||
errinf_dname(qstate, "for key", qinfo->qname);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user