- Implemented opportunistic IPsec support module (ipsecmod).

- Some whitespace fixup.


git-svn-id: file:///svn/unbound/trunk@4158 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
George Thessalonikefs 2017-05-16 12:39:24 +00:00
parent 5febdd39a1
commit 491b0a26e4
29 changed files with 2869 additions and 229 deletions

View File

@ -100,6 +100,9 @@ PYUNBOUND_OBJ=@PYUNBOUND_OBJ@
SUBNET_SRC=edns-subnet/edns-subnet.c edns-subnet/subnetmod.c edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c
SUBNET_OBJ=@SUBNET_OBJ@
SUBNET_HEADER=@SUBNET_HEADER@
IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c
IPSECMOD_OBJ=@IPSECMOD_OBJ@
IPSECMOD_HEADER=@IPSECMOD_HEADER@
COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \
util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \
util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
@ -122,7 +125,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
$(DNSTAP_SRC) $(DNSCRYPT_SRC)
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@ -133,7 +136,8 @@ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ)
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ)
COMMON_OBJ_WITHOUT_NETCALL+=respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
@ -605,6 +609,7 @@ depend:
-e 's?$$(srcdir)/dnscrypt/dnscrypt_config.h??g' \
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2)

View File

@ -663,6 +663,9 @@
/* Define to 1 to use cachedb support */
#undef USE_CACHEDB
/* Define to 1 to use ipsecmod support */
#undef USE_IPSECMOD
/* Define to 1 to enable dnscrypt support */
#undef USE_DNSCRYPT

View File

@ -1353,6 +1353,21 @@ case "$enable_cachedb" in
;;
esac
# check for ipsecmod if requested
AC_ARG_ENABLE(ipsecmod, AC_HELP_STRING([--enable-ipsecmod], [Enable ipsecmod module that facilitates opportunistic IPsec]))
case "$enable_ipsecmod" in
yes)
AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.])
IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo"
AC_SUBST(IPSECMOD_OBJ)
IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h'
AC_SUBST(IPSECMOD_HEADER)
;;
no|*)
# nothing
;;
esac
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).

View File

@ -871,6 +871,9 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
#ifdef CLIENT_SUBNET
size_t subnet = 0;
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
size_t ipsecmod = 0;
#endif /* USE_IPSECMOD */
msg = slabhash_get_mem(daemon->env->msg_cache);
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
val=0;
@ -906,6 +909,15 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
(&worker->env, m);
}
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
m = modstack_find(&worker->env.mesh->mods, "ipsecmod");
if(m != -1) {
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
mods.mod[m]->get_mem));
ipsecmod = (*worker->env.mesh->mods.mod[m]->get_mem)
(&worker->env, m);
}
#endif /* USE_IPSECMOD */
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
return 0;
@ -921,6 +933,10 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
if(!print_longnum(ssl, "mem.mod.subnet"SQ, subnet))
return 0;
#endif /* CLIENT_SUBNET */
#ifdef USE_IPSECMOD
if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod))
return 0;
#endif /* USE_IPSECMOD */
return 1;
}

View File

@ -1,3 +1,7 @@
16 May 2017: George
- Implemented opportunistic IPsec support module (ipsecmod).
- Some whitespace fixup.
16 May 2017: Wouter
- updated dependencies in the makefile.
- document trust-anchor-signaling in example config file.

View File

@ -701,6 +701,34 @@ server:
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10
# 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
# module-config above). Can be used when ipsecmod needs to be
# enabled/disabled via remote-control(below).
# ipsecmod-enabled: yes
#
# Path to executable external hook. It must be defined when ipsecmod is
# listed in module-config (above).
# ipsecmod-hook: "./my_executable"
#
# When enabled unbound will reply with SERVFAIL if the return value of
# the ipsecmod-hook is not 0.
# ipsecmod-strict: no
#
# Maximum time to live (TTL) for cached A/AAAA records with IPSECKEY.
# ipsecmod-max-ttl: 3600
#
# Reply with A/AAAA even if the relevant IPSECKEY is bogus. Mainly used for
# testing.
# ipsecmod-ignore-bogus: no
#
# Domains for which ipsecmod will be triggered. If not defined (default)
# all domains are treated as being whitelisted.
# ipsecmod-whitelist: "example.com"
# ipsecmod-whitelist: "nlnetlabs.nl"
# Python config section. To enable:
# o use --with-pythonmodule to configure before compiling.

View File

