mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- 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:
parent
5febdd39a1
commit
491b0a26e4
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
15
configure.ac
15
configure.ac
@ -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).
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
158
ipsecmod/ipsecmod-whitelist.c
Normal file
158
ipsecmod/ipsecmod-whitelist.c
Normal 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 */
|
82
ipsecmod/ipsecmod-whitelist.h
Normal file
82
ipsecmod/ipsecmod-whitelist.h
Normal 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
512
ipsecmod/ipsecmod.c
Normal 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
99
ipsecmod/ipsecmod.h
Normal 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 */
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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':
|
||||
|
BIN
testdata/03-testbound.tpkg
vendored
BIN
testdata/03-testbound.tpkg
vendored
Binary file not shown.
236
testdata/ipsecmod_bogus_ipseckey.crpl
vendored
Normal file
236
testdata/ipsecmod_bogus_ipseckey.crpl
vendored
Normal 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
219
testdata/ipsecmod_enabled.crpl
vendored
Normal 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
2
testdata/ipsecmod_hook.sh
vendored
Executable file
@ -0,0 +1,2 @@
|
||||
echo " ---[ IPsec external hook FAIL; only care if ipsecmod-strict: yes ]---"
|
||||
exit 1
|
257
testdata/ipsecmod_ignore_bogus_ipseckey.crpl
vendored
Normal file
257
testdata/ipsecmod_ignore_bogus_ipseckey.crpl
vendored
Normal 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
228
testdata/ipsecmod_max_ttl.crpl
vendored
Normal 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
217
testdata/ipsecmod_strict.crpl
vendored
Normal 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
294
testdata/ipsecmod_whitelist.crpl
vendored
Normal 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
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user