update to 1.17.0

This commit is contained in:
eaglegai 2022-11-08 03:35:07 +00:00
parent 97bd1fa58f
commit 49b5292e2c
8 changed files with 432 additions and 958 deletions

View File

@ -1,624 +0,0 @@
From f6753a0f1018133df552347a199e0362fc1dac68 Mon Sep 17 00:00:00 2001
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
Date: Mon, 1 Aug 2022 13:24:40 +0200
Subject: [PATCH] - Fix the novel ghost domain issues CVE-2022-30698 and
CVE-2022-30699.
---
cachedb/cachedb.c | 2 +-
daemon/cachedump.c | 5 +-
daemon/worker.c | 2 +-
dns64/dns64.c | 4 +-
ipsecmod/ipsecmod.c | 2 +-
iterator/iter_utils.c | 4 +-
iterator/iter_utils.h | 3 +-
iterator/iterator.c | 19 +--
pythonmod/interface.i | 5 +-
pythonmod/pythonmod_utils.c | 3 +-
services/cache/dns.c | 111 +++++++++++++++---
services/cache/dns.h | 18 ++-
services/mesh.c | 1 +
testdata/iter_prefetch_change.rpl | 16 +--
util/module.h | 6 +
validator/validator.c | 4 +-
16 files changed, 157 insertions(+), 48 deletions(-)
diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c
index af4ffe5..6e3dcfd 100644
--- a/cachedb/cachedb.c
+++ b/cachedb/cachedb.c
@@ -662,7 +662,7 @@ cachedb_intcache_store(struct module_qstate* qstate)
return;
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
- qstate->region, store_flags);
+ qstate->region, store_flags, qstate->qstarttime);
}
/**
diff --git a/daemon/cachedump.c b/daemon/cachedump.c
index b1ce53b..908d2f9 100644
--- a/daemon/cachedump.c
+++ b/daemon/cachedump.c
@@ -677,7 +677,8 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
if(!go_on)
return 1; /* skip this one, not all references satisfied */
- if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
+ if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags,
+ *worker->env.now)) {
log_warn("error out of memory");
return 0;
}
@@ -848,7 +849,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
while(1) {
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
qinfo.qtype, qinfo.qclass, region, &msg,
- *worker->env.now);
+ *worker->env.now, 0, NULL, 0);
if(!dp) {
return ssl_printf(ssl, "no delegation from "
"cache; goes to configured roots\n");
diff --git a/daemon/worker.c b/daemon/worker.c
index e9e163a..9c0263f 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -460,7 +460,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
dp = dns_cache_find_delegation(&worker->env, qinfo->qname,
qinfo->qname_len, qinfo->qtype, qinfo->qclass,
- worker->scratchpad, &msg, timenow);
+ worker->scratchpad, &msg, timenow, 0, NULL, 0);
if(!dp) { /* no delegation, need to reprime */
return 0;
}
diff --git a/dns64/dns64.c b/dns64/dns64.c
index c79bc9c..0546364 100644
--- a/dns64/dns64.c
+++ b/dns64/dns64.c
@@ -652,7 +652,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
if ( (!iq || !iq->started_no_cache_store) &&
qstate->return_msg && qstate->return_msg->rep &&
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
- 0, 0, 0, NULL, qstate->query_flags))
+ 0, 0, 0, NULL, qstate->query_flags, qstate->qstarttime))
log_err("out of memory");
/* do nothing */
@@ -986,7 +986,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
/* Store the generated response in cache. */
if ( (!super_dq || !super_dq->started_no_cache_store) &&
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
- 0, 0, 0, NULL, super->query_flags))
+ 0, 0, 0, NULL, super->query_flags, qstate->qstarttime))
log_err("out of memory");
}
diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c
index e42af6f..a35f6e6 100644
--- a/ipsecmod/ipsecmod.c
+++ b/ipsecmod/ipsecmod.c
@@ -456,7 +456,7 @@ ipsecmod_handle_query(struct module_qstate* qstate,
/* 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)) {
+ 0, qstate->region, qstate->query_flags, qstate->qstarttime)) {
log_err("ipsecmod: out of memory caching record");
}
qstate->ext_state[id] = module_finished;
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 668f898..25060ab 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -656,10 +656,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
void
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
- struct regional* region, uint16_t flags)
+ struct regional* region, uint16_t flags, time_t qstarttime)
{
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
- pside, region, flags))
+ pside, region, flags, qstarttime))
log_err("out of memory: cannot store data in cache");
}
diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h
index 509d292..6253b5f 100644
--- a/iterator/iter_utils.h
+++ b/iterator/iter_utils.h
@@ -132,6 +132,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
* can be prefetch-updates.
* @param region: to copy modified (cache is better) rrs back to.
* @param flags: with BIT_CD for dns64 AAAA translated queries.
+ * @param qstarttime: time of query start.
* return void, because we are not interested in alloc errors,
* the iterator and validator can operate on the results in their
* scratch space (the qstate.region) and are not dependent on the cache.
@@ -140,7 +141,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
*/
void iter_dns_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
- struct regional* region, uint16_t flags);
+ struct regional* region, uint16_t flags, time_t qstarttime);
/**
* Select randomly with n/m probability.
diff --git a/iterator/iterator.c b/iterator/iterator.c
index f0105ad..40afbc8 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -370,7 +370,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
err.security = sec_status_indeterminate;
verbose(VERB_ALGO, "store error response in message cache");
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
- qstate->query_flags);
+ qstate->query_flags, qstate->qstarttime);
}
return error_response(qstate, id, rcode);
}
@@ -1477,7 +1477,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg,
- *qstate->env->now+qstate->prefetch_leeway);
+ *qstate->env->now+qstate->prefetch_leeway, 1,
+ dpname, dpnamelen);
else iq->dp = NULL;
/* If the cache has returned nothing, then we have a
@@ -1799,7 +1800,8 @@ generate_parentside_target_query(struct module_qstate* qstate,
subiq->dp = dns_cache_find_delegation(qstate->env,
name, namelen, qtype, qclass, subq->region,
&subiq->deleg_msg,
- *qstate->env->now+subq->prefetch_leeway);
+ *qstate->env->now+subq->prefetch_leeway,
+ 1, NULL, 0);
/* if no dp, then it's from root, refetch unneeded */
if(subiq->dp) {
subiq->dnssec_expected = iter_indicates_dnssec(
@@ -2847,7 +2849,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
- qstate->region, qstate->query_flags);
+ qstate->region, qstate->query_flags,
+ qstate->qstarttime);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
@@ -2944,7 +2947,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* Store the referral under the current query */
/* no prefetch-leeway, since its not the answer */
iter_dns_store(qstate->env, &iq->response->qinfo,
- iq->response->rep, 1, 0, 0, NULL, 0);
+ iq->response->rep, 1, 0, 0, NULL, 0,
+ qstate->qstarttime);
if(iq->store_parent_NS)
iter_store_parentside_NS(qstate->env,
iq->response->rep);
@@ -3057,7 +3061,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS, NULL,
- qstate->query_flags);
+ qstate->query_flags, qstate->qstarttime);
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
@@ -3626,7 +3630,8 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
- qstate->region, qstate->query_flags);
+ qstate->region, qstate->query_flags,
+ qstate->qstarttime);
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index ce7dcde..bdd6906 100644
--- a/pythonmod/interface.i
+++ b/pythonmod/interface.i
@@ -1371,7 +1371,8 @@ int set_return_msg(struct module_qstate* qstate,
/* Functions which we will need to lookup delegations */
struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
- struct regional* region, struct dns_msg** msg, uint32_t timenow);
+ struct regional* region, struct dns_msg** msg, uint32_t timenow,
+ int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp);
struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
@@ -1400,7 +1401,7 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
qinfo.qclass = LDNS_RR_CLASS_IN;
while(1) {
- dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow);
+ dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow, 0, NULL, 0);
if(!dp)
return NULL;
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c
index 21a16bb..05ce136 100644
--- a/pythonmod/pythonmod_utils.c
+++ b/pythonmod/pythonmod_utils.c
@@ -72,7 +72,8 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo,
}
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
- qstate->prefetch_leeway, 0, NULL, qstate->query_flags);
+ qstate->prefetch_leeway, 0, NULL, qstate->query_flags,
+ qstate->qstarttime);
}
/* Invalidate the message associated with query_info stored in message cache */
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 5b64fe4..c29b909 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -68,11 +68,16 @@
* in a prefetch situation to be updated (without becoming sticky).
* @param qrep: update rrsets here if cache is better
* @param region: for qrep allocs.
+ * @param qstarttime: time when delegations were looked up, this is perhaps
+ * earlier than the time in now. The time is used to determine if RRsets
+ * of type NS have expired, so that they can only be updated using
+ * lookups of delegation points that did not use them, since they had
+ * expired then.
*/
static void
store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
time_t leeway, int pside, struct reply_info* qrep,
- struct regional* region)
+ struct regional* region, time_t qstarttime)
{
size_t i;
/* see if rrset already exists in cache, if not insert it. */
@@ -81,8 +86,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
rep->ref[i].id = rep->rrsets[i]->id;
/* update ref if it was in the cache */
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
- env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
- LDNS_RR_TYPE_NS && !pside)?0:leeway))) {
+ env->alloc, ((ntohs(rep->ref[i].key->rk.type)==
+ LDNS_RR_TYPE_NS && !pside)?qstarttime:now + leeway))) {
case 0: /* ref unchanged, item inserted */
break;
case 2: /* ref updated, cache is superior */
@@ -155,7 +160,8 @@ msg_del_servfail(struct module_env* env, struct query_info* qinfo,
void
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
- struct reply_info* qrep, uint32_t flags, struct regional* region)
+ struct reply_info* qrep, uint32_t flags, struct regional* region,
+ time_t qstarttime)
{
struct msgreply_entry* e;
time_t ttl = rep->ttl;
@@ -170,7 +176,8 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
/* there was a reply_info_sortref(rep) here but it seems to be
* unnecessary, because the cache gets locked per rrset. */
reply_info_set_ttls(rep, *env->now);
- store_rrsets(env, rep, *env->now, leeway, pside, qrep, region);
+ store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
+ qstarttime);
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
/* we do not store the message, but we did store the RRs,
* which could be useful for delegation information */
@@ -194,10 +201,51 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc);
}
+/** see if an rrset is expired above the qname, return upper qname. */
+static int
+rrset_expired_above(struct module_env* env, uint8_t** qname, size_t* qnamelen,
+ uint16_t searchtype, uint16_t qclass, time_t now, uint8_t* expiretop,
+ size_t expiretoplen)
+{
+ struct ub_packed_rrset_key *rrset;
+ uint8_t lablen;
+
+ while(*qnamelen > 0) {
+ /* look one label higher */
+ lablen = **qname;
+ *qname += lablen + 1;
+ *qnamelen -= lablen + 1;
+ if(*qnamelen <= 0)
+ break;
+
+ /* looks up with a time of 0, to see expired entries */
+ if((rrset = rrset_cache_lookup(env->rrset_cache, *qname,
+ *qnamelen, searchtype, qclass, 0, 0, 0))) {
+ struct packed_rrset_data* data =
+ (struct packed_rrset_data*)rrset->entry.data;
+ if(now > data->ttl) {
+ /* it is expired, this is not wanted */
+ lock_rw_unlock(&rrset->entry.lock);
+ log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
+ return 1;
+ }
+ /* it is not expired, continue looking */
+ lock_rw_unlock(&rrset->entry.lock);
+ }
+
+ /* do not look above the expiretop. */
+ if(expiretop && *qnamelen == expiretoplen &&
+ query_dname_compare(*qname, expiretop)==0)
+ break;
+ }
+ return 0;
+}
+
/** find closest NS or DNAME and returns the rrset (locked) */
static struct ub_packed_rrset_key*
find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
- uint16_t qclass, time_t now, uint16_t searchtype, int stripfront)
+ uint16_t qclass, time_t now, uint16_t searchtype, int stripfront,
+ int noexpiredabove, uint8_t* expiretop, size_t expiretoplen)
{
struct ub_packed_rrset_key *rrset;
uint8_t lablen;
@@ -212,8 +260,40 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
/* snip off front part of qname until the type is found */
while(qnamelen > 0) {
if((rrset = rrset_cache_lookup(env->rrset_cache, qname,
- qnamelen, searchtype, qclass, 0, now, 0)))
- return rrset;
+ qnamelen, searchtype, qclass, 0, now, 0))) {
+ uint8_t* origqname = qname;
+ size_t origqnamelen = qnamelen;
+ if(!noexpiredabove)
+ return rrset;
+ /* if expiretop set, do not look above it, but
+ * qname is equal, so the just found result is also
+ * the nonexpired above part. */
+ if(expiretop && qnamelen == expiretoplen &&
+ query_dname_compare(qname, expiretop)==0)
+ return rrset;
+ /* check for expiry, but we have to let go of the rrset
+ * for the lock ordering */
+ lock_rw_unlock(&rrset->entry.lock);
+ /* the expired_above function always takes off one
+ * label (if qnamelen>0) and returns the final qname
+ * where it searched, so we can continue from there
+ * turning the O N*N search into O N. */
+ if(!rrset_expired_above(env, &qname, &qnamelen,
+ searchtype, qclass, now, expiretop,
+ expiretoplen)) {
+ /* we want to return rrset, but it may be
+ * gone from cache, if so, just loop like
+ * it was not in the cache in the first place.
+ */
+ if((rrset = rrset_cache_lookup(env->
+ rrset_cache, origqname, origqnamelen,
+ searchtype, qclass, 0, now, 0))) {
+ return rrset;
+ }
+ }
+ log_nametypeclass(VERB_ALGO, "ignoring rrset because expired rrsets exist above it", origqname, searchtype, qclass);
+ continue;
+ }
/* snip off front label */
lablen = *qname;
@@ -461,7 +541,8 @@ dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
struct delegpt*
dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
size_t qnamelen, uint16_t qtype, uint16_t qclass,
- struct regional* region, struct dns_msg** msg, time_t now)
+ struct regional* region, struct dns_msg** msg, time_t now,
+ int noexpiredabove, uint8_t* expiretop, size_t expiretoplen)
{
/* try to find closest NS rrset */
struct ub_packed_rrset_key* nskey;
@@ -469,7 +550,7 @@ dns_cache_find_delegation(struct module_env* env, uint8_t* qname,
struct delegpt* dp;
nskey = find_closest_of_type(env, qname, qnamelen, qclass, now,
- LDNS_RR_TYPE_NS, 0);
+ LDNS_RR_TYPE_NS, 0, noexpiredabove, expiretop, expiretoplen);
if(!nskey) /* hope the caller has hints to prime or something */
return NULL;
nsdata = (struct packed_rrset_data*)nskey->entry.data;
@@ -835,7 +916,7 @@ dns_cache_lookup(struct module_env* env,
* consistent with the DNAME */
if(!no_partial &&
(rrset=find_closest_of_type(env, qname, qnamelen, qclass, now,
- LDNS_RR_TYPE_DNAME, 1))) {
+ LDNS_RR_TYPE_DNAME, 1, 0, NULL, 0))) {
/* synthesize a DNAME+CNAME message based on this */
enum sec_status sec_status = sec_status_unchecked;
struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k,
@@ -968,7 +1049,7 @@ dns_cache_lookup(struct module_env* env,
int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
- struct regional* region, uint32_t flags)
+ struct regional* region, uint32_t flags, time_t qstarttime)
{
struct reply_info* rep = NULL;
/* alloc, malloc properly (not in region, like msg is) */
@@ -991,9 +1072,9 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
/*ignore ret: it was in the cache, ref updated */
/* no leeway for typeNS */
(void)rrset_cache_update(env->rrset_cache, &ref,
- env->alloc, *env->now +
+ env->alloc,
((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS
- && !pside) ? 0:leeway));
+ && !pside) ? qstarttime:*env->now + leeway));
}
free(rep);
return 1;
@@ -1015,7 +1096,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
rep->flags &= ~(BIT_AA | BIT_CD);
h = query_info_hash(&qinf, (uint16_t)flags);
dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep,
- flags, region);
+ flags, region, qstarttime);
/* qname is used inside query_info_entrysetup, and set to
* NULL. If it has not been used, free it. free(0) is safe. */
free(qinf.qname);
diff --git a/services/cache/dns.h b/services/cache/dns.h
index bece837..6ae4514 100644
--- a/services/cache/dns.h
+++ b/services/cache/dns.h
@@ -88,11 +88,13 @@ struct dns_msg {
* @param flags: flags with BIT_CD for AAAA queries in dns64 translation.
* The higher 16 bits are used internally to customize the cache policy.
* (See DNSCACHE_STORE_xxx flags).
+ * @param qstarttime: time when the query was started, and thus when the
+ * delegations were looked up.
* @return 0 on alloc error (out of memory).
*/
int dns_cache_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
- struct regional* region, uint32_t flags);
+ struct regional* region, uint32_t flags, time_t qstarttime);
/**
* Store message in the cache. Stores in message cache and rrset cache.
@@ -112,11 +114,14 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
* can be updated to full TTL even in prefetch situations.
* @param qrep: message that can be altered with better rrs from cache.
* @param flags: customization flags for the cache policy.
+ * @param qstarttime: time when the query was started, and thus when the
+ * delegations were looked up.
* @param region: to allocate into for qmsg.
*/
void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
- struct reply_info* qrep, uint32_t flags, struct regional* region);
+ struct reply_info* qrep, uint32_t flags, struct regional* region,
+ time_t qstarttime);
/**
* Find a delegation from the cache.
@@ -129,11 +134,18 @@ void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
* @param msg: if not NULL, delegation message is returned here, synthesized
* from the cache.
* @param timenow: the time now, for checking if TTL on cache entries is OK.
+ * @param noexpiredabove: if set, no expired NS rrsets above the one found
+ * are tolerated. It only returns delegations where the delegations above
+ * it are valid.
+ * @param expiretop: if not NULL, name where check for expiry ends for
+ * noexpiredabove.
+ * @param expiretoplen: length of expiretop dname.
* @return new delegation or NULL on error or if not found in cache.
*/
struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
- struct regional* region, struct dns_msg** msg, time_t timenow);
+ struct regional* region, struct dns_msg** msg, time_t timenow,
+ int noexpiredabove, uint8_t* expiretop, size_t expiretoplen);
/**
* generate dns_msg from cached message
diff --git a/services/mesh.c b/services/mesh.c
index 5679a8b..b9aac54 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -839,6 +839,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
mstate->s.no_cache_store = 0;
mstate->s.need_refetch = 0;
mstate->s.was_ratelimited = 0;
+ mstate->s.qstarttime = *env->now;
/* init modules */
for(i=0; i<env->mesh->mods.num; i++) {
diff --git a/testdata/iter_prefetch_change.rpl b/testdata/iter_prefetch_change.rpl
index 007025a..1be9e6a 100644
--- a/testdata/iter_prefetch_change.rpl
+++ b/testdata/iter_prefetch_change.rpl
@@ -22,9 +22,9 @@ REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
-. IN NS K.ROOT-SERVERS.NET.
+. 86400 IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
-K.ROOT-SERVERS.NET. IN A 193.0.14.129
+K.ROOT-SERVERS.NET. 86400 IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
@@ -34,9 +34,9 @@ REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
-com. IN NS a.gtld-servers.net.
+com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
-a.gtld-servers.net. IN A 192.5.6.30
+a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
RANGE_END
@@ -50,9 +50,9 @@ REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
-com. IN NS a.gtld-servers.net.
+com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
-a.gtld-servers.net. IN A 192.5.6.30
+a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
@@ -78,9 +78,9 @@ REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
-com. IN NS a.gtld-servers.net.
+com. 86400 IN NS a.gtld-servers.net.
SECTION ADDITIONAL
-a.gtld-servers.net. IN A 192.5.6.30
+a.gtld-servers.net. 86400 IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
diff --git a/util/module.h b/util/module.h
index 81a31a9..09854a1 100644
--- a/util/module.h
+++ b/util/module.h
@@ -652,6 +652,12 @@ struct module_qstate {
int need_refetch;
/** whether the query (or a subquery) was ratelimited */
int was_ratelimited;
+ /** time when query was started. This is when the qstate is created.
+ * This is used so that type NS data cannot be overwritten by them
+ * expiring while the lookup is in progress, using data fetched from
+ * those servers. By comparing expiry time with qstarttime for type NS.
+ */
+ time_t qstarttime;
/**
* Attributes of clients that share the qstate that may affect IP-based
diff --git a/validator/validator.c b/validator/validator.c
index d4d48d9..4b731f5 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -2145,7 +2145,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
if(!qstate->no_cache_store) {
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL,
- qstate->query_flags)) {
+ qstate->query_flags, qstate->qstarttime)) {
log_err("out of memory caching validator results");
}
}
@@ -2154,7 +2154,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
/* and this does not get prefetched, so no leeway */
if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo,
vq->orig_msg->rep, 1, 0, 0, NULL,
- qstate->query_flags)) {
+ qstate->query_flags, qstate->qstarttime)) {
log_err("out of memory caching validator results");
}
}
--
2.33.0

