- Fix rpz for cname override action after nsdname and nsip triggers.

This commit is contained in:
W.C.A. Wijngaards 2024-03-13 17:14:14 +01:00
parent afe52595a9
commit 4b54d8e15e
4 changed files with 425 additions and 1 deletions

View File

@ -6,6 +6,7 @@
clientip localdata action is logged. Fix rpz override action cname
for the clientip trigger.
- Fix to unify codepath for local alias for rpz cname action override.
- Fix rpz for cname override action after nsdname and nsip triggers.
12 March 2024: Yorgos
- Merge #1028: Clearer documentation for tcp-idle-timeout and

View File

@ -2746,8 +2746,48 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
delegpt_add_unused_targets(iq->dp);
if(qstate->env->auth_zones) {
uint8_t* sname = NULL;
size_t snamelen = 0;
/* apply rpz triggers at query time */
struct dns_msg* forged_response_after_cname;
struct dns_msg* forged_response = rpz_callback_from_iterator_module(qstate, iq);
while(forged_response && reply_find_rrset_section_an(
forged_response->rep, iq->qchase.qname,
iq->qchase.qname_len, LDNS_RR_TYPE_CNAME,
iq->qchase.qclass)) {
/* another cname to follow */
if(!handle_cname_response(qstate, iq, forged_response,
&sname, &snamelen)) {
errinf(qstate, "malloc failure, CNAME info");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
forged_response_after_cname =
rpz_callback_from_iterator_cname(qstate, iq);
if(forged_response_after_cname) {
forged_response = forged_response_after_cname;
} else {
/* Follow the CNAME with a query restart */
iq->deleg_msg = NULL;
iq->dp = NULL;
iq->dsns_point = NULL;
iq->auth_zone_response = 0;
iq->refetch_glue = 0;
iq->query_restart_count++;
iq->sent_count = 0;
iq->dp_target_count = 0;
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
fptr_ok(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
return next_state(iq, INIT_REQUEST_STATE);
}
}
if(forged_response != NULL) {
qstate->ext_state[id] = module_finished;
qstate->return_rcode = LDNS_RCODE_NOERROR;

View File

@ -2139,6 +2139,58 @@ rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
return rpz_synthesize_localdata_from_rrset(r, ms, qinfo, rrset, az);
}
/** Synthesize a CNAME message for RPZ action override */
static struct dns_msg*
rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms,
struct query_info* qinfo)
{
struct dns_msg* msg = NULL;
struct reply_info* new_reply_info;
struct ub_packed_rrset_key* rp;
msg = rpz_dns_msg_new(ms->region);
if(msg == NULL) { return NULL; }
new_reply_info = construct_reply_info_base(ms->region,
LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1, /* qd */
0, /* ttl */
0, /* prettl */
0, /* expttl */
1, /* an */
0, /* ns */
0, /* ar */
1, /* total */
sec_status_insecure,
LDNS_EDE_NONE);
if(new_reply_info == NULL) {
log_err("out of memory");
return NULL;
}
new_reply_info->authoritative = 1;
rp = respip_copy_rrset(r->cname_override, ms->region);
if(rp == NULL) {
log_err("out of memory");
return NULL;
}
rp->rk.dname = qinfo->qname;
rp->rk.dname_len = qinfo->qname_len;
/* this rrset is from the rpz data, or synthesized.
* It is not actually from the network, so we flag it with this
* flags as a fake RRset. If later the cache is used to look up
* rrsets, then the fake ones are not returned (if you look without
* the flag). For like CNAME lookups from the iterator or A, AAAA
* lookups for nameserver targets, it would use the without flag
* actual data. So that the actual network data and fake data
* are kept track of separately. */
rp->rk.flags |= PACKED_RRSET_RPZ;
new_reply_info->rrsets[0] = rp;
msg->rep = new_reply_info;
return msg;
}
static int
rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
struct local_zone* z, enum localzone_type lzt, struct query_info* qinfo,
@ -2244,6 +2296,9 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
ret = NULL;
ms->rpz_passthru = 1;
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, &ms->qinfo);
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
rpz_action_to_string(action));
@ -2299,8 +2354,11 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
ret = NULL;
ms->rpz_passthru = 1;
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, &ms->qinfo);
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'",
rpz_action_to_string(action));
ret = NULL;
}

325
testdata/rpz_nsdname_override.rpl vendored Normal file
View File

