From: W.C.A. Wijngaards Date: Tue, 9 Sep 2025 10:34:11 +0000 (+0200) Subject: - Fix #1332: CNAME chains are sometimes not followed when RPZs add a X-Git-Tag: release-1.24.0rc1~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4267de87b53301de1917c032eb79a701c0f58daf;p=thirdparty%2Funbound.git - Fix #1332: CNAME chains are sometimes not followed when RPZs add a local CNAME rewrite. --- diff --git a/doc/Changelog b/doc/Changelog index 5fe960354..3c3c835cb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +9 September 2025: Wouter + - Fix #1332: CNAME chains are sometimes not followed when RPZs add a + local CNAME rewrite. + 8 September 2025: Yorgos - Update documentation for using "SET ... EX" in Redis. - Document max buffer sizes for Redis commands. diff --git a/services/rpz.c b/services/rpz.c index df39e75b0..f45cf6542 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -2121,8 +2121,17 @@ rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms, rpz_log_dname("nsdname local data", key.name, key.namelen); ld = (struct local_data*)rbtree_search(&z->data, &key.node); + if(ld == NULL && dname_is_wild(z->name)) { + key.name = z->name; + key.namelen = z->namelen; + key.namelabs = z->namelabs; + ld = (struct local_data*)rbtree_search(&z->data, &key.node); + /* rpz_synthesize_localdata_from_rrset is going to make + * the rrset source name equal to the query name. So no need + * to make the wildcard rrset here. */ + } if(ld == NULL) { - verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found"); + verbose(VERB_ALGO, "rpz: nsdname: qname not found"); return NULL; } @@ -2148,6 +2157,15 @@ rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms, key.namelen = qinfo->qname_len; key.namelabs = dname_count_labels(qinfo->qname); ld = (struct local_data*)rbtree_search(&z->data, &key.node); + if(ld == NULL && dname_is_wild(z->name)) { + key.name = z->name; + key.namelen = z->namelen; + key.namelabs = z->namelabs; + ld = (struct local_data*)rbtree_search(&z->data, &key.node); + /* rpz_synthesize_localdata_from_rrset is going to make + * the rrset source name equal to the query name. So no need + * to make the wildcard rrset here. */ + } if(ld == NULL) { verbose(VERB_ALGO, "rpz: qname: name not found"); return NULL; diff --git a/testdata/rpz_cname_wild.rpl b/testdata/rpz_cname_wild.rpl new file mode 100644 index 000000000..ce7200acc --- /dev/null +++ b/testdata/rpz_cname_wild.rpl @@ -0,0 +1,190 @@ +; 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" + 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. +*.gotham5.a CNAME static.gotham6.a. +*.gotham7.a.rpz-nsdname CNAME static.gotham8.a. +TEMPFILE_END + +stub-zone: + name: "a." + stub-addr: 10.20.30.40 +CONFIG_END + +SCENARIO_BEGIN Test RPZ with CNAME with a wildcarded qname trigger after it. + +; a. +RANGE_BEGIN 0 100 + ADDRESS 10.20.30.40 +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +gotham.a. IN NS +SECTION AUTHORITY +gotham.a. NS ns1.gotham.a. +SECTION ADDITIONAL +ns1.gotham.a. A 10.20.30.41 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +gotham2.a. IN NS +SECTION AUTHORITY +gotham2.a. NS ns1.gotham2.a. +SECTION ADDITIONAL +ns1.gotham2.a. A 10.20.30.42 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +gotham6.a. IN NS +SECTION AUTHORITY +gotham6.a. NS ns1.gotham6.a. +SECTION ADDITIONAL +ns1.gotham6.a. A 10.20.30.46 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +gotham7.a. IN NS +SECTION AUTHORITY +gotham7.a. NS ns1.gotham7.a. +SECTION ADDITIONAL +ns1.gotham7.a. A 10.20.30.47 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR NOERROR +SECTION QUESTION +gotham8.a. IN NS +SECTION AUTHORITY +gotham8.a. NS ns1.gotham8.a. +SECTION ADDITIONAL +ns1.gotham8.a. A 10.20.30.48 +ENTRY_END +RANGE_END + +; gotham.a. +RANGE_BEGIN 0 100 + ADDRESS 10.20.30.41 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.gotham.a. IN A +SECTION ANSWER +www.gotham.a. CNAME host.gotham5.a. +ENTRY_END +RANGE_END + +; gotham2.a. +RANGE_BEGIN 0 100 + ADDRESS 10.20.30.42 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.gotham2.a. IN A +SECTION ANSWER +www.gotham2.a. CNAME host.gotham7.a. +ENTRY_END +RANGE_END + +; gotham6.a. +RANGE_BEGIN 0 100 + ADDRESS 10.20.30.46 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +static.gotham6.a. IN A +SECTION ANSWER +static.gotham6.a. A 1.2.3.4 +ENTRY_END +RANGE_END + +; gotham8.a. +RANGE_BEGIN 0 100 + ADDRESS 10.20.30.48 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +static.gotham8.a. IN A +SECTION ANSWER +static.gotham8.a. A 1.2.3.5 +ENTRY_END +RANGE_END + +STEP 10 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.gotham.a. IN A +ENTRY_END + +STEP 20 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.gotham.a. IN A +SECTION ANSWER +www.gotham.a. CNAME host.gotham5.a. +host.gotham5.a CNAME static.gotham6.a. +static.gotham6.a. A 1.2.3.4 +ENTRY_END + +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.gotham2.a. IN A +ENTRY_END + +STEP 40 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.gotham2.a. IN A +SECTION ANSWER +www.gotham2.a. CNAME host.gotham7.a. +host.gotham7.a CNAME static.gotham8.a. +static.gotham8.a. A 1.2.3.5 +ENTRY_END + +SCENARIO_END