View File

@ -1,218 +0,0 @@
From 137719522a8ea5b380fbb6206d2466f402f5b554 Mon Sep 17 00:00:00 2001
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
Date: Wed, 21 Sep 2022 11:10:38 +0200
Subject: [PATCH] - Patch for CVE-2022-3204 Non-Responsive Delegation Attack.
---
iterator/iter_delegpt.c | 3 +++
iterator/iter_delegpt.h | 2 ++
iterator/iter_utils.c | 3 +++
iterator/iter_utils.h | 9 +++++++++
iterator/iterator.c | 36 +++++++++++++++++++++++++++++++++++-
services/cache/dns.c | 3 +++
services/mesh.c | 7 +++++++
services/mesh.h | 11 +++++++++++
8 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c
index 9a672b0..55a025b 100644
--- a/iterator/iter_delegpt.c
+++ b/iterator/iter_delegpt.c
@@ -76,6 +76,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
for(ns = dp->nslist; ns; ns = ns->next) {
if(!delegpt_add_ns(copy, region, ns->name, ns->lame))
return NULL;
+ copy->nslist->cache_lookup_count = ns->cache_lookup_count;
copy->nslist->resolved = ns->resolved;
copy->nslist->got4 = ns->got4;
copy->nslist->got6 = ns->got6;
@@ -119,6 +120,7 @@ delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
ns->namelen = len;
dp->nslist = ns;
ns->name = regional_alloc_init(region, name, ns->namelen);
+ ns->cache_lookup_count = 0;
ns->resolved = 0;
ns->got4 = 0;
ns->got6 = 0;
@@ -597,6 +599,7 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
}
ns->next = dp->nslist;
dp->nslist = ns;
+ ns->cache_lookup_count = 0;
ns->resolved = 0;
ns->got4 = 0;
ns->got6 = 0;
diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h
index 138eb6e..8265c71 100644
--- a/iterator/iter_delegpt.h
+++ b/iterator/iter_delegpt.h
@@ -99,6 +99,8 @@ struct delegpt_ns {
uint8_t* name;
/** length of name */
size_t namelen;
+ /** number of cache lookups for the name */
+ int cache_lookup_count;
/**
* If the name has been resolved. false if not queried for yet.
* true if the A, AAAA queries have been generated.
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 25060ab..39a9c51 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -1194,6 +1194,9 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
struct delegpt_ns* ns;
size_t num = delegpt_count_targets(dp);
for(ns = dp->nslist; ns; ns = ns->next) {
+ if(ns->cache_lookup_count > ITERATOR_NAME_CACHELOOKUP_MAX_PSIDE)
+ continue;
+ ns->cache_lookup_count++;
/* get cached parentside A */
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qinfo->qclass,
diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h
index 3787cda..c2e3afd 100644
--- a/iterator/iter_utils.h
+++ b/iterator/iter_utils.h
@@ -62,6 +62,15 @@ struct ub_packed_rrset_key;
struct module_stack;
struct outside_network;
+/* max number of lookups in the cache for target nameserver names.
+ * This stops, for large delegations, N*N lookups in the cache. */
+#define ITERATOR_NAME_CACHELOOKUP_MAX 3
+/* max number of lookups in the cache for parentside glue for nameserver names
+ * This stops, for larger delegations, N*N lookups in the cache.
+ * It is a little larger than the nonpside max, so it allows a couple extra
+ * lookups of parent side glue. */
+#define ITERATOR_NAME_CACHELOOKUP_MAX_PSIDE 5
+
/**
* Process config options and set iterator module state.
* Sets default values if no config is found.
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 4c4f9cd..7944d8c 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -1206,6 +1206,15 @@ generate_dnskey_prefetch(struct module_qstate* qstate,
(qstate->query_flags&BIT_RD) && !(qstate->query_flags&BIT_CD)){
return;
}
+ /* we do not generate this prefetch when the query list is full,
+ * the query is fetched, if needed, when the validator wants it.
+ * At that time the validator waits for it, after spawning it.
+ * This means there is one state that uses cpu and a socket, the
+ * spawned while this one waits, and not several at the same time,
+ * if we had created the lookup here. And this helps to keep
+ * the total load down, but the query still succeeds to resolve. */
+ if(mesh_jostle_exceeded(qstate->env->mesh))
+ return;
/* if the DNSKEY is in the cache this lookup will stop quickly */
log_nametypeclass(VERB_ALGO, "schedule dnskey prefetch",
@@ -1923,6 +1932,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
query_count++;
+ /* If the mesh query list is full, exit the loop here.
+ * This makes the routine spawn one query at a time,
+ * and this means there is no query state load
+ * increase, because the spawned state uses cpu and a
+ * socket while this state waits for that spawned
+ * state. Next time we can look up further targets */
+ if(mesh_jostle_exceeded(qstate->env->mesh))
+ break;
}
/* Send the A request. */
if(ie->supports_ipv4 && !ns->got4) {
@@ -1935,6 +1952,9 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
query_count++;
+ /* If the mesh query list is full, exit the loop. */
+ if(mesh_jostle_exceeded(qstate->env->mesh))
+ break;
}
/* mark this target as in progress. */
@@ -2093,6 +2113,15 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
ns->done_pside6 = 1;
query_count++;
+ if(mesh_jostle_exceeded(qstate->env->mesh)) {
+ /* Wait for the lookup; do not spawn multiple
+ * lookups at a time. */
+ verbose(VERB_ALGO, "try parent-side glue lookup");
+ iq->num_target_queries += query_count;
+ target_count_increase(iq, query_count);
+ qstate->ext_state[id] = module_wait_subquery;
+ return 0;
+ }
}
if(ie->supports_ipv4 && !ns->done_pside4) {
/* Send the A request. */
@@ -2461,7 +2490,12 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->depth < ie->max_dependency_depth
&& iq->num_target_queries == 0
&& (!iq->target_count || iq->target_count[2]==0)
- && iq->sent_count < TARGET_FETCH_STOP) {
+ && iq->sent_count < TARGET_FETCH_STOP
+ /* if the mesh query list is full, then do not waste cpu
+ * and sockets to fetch promiscuous targets. They can be
+ * looked up when needed. */
+ && !mesh_jostle_exceeded(qstate->env->mesh)
+ ) {
tf_policy = ie->target_fetch_policy[iq->depth];
}
diff --git a/services/cache/dns.c b/services/cache/dns.c
index d010b77..4b6fe20 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -404,6 +404,9 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
struct ub_packed_rrset_key* akey;
time_t now = *env->now;
for(ns = dp->nslist; ns; ns = ns->next) {
+ if(ns->cache_lookup_count > ITERATOR_NAME_CACHELOOKUP_MAX)
+ continue;
+ ns->cache_lookup_count++;
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(akey) {
diff --git a/services/mesh.c b/services/mesh.c
index b9aac54..7f74365 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -2061,3 +2061,10 @@ mesh_serve_expired_callback(void* arg)
mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c, &tv);
}
}
+
+int mesh_jostle_exceeded(struct mesh_area* mesh)
+{
+ if(mesh->all.count < mesh->max_reply_states)
+ return 0;
+ return 1;
+}
diff --git a/services/mesh.h b/services/mesh.h
index d0a4b5f..2248178 100644
--- a/services/mesh.h
+++ b/services/mesh.h
@@ -674,4 +674,15 @@ struct dns_msg*
mesh_serve_expired_lookup(struct module_qstate* qstate,
struct query_info* lookup_qinfo);
+/**
+ * See if the mesh has space for more queries. You can allocate queries
+ * anyway, but this checks for the allocated space.
+ * @param mesh: mesh area.
+ * @return true if the query list is full.
+ * It checks the number of all queries, not just number of reply states,
+ * that have a client address. So that spawned queries count too,
+ * that were created by the iterator, or other modules.
+ */
+int mesh_jostle_exceeded(struct mesh_area* mesh);
+
#endif /* SERVICES_MESH_H */
--
2.33.0

