- Merge patch to fix for glue that is outside of zone, with

`harden-unverified-glue`, from Karthik Umashankar (Microsoft).
  Enabling this option protects the Unbound resolver against bad
  glue, that is unverified out of zone glue, by resolving them.
  It uses the records as last resort if there is no other working
  glue.
This commit is contained in:
W.C.A. Wijngaards 2024-08-23 08:56:48 +02:00
parent 348df52e05
commit 1e0cf1e86b
16 changed files with 416 additions and 9 deletions

View File

@ -1,3 +1,11 @@
23 August 2024: Wouter
- Merge patch to fix for glue that is outside of zone, with
`harden-unverified-glue`, from Karthik Umashankar (Microsoft).
Enabling this option protects the Unbound resolver against bad
glue, that is unverified out of zone glue, by resolving them.
It uses the records as last resort if there is no other working
glue.
21 August 2024: Wouter 21 August 2024: Wouter
- Add cross platform freebsd, openbsd and netbsd to github ci. - Add cross platform freebsd, openbsd and netbsd to github ci.
- Fix for char signedness warnings on NetBSD. - Fix for char signedness warnings on NetBSD.

View File

@ -533,6 +533,9 @@ server:
# Harden against out of zone rrsets, to avoid spoofing attempts. # Harden against out of zone rrsets, to avoid spoofing attempts.
# harden-glue: yes # harden-glue: yes
# Harden against unverified (outside-zone, including sibling zone) glue rrsets
# harden-unverified-glue: no
# Harden against receiving dnssec-stripped data. If you turn it # Harden against receiving dnssec-stripped data. If you turn it
# off, failing to validate dnskey data for a trustanchor will # off, failing to validate dnskey data for a trustanchor will
# trigger insecure mode for that zone (like without a trustanchor). # trigger insecure mode for that zone (like without a trustanchor).

View File

@ -1048,6 +1048,11 @@ payload is very large.
.B harden\-glue: \fI<yes or no> .B harden\-glue: \fI<yes or no>
Will trust glue only if it is within the servers authority. Default is yes. Will trust glue only if it is within the servers authority. Default is yes.
.TP .TP
.B harden\-unverified\-glue: \fI<yes or no>
Will trust only in-zone glue. Will try to resolve all out of zone
(\fI<unverfied>) glue. Will fallback to the original glue if unable to resolve.
Default is no.
.TP
.B harden\-dnssec\-stripped: \fI<yes or no> .B harden\-dnssec\-stripped: \fI<yes or no>
Require DNSSEC data for trust\-anchored zones, if such data is absent, Require DNSSEC data for trust\-anchored zones, if such data is absent,
the zone becomes bogus. If turned off, and no DNSSEC data is received the zone becomes bogus. If turned off, and no DNSSEC data is received

View File

@ -871,6 +871,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
{ {
int del_addi = 0; /* if additional-holding rrsets are deleted, we int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */ do not trust the normalized additional-A-AAAA any more */
uint8_t* ns_rrset_dname = NULL;
int added_rrlen_ede = 0; int added_rrlen_ede = 0;
struct rrset_parse* rrset, *prev; struct rrset_parse* rrset, *prev;
prev = NULL; prev = NULL;
@ -976,6 +977,16 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
continue; continue;
} }
} }
if(rrset->type == LDNS_RR_TYPE_NS &&
(rrset->section == LDNS_SECTION_AUTHORITY ||
rrset->section == LDNS_SECTION_ANSWER)) {
/* If the type is NS, and we're in the
* answer or authority section, then
* store the dname so we can check
* against the glue records
* further down */
ns_rrset_dname = rrset->dname;
}
if(del_addi && rrset->section == LDNS_SECTION_ADDITIONAL) { if(del_addi && rrset->section == LDNS_SECTION_ADDITIONAL) {
remove_rrset("sanitize: removing potential " remove_rrset("sanitize: removing potential "
"poison reference RRset:", pkt, msg, prev, &rrset); "poison reference RRset:", pkt, msg, prev, &rrset);
@ -988,6 +999,26 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset); "RRset:", pkt, msg, prev, &rrset);
continue; continue;
} }
if(env->cfg->harden_unverified_glue && ns_rrset_dname &&
rrset->section == LDNS_SECTION_ADDITIONAL &&
(rrset->type == LDNS_RR_TYPE_A || rrset->type == LDNS_RR_TYPE_AAAA) &&
!pkt_strict_sub(pkt, rrset->dname, ns_rrset_dname)) {
/* We're in the additional section, looking
* at an A/AAAA rrset, have a previous
* delegation point and we notice that
* the glue records are NOT for strict
* subdomains of the delegation. So set a
* flag, recompute the hash for the rrset
* and write the A/AAAA record to cache.
* It'll be retrieved if we can't separately
* resolve the glue */
rrset->flags = PACKED_RRSET_UNVERIFIED_GLUE;
rrset->hash = pkt_hash_rrset(pkt, rrset->dname, rrset->type, rrset->rrset_class, rrset->flags);
store_rrset(pkt, msg, env, rrset);
remove_rrset("sanitize: storing potential "
"unverified glue reference RRset:", pkt, msg, prev, &rrset);
continue;
}
prev = rrset; prev = rrset;
rrset = rrset->rrset_all_next; rrset = rrset->rrset_all_next;
} }