@ -16,7 +16,8 @@
.B unbound.conf
is used to configure
\fIunbound\fR(8).
The file format has attributes and values. Some attributes have attributes inside them.
The file format has attributes and values. Some attributes have attributes
inside them.
The notation is: attribute: value.
.P
Comments start with # and last to the end of line. Empty lines are
@ -62,8 +63,8 @@ server:
access\-control: 2001:DB8::/64 allow
.fi
.SH "FILE FORMAT"
There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute
is followed by its containing attributes, or a value.
There must be whitespace between keywords. Attribute keywords end with a colon ':'.
An attribute is followed by its containing attributes, or a value.
.P
Files can be included using the
.B include:
@ -393,7 +394,8 @@ Default is no. Useful in tunneling scenarios.
.B ssl\-upstream: \fI<yes or no>
Enabled or disable whether the upstream queries use SSL only for transport.
Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
TCP wireformat. The other server must support this (see \fBssl\-service\-key\fR).
TCP wireformat. The other server must support this (see
\fBssl\-service\-key\fR).
.TP
.B ssl\-service-key: \fI<file>
If enabled, the server provider SSL service on its TCP sockets. The clients
@ -815,8 +817,8 @@ File with trusted keys for DLV (DNSSEC Lookaside Validation). Both DS and
DNSKEY entries can be used in the file, in the same format as for
\fItrust\-anchor\-file:\fR statements. Only one DLV can be configured, more
would be slow. The DLV configured is used as a root trusted DLV, this
means that it is a lookaside for the root. Default is "", or no dlv anchor file.
DLV is going to be decommissioned. Please do not use it any more.
means that it is a lookaside for the root. Default is "", or no dlv anchor
file. DLV is going to be decommissioned. Please do not use it any more.
.TP
.B dlv\-anchor: \fI<"Resource Record">
Much like trust\-anchor, this is a DLV anchor with the DS or DNSKEY inline.
@ -1395,10 +1397,10 @@ Default is no.
There may be multiple
.B view:
clauses. Each with a \fBname:\fR and zero or more \fBlocal\-zone\fR and
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the view
name in an \fBaccess\-control\-view\fR element. Options from matching views will
override global options. Global options will be used if no matching view
is found.
\fBlocal\-data\fR elements. View can be mapped to requests by specifying the
view name in an \fBaccess\-control\-view\fR element. Options from matching
views will override global options. Global options will be used if no matching
view is found.
.TP
.B name: \fI<view name>
Name of the view. Must be unique. This name is used in access\-control\-view
@ -1459,7 +1461,8 @@ clause give the settings of the dnscrypt channel. While those options are
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.
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/\
dnscrypt-wrapper/blob/master/README.md#usage
.TP
.B dnscrypt\-enable: \fI<yes or no>\fR
Whether or not the \fBdnscrypt\fR config should be enabled. You may define
@ -1480,19 +1483,19 @@ Path to the time limited secret key file. This option may be specified multiple
times.
.TP
.B dnscrypt\-provider\-cert: \fI<path to cert file>\fR
Path to the certificate related to the \fBdnscrypt\-secret\-key\fRs. This option
may be specified multiple times.
Path to the certificate related to the \fBdnscrypt\-secret\-key\fRs.
This option may be specified multiple times.
.SS "EDNS Client Subnet Module Options"
.LP
The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache
validator iterator" directive and be compiled into the daemon to be
enabled. These settings go in the \fBserver:\fR section.
.LP
If the destination address is whitelisted with Unbound will add the EDNS0 option
to the query containing the relevant part of the client's address. When an
answer contains the ECS option the response and the option are placed in a
specialized cache. If the authority indicated no support, the response is stored
in the regular cache.
If the destination address is whitelisted with Unbound will add the EDNS0
option to the query containing the relevant part of the client's address. When
an answer contains the ECS option the response and the option are placed in a
specialized cache. If the authority indicated no support, the response is
stored in the regular cache.
.LP
Additionally, when a client includes the option in its queries, Unbound will
forward the option to the authority if prensent in the whitelist, or
@ -1525,6 +1528,72 @@ to expose to third parties for IPv6. Defaults to 56.
.B max\-client\-subnet\-ipv4: \fI<number>\fR
Specifies the maximum prefix length of the client source address we are willing
to expose to third parties for IPv4. Defaults to 24.
.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.
.LP
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
will call an external hook passing the following arguments:
.TP 10
\h'5'\fIQNAME\fR
Domain name of the A/AAAA and IPSECKEY query. In string format.
.TP 10
\h'5'\fIIPSECKEY TTL\fR
TTL of the IPSECKEY RRset.
.TP 10
\h'5'\fIA/AAAA\fR
String of space separated IP addresses present in the A/AAAA RRset. The IP
addresses are in string format.
.TP 10
\h'5'\fIIPSECKEY\fR
String of space separated IPSECKEY RDATA present in the IPSECKEY RRset. The
IPSECKEY RDATA are in DNS presentation format.
.LP
The A/AAAA answer is then cached and returned to the client. If the external
hook was called the TTL changes to ensure it doesn't surpass
\fBipsecmod-max-ttl\fR.
.LP
The same procedure is also followed when \fBprefetch:\fR is used, but the
A/AAAA answer is given to the client before the hook is called.
\fBipsecmod-max-ttl\fR ensures that the A/AAAA answer given from cache is still
relevant for opportunistic IPsec.
.TP
.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.
Defaults to yes.
.TP
.B ipsecmod\-hook: \fI<filename>\fR
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
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
not be cached. Defaults to no.
.TP
.B ipsecmod\-max-ttl: \fI<seconds>\fR
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
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.
.TP
.B ipsecmod\-whitelist: \fI<domain>\fR
Whitelist the domain so that the module logic will be executed. Can
be given multiple times, for different domains. If the option is not
specified, all domains are treated as being whitelisted (default).
.SH "MEMORY CONTROL EXAMPLE"
In the example config settings below memory usage is reduced. Some service
levels are lower, notable very large data and a high TCP load are no longer

View File

@ -0,0 +1,158 @@
/*
* ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to
* operate on.
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed domains for ipsecmod.
*/
#include "config.h"
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#include "ipsecmod/ipsecmod-whitelist.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/rbtree.h"
#include "util/data/dname.h"
#include "util/storage/dnstree.h"
#include "sldns/str2wire.h"
/** Apply ipsecmod-whitelist string. */
static int
whitelist_str_cfg(rbtree_type* whitelist, const char* name)
{
struct name_tree_node* n;
size_t len;
uint8_t* nm = sldns_str2wire_dname(name, &len);
if(!nm) {
log_err("ipsecmod: could not parse %s for whitelist.", name);
return 0;
}
n = (struct name_tree_node*)calloc(1, sizeof(*n));
if(!n) {
log_err("ipsecmod: out of memory while creating whitelist.");
free(nm);
return 0;
}
n->node.key = n;
n->name = nm;
n->len = len;
n->labs = dname_count_labels(nm);
n->dclass = LDNS_RR_CLASS_IN;
if(!name_tree_insert(whitelist, n, nm, len, n->labs, n->dclass)) {
/* duplicate element ignored, idempotent */
free(n->name);
free(n);
}
return 1;
}
/** Read ipsecmod-whitelist config. */
static int
read_whitelist(rbtree_type* whitelist, struct config_file* cfg)
{
struct config_strlist* p;
for(p = cfg->ipsecmod_whitelist; p; p = p->next) {
log_assert(p->str);
if(!whitelist_str_cfg(whitelist, p->str))
return 0;
}
return 1;
}
int
ipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie,
struct config_file* cfg)
{
ie->whitelist = rbtree_create(name_tree_compare);
if(!read_whitelist(ie->whitelist, cfg))
return 0;
name_tree_init_parents(ie->whitelist);
return 1;
}
/** Delete ipsecmod_env->whitelist element. */
static void
whitelist_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
free(n);
}
}
/** Get memory usage of ipsecmod_env->whitelist element. */
static void
whitelist_get_mem(struct rbnode_type* n, void* arg)
{
struct name_tree_node* node = (struct name_tree_node*)n;
size_t* size = (size_t*) arg;
if(node) {
*size += sizeof(node) + node->len;
}
}
void
ipsecmod_whitelist_delete(rbtree_type* whitelist)
{
if(whitelist) {
traverse_postorder(whitelist, whitelist_free, NULL);
free(whitelist);
}
}
int
ipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname,
size_t dname_len, uint16_t qclass)
{
if(!ie->whitelist) return 1; /* No whitelist, treat as whitelisted. */
return name_tree_lookup(ie->whitelist, dname, dname_len,
dname_count_labels(dname), qclass) != NULL;
}
size_t
ipsecmod_whitelist_get_mem(rbtree_type* whitelist)
{
size_t size = 0;
if(whitelist) {
traverse_postorder(whitelist, whitelist_get_mem, &size);
}
return size;
}
#endif /* USE_IPSECMOD */

View File

@ -0,0 +1,82 @@
/*
* ipsecmod/ipsecmod-whitelist.h - White listed domains for the ipsecmod to
* operate on.
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* Keep track of the white listed domains for ipsecmod.
*/
#ifndef IPSECMOD_WHITELIST_H
#define IPSECMOD_WHITELIST_H
#include "util/storage/dnstree.h"
struct config_file;
struct regional;
/**
* Process ipsecmod_whitelist config.
* @param ie: ipsecmod environment.
* @param cfg: config options.
* @return 0 on error.
*/
int ipsecmod_whitelist_apply_cfg(struct ipsecmod_env* ie,
struct config_file* cfg);
/**
* Delete the ipsecmod whitelist.
* @param whitelist: ipsecmod whitelist.
*/
void ipsecmod_whitelist_delete(rbtree_type* whitelist);
/**
* See if a domain is whitelisted.
* @param ie: ipsecmod environment.
* @param dname: domain name to check.
* @param dname_len: length of domain name.
* @param qclass: query CLASS.
* @return: true if the domain is whitelisted for the ipsecmod.
*/
int ipsecmod_domain_is_whitelisted(struct ipsecmod_env* ie, uint8_t* dname,
size_t dname_len, uint16_t qclass);
/**
* Get memory used by ipsecmod whitelist.
* @param whitelist: structure for domain storage.
* @return bytes in use.
*/
size_t ipsecmod_whitelist_get_mem(rbtree_type* whitelist);
#endif /* IPSECMOD_WHITELIST_H */