View File

@ -1,46 +0,0 @@
From c60bed8eef8962c6f7d8deb266d438ff77baaaf5 Mon Sep 17 00:00:00 2001
From: eaglegai <eaglegai@163.com>
Date: Fri, 18 Mar 2022 19:08:02 +0800
Subject: [PATCH] fix -q doesn't work when use with 'unbound-control stats_shm'
Signed-off-by: eaglegai <eaglegai@163.com>
---
smallapp/unbound-control.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c
index c7c38276f..b0835e3e1 100644
--- a/smallapp/unbound-control.c
+++ b/smallapp/unbound-control.c
@@ -444,7 +444,7 @@ static void do_stats_shm(struct config_file* cfg, struct ub_stats_info* stats,
#endif /* HAVE_SHMGET */
/** print statistics from shm memory segment */
-static void print_stats_shm(const char* cfgfile)
+static void print_stats_shm(const char* cfgfile, int quiet)
{
#ifdef HAVE_SHMGET
struct config_file* cfg;
@@ -474,8 +474,11 @@ static void print_stats_shm(const char* cfgfile)
fatal_exit("shmat(%d): %s", id_arr, strerror(errno));
}
- /* print the stats */
- do_stats_shm(cfg, stats, shm_stat);
+
+ if (!quiet) {
+ /* print the stats */
+ do_stats_shm(cfg, stats, shm_stat);
+ }
/* shutdown */
shmdt(shm_stat);
@@ -987,7 +990,7 @@ int main(int argc, char* argv[])
#endif
}
if(argc >= 1 && strcmp(argv[0], "stats_shm")==0) {
- print_stats_shm(cfgfile);
+ print_stats_shm(cfgfile, quiet);
return 0;
}
check_args_for_listcmd(argc, argv);