View File

@ -254,7 +254,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
} else { } else {
/* see if the failure did get (parent-lame) info */ /* see if the failure did get (parent-lame) info */
if(!cache_fill_missing(super->env, super_iq->qchase.qclass, if(!cache_fill_missing(super->env, super_iq->qchase.qclass,
super->region, super_iq->dp)) super->region, super_iq->dp, 0))
log_err("out of memory adding missing"); log_err("out of memory adding missing");
} }
delegpt_mark_neg(dpns, qstate->qinfo.qtype); delegpt_mark_neg(dpns, qstate->qinfo.qtype);
@ -1571,7 +1571,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }
if(!cache_fill_missing(qstate->env, iq->qchase.qclass, if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp)) { qstate->region, iq->dp, 0)) {
errinf(qstate, "malloc failure, copy extra info into delegation point"); errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }
@ -2152,6 +2152,15 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL"); verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
} }
if(qstate->env->cfg->harden_unverified_glue) {
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, PACKED_RRSET_UNVERIFIED_GLUE))
log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try unverified glue from cache");
return next_state(iq, QUERYTARGETS_STATE);
}
}
if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) { if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
struct delegpt* dp; struct delegpt* dp;
int nolock = 0; int nolock = 0;
@ -2194,7 +2203,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
} }
/* see if that makes new names available */ /* see if that makes new names available */
if(!cache_fill_missing(qstate->env, iq->qchase.qclass, if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp)) qstate->region, iq->dp, 0))
log_err("out of memory in cache_fill_missing"); log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) { if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try parent-side-name, w. glue from cache"); verbose(VERB_ALGO, "try parent-side-name, w. glue from cache");
@ -3426,7 +3435,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
old_dp->name, old_dp->namelen); old_dp->name, old_dp->namelen);
} }
if(!cache_fill_missing(qstate->env, iq->qchase.qclass, if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp)) { qstate->region, iq->dp, 0)) {
errinf(qstate, "malloc failure, copy extra info into delegation point"); errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }

View File

@ -176,6 +176,10 @@ config_file
Harden against spoofed glue (out of zone data). Harden against spoofed glue (out of zone data).
.. attribute:: harden_unverified_glue
Harden against unverified glue.
.. attribute:: harden_dnssec_stripped .. attribute:: harden_dnssec_stripped
Harden against receiving no DNSSEC data for trust anchor. Harden against receiving no DNSSEC data for trust anchor.

View File