512
ipsecmod/ipsecmod.c Normal file
View File

@ -0,0 +1,512 @@
/*
* ipsecmod/ipsecmod.c - facilitate opportunistic IPsec module
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a module that facilitates opportunistic IPsec. It does so
* by also quering for the IPSECKEY for A/AAAA queries and calling a
* configurable hook (eg. signaling an IKE daemon) before replying.
*/
#include "config.h"
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#include "ipsecmod/ipsecmod-whitelist.h"
#include "util/fptr_wlist.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "services/cache/dns.h"
#include "sldns/wire2str.h"
/** Apply configuration to ipsecmod module 'global' state. */
static int
ipsecmod_apply_cfg(struct ipsecmod_env* ipsecmod_env, struct config_file* cfg)
{
if(!cfg->ipsecmod_hook || (cfg->ipsecmod_hook && !cfg->ipsecmod_hook[0])) {
log_err("ipsecmod: missing ipsecmod-hook.");
return 0;
}
if(cfg->ipsecmod_whitelist &&
!ipsecmod_whitelist_apply_cfg(ipsecmod_env, cfg))
return 0;
return 1;
}
int
ipsecmod_init(struct module_env* env, int id)
{
struct ipsecmod_env* ipsecmod_env = (struct ipsecmod_env*)calloc(1,
sizeof(struct ipsecmod_env));
if(!ipsecmod_env) {
log_err("malloc failure");
return 0;
}
env->modinfo[id] = (void*)ipsecmod_env;
ipsecmod_env->whitelist = NULL;
if(!ipsecmod_apply_cfg(ipsecmod_env, env->cfg)) {
log_err("ipsecmod: could not apply configuration settings.");
return 0;
}
return 1;
}
void
ipsecmod_deinit(struct module_env* env, int id)
{
struct ipsecmod_env* ipsecmod_env;
if(!env || !env->modinfo[id])
return;
ipsecmod_env = (struct ipsecmod_env*)env->modinfo[id];
/* Free contents. */
ipsecmod_whitelist_delete(ipsecmod_env->whitelist);
free(ipsecmod_env);
env->modinfo[id] = NULL;
}
/** New query for ipsecmod. */
static int
ipsecmod_new(struct module_qstate* qstate, int id)
{
struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)regional_alloc(
qstate->region, sizeof(struct ipsecmod_qstate));
memset(iq, 0, sizeof(*iq));
qstate->minfo[id] = iq;
if(!iq)
return 0;
/* Initialise it. */
iq->enabled = qstate->env->cfg->ipsecmod_enabled;
iq->is_whitelisted = ipsecmod_domain_is_whitelisted(
(struct ipsecmod_env*)qstate->env->modinfo[id], qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qclass);
iq->region = regional_create();
return 1;
}
/**
* Exit module with an error status.
* @param qstate: query state
* @param id: module id.
*/
static void
ipsecmod_error(struct module_qstate* qstate, int id)
{
qstate->ext_state[id] = module_error;
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
}
/**
* Generate a request for the IPSECKEY.
*
* @param qstate: query state that is the parent.
* @param id: module id.
* @param name: what name to query for.
* @param namelen: length of name.
* @param qtype: query type.
* @param qclass: query class.
* @param flags: additional flags, such as the CD bit (BIT_CD), or 0.
* @return false on alloc failure.
*/
static int
generate_request(struct module_qstate* qstate, int id, uint8_t* name,
size_t namelen, uint16_t qtype, uint16_t qclass, uint16_t flags)
{
struct module_qstate* newq;
struct query_info ask;
ask.qname = name;
ask.qname_len = namelen;
ask.qtype = qtype;
ask.qclass = qclass;
ask.local_alias = NULL;
log_query_info(VERB_ALGO, "ipsecmod: generate request", &ask);
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &ask,
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
log_err("Could not generate request: out of memory");
return 0;
}
qstate->ext_state[id] = module_wait_subquery;
return 1;
}
/**
* Prepare the data and call the hook.
*
* @param iq: ipsecmod qstate.
* @param ie: ipsecmod environment.
* @param rrset_data: IPSECKEY rrset.
* @return true on success, false otherwise.
*/
static int
call_hook(struct module_qstate* qstate, struct ipsecmod_qstate* iq,
struct ipsecmod_env* ie)
{
size_t slen, tempdata_len, tempstring_len;
char str[65535], *s, *tempstring;
int i, w;
struct ub_packed_rrset_key* rrset_key;
struct packed_rrset_data* rrset_data;
uint8_t *tempdata;
/* Check if a shell is available */
if(system(NULL) == 0) {
log_err("ipsecmod: no shell available for ipsecmod-hook");
return 0;
}
/* Zero the buffer. */
s = str;
slen = sizeof(str);
memset(s, 0, slen);
/* Copy the hook into the buffer. */
sldns_str_print(&s, &slen, "%s", qstate->env->cfg->ipsecmod_hook);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the qname into the buffer. */
tempstring = sldns_wire2str_dname(qstate->qinfo.qname,
qstate->qinfo.qname_len);
if(!tempstring) {
log_err("ipsecmod: out of memory when calling the hook");
return 0;
}
sldns_str_print(&s, &slen, "\"%s\"", tempstring);
free(tempstring);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the IPSECKEY TTL into the buffer. */
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
sldns_str_print(&s, &slen, "\"%ld\"", rrset_data->ttl);
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the A/AAAA record(s) into the buffer. Start and end this section
* with a double quote. */
rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep);
rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
sldns_str_print(&s, &slen, "\"");
for(i=0; i<rrset_data->count; i++) {
if(i > 0) {
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
}
/* Ignore the first two bytes, they are the rr_data len. */
w = sldns_wire2str_rdata_buf(rrset_data->rr_data[i] + 2,
rrset_data->rr_len[i] - 2, s, slen, qstate->qinfo.qtype);
if(w < 0) {
/* Error in printout. */
return -1;
} else if((size_t)w >= slen) {
s = NULL; /* We do not want str to point outside of buffer. */
slen = 0;
return -1;
} else {
s += w;
slen -= w;
}
}
sldns_str_print(&s, &slen, "\"");
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
/* Copy the IPSECKEY record(s) into the buffer. Start and end this section
* with a double quote. */
sldns_str_print(&s, &slen, "\"");
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
for(i=0; i<rrset_data->count; i++) {
if(i > 0) {
/* Put space into the buffer. */
sldns_str_print(&s, &slen, " ");
}
/* Ignore the first two bytes, they are the rr_data len. */
tempdata = rrset_data->rr_data[i] + 2;
tempdata_len = rrset_data->rr_len[i] - 2;
/* Save the buffer pointers. */
tempstring = s; tempstring_len = slen;
w = sldns_wire2str_ipseckey_scan(&tempdata, &tempdata_len, &s, &slen,
NULL, 0);
/* There was an error when parsing the IPSECKEY; reset the buffer
* pointers to their previous values. */
if(w == -1){
s = tempstring; slen = tempstring_len;
}
}
sldns_str_print(&s, &slen, "\"");
verbose(VERB_ALGO, "ipsecmod: hook command: '%s'", str);
/* ipsecmod-hook should return 0 on success. */
if(system(str) != 0)
return 0;
return 1;
}
/**
* Handle an ipsecmod module event with a query
* @param qstate: query state (from the mesh), passed between modules.
* contains qstate->env module environment with global caches and so on.
* @param iq: query state specific for this module. per-query.
* @param ie: environment specific for this module. global.
* @param id: module id.
*/
static void
ipsecmod_handle_query(struct module_qstate* qstate,
struct ipsecmod_qstate* iq, struct ipsecmod_env* ie, int id)
{
struct ub_packed_rrset_key* rrset_key;
struct packed_rrset_data* rrset_data;
size_t i;
/* Pass to next module if we are not enabled and whitelisted. */
if(!(iq->enabled && iq->is_whitelisted)) {
qstate->ext_state[id] = module_wait_module;
return;
}
/* New query, check if the query is for an A/AAAA record and disable
* caching for other modules. */
if(!iq->ipseckey_done) {
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
verbose(VERB_ALGO, "ipsecmod: query for %s; engaging",
sldns_rr_descript(qstate->qinfo.qtype)->_name);
qstate->no_cache_store = 1;
}
/* Pass request to next module. */
qstate->ext_state[id] = module_wait_module;
return;
}
/* IPSECKEY subquery is finished. */
/* We have an IPSECKEY answer. */
if(iq->ipseckey_rrset) {
rrset_data = (struct packed_rrset_data*)iq->ipseckey_rrset->entry.data;
if(rrset_data) {
/* If bogus return SERVFAIL. */
if(!qstate->env->cfg->ipsecmod_ignore_bogus &&
rrset_data->security == sec_status_bogus) {
log_err("ipsecmod: bogus IPSECKEY");
ipsecmod_error(qstate, id);
return;
}
/* We have a valid IPSECKEY reply, call hook. */
if(!call_hook(qstate, iq, ie) &&
qstate->env->cfg->ipsecmod_strict) {
log_err("ipsecmod: ipsecmod-hook failed");
ipsecmod_error(qstate, id);
return;
}
/* Make sure the A/AAAA's TTL is equal/less than the
* ipsecmod_max_ttl. */
rrset_key = reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep);
rrset_data = (struct packed_rrset_data*)rrset_key->entry.data;
if(rrset_data->ttl > (time_t)qstate->env->cfg->ipsecmod_max_ttl) {
/* Update TTL for rrset to fixed value. */
rrset_data->ttl = qstate->env->cfg->ipsecmod_max_ttl;
for(i=0; i<rrset_data->count+rrset_data->rrsig_count; i++)
rrset_data->rr_ttl[i] = qstate->env->cfg->ipsecmod_max_ttl;
/* Also update reply_info's TTL */
qstate->return_msg->rep->ttl =
qstate->env->cfg->ipsecmod_max_ttl;
qstate->return_msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(
qstate->return_msg->rep->ttl);
}
}
}
/* Store A/AAAA in cache. */
if(!dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway,
0, qstate->region, qstate->query_flags)) {
log_err("ipsecmod: out of memory caching record");
}
qstate->ext_state[id] = module_finished;
}
/**
* Handle an ipsecmod module event with a response from the iterator.
* @param qstate: query state (from the mesh), passed between modules.
* contains qstate->env module environment with global caches and so on.
* @param iq: query state specific for this module. per-query.
* @param ie: environment specific for this module. global.
* @param id: module id.
*/
static void
ipsecmod_handle_response(struct module_qstate* qstate,
struct ipsecmod_qstate* ATTR_UNUSED(iq), struct ipsecmod_env* ie, int id)
{
/* Pass to previous module if we are not enabled and whitelisted. */
if(!(iq->enabled && iq->is_whitelisted)) {
qstate->ext_state[id] = module_finished;
return;
}
/* check if the response is for an A/AAAA query. */
if((qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) &&
/* check that we had an answer for the A/AAAA query. */
qstate->return_msg &&
reply_find_answer_rrset(&qstate->return_msg->qinfo,
qstate->return_msg->rep) &&
/* check that another module didn't SERVFAIL. */
qstate->return_rcode != LDNS_RCODE_SERVFAIL) {
verbose(VERB_ALGO, "ipsecmod: response for %s; generating IPSECKEY "
"subquery", sldns_rr_descript(qstate->qinfo.qtype)->_name);
/* generate an IPSECKEY query. */
if(!generate_request(qstate, id, qstate->qinfo.qname,
qstate->qinfo.qname_len, LDNS_RR_TYPE_IPSECKEY,
qstate->qinfo.qclass, 0)) {
log_err("ipsecmod: could not generate subquery.");
ipsecmod_error(qstate, id);
}
return;
}
/* we are done with the query. */
qstate->ext_state[id] = module_finished;
}
void
ipsecmod_operate(struct module_qstate* qstate, enum module_ev event, int id,
struct outbound_entry* outbound)
{
struct ipsecmod_env* ie = (struct ipsecmod_env*)qstate->env->modinfo[id];
struct ipsecmod_qstate* iq = (struct ipsecmod_qstate*)qstate->minfo[id];
verbose(VERB_QUERY, "ipsecmod[module %d] operate: extstate:%s event:%s",
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
if(iq) log_query_info(VERB_QUERY, "ipsecmod operate: query",
&qstate->qinfo);
/* create ipsecmod_qstate. */
if((event == module_event_new || event == module_event_pass) &&
iq == NULL) {
if(!ipsecmod_new(qstate, id)) {
ipsecmod_error(qstate, id);
return;
}
iq = (struct ipsecmod_qstate*)qstate->minfo[id];
}
if(iq && (event == module_event_pass || event == module_event_new)) {
ipsecmod_handle_query(qstate, iq, ie, id);
return;
}
if(iq && (event == module_event_moddone)) {
ipsecmod_handle_response(qstate, iq, ie, id);
return;
}
if(iq && outbound) {
/* cachedb does not need to process responses at this time
* ignore it.
cachedb_process_response(qstate, iq, ie, id, outbound, event);
*/
return;
}
if(event == module_event_error) {
verbose(VERB_ALGO, "got called with event error, giving up");
ipsecmod_error(qstate, id);
return;
}
if(!iq && (event == module_event_moddone)) {
/* during priming, module done but we never started. */
qstate->ext_state[id] = module_finished;
return;
}
log_err("ipsecmod: bad event %s", strmodulevent(event));
ipsecmod_error(qstate, id);
return;
}
void
ipsecmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super)
{
log_query_info(VERB_ALGO, "ipsecmod: inform_super, sub is",
&qstate->qinfo);
log_query_info(VERB_ALGO, "super is", &super->qinfo);
struct ipsecmod_qstate* siq = (struct ipsecmod_qstate*)super->minfo[id];
if(!siq) {
verbose(VERB_ALGO, "super has no ipsecmod state");
return;
}
if(qstate->return_msg) {
struct ub_packed_rrset_key* rrset_key = reply_find_answer_rrset(
&qstate->return_msg->qinfo, qstate->return_msg->rep);
if(rrset_key) {
/* We have an answer. */
/* Copy to super's region. */
rrset_key = packed_rrset_copy_region(rrset_key, siq->region, 0);
siq->ipseckey_rrset = rrset_key;
if(!rrset_key) {
log_err("ipsecmod: out of memory.");
}
}
}
/* Notify super to proceed. */
siq->ipseckey_done = 1;
}
void
ipsecmod_clear(struct module_qstate* qstate, int id)
{
struct ipsecmod_qstate* iq;
if(!qstate)
return;
iq = (struct ipsecmod_qstate*)qstate->minfo[id];
if(iq) {
/* free contents of iq. */
regional_destroy(iq->region);
}
qstate->minfo[id] = NULL;
}
size_t
ipsecmod_get_mem(struct module_env* env, int id)
{
struct ipsecmod_env* ie = (struct ipsecmod_env*)env->modinfo[id];
if(!ie)
return 0;
return sizeof(*ie) + ipsecmod_whitelist_get_mem(ie->whitelist);
}
/**
* The ipsecmod function block
*/
static struct module_func_block ipsecmod_block = {
"ipsecmod",
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
};
struct module_func_block*
ipsecmod_get_funcblock(void)
{
return &ipsecmod_block;
}
#endif /* USE_IPSECMOD */