@ -0,0 +1,325 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
rpz:
name: "rpz.example.com."
rpz-log: yes
rpz-log-name: "rpz.example.com"
rpz-action-override: "nxdomain"
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
ns1.gotham.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
rpz:
name: "rpz2.example.com."
rpz-log: yes
rpz-log-name: "rpz2.example.com"
rpz-action-override: "nodata"
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN example.com.
rpz2 3600 IN SOA ns1.rpz2.example.com. hostmaster.rpz2.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz2.example.com.
3600 IN NS ns2.rpz2.example.com.
$ORIGIN rpz2.example.com.
ns1.gotham2.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
rpz:
name: "rpz3.example.com."
rpz-log: yes
rpz-log-name: "rpz3.example.com"
rpz-action-override: "passthru"
zonefile:
TEMPFILE_NAME rpz3.example.com
TEMPFILE_CONTENTS rpz3.example.com
$ORIGIN example.com.
rpz3 3600 IN SOA ns1.rpz3.example.com. hostmaster.rpz3.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz3.example.com.
3600 IN NS ns2.rpz3.example.com.
$ORIGIN rpz3.example.com.
ns1.gotham3.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
rpz:
name: "rpz4.example.com."
rpz-log: yes
rpz-log-name: "rpz4.example.com"
rpz-action-override: "drop"
zonefile:
TEMPFILE_NAME rpz4.example.com
TEMPFILE_CONTENTS rpz4.example.com
$ORIGIN example.com.
rpz4 3600 IN SOA ns1.rpz4.example.com. hostmaster.rpz4.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz4.example.com.
3600 IN NS ns2.rpz4.example.com.
$ORIGIN rpz4.example.com.
ns1.gotham3.a.rpz-nsdname A 1.2.3.5
ns1.gotham4.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
rpz:
name: "rpz5.example.com."
rpz-log: yes
rpz-log-name: "rpz5.example.com"
rpz-action-override: "cname"
rpz-cname-override: "target.a"
zonefile:
TEMPFILE_NAME rpz5.example.com
TEMPFILE_CONTENTS rpz5.example.com
$ORIGIN example.com.
rpz5 3600 IN SOA ns1.rpz5.example.com. hostmaster.rpz5.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz5.example.com.
3600 IN NS ns2.rpz5.example.com.
$ORIGIN rpz5.example.com.
ns1.gotham5.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
rpz:
name: "rpz6.example.com."
rpz-log: yes
rpz-log-name: "rpz6.example.com"
rpz-action-override: "disabled"
zonefile:
TEMPFILE_NAME rpz6.example.com
TEMPFILE_CONTENTS rpz6.example.com
$ORIGIN example.com.
rpz6 3600 IN SOA ns1.rpz6.example.com. hostmaster.rpz6.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz6.example.com.
3600 IN NS ns2.rpz6.example.com.
$ORIGIN rpz6.example.com.
ns1.gotham6.a.rpz-nsdname A 1.2.3.5
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ action override with trigger from nsdname.
; a.
RANGE_BEGIN 0 1000
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham.a. IN A
SECTION AUTHORITY
gotham.a. NS ns1.gotham.a.
SECTION ADDITIONAL
ns1.gotham.a. A 10.20.30.41
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham2.a. IN A
SECTION AUTHORITY
gotham2.a. NS ns1.gotham2.a.
SECTION ADDITIONAL
ns1.gotham2.a. A 10.20.30.42
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION AUTHORITY
gotham3.a. NS ns1.gotham3.a.
SECTION ADDITIONAL
ns1.gotham3.a. A 10.20.30.43
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham4.a. IN A
SECTION AUTHORITY
gotham4.a. NS ns1.gotham4.a.
SECTION ADDITIONAL
ns1.gotham4.a. A 10.20.30.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham5.a. IN A
SECTION AUTHORITY
gotham5.a. NS ns1.gotham5.a.
SECTION ADDITIONAL
ns1.gotham5.a. A 10.20.30.45
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham6.a. IN A
SECTION AUTHORITY
gotham6.a. NS ns1.gotham6.a.
SECTION ADDITIONAL
ns1.gotham6.a. A 10.20.30.46
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
target.a. IN A
SECTION ANSWER
target.a. IN A 1.2.3.6
ENTRY_END
RANGE_END
; gotham3.a.
RANGE_BEGIN 0 1000
ADDRESS 10.20.30.43
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION ANSWER
www.gotham3.a. A 1.2.3.4
ENTRY_END
RANGE_END
; gotham6.a.
RANGE_BEGIN 0 1000
ADDRESS 10.20.30.46
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.gotham6.a. IN A
SECTION ANSWER
www.gotham6.a. A 1.2.3.4
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham.a. IN A
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
www.gotham.a. IN A
SECTION ANSWER
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham2.a. IN A
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
www.gotham2.a. IN A
SECTION ANSWER
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham3.a. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham3.a. IN A
SECTION ANSWER
www.gotham3.a. A 1.2.3.4
ENTRY_END
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham4.a. IN A
ENTRY_END
;dropped
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham5.a. IN A
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham5.a. IN A
SECTION ANSWER
www.gotham5.a. CNAME target.a
target.a A 1.2.3.6
ENTRY_END
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.gotham6.a. IN A
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.gotham6.a. IN A
SECTION ANSWER
www.gotham6.a. A 1.2.3.4
ENTRY_END
SCENARIO_END