@ -1009,6 +1009,7 @@ struct config_file {
int harden_short_bufsize; int harden_short_bufsize;
int harden_large_queries; int harden_large_queries;
int harden_glue; int harden_glue;
int harden_unverified_glue;
int harden_dnssec_stripped; int harden_dnssec_stripped;
int harden_referral_path; int harden_referral_path;
int use_caps_bits_for_id; int use_caps_bits_for_id;

View File

@ -365,7 +365,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
/** find and add A and AAAA records for missing nameservers in delegpt */ /** find and add A and AAAA records for missing nameservers in delegpt */
int int
cache_fill_missing(struct module_env* env, uint16_t qclass, cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp) struct regional* region, struct delegpt* dp, uint32_t flags)
{ {
struct delegpt_ns* ns; struct delegpt_ns* ns;
struct msgreply_entry* neg; struct msgreply_entry* neg;
@ -376,7 +376,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
continue; continue;
ns->cache_lookup_count++; ns->cache_lookup_count++;
akey = rrset_cache_lookup(env->rrset_cache, ns->name, akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0); ns->namelen, LDNS_RR_TYPE_A, qclass, flags, now, 0);
if(akey) { if(akey) {
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame, if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
NULL)) { NULL)) {

View File

@ -205,7 +205,7 @@ struct dns_msg* dns_cache_lookup(struct module_env* env,
* @return false on alloc failure. * @return false on alloc failure.
*/ */
int cache_fill_missing(struct module_env* env, uint16_t qclass, int cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp); struct regional* region, struct delegpt* dp, uint32_t flags);
/** /**
* Utility, create new, unpacked data structure for cache response. * Utility, create new, unpacked data structure for cache response.

188
testdata/iter_unverified_glue.rpl vendored Normal file
View File

@ -0,0 +1,188 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: no
do-ip6: no
harden-unverified-glue: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test iterative resolve with lame hints.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA 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 RA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN A
SECTION AUTHORITY
net. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
www.example.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
a.gtld-servers.net. IN A
SECTION ANSWER
a.gtld-servers.net. IN A 192.5.6.30
SECTION AUTHORITY
net. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.4
ENTRY_END
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 qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns1.examplesibling.com. IN A
SECTION ANSWER
ns1.examplesibling.com. IN A 1.2.3.5
ENTRY_END
RANGE_END
; stale ns1.examplesibling.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 ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.5
ENTRY_END
RANGE_END
; actual ns1.examplesibling.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.50
SECTION AUTHORITY
example.com. IN NS ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.5
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.50
SECTION AUTHORITY
example.com. IN NS ns1.examplesibling.com.
ENTRY_END
SCENARIO_END

View File

@ -0,0 +1,138 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
minimal-responses: no
do-ip6: no
harden-unverified-glue: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test iterative resolve with lame hints.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA 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 RA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN A
SECTION AUTHORITY
net. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR RA NOERROR
SECTION QUESTION
www.example.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
a.gtld-servers.net. IN A
SECTION ANSWER
a.gtld-servers.net. IN A 192.5.6.30
SECTION AUTHORITY
net. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns1.examplesibling.com.
SECTION ADDITIONAL
ns1.examplesibling.com. IN A 1.2.3.4
ENTRY_END
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 qtype qname
ADJUST copy_id
REPLY QR NXDOMAIN
SECTION QUESTION
ns1.examplesibling.com. IN A
ENTRY_END
RANGE_END
; stale ns1.examplesibling.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
SCENARIO_END

View File

@ -237,6 +237,7 @@ config_create(void)
cfg->harden_short_bufsize = 1; cfg->harden_short_bufsize = 1;
cfg->harden_large_queries = 0; cfg->harden_large_queries = 0;
cfg->harden_glue = 1; cfg->harden_glue = 1;
cfg->harden_unverified_glue = 0;
cfg->harden_dnssec_stripped = 1; cfg->harden_dnssec_stripped = 1;
cfg->harden_below_nxdomain = 1; cfg->harden_below_nxdomain = 1;
cfg->harden_referral_path = 0; cfg->harden_referral_path = 0;
@ -675,6 +676,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STRLIST("root-hints:", root_hints) else S_STRLIST("root-hints:", root_hints)
else S_STR("target-fetch-policy:", target_fetch_policy) else S_STR("target-fetch-policy:", target_fetch_policy)
else S_YNO("harden-glue:", harden_glue) else S_YNO("harden-glue:", harden_glue)
else S_YNO("harden-unverified-glue:", harden_unverified_glue)
else S_YNO("harden-short-bufsize:", harden_short_bufsize) else S_YNO("harden-short-bufsize:", harden_short_bufsize)
else S_YNO("harden-large-queries:", harden_large_queries) else S_YNO("harden-large-queries:", harden_large_queries)
else S_YNO("harden-dnssec-stripped:", harden_dnssec_stripped) else S_YNO("harden-dnssec-stripped:", harden_dnssec_stripped)
@ -1168,6 +1170,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "harden-short-bufsize", harden_short_bufsize) else O_YNO(opt, "harden-short-bufsize", harden_short_bufsize)
else O_YNO(opt, "harden-large-queries", harden_large_queries) else O_YNO(opt, "harden-large-queries", harden_large_queries)
else O_YNO(opt, "harden-glue", harden_glue) else O_YNO(opt, "harden-glue", harden_glue)
else O_YNO(opt, "harden-unverified-glue", harden_unverified_glue)
else O_YNO(opt, "harden-dnssec-stripped", harden_dnssec_stripped) else O_YNO(opt, "harden-dnssec-stripped", harden_dnssec_stripped)
else O_YNO(opt, "harden-below-nxdomain", harden_below_nxdomain) else O_YNO(opt, "harden-below-nxdomain", harden_below_nxdomain)
else O_YNO(opt, "harden-referral-path", harden_referral_path) else O_YNO(opt, "harden-referral-path", harden_referral_path)

View File

@ -288,6 +288,8 @@ struct config_file {
int harden_large_queries; int harden_large_queries;
/** harden against spoofed glue (out of zone data) */ /** harden against spoofed glue (out of zone data) */
int harden_glue; int harden_glue;
/** harden against unverified glue */
int harden_unverified_glue;
/** harden against receiving no DNSSEC data for trust anchor */ /** harden against receiving no DNSSEC data for trust anchor */
int harden_dnssec_stripped; int harden_dnssec_stripped;
/** harden against queries that fall under known nxdomain names */ /** harden against queries that fall under known nxdomain names */

View File

@ -315,6 +315,7 @@ target-fetch-policy{COLON} { YDVAR(1, VAR_TARGET_FETCH_POLICY) }
harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) } harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) }
harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) } harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) }
harden-glue{COLON} { YDVAR(1, VAR_HARDEN_GLUE) } harden-glue{COLON} { YDVAR(1, VAR_HARDEN_GLUE) }
harden-unverified-glue{COLON} { YDVAR(1, VAR_HARDEN_UNVERIFIED_GLUE) }
harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) } harden-dnssec-stripped{COLON} { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) }
harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) } harden-below-nxdomain{COLON} { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) }
harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }

View File

@ -206,7 +206,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE %token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED %token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
%token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME %token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME
%token VAR_MAX_GLOBAL_QUOTA %token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -345,7 +345,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_proxy_protocol_port | server_statistics_inhibit_zero | server_proxy_protocol_port | server_statistics_inhibit_zero |
server_harden_unknown_additional | server_disable_edns_do | server_harden_unknown_additional | server_disable_edns_do |
server_log_destaddr | server_cookie_secret_file | server_log_destaddr | server_cookie_secret_file |
server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota |
server_harden_unverified_glue
; ;
stubstart: VAR_STUB_ZONE stubstart: VAR_STUB_ZONE
{ {
@ -1807,6 +1808,16 @@ server_harden_glue: VAR_HARDEN_GLUE STRING_ARG
free($2); free($2);
} }
; ;
server_harden_unverified_glue: VAR_HARDEN_UNVERIFIED_GLUE STRING_ARG
{
OUTYY(("P(server_harden_unverified_glue:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->harden_unverified_glue =
(strcmp($2, "yes")==0);
free($2);
}
;
server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG
{ {
OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2)); OUTYY(("P(server_harden_dnssec_stripped:%s)\n", $2));

View File

@ -68,6 +68,8 @@ typedef uint64_t rrset_id_type;
* actual network. But messages with these records in it can be stored in * actual network. But messages with these records in it can be stored in
* the cache and retrieved for a reply. */ * the cache and retrieved for a reply. */
#define PACKED_RRSET_RPZ 0x8 #define PACKED_RRSET_RPZ 0x8
/** this rrset is A/AAAA and is an unverified glue record */
#define PACKED_RRSET_UNVERIFIED_GLUE 0x10
/** number of rrs and rrsets for integer overflow protection. More than /** number of rrs and rrsets for integer overflow protection. More than
* this is not really possible (64K packet has much less RRs and RRsets) in * this is not really possible (64K packet has much less RRs and RRsets) in
@ -96,6 +98,7 @@ struct packed_rrset_key {
* o PACKED_RRSET_SOA_NEG * o PACKED_RRSET_SOA_NEG
* o PACKED_RRSET_FIXEDTTL (not supposed to be cached) * o PACKED_RRSET_FIXEDTTL (not supposed to be cached)
* o PACKED_RRSET_RPZ * o PACKED_RRSET_RPZ
* o PACKED_RRSET_UNVERIFIED_GLUE
*/ */
uint32_t flags; uint32_t flags;
/** the rrset type in network format */ /** the rrset type in network format */