99
ipsecmod/ipsecmod.h Normal file
View File

@ -0,0 +1,99 @@
/*
* ipsecmod/ipsecmod.h - facilitate opportunistic IPsec module
*
* Copyright (c) 2017, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a module that facilitates opportunistic IPsec. It does so
* by also quering for the IPSECKEY for A/AAAA queries and calling a
* configurable hook (eg. signaling an IKE daemon) before replying.
*/
#ifndef IPSECMOD_H
#define IPSECMOD_H
#include "util/module.h"
#include "util/rbtree.h"
/**
* The global variable environment contents for the ipsecmod
* Shared between threads, this represents long term information.
*/
struct ipsecmod_env {
/** White listed domains for ipsecmod. */
rbtree_type* whitelist;
};
/**
* Per query state for the ipsecmod module.
*/
struct ipsecmod_qstate {
/** State of the IPsec module. */
/** NOTE: This value is copied here from the configuration so that a change
* with unbound-control would not complicate an already running mesh. */
int enabled;
/** If the qname is whitelisted or not. */
/** NOTE: No whitelist means all qnames are whitelisted. */
int is_whitelisted;
/** Region to store the IPSECKEY rrset. */
struct regional* region;
/** Pointer to IPSECKEY rrset allocated in the above region. NULL if there
* was no IPSECKEY reply from the subquery. */
struct ub_packed_rrset_key* ipseckey_rrset;
/** If the IPSECKEY subquery has finished. */
int ipseckey_done;
};
/** Init the ipsecmod module */
int ipsecmod_init(struct module_env* env, int id);
/** Deinit the ipsecmod module */
void ipsecmod_deinit(struct module_env* env, int id);
/** Operate on an event on a query (in qstate). */
void ipsecmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** Subordinate query done, inform this super request of its conclusion */
void ipsecmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** clear the ipsecmod query-specific contents out of qstate */
void ipsecmod_clear(struct module_qstate* qstate, int id);
/** return memory estimate for the ipsecmod module */
size_t ipsecmod_get_mem(struct module_env* env, int id);
/**
* Get the function block with pointers to the ipsecmod functions
* @return the function block for "ipsecmod".
*/
struct module_func_block* ipsecmod_get_funcblock(void);
#endif /* IPSECMOD_H */