Binary file not shown.

BIN
unbound-1.17.0.tar.gz Normal file

Binary file not shown.

View File

@ -5,9 +5,13 @@
#
# this is a comment.
#Use this to include other text into the file.
# Use this anywhere in the file to include other text into this file.
#include: "otherfile.conf"
# Use this anywhere in the file to include other text, that explicitly starts a
# clause, into this file. Text after this directive needs to start a clause.
#include-toplevel: "otherfile.conf"
# The server clause sets the main parameters.
server:
# whitespace is not necessary, but looks cleaner.
@ -67,6 +71,10 @@ server:
# NOTE: If deploying on non-default port, eg 80/443, this needs to be disabled
interface-automatic: no
# instead of the default port, open additional ports separated by
# spaces when interface-automatic is enabled, by listing them here.
# interface-automatic-ports: ""
# port to answer queries from
# port: 53
@ -86,19 +94,22 @@ server:
# Set this to yes to prefer ipv6 upstream servers over ipv4.
# prefer-ip6: no
# Prefer ipv4 upstream servers, even if ipv6 is available.
# prefer-ip4: no
# number of ports to allocate per thread, determines the size of the
# port range that can be open simultaneously. About double the
# num-queries-per-thread, or, use as many as the OS will allow you.
# outgoing-range: 4096
# permit unbound to use this port number or port range for
# permit Unbound to use this port number or port range for
# making outgoing queries, using an outgoing interface.
# Only ephemeral ports are allowed by SElinux
outgoing-port-permit: 32768-60999
# deny unbound the use this of port number or port range for
# deny Unbound the use this of port number or port range for
# making outgoing queries, using an outgoing interface.
# Use this to make sure unbound does not grab a UDP port that some
# Use this to make sure Unbound does not grab a UDP port that some
# other server on this computer needs. The default is to avoid
# IANA-assigned port numbers.
# If multiple outgoing-port-permit and outgoing-port-avoid options
@ -122,6 +133,7 @@ server:
# so-sndbuf: 0
# use SO_REUSEPORT to distribute queries over threads.
# at extreme load it could be better to turn it off to distribute even.
so-reuseport: yes
# use IP_TRANSPARENT so the interface: addresses can be non-local
@ -134,9 +146,14 @@ server:
# Linux only. On Linux you also have ip-transparent that is similar.
# ip-freebind: no
# the value of the Differentiated Services Codepoint (DSCP)
# in the differentiated services field (DS) of the outgoing
# IP packets
# ip-dscp: 0
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts).
# edns-buffer-size: 4096
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts)
# edns-buffer-size: 1232
# Maximum UDP response size (not applied to TCP response).
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
@ -144,6 +161,9 @@ server:
# Helps mitigating DDOS
max-udp-size: 3072
# max memory to use for stream(tcp and tls) waiting result buffers.
# stream-wait-size: 4m
# buffer size for handling DNS data. No messages larger than this
# size can be sent or received, by UDP or TCP. In bytes.
# msg-buffer-size: 65552
@ -166,6 +186,17 @@ server:
# msec to wait before close of port on timeout UDP. 0 disables.
# delay-close: 0
# perform connect for UDP sockets to mitigate ICMP side channel.
# udp-connect: yes
# The number of retries, per upstream nameserver in a delegation, when
# a throwaway response (also timeouts) is received.
# outbound-msg-retry: 5
# msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376
# the amount of memory to use for the RRset cache.
# plain value in bytes or you can append k, m or G. default is "4Mb".
# rrset-cache-size: 4m
@ -193,6 +224,12 @@ server:
# minimum wait time for responses, increase if uplink is long. In msec.
# infra-cache-min-rtt: 50
# maximum wait time for responses. In msec.
# infra-cache-max-rtt: 120000
# enable to make server probe down hosts more frequently.
# infra-keep-probing: no
# the number of slabs to use for the Infrastructure cache.
# the number of slabs must be a power of 2.
# more slabs reduce lock contention, but fragment memory usage.
@ -212,7 +249,7 @@ server:
# do-ip6: yes
# Enable UDP, "yes" or "no".
# NOTE: if setting up an unbound on tls443 for public use, you might want to
# NOTE: if setting up an Unbound on tls443 for public use, you might want to
# disable UDP to avoid being used in DNS amplification attacks.
# do-udp: yes
@ -235,12 +272,21 @@ server:
# Default is 0, system default MSS.
# outgoing-tcp-mss: 0
# Idle TCP timeout, connection closed in milliseconds
# tcp-idle-timeout: 30000
# Enable EDNS TCP keepalive option.
edns-tcp-keepalive: yes
# Timeout for EDNS TCP keepalive, in msec.
# edns-tcp-keepalive-timeout: 120000
# Fedora note: do not activate this - can cause a crash
# Use systemd socket activation for UDP, TCP, and control sockets.
# use-systemd: no
# Detach from the terminal, run in background, "yes" or "no".
# Set the value to "no" when unbound runs as systemd service.
# Set the value to "no" when Unbound runs as systemd service.
# do-daemonize: yes
# control which clients are allowed to make (recursive) queries
@ -262,7 +308,7 @@ server:
# are tagged with one of these tags.
# access-control-tag: 192.0.2.0/24 "tag2 tag3"
# set action for particular tag for given access control element
# set action for particular tag for given access control element.
# if you have multiple tag values, the tag used to lookup the action
# is the first tag match between access-control-tag and local-zone-tag
# where "first" comes from the order of the define-tag values.
@ -274,6 +320,58 @@ server:
# Set view for access control element
# access-control-view: 192.0.2.0/24 viewname
# Similar to 'access-control:' but for interfaces.
# Control which listening interfaces are allowed to accept (recursive)
# queries for this server.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the action.
# The actions are the same as 'access-control:' above.
# By default all the interfaces configured are refused.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-action: 192.0.2.153 allow
# interface-action: 192.0.2.154 allow
# interface-action: 192.0.2.154@5003 allow
# interface-action: 2001:DB8::5 allow
# interface-action: eth0@5003 allow
# Similar to 'access-control-tag:' but for interfaces.
# Tag interfaces with a list of tags (in "" with spaces between).
# Interfaces using these tags use localzones that are tagged with one
# of these tags.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the list of tags.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag: eth0@5003 "tag2 tag3"
# Similar to 'access-control-tag-action:' but for interfaces.
# Set action for particular tag for a given interface element.
# If you have multiple tag values, the tag used to lookup the action
# is the first tag match between interface-tag and local-zone-tag
# where "first" comes from the order of the define-tag values.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the tag and action.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag-action: eth0@5003 tag3 refuse
# Similar to 'access-control-tag-data:' but for interfaces.
# Set redirect data for a particular tag for an interface element.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the tag and the redirect data.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-tag-data: eth0@5003 tag2 "A 127.0.0.1"
# Similar to 'access-control-view:' but for interfaces.
# Set view for an interface element.
# The specified interfaces should be the same as the ones specified in
# 'interface:' followed by the view name.
# Note: any 'access-control*:' setting overrides all 'interface-*:'
# settings for targeted clients.
# interface-view: eth0@5003 viewname
# if given, a chroot(2) is done to the given directory.
# i.e. you can chroot to the working directory, for example,
# for extra security, but make sure all files are in that directory.
@ -293,7 +391,7 @@ server:
# The pid file can be absolute and outside of the chroot, it is
# written just prior to performing the chroot and dropping permissions.
#
# Additionally, unbound may need to access /dev/random (for entropy).
# Additionally, Unbound may need to access /dev/urandom (for entropy).
# How to do this is specific to your OS.
#
# If you give "" no chroot is performed. The path must not end in a /.
@ -334,6 +432,17 @@ server:
# timetoresolve, fromcache and responsesize.
# log-replies: no
# log with tag 'query' and 'reply' instead of 'info' for
# filtering log-queries and log-replies from the log.
# log-tag-queryreply: no
# log the local-zone actions, like local-zone type inform is enabled
# also for the other local zone types.
# log-local-actions: no
# print log lines that say why queries return SERVFAIL to clients.
# log-servfail: no
# the pid file. Can be an absolute path outside of chroot/work dir.
pidfile: "/var/run/unbound/unbound.pid"
@ -350,12 +459,22 @@ server:
# enable to not answer trustanchor.unbound queries.
# hide-trustanchor: no
# enable to not set the User-Agent HTTP header.
# hide-http-user-agent: no
# the identity to report. Leave "" or default to return hostname.
# identity: ""
# the version to report. Leave "" or default to return package version.
# version: ""
# NSID identity (hex string, or "ascii_somestring"). default disabled.
# nsid: "aabbccdd"
# User-Agent HTTP header to use. Leave "" or default to use package name
# and version.
# http-user-agent: ""
# the target fetch policy.
# series of integers describing the policy per dependency depth.
# The number of values in the list determines the maximum dependency
@ -367,7 +486,7 @@ server:
# target-fetch-policy: "3 2 1 0 0"
# Harden against very small EDNS buffer sizes.
# harden-short-bufsize: no
# harden-short-bufsize: yes
# Harden against unseemly large queries.
# harden-large-queries: no
@ -397,7 +516,7 @@ server:
# Sent minimum amount of information to upstream servers to enhance
# privacy. Only sent minimum required labels of the QNAME and set QTYPE
# to NS when possible.
# to A when possible.
qname-minimisation: yes
# QNAME minimisation in strict mode. Do not fall-back to sending full
@ -416,8 +535,8 @@ server:
# Domains (and domains in them) without support for dns-0x20 and
# the fallback fails because they keep sending different answers.
# caps-whitelist: "licdn.com"
# caps-whitelist: "senderbase.org"
# caps-exempt: "licdn.com"
# caps-exempt: "senderbase.org"
# Enforce privacy of these addresses. Strips them away from answers.
# It may cause DNSSEC validation to additionally mark it as bogus.
@ -458,6 +577,9 @@ server:
# if yes, perform key lookups adjacent to normal lookups.
prefetch-key: yes
# deny queries of type ANY with an empty response.
deny-any: yes
# if yes, Unbound rotates RRSet order in response.
rrset-roundrobin: yes
@ -470,6 +592,9 @@ server:
# module configuration of the server. A string with identifiers
# separated by spaces. Syntax: "[dns64] [validator] iterator"
# most modules have to be listed at the beginning of the line,
# except cachedb(just before iterator), and python (at the beginning,
# or, just before the iterator).
module-config: "ipsecmod validator iterator"
# File with trusted keys, kept uptodate using RFC5011 probes,
@ -477,7 +602,7 @@ server:
# Use several entries, one per domain name, to track multiple zones.
#
# If you want to perform DNSSEC validation, run unbound-anchor before
# you start unbound (i.e. in the system boot scripts). And enable:
# you start Unbound (i.e. in the system boot scripts). And enable:
# Please note usage of unbound-anchor root anchor is at your own risk
# and under the terms of our LICENSE (see that file in the source).
# auto-trust-anchor-file: "/var/lib/unbound/root.key"
@ -488,11 +613,6 @@ server:
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
root-key-sentinel: yes
# File with DLV trusted keys. Same format as trust-anchor-file.
# There can be only one DLV configured, it is trusted from root down.
# DLV is going to be decommissioned. Please do not use it any more.
# dlv-anchor-file: "dlv.isc.org.key"
# File with trusted keys for validation. Specify more than one file
# with several entries, one file per entry.
# Zone file format, with DS and DNSKEY entries.
@ -534,6 +654,10 @@ server:
# val-sig-skew-min: 3600
# val-sig-skew-max: 86400
# The maximum number the validator should restart validation with
# another authority in case of failed validation.
# val-max-restart: 5
# Should additional section of secure message also be kept clean of
# unsecure data. Useful to shield the users of this validator from
# potential bogus data in the additional section. All unsigned data
@ -549,13 +673,40 @@ server:
val-permissive-mode: no
# Ignore the CD flag in incoming queries and refuse them bogus data.
# Enable it if the only clients of unbound are legacy servers (w2008)
# Enable it if the only clients of Unbound are legacy servers (w2008)
# that set CD but cannot validate themselves.
# ignore-cd-flag: no
# Serve expired responses from cache, with TTL 0 in the response,
# and then attempt to fetch the data afresh.
# Serve expired responses from cache, with serve-expired-reply-ttl in
# the response, and then attempt to fetch the data afresh.
serve-expired: yes
#
# Limit serving of expired responses to configured seconds after
# expiration. 0 disables the limit.
serve-expired-ttl: 14400
#
# Set the TTL of expired records to the serve-expired-ttl value after a
# failed attempt to retrieve the record from upstream. This makes sure
# that the expired records will be served as long as there are queries
# for it.
# serve-expired-ttl-reset: no
#
# TTL value to use when replying with expired data.
# serve-expired-reply-ttl: 30
#
# Time in milliseconds before replying to the client with expired data.
# This essentially enables the serve-stale behavior as specified in
# RFC 8767 that first tries to resolve before
# immediately responding with expired data. 0 disables this behavior.
# A recommended value is 1800.
# serve-expired-client-timeout: 0
# Return the original TTL as received from the upstream name server rather
# than the decrementing TTL as stored in the cache. Enabling this feature
# does not impact cache expiry, it only changes the TTL Unbound embeds in
# responses to queries. Note that enabling this feature implicitly disables
# enforcement of the configured minimum and maximum TTL.
# serve-original-ttl: no
# Have the validator log failed validations for your diagnosis.
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
@ -565,7 +716,10 @@ server:
# keysize. Keep this table very short, as linear search is done.
# A message with an NSEC3 with larger count is marked insecure.
# List in ascending order the keysize and count values.
# val-nsec3-keysize-iterations: "1024 150 2048 500 4096 2500"
# val-nsec3-keysize-iterations: "1024 150 2048 150 4096 150"
# if enabled, ZONEMD verification failures do not block the zone.
# zonemd-permissive-mode: no
# instruct the auto-trust-anchor-file probing to add anchors after ttl.
# add-holddown: 2592000 # 30 days
@ -590,7 +744,7 @@ server:
# more slabs reduce lock contention, but fragment memory usage.
# key-cache-slabs: 4
# the amount of memory to use for the negative cache (used for DLV).
# the amount of memory to use for the negative cache.
# plain value in bytes or you can append k, m or G. default is "1Mb".
# neg-cache-size: 1m
@ -603,6 +757,7 @@ server:
# local-zone: "localhost." nodefault
# local-zone: "127.in-addr.arpa." nodefault
# local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
# local-zone: "home.arpa." nodefault
# local-zone: "onion." nodefault
# local-zone: "test." nodefault
# local-zone: "invalid." nodefault
@ -639,9 +794,12 @@ server:
# local-zone: "8.b.d.0.1.0.0.2.ip6.arpa." nodefault
# And for 64.100.in-addr.arpa. to 127.100.in-addr.arpa.
# If unbound is running service for the local host then it is useful
# Add example.com into ipset
# local-zone: "example.com" ipset
# If Unbound is running service for the local host then it is useful
# to perform lan-wide lookups to the upstream, and unblock the
# long list of local-zones above. If this unbound is a dns server
# long list of local-zones above. If this Unbound is a dns server
# for a network of computers, disabled is better and stops information
# leakage of local lan information.
# unblock-lan-zones: no
@ -662,8 +820,11 @@ server:
# o typetransparent resolves normally for other types and other names
# o inform acts like transparent, but logs client IP address
# o inform_deny drops queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, resolve in
# that way but ignore local data for that name
# o inform_redirect redirects queries and logs client IP address
# o always_transparent, always_refuse, always_nxdomain, always_nodata,
# always_deny resolve in that way but ignore local data for
# that name
# o always_null returns 0.0.0.0 or ::0 for any name in the zone.
# o noview breaks out of that view towards global local-zones.
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
@ -699,14 +860,43 @@ server:
# add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse
# service clients over SSL (on the TCP sockets), with plain DNS inside
# the SSL stream. Give the certificate to use and private key.
# service clients over TLS (on the TCP sockets) with plain DNS inside
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
# Give the certificate to use and private key.
# default is "" (disabled). requires restart to take effect.
# tls-service-key: "/etc/unbound/unbound_server.key"
# tls-service-pem: "/etc/unbound/unbound_server.pem"
# tls-port: 853
#
# request upstream over SSL (with plain DNS inside the SSL stream).
# https-port: 443
# cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
# cipher setting for TLSv1.3
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
# Fedora/RHEL: use system-wide crypto policies
tls-ciphers: "PROFILE=SYSTEM"
# TODO: ask system-wide crypto people what to use here
#tls-ciphersuites: "PROFILE=SYSTEM" # does not work
# Pad responses to padded queries received over TLS
# pad-responses: yes
# Padded responses will be padded to the closest multiple of this size.
# pad-responses-block-size: 468
# Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload.
# tls-use-sni: yes
# Add the secret file for TLS Session Ticket.
# Secret file must be 80 bytes of random data.
# First key use to encrypt and decrypt TLS session tickets.
# Other keys use to decrypt only.
# requires restart to take effect.
# tls-session-ticket-keys: "path/to/secret_file1"
# tls-session-ticket-keys: "path/to/secret_file2"
# request upstream over TLS (with plain DNS inside the TLS stream).
# Default is no. Can be turned on and off with unbound-control.
# tls-upstream: no
@ -715,14 +905,48 @@ server:
# Add system certs to the cert bundle, from the Windows Cert Store
# tls-win-cert: no
# and on other systems, the default openssl certificates
# tls-system-cert: no
# Pad queries over TLS upstreams
# pad-queries: yes
# Padded queries will be padded to the closest multiple of this size.
# pad-queries-block-size: 128
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-ports: portno for each of the port numbers.
# tls-additional-port: portno for each of the port numbers.
# HTTP endpoint to provide DNS-over-HTTPS service on.
# http-endpoint: "/dns-query"
# HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS value to use.
# http-max-streams: 100
# Maximum number of bytes used for all HTTP/2 query buffers.
# http-query-buffer-size: 4m
# Maximum number of bytes used for all HTTP/2 response buffers.
# http-response-buffer-size: 4m
# Set TCP_NODELAY socket option on sockets used for DNS-over-HTTPS
# service.
# http-nodelay: yes
# Disable TLS for DNS-over-HTTP downstream service.
# http-notls-downstream: no
# The interfaces that use these listed port numbers will support and
# expect PROXYv2. For UDP and TCP/TLS interfaces.
# proxy-protocol-port: portno for each of the port numbers.
# DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96
# DNS64 ignore AAAA records for these domains and use A instead.
# dns64-ignore-aaaa: "example.com"
# ratelimit for uncached, new queries, this limits recursion effort.
# ratelimiting is experimental, and may help against randomqueryflood.
# if 0(default) it is disabled, otherwise state qps allowed per zone.
@ -736,11 +960,9 @@ server:
# 0 blocks when ratelimited, otherwise let 1/xth traffic through
# ratelimit-factor: 10
# what is considered a low rtt (ping time for upstream server), in msec
# low-rtt: 45
# select low rtt this many times out of 1000. 0 means the fast server
# select is disabled. prefetches are not sped up.
# low-rtt-permil: 0
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ratelimit-backoff: no
# override the ratelimit for a specific domain name.
# give this setting multiple times to have multiple overrides.
@ -762,7 +984,28 @@ 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
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ip-ratelimit-backoff: no
# Limit the number of connections simultaneous from a netblock
# tcp-connection-limit: 192.0.2.0/24 12
# select from the fastest servers this many times out of 1000. 0 means
# the fast server select is disabled. prefetches are not sped up.
# fast-server-permil: 0
# the number of servers that will be used in the fast server selection.
# fast-server-num: 3
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
ede: yes
# Enable to attach an Extended DNS Error (RFC8914) Code 3 - Stale
# Answer as EDNS0 option to expired responses.
# Note that the ede option above needs to be enabled for this to work.
ede-serve-expired: yes
# 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
@ -776,7 +1019,7 @@ server:
# ipsecmod-hook: "./my_executable"
ipsecmod-hook:/usr/libexec/ipsec/_unbound-hook
# When enabled unbound will reply with SERVFAIL if the return value of
# When enabled Unbound will reply with SERVFAIL if the return value of
# the ipsecmod-hook is not 0.
# ipsecmod-strict: no
#
@ -788,18 +1031,38 @@ server:
# ipsecmod-ignore-bogus: no
#
# Domains for which ipsecmod will be triggered. If not defined (default)
# all domains are treated as being whitelisted.
# ipsecmod-whitelist: "libreswan.org"
# ipsecmod-whitelist: "nlnetlabs.nl"
# all domains are treated as being allowed.
# ipsecmod-allow: "example.com"
# ipsecmod-allow: "nlnetlabs.nl"
# Timeout for REUSE entries in milliseconds.
# tcp-reuse-timeout: 60000
# Max number of queries on a reuse connection.
# max-reuse-tcp-queries: 200
# Timeout in milliseconds for TCP queries to auth servers.
# tcp-auth-query-timeout: 3000
# Python config section. To enable:
# o use --with-pythonmodule to configure before compiling.
# o list python in the module-config string (above) to enable.
# It can be at the start, it gets validated results, or just before
# the iterator and process before DNSSEC validation.
# o and give a python-script to run.
python:
# Script file to load
# python-script: "/etc/unbound/ubmodule-tst.py"
# Dynamic library config section. To enable:
# o use --with-dynlibmodule to configure before compiling.
# o list dynlib in the module-config string (above) to enable.
# It can be placed anywhere, the dynlib module is only a very thin wrapper
# to load modules dynamically.
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
# the module-config then you need one dynlib-file per instance.
dynlib:
# Script file to load
# dynlib-file: "/etc/unbound/dynlib.so"
# Remote control config section.
remote-control:
# Enable remote control with unbound-control(8) here.
@ -813,16 +1076,22 @@ remote-control:
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
# set to an absolute path to use a unix local name pipe, certificates
# are not used for that, so key and cert files need not be present.
# control-interface: 127.0.0.1
# control-interface: ::1
# port number for remote control operations.
# control-port: 8953
# unbound server key file.
# for localhost, you can disable use of TLS by setting this to "no"
# For local sockets this option is ignored, and TLS is not used.
control-use-cert: "no"
# Unbound server key file.
server-key-file: "/etc/unbound/unbound_server.key"
# unbound server certificate file.
# Unbound server certificate file.
server-cert-file: "/etc/unbound/unbound_server.pem"
# unbound-control key file.
@ -847,7 +1116,9 @@ include: /etc/unbound/conf.d/*.conf
# stub-addr: 192.0.2.68
# stub-prime: no
# stub-first: no
# stub-tcp-upstream: no
# stub-tls-upstream: no
# stub-no-cache: no
# stub-zone:
# name: "example.org"
# stub-host: ns.example.com.
@ -867,7 +1138,9 @@ include: /etc/unbound/conf.d/*.conf
# forward-addr: 192.0.2.68
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
# forward-first: no
# forward-tcp-upstream: no
# forward-tls-upstream: no
# forward-no-cache: no
# forward-zone:
# name: "example.org"
# forward-host: fwd.example.com
@ -883,21 +1156,36 @@ include: /etc/unbound/conf.d/*.conf
# has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from masters) sources of
# notifies.
auth-zone:
name: "."
primary: 199.9.14.201 # b.root-servers.net
primary: 192.33.4.12 # c.root-servers.net
primary: 199.7.91.13 # d.root-servers.net
primary: 192.5.5.241 # f.root-servers.net
primary: 192.112.36.4 # g.root-servers.net
primary: 193.0.14.129 # k.root-servers.net
primary: 192.0.47.132 # xfr.cjr.dns.icann.org
primary: 192.0.32.132 # xfr.lax.dns.icann.org
primary: 2001:500:200::b # b.root-servers.net
primary: 2001:500:2::c # c.root-servers.net
primary: 2001:500:2d::d # d.root-servers.net
primary: 2001:500:2f::f # f.root-servers.net
primary: 2001:500:12::d0d # g.root-servers.net
primary: 2001:7fd::1 # k.root-servers.net
primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
primary: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
fallback-enabled: yes
for-downstream: no
for-upstream: yes
fallback-enabled: yes
master: b.root-servers.net
master: c.root-servers.net
master: e.root-servers.net
master: f.root-servers.net
master: g.root-servers.net
master: k.root-servers.net
# auth-zone:
# name: "example.org"
# for-downstream: yes
# for-upstream: yes
# zonemd-check: no
# zonemd-reject-absence: no
# zonefile: "example.org.zone"
# Views
@ -911,7 +1199,7 @@ auth-zone:
# name: "viewname"
# local-zone: "example.com" redirect
# local-data: "example.com A 192.0.2.3"
# local-data-ptr: "192.0.2.3 www.example.com"
# local-data-ptr: "192.0.2.3 www.example.com"
# view-first: no
# view:
# name: "anotherview"
@ -921,8 +1209,9 @@ auth-zone:
# another crypto library
#
# DNSCrypt
# o enable, use --enable-dnscrypt to configure before compiling.
# Caveats:
# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper
# 1. the keys/certs cannot be produced by Unbound. You can use dnscrypt-wrapper
# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to
# listen on `dnscrypt-port` with the follo0wing snippet:
@ -941,18 +1230,92 @@ auth-zone:
# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert
# CacheDB
# Enable external backend DB as auxiliary cache. Specify the backend name
# External backend DB as auxiliary cache.
# To enable, use --enable-cachedb to configure before compiling.
# Specify the backend name
# (default is "testframe", which has no use other than for debugging and
# testing) and backend-specific options. The 'cachedb' module must be
# included in module-config.
# included in module-config, just before the iterator module.
# cachedb:
# backend: "testframe"
# # secret seed string to calculate hashed keys
# secret-seed: "default"
#
# # For "redis" backend:
# # (to enable, use --with-libhiredis to configure before compiling)
# # redis server's IP address or host name
# redis-server-host: 127.0.0.1
# # redis server's TCP port
# redis-server-port: 6379
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# # set timeout on redis records based on DNS response TTL
# redis-expire-records: no
# IPSet
# Add specify domain into set via ipset.
# To enable:
# o use --enable-ipset to configure before compiling;
# o Unbound then needs to run as root user.
# ipset:
# # set name for ip v4 addresses
# name-v4: "list-v4"
# # set name for ip v6 addresses
# name-v6: "list-v6"
#
# Dnstap logging support, if compiled in by using --enable-dnstap to configure.
# To enable, set the dnstap-enable to yes and also some of
# dnstap-log-..-messages to yes. And select an upstream log destination, by
# socket path, TCP or TLS destination.
# dnstap:
# dnstap-enable: no
# # if set to yes frame streams will be used in bidirectional mode
# dnstap-bidirectional: yes
# dnstap-socket-path: "/etc/unbound/dnstap.sock"
# # if "" use the unix socket in dnstap-socket-path, otherwise,
# # set it to "IPaddress[@port]" of the destination.
# dnstap-ip: ""
# # if set to yes if you want to use TLS to dnstap-ip, no for TCP.
# dnstap-tls: yes
# # name for authenticating the upstream server. or "" disabled.
# dnstap-tls-server-name: ""
# # if "", it uses the cert bundle from the main Unbound config.
# dnstap-tls-cert-bundle: ""
# # key file for client authentication, or "" disabled.
# dnstap-tls-client-key-file: ""
# # cert file for client authentication, or "" disabled.
# dnstap-tls-client-cert-file: ""
# dnstap-send-identity: no
# dnstap-send-version: no
# # if "" it uses the hostname.
# dnstap-identity: ""
# # if "" it uses the package version.
# dnstap-version: ""
# dnstap-log-resolver-query-messages: no
# dnstap-log-resolver-response-messages: no
# dnstap-log-client-query-messages: no
# dnstap-log-client-response-messages: no
# dnstap-log-forwarder-query-messages: no
# dnstap-log-forwarder-response-messages: no
# Response Policy Zones
# RPZ policies. Applied in order of configuration. QNAME, Response IP
# Address, nsdname, nsip and clientip triggers are supported. Supported
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
# and drop. Policies can be loaded from a file, or using zone
# transfer, or using HTTP. The respip module needs to be added
# to the module-config, e.g.: module-config: "respip validator iterator".
# rpz:
# name: "rpz.example.com"
# zonefile: "rpz.example.com"
# primary: 192.0.2.0
# allow-notify: 192.0.2.0/32
# url: http://www.example.com/rpz.example.org.zone
# rpz-action-override: cname
# rpz-cname-override: www.example.org
# rpz-log: yes
# rpz-log-name: "example policy"
# rpz-signal-nxdomain-ra: no
# for-downstream: no
# tags: "example"

View File

@ -1,6 +1,6 @@
[Unit]
Description=Unbound recursive Domain Name Server
After=network.target
After=network-online.target
After=unbound-keygen.service
Wants=unbound-keygen.service
Wants=unbound-anchor.timer
@ -11,7 +11,7 @@ Wants=nss-lookup.target
Type=simple
EnvironmentFile=-/etc/sysconfig/unbound
ExecStartPre=/usr/sbin/unbound-checkconf
ExecStartPre=-/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_UNBOUND_ANCHOR" == "yes" ]; then /usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R; else echo "Updates of root keys with unbound-anchor is disabled"; fi'
ExecStart=/usr/sbin/unbound -d $UNBOUND_OPTIONS
ExecReload=/usr/sbin/unbound-control reload

View File

@ -1,10 +1,10 @@
%{!?delete_la: %global delete_la find $RPM_BUILD_ROOT -type f -name "*.la" -delete}
Name: unbound
Version: 1.13.2
Release: 6
Version: 1.17.0
Release: 1
Summary: Unbound is a validating, recursive, caching DNS resolver
License: BSD
License: BSD-3-Clause
Url: https://nlnetlabs.nl/projects/unbound/about/
Source: https://nlnetlabs.nl/downloads/unbound/%{name}-%{version}.tar.gz
Source1: unbound.service
@ -21,10 +21,7 @@ Source11: unbound.sysconfig
Source12: unbound-anchor.timer
Source13: unbound-anchor.service
Patch0: backport-fix-q-doesnt-work-when-use-with-unbound-control-stats_shm.patch
Patch1: unbound-remove-buildin-key.patch
Patch2: backport-CVE-2022-30698-and-CVE-2022-30699.patch
Patch3: backport-CVE-2022-3204.patch
BuildRequires: make flex swig pkgconfig systemd
BuildRequires: libevent-devel expat-devel openssl-devel python3-devel
@ -32,6 +29,7 @@ BuildRequires: gcc
%{?systemd_requires}
Requires: %{name}-libs = %{version}-%{release}
Requires: openssl
%description
Unbound is a validating, recursive, caching DNS resolver. It is designed
@ -126,11 +124,6 @@ install -p -m 0644 %{SOURCE13} $RPM_BUILD_ROOT%{_unitdir}/unbound-anchor.service
%delete_la
for mpage in ub_ctx ub_result ub_ctx_create ub_ctx_delete ub_ctx_set_option ub_ctx_get_option ub_ctx_config ub_ctx_set_fwd ub_ctx_resolvconf ub_ctx_hosts ub_ctx_add_ta ub_ctx_add_ta_file ub_ctx_trustedkeys ub_ctx_debugout ub_ctx_debuglevel ub_ctx_async ub_poll ub_wait ub_fd ub_process ub_resolve ub_resolve_async ub_cancel ub_resolve_free ub_strerror ub_ctx_print_local_zones ub_ctx_zone_add ub_ctx_zone_remove ub_ctx_data_add ub_ctx_data_remove;
do
echo ".so man3/libunbound.3" > $RPM_BUILD_ROOT%{_mandir}/man3/$mpage ;
done
install -d $RPM_BUILD_ROOT%{_localstatedir}/run/unbound
install -d $RPM_BUILD_ROOT%{_sysconfdir}/unbound/{keys.d,conf.d,local.d}
@ -240,6 +233,12 @@ popd
%{_mandir}/man*
%changelog
* Tue Nov 08 2022 gaihuiying <eaglegai@163.com> - 1.17.0-1
- Type:requirement
- CVE:NA
- SUG:NA
- DESC:update to 1.17.0
* Thu Sep 22 2022 xingwei <xingwei14@h-partners.com> - 1.13.2-6
- Type:cves
- CVE:CVE-2022-3204