View File

@ -606,22 +606,22 @@ const char* ub_version(void);
* this struct is shared on a shm segment (shm-key in unbound.conf)
*/
struct ub_shm_stat_info {
int num_threads;
int num_threads;
struct {
struct {
long long now_sec, now_usec;
long long up_sec, up_usec;
long long elapsed_sec, elapsed_usec;
} time;
} time;
struct {
long long msg;
long long rrset;
long long val;
long long iter;
long long subnet;
} mem;
struct {
long long msg;
long long rrset;
long long val;
long long iter;
long long subnet;
long long ipsecmod;
} mem;
};
/** number of qtype that is stored for in array */

View File

@ -54,6 +54,9 @@
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#endif
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
@ -131,6 +134,9 @@ module_list_avail(void)
#ifdef USE_CACHEDB
"cachedb",
#endif
#ifdef USE_IPSECMOD
"ipsecmod",
#endif
#ifdef CLIENT_SUBNET
"subnetcache",
#endif
@ -156,6 +162,9 @@ module_funcs_avail(void)
#ifdef USE_CACHEDB
&cachedb_get_funcblock,
#endif
#ifdef USE_IPSECMOD
&ipsecmod_get_funcblock,
#endif
#ifdef CLIENT_SUBNET
&subnetmod_get_funcblock,
#endif

View File

@ -426,6 +426,10 @@ morechecks(struct config_file* cfg, const char* fname)
cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file,
cfg->chrootdir, cfg);
#ifdef USE_IPSECMOD
check_chroot_string("ipsecmod-hook", &cfg->ipsecmod_hook, cfg->chrootdir,
cfg);
#endif
/* remove chroot setting so that modules are not stripping pathnames*/
free(cfg->chrootdir);
cfg->chrootdir = NULL;
@ -478,6 +482,18 @@ morechecks(struct config_file* cfg, const char* fname)
&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
#endif
#ifdef USE_IPSECMOD
&& strcmp(cfg->module_conf, "ipsecmod iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
#endif
#if defined(WITH_PYTHONMODULE) && defined(USE_IPSECMOD)
&& strcmp(cfg->module_conf, "python ipsecmod iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod python iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "python ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod python validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator python iterator") != 0
#endif
) {
fatal_exit("module conf '%s' is not known to work",

View File

@ -78,6 +78,7 @@ testbound_usage(void)
printf("-g detect GOST support (exit code 0 or 1)\n");
printf("-e detect ECDSA support (exit code 0 or 1)\n");
printf("-c detect CLIENT_SUBNET support (exit code 0 or 1)\n");
printf("-i detect IPSECMOD support (exit code 0 or 1)\n");
printf("-s testbound self-test - unit test of testbound parts.\n");
printf("-o str unbound commandline options separated by spaces.\n");
printf("Version %s\n", PACKAGE_VERSION);
@ -281,7 +282,7 @@ main(int argc, char* argv[])
pass_argc = 1;
pass_argv[0] = "unbound";
add_opts("-d", &pass_argc, pass_argv);
while( (c=getopt(argc, argv, "12egcho:p:s")) != -1) {
while( (c=getopt(argc, argv, "12egciho:p:s")) != -1) {
switch(c) {
case 's':
free(pass_argv[1]);
@ -335,6 +336,15 @@ main(int argc, char* argv[])
#else
printf("CLIENT_SUBNET not supported\n");
exit(1);
#endif
break;
case 'i':
#ifdef USE_IPSECMOD
printf("IPSECMOD supported\n");
exit(0);
#else
printf("IPSECMOD not supported\n");
exit(1);
#endif
break;
case 'p':

Binary file not shown.

236
testdata/ipsecmod_bogus_ipseckey.crpl vendored Normal file
View File

@ -0,0 +1,236 @@
; Test ipsecmod with bogus IPSECKEY
; config options
; The island of trust is at example.com
server:
trust-anchor: "example.com. IN DS 48069 8 2 fce2bcb0d88b828064faad58e935ca2e32ff0bbd8bd8407a8f344d8f8e8c438a"
val-override-date: "-1"
target-fetch-policy: "0 0 0 0 0"
# test that default value of harden-dnssec-stripped is still yes.
fake-sha1: yes
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: no
ipsecmod-max-ttl: 200
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod with bogus IPSECKEY
; Scenario overview:
; - query for example.com. IN A
; - check that query for example.com. IN IPSECKEY is generated
; - check that we get an answer for example.com. IN A with the correct TTL
; - check that the get the same answer from cache
; - check that we don't get the IPSECKEY answer from cache (bogus)
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 86400 IN SOA ns.example.com. example.com. 2002022401 10800 15 604800 10800
example.com. 86400 IN RRSIG SOA 8 2 86400 20170609142855 20170512142855 48069 example.com. fr6oVOsRMnm3D8N01LxzPvT9lWdNDhTlmwR1co42c3H2ra1EjbbKqkLcrXQAsq7E/ddzqgL3RnYS+3USojXycI1xhjXC8YT2xsW3uH8uTY1Qvk1K75lu1OXmDiU6wvHplFowl0OX7sx76lB1itbvsau4bMPMt03sf4u8po7V35s=
ENTRY_END
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
example.com. 3600 IN RRSIG A 8 2 3600 20170609142855 20170512142855 48069 example.com. Qviw6w8ReMG2WZxenvzj/YwoeM3Ln59Fnw6s1MRWGsD2yA3+y0loFdUEHZdRhrEiV0kvtQGC+kBhMuSMq/cyjprbKLw5pkS9+MMDDnVPP1PQb17LY4NIxPtq710AN1sjhBK6PVa6XN+3ciUmCcLs1ESviQkVKpgAY/QlV0TaarQ=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
; response to IPSECKEY query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
;(correct answer) example.com. 3600 IN RRSIG IPSECKEY 8 2 3600 20170609144114 20170512144114 48069 example.com. UqRbG6P8mWQEVt16j86cS6fqEN8c+5t8qtePr9ghRqIxeuPOCkLiSqmXQYcQbOeOK4YoWQ3gD2az2JMWQMxEKeBLpxXZbgZN+2uIZ9LLEkyYjGRulr9kameKTM1feSe31A9mR9IgMNrY/ZeUkfxC+8Q7s8avOqYH2jVMFUg9raE=
; (bogus answer)
example.com. 3600 IN RRSIG IPSECKEY 8 2 3600 20170609144114 20170512144114 48069 example.com. Bogus6P8mWQEVt16j86cS6fqEN8c+5t8qtePr9ghRqIxeuPOCkLiSqmXQYcQbOeOK4YoWQ3gD2az2JMWQMxEKeBLpxXZbgZN+2uIZ9LLEkyYjGRulr9kameKTM1feSe31A9mR9IgMNrY/ZeUkfxC+8Q7s8avOqYH2jVMFUg9raE=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 86400 IN DNSKEY 256 3 8 AwEAAddE7q1HL4Id+gpQ7imk+RyNEhCWgtew5tstsqIR/fXq0RBn0rF4SI1H6ysbb3nfqAV1xRDJ01ddpgfGyz9zXXHQ/H/9qEpeWapqfNTQ5GHHdxBL2iST7XusThfXEyX/pouKIpvtknvtLs8tmH64dajxoJkaejU2EKXKaBaRKcYx ;{id = 48069 (zsk), size = 1024b}
example.com. 86400 IN RRSIG DNSKEY 8 2 86400 20170609144114 20170512144114 48069 example.com. mJU3LnubfYW7vhksiC1STWbrSjCe6TG1kEpnk4jRrYovues6bzOTIFSXEMjPW1mikulapnx3nMtTWdrW2InjfP9wLV/u2Wx1Vu3s9uzli/27y//3DOkZSeBa5RZdKpC1h8UB5GAxq4MRiSidgEBB1qaDIaE29sWmn9kPHEgNcgI=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 2 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
SECTION ANSWER
ENTRY_END
; Query without RD, check if not cached
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

219
testdata/ipsecmod_enabled.crpl vendored Normal file
View File

@ -0,0 +1,219 @@
; Test ipsecmod-enabled option.
; config options
server:
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: no
ipsecmod-max-ttl: 200
ipsecmod-enabled: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod-enabled option
; Scenario overview:
; - query for example.com. IN A
; - check that we get an answer for example.com. IN A with the correct TTL
; - check that the get the same answer from cache
; - check that we don't get the IPSECKEY answer from cache
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 10
ENTRY_END
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to IPSECKEY query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; Query with RD flag
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if cached and with correct TTL
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if IPSECKEY cached
STEP 21 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

2
testdata/ipsecmod_hook.sh vendored Executable file
View File

@ -0,0 +1,2 @@
echo " ---[ IPsec external hook FAIL; only care if ipsecmod-strict: yes ]---"
exit 1

View File

@ -0,0 +1,257 @@
; Test ipsecmod-ignore-bogus option
; config options
; The island of trust is at example.com
server:
trust-anchor: "example.com. IN DS 48069 8 2 fce2bcb0d88b828064faad58e935ca2e32ff0bbd8bd8407a8f344d8f8e8c438a"
val-override-date: "-1"
target-fetch-policy: "0 0 0 0 0"
# test that default value of harden-dnssec-stripped is still yes.
fake-sha1: yes
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: no
ipsecmod-max-ttl: 200
ipsecmod-ignore-bogus: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod-ignore-bogus option
; Scenario overview:
; - query for example.com. IN A
; - check that query for example.com. IN IPSECKEY is generated
; - check that we get an answer for example.com. IN A with the correct TTL
; - check that the get the same answer from cache
; - check that we don't get the IPSECKEY answer from cache (bogus)
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 86400 IN SOA ns.example.com. example.com. 2002022401 10800 15 604800 10800
example.com. 86400 IN RRSIG SOA 8 2 86400 20170609142855 20170512142855 48069 example.com. fr6oVOsRMnm3D8N01LxzPvT9lWdNDhTlmwR1co42c3H2ra1EjbbKqkLcrXQAsq7E/ddzqgL3RnYS+3USojXycI1xhjXC8YT2xsW3uH8uTY1Qvk1K75lu1OXmDiU6wvHplFowl0OX7sx76lB1itbvsau4bMPMt03sf4u8po7V35s=
ENTRY_END
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
example.com. 3600 IN RRSIG A 8 2 3600 20170609142855 20170512142855 48069 example.com. Qviw6w8ReMG2WZxenvzj/YwoeM3Ln59Fnw6s1MRWGsD2yA3+y0loFdUEHZdRhrEiV0kvtQGC+kBhMuSMq/cyjprbKLw5pkS9+MMDDnVPP1PQb17LY4NIxPtq710AN1sjhBK6PVa6XN+3ciUmCcLs1ESviQkVKpgAY/QlV0TaarQ=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
; response to IPSECKEY query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
;(correct answer) example.com. 3600 IN RRSIG IPSECKEY 8 2 3600 20170609144114 20170512144114 48069 example.com. UqRbG6P8mWQEVt16j86cS6fqEN8c+5t8qtePr9ghRqIxeuPOCkLiSqmXQYcQbOeOK4YoWQ3gD2az2JMWQMxEKeBLpxXZbgZN+2uIZ9LLEkyYjGRulr9kameKTM1feSe31A9mR9IgMNrY/ZeUkfxC+8Q7s8avOqYH2jVMFUg9raE=
; (bogus answer)
example.com. 3600 IN RRSIG IPSECKEY 8 2 3600 20170609144114 20170512144114 48069 example.com. Bogus6P8mWQEVt16j86cS6fqEN8c+5t8qtePr9ghRqIxeuPOCkLiSqmXQYcQbOeOK4YoWQ3gD2az2JMWQMxEKeBLpxXZbgZN+2uIZ9LLEkyYjGRulr9kameKTM1feSe31A9mR9IgMNrY/ZeUkfxC+8Q7s8avOqYH2jVMFUg9raE=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 86400 IN DNSKEY 256 3 8 AwEAAddE7q1HL4Id+gpQ7imk+RyNEhCWgtew5tstsqIR/fXq0RBn0rF4SI1H6ysbb3nfqAV1xRDJ01ddpgfGyz9zXXHQ/H/9qEpeWapqfNTQ5GHHdxBL2iST7XusThfXEyX/pouKIpvtknvtLs8tmH64dajxoJkaejU2EKXKaBaRKcYx ;{id = 48069 (zsk), size = 1024b}
example.com. 86400 IN RRSIG DNSKEY 8 2 86400 20170609144114 20170512144114 48069 example.com. mJU3LnubfYW7vhksiC1STWbrSjCe6TG1kEpnk4jRrYovues6bzOTIFSXEMjPW1mikulapnx3nMtTWdrW2InjfP9wLV/u2Wx1Vu3s9uzli/27y//3DOkZSeBa5RZdKpC1h8UB5GAxq4MRiSidgEBB1qaDIaE29sWmn9kPHEgNcgI=
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 8 2 3600 20170609142855 20170512142855 48069 example.com. SYFM1dsPEly0PjdShX8EsRnpq6XTysrvUBWB+LjGaC0wn3RFd0A2TG3WhVkUxhjTzRjt9jn3rz+JUJyybrhBkYXjBeBBjLep6Le7PQSct+FFDTIuX8duixfOzEN5LSYRMUnSuAq/z0LJHUB6nqTw8XWRm6EIImdEBc6D0u1KSes=
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 8 3 3600 20170609142855 20170512142855 48069 example.com. kK5LZnGi2VmVmKUXkVenYCQMHGqwhGaEOwjwVG9ScOVzvqNA+n7KWwxdLDsIVLgr/BjR9Cj9+HYB9hYMhk+LnsbHqf5ovY3+n7CV4v3MDWJBLYt7NHvXwoywbaD71w7koo0SUiBXMB/FyuxRj6BXEk4dlGh7mgHZXE+X/gCYxsM=
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 2 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if cached and with correct TTL
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if IPSECKEY is not cached
STEP 21 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA SERVFAIL
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
SCENARIO_END

228
testdata/ipsecmod_max_ttl.crpl vendored Normal file
View File

@ -0,0 +1,228 @@
; Test ipsecmod-max-ttl option.
; config options
server:
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: no
ipsecmod-max-ttl: 200
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod-max-ttl option
; Scenario overview:
; - query for example.com. IN A
; - check that query for example.com. IN IPSECKEY is generated
; - check that we get an answer for example.com. IN A with the correct TTL
; - check that the get the same answer from cache
; - check that we get the IPSECKEY answer from cache
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 10
ENTRY_END
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to IPSECKEY query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; Query with RD flag
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 2 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if cached and with correct TTL
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; Query without RD, check if IPSECKEY cached
STEP 21 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

217
testdata/ipsecmod_strict.crpl vendored Normal file
View File

@ -0,0 +1,217 @@
; Test ipsecmod-strict option
; config options
server:
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: yes
ipsecmod-max-ttl: 200
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod-strict option
; Scenario overview:
; - query for example.com. IN A
; - check that query for example.com. IN IPSECKEY is generated
; - check that we get SERVFAIL as answer (the hook failed)
; - check that the example.com. IN A answer is not cached
; - check that the example.com. IN IPSECKEY answer is cached
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 10
ENTRY_END
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to IPSECKEY query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 2 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 21 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN IPSECKEY
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
example.com. IN IPSECKEY
SECTION ANSWER
example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

294
testdata/ipsecmod_whitelist.crpl vendored Normal file
View File

@ -0,0 +1,294 @@
; Test ipsecmod-whitelist option.
; config options
server:
access-control: 127.0.0.1 allow_snoop
module-config: "ipsecmod validator iterator"
; ../../ is there because the test runs from testdata/03-testbound.dir
ipsecmod-hook: "../../testdata/ipsecmod_hook.sh"
ipsecmod-strict: no
ipsecmod-max-ttl: 200
ipsecmod-whitelist: white.example.com
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test ipsecmod-whitelist option
; Scenario overview:
; - query for black.example.com. IN A
; - check that we get an answer for black.example.com. IN A with the correct TTL
; - check that an answer for black.example.com. IN IPSECKEY is not cached (not given)
; - query for white.example.com. IN A
; - check that query for white.example.com. IN IPSECKEY is generated
; - check that we get an answer for white.example.com. IN A with the correct TTL
; - check that the get the same answer from cache
; - check that we get the IPSECKEY answer from cache
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 10
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
white.example.com. IN A
SECTION ANSWER
white.example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
white.example.com. IN IPSECKEY
SECTION ANSWER
white.example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
black.example.com. IN A
SECTION ANSWER
black.example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
black.example.com. IN IPSECKEY
SECTION ANSWER
black.example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
black.example.com. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
black.example.com. IN A
SECTION ANSWER
black.example.com. 3600 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
black.example.com. IN IPSECKEY
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
black.example.com. IN IPSECKEY
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
white.example.com. IN A
ENTRY_END
STEP 21 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype opcode
SECTION QUESTION
white.example.com. IN IPSECKEY
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
white.example.com. IN A
SECTION ANSWER
white.example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 31 QUERY
ENTRY_BEGIN
SECTION QUESTION
white.example.com. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
SECTION QUESTION
white.example.com. IN A
SECTION ANSWER
white.example.com. 200 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
STEP 41 QUERY
ENTRY_BEGIN
SECTION QUESTION
white.example.com. IN IPSECKEY
ENTRY_END
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA NOERROR
SECTION QUESTION
white.example.com. IN IPSECKEY
SECTION ANSWER
white.example.com. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

View File

@ -280,6 +280,14 @@ config_create(void)
cfg->dnscrypt_provider = NULL;
cfg->dnscrypt_provider_cert = NULL;
cfg->dnscrypt_secret_key = NULL;
#ifdef USE_IPSECMOD
cfg->ipsecmod_enabled = 1;
cfg->ipsecmod_ignore_bogus = 0;
cfg->ipsecmod_hook = NULL;
cfg->ipsecmod_max_ttl = 3600;
cfg->ipsecmod_whitelist = NULL;
cfg->ipsecmod_strict = 0;
#endif
return cfg;
error_exit:
config_delete(cfg);
@ -568,6 +576,13 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
else S_YNO("qname-minimisation:", qname_minimisation)
else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
#ifdef USE_IPSECMOD
else S_YNO("ipsecmod-enabled:", ipsecmod_enabled)
else S_YNO("ipsecmod-ignore-bogus:", ipsecmod_ignore_bogus)
else if(strcmp(opt, "ipsecmod-max-ttl:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
#endif
else if(strcmp(opt, "define-tag:") ==0) {
return config_add_tag(cfg, val);
/* val_sig_skew_min and max are copied into val_env during init,
@ -595,9 +610,10 @@ int config_set_option(struct config_file* cfg, const char* opt,
* stub-ssl-upstream, forward-zone,
* name, forward-addr, forward-host,
* ratelimit-for-domain, ratelimit-below-domain,
* local-zone-tag, access-control-view
* send-client-subnet client-subnet-always-forward
* max-client-subnet-ipv4 max-client-subnet-ipv6 */
* local-zone-tag, access-control-view,
* send-client-subnet, client-subnet-always-forward,
* max-client-subnet-ipv4, max-client-subnet-ipv6, ipsecmod_hook,
* ipsecmod_whitelist. */
return 0;
}
return 1;
@ -931,6 +947,14 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
else O_LS2(opt, "access-control-view", acl_view)
#ifdef USE_IPSECMOD
else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled)
else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus)
else O_STR(opt, "ipsecmod-hook", ipsecmod_hook)
else O_DEC(opt, "ipsecmod-max-ttl", ipsecmod_max_ttl)
else O_LST(opt, "ipsecmod-whitelist", ipsecmod_whitelist)
else O_YNO(opt, "ipsecmod-strict", ipsecmod_strict)
#endif
/* not here:
* outgoing-permit, outgoing-avoid - have list of ports
* local-zone - zones and nodefault variables
@ -1226,6 +1250,10 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_version);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);
#endif
free(cfg);
}

View File

@ -460,6 +460,22 @@ struct config_file {
struct config_strlist* dnscrypt_secret_key;
/** dnscrypt provider certs 1.cert */
struct config_strlist* dnscrypt_provider_cert;
/** IPsec module */
#ifdef USE_IPSECMOD
/** false to bypass the IPsec module */
int ipsecmod_enabled;
/** whitelisted domains for ipsecmod */
struct config_strlist* ipsecmod_whitelist;
/** path to external hook */
char* ipsecmod_hook;
/** true to proceed even with a bogus IPSECKEY */
int ipsecmod_ignore_bogus;
/** max TTL for the A/AAAA records that call the hook */
int ipsecmod_max_ttl;
/** false to proceed even when ipsecmod_hook fails */
int ipsecmod_strict;
#endif
};
/** from cfg username, after daemonise setup performed */

View File

@ -416,6 +416,12 @@ dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
dnscrypt-provider{COLON} { YDVAR(1, VAR_DNSCRYPT_PROVIDER) }
dnscrypt-secret-key{COLON} { YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) }
dnscrypt-provider-cert{COLON} { YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) }
ipsecmod-enabled{COLON} { YDVAR(1, VAR_IPSECMOD_ENABLED) }
ipsecmod-ignore-bogus{COLON} { YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) }
ipsecmod-hook{COLON} { YDVAR(1, VAR_IPSECMOD_HOOK) }
ipsecmod-max-ttl{COLON} { YDVAR(1, VAR_IPSECMOD_MAX_TTL) }
ipsecmod-whitelist{COLON} { YDVAR(1, VAR_IPSECMOD_WHITELIST) }
ipsecmod-strict{COLON} { YDVAR(1, VAR_IPSECMOD_STRICT) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
/* Quoted strings. Strip leading and ending quotes */

View File

@ -144,6 +144,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
%token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS
%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -228,7 +230,10 @@ content_server: server_num_threads | server_verbosity | server_port |
server_fake_dsa | server_log_identity | server_use_systemd |
server_response_ip_tag | server_response_ip | server_response_ip_data |
server_shm_enable | server_shm_key | server_fake_sha1 |
server_hide_trustanchor | server_trust_anchor_signaling
server_hide_trustanchor | server_trust_anchor_signaling |
server_ipsecmod_enabled | server_ipsecmod_hook |
server_ipsecmod_ignore_bogus | server_ipsecmod_max_ttl |
server_ipsecmod_whitelist | server_ipsecmod_strict
;
stubstart: VAR_STUB_ZONE
{
@ -1794,6 +1799,80 @@ server_qname_minimisation_strict: VAR_QNAME_MINIMISATION_STRICT STRING_ARG
free($2);
}
;
server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_enabled:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ipsecmod_enabled = (strcmp($2, "yes")==0);
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_ignore_bogus:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ipsecmod_ignore_bogus = (strcmp($2, "yes")==0);
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_hook:%s)\n", $2));
free(cfg_parser->cfg->ipsecmod_hook);
cfg_parser->cfg->ipsecmod_hook = $2;
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
server_ipsecmod_max_ttl: VAR_IPSECMOD_MAX_TTL STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_max_ttl:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->ipsecmod_max_ttl = atoi($2);
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
server_ipsecmod_whitelist: VAR_IPSECMOD_WHITELIST STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_whitelist:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->ipsecmod_whitelist, $2))
yyerror("out of memory");
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
{
#ifdef USE_IPSECMOD
OUTYY(("P(server_ipsecmod_strict:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ipsecmod_strict = (strcmp($2, "yes")==0);
free($2);
#else
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
#endif
}
;
stub_name: VAR_NAME STRING_ARG
{
OUTYY(("P(name:%s)\n", $2));

View File

@ -83,6 +83,9 @@
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
#ifdef USE_IPSECMOD
#include "ipsecmod/ipsecmod.h"
#endif
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#endif
@ -345,6 +348,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
#ifdef USE_CACHEDB
else if(fptr == &cachedb_init) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_init) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_init) return 1;
#endif
@ -364,6 +370,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
#ifdef USE_CACHEDB
else if(fptr == &cachedb_deinit) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_deinit) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_deinit) return 1;
#endif
@ -384,6 +393,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
#ifdef USE_CACHEDB
else if(fptr == &cachedb_operate) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_operate) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_operate) return 1;
#endif
@ -404,6 +416,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)(
#ifdef USE_CACHEDB
else if(fptr == &cachedb_inform_super) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_inform_super) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_inform_super) return 1;
#endif
@ -424,6 +439,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate,
#ifdef USE_CACHEDB
else if(fptr == &cachedb_clear) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_clear) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_clear) return 1;
#endif
@ -443,6 +461,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id))
#ifdef USE_CACHEDB
else if(fptr == &cachedb_get_mem) return 1;
#endif
#ifdef USE_IPSECMOD
else if(fptr == &ipsecmod_get_mem) return 1;
#endif
#ifdef CLIENT_SUBNET
else if(fptr == &subnetmod_get_mem) return 1;
#endif

View File

@ -273,6 +273,17 @@ void shm_main_run(struct worker *worker)
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->mods.mod[modstack]->get_mem));
shm_stat->mem.subnet = (long long)(*worker->env.mesh->mods.mod[modstack]->get_mem)(&worker->env, modstack);
}
#endif
/* ipsecmod mem value is available in shm, also when not enabled,
* to make the struct easier to memmap by other applications,
* independent of the configuration of unbound */
shm_stat->mem.ipsecmod = 0;
#ifdef USE_IPSECMOD
modstack = modstack_find(&worker->env.mesh->mods, "ipsecmod");
if(modstack != -1) {
fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->mods.mod[modstack]->get_mem));
shm_stat->mem.ipsecmod = (*worker->env.mesh->mods.mod[modstack]->get_mem)(&worker->env, modstack);
}
#endif
}