]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Added new static zone type block_a to suppress all A queries for specific zones 819/head
authorPavel Odintsov <pavel.odintsov@gmail.com>
Tue, 3 Jan 2023 16:44:10 +0000 (16:44 +0000)
committerPavel Odintsov <pavel.odintsov@gmail.com>
Tue, 3 Jan 2023 19:17:51 +0000 (19:17 +0000)
doc/example.conf.in
doc/unbound.conf.5.in
services/localzone.c
services/localzone.h
util/configparser.y

index 47c3c48912afb8576fc37ea9c7a59ce947695c0b..07dbce4e92637a5e30624ede69b4e407e4efcb24 100644 (file)
@@ -810,6 +810,8 @@ server:
        # o always_transparent, always_refuse, always_nxdomain, always_nodata,
        #   always_deny resolve in that way but ignore local data for
        #   that name
+       # o block_a resolves all records normally but returns
+       #   NODATA for A queries and ignores 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.
        #
index 572ebc34f9e0a26c6961f57b49e0457746483c77..0d5fb27bbfc3ef2280bd07619fcf4e62c4c94d9e 100644 (file)
@@ -1391,10 +1391,10 @@ address space are not validated.  This is usually required whenever
 Configure a local zone. The type determines the answer to give if
 there is no match from local\-data. The types are deny, refuse, static,
 transparent, redirect, nodefault, typetransparent, inform, inform_deny,
-inform_redirect, always_transparent, always_refuse, always_nxdomain, always_null, noview,
-and are explained below. After that the default settings are listed. Use
-local\-data: to enter data into the local zone. Answers for local zones
-are authoritative DNS answers. By default the zones are class IN.
+inform_redirect, always_transparent, block_a, always_refuse, always_nxdomain,
+always_null, noview, and are explained below. After that the default settings
+are listed. Use local\-data: to enter data into the local zone. Answers for
+local zones are authoritative DNS answers. By default the zones are class IN.
 .IP
 If you need more complicated authoritative data, with referrals, wildcards,
 CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for
@@ -1469,6 +1469,12 @@ Ie. answer queries with fixed data and also log the machines that ask.
 \h'5'\fIalways_transparent\fR
 Like transparent, but ignores local data and resolves normally.
 .TP 10
+\h'5'\fIblock_a\fR
+Like transparent, but ignores local data and resolves normally all query
+types excluding A. For A queries it unconditionally returns NODATA.
+Useful in cases when there is a need to explicitly force all apps to use
+IPv6 protocol and avoid any queries to IPv4.
+.TP 10
 \h'5'\fIalways_refuse\fR
 Like refuse, but ignores local data and refuses the query.
 .TP 10
index 3536b7aaa91b9c8cd1985522c720d5a37f96d6fa..996acdbf9133a70638b4a7e21cfba4028f796b4c 100644 (file)
@@ -1603,7 +1603,7 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
        struct local_data key;
        struct local_data* ld = NULL;
        struct local_rrset* lr = NULL;
-       if(z->type == local_zone_always_transparent)
+       if(z->type == local_zone_always_transparent || z->type == local_zone_block_a)
                return 1;
        if(z->type != local_zone_transparent
                && z->type != local_zone_typetransparent
@@ -1679,6 +1679,16 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
        } else if(lz_type == local_zone_typetransparent
                || lz_type == local_zone_always_transparent) {
                /* no NODATA or NXDOMAINS for this zone type */
+               return 0;
+       } else if(lz_type == local_zone_block_a) {
+               // Return NODATA for all A queries
+               if(qinfo->qtype == LDNS_RR_TYPE_A) {
+                       local_error_encode(qinfo, env, edns, repinfo, buf, temp,
+                               LDNS_RCODE_NOERROR, (LDNS_RCODE_NOERROR|BIT_AA),
+                               LDNS_EDE_NONE, NULL);
+                               return 1;
+               }
+
                return 0;
        } else if(lz_type == local_zone_always_null) {
                /* 0.0.0.0 or ::0 or noerror/nodata for this zone type,
@@ -1846,7 +1856,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
                if(z && (lzt == local_zone_transparent ||
                        lzt == local_zone_typetransparent ||
                        lzt == local_zone_inform ||
-                       lzt == local_zone_always_transparent) &&
+                       lzt == local_zone_always_transparent ||
+                       lzt == local_zone_block_a) &&
                        local_zone_does_not_cover(z, qinfo, labs)) {
                        lock_rw_unlock(&z->lock);
                        z = NULL;
@@ -1894,6 +1905,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
 
        if(lzt != local_zone_always_refuse
                && lzt != local_zone_always_transparent
+               && lzt != local_zone_block_a
                && lzt != local_zone_always_nxdomain
                && lzt != local_zone_always_nodata
                && lzt != local_zone_always_deny
@@ -1924,6 +1936,7 @@ const char* local_zone_type2str(enum localzone_type t)
                case local_zone_inform_deny: return "inform_deny";
                case local_zone_inform_redirect: return "inform_redirect";
                case local_zone_always_transparent: return "always_transparent";
+               case local_zone_block_a: return "block_a";
                case local_zone_always_refuse: return "always_refuse";
                case local_zone_always_nxdomain: return "always_nxdomain";
                case local_zone_always_nodata: return "always_nodata";
@@ -1958,6 +1971,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
                *t = local_zone_inform_redirect;
        else if(strcmp(type, "always_transparent") == 0)
                *t = local_zone_always_transparent;
+       else if(strcmp(type, "block_a") == 0)
+               *t = local_zone_block_a;
        else if(strcmp(type, "always_refuse") == 0)
                *t = local_zone_always_refuse;
        else if(strcmp(type, "always_nxdomain") == 0)
index 19534f7509ed37ed8883a7f844d2aa66cb566457..4456893ee1124b1a329726459c7de7e50607c5f4 100644 (file)
@@ -88,6 +88,8 @@ enum localzone_type {
        local_zone_inform_redirect,
        /** resolve normally, even when there is local data */  
        local_zone_always_transparent,
+       /** resolve normally, even when there is local data but return NODATA for A queries */
+       local_zone_block_a,
        /** answer with error, even when there is local data */ 
        local_zone_always_refuse,
        /** answer with nxdomain, even when there is local data */
index f21c30815b3f8c2c3a04b02db6fc7c5d248cffa0..56d97e82e12bcccfe716b942806310823bc71d50 100644 (file)
@@ -2206,6 +2206,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
                   strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0
                   && strcmp($3, "typetransparent")!=0
                   && strcmp($3, "always_transparent")!=0
+                  && strcmp($3, "block_a")!=0
                   && strcmp($3, "always_refuse")!=0
                   && strcmp($3, "always_nxdomain")!=0
                   && strcmp($3, "always_nodata")!=0
@@ -2218,7 +2219,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
                        yyerror("local-zone type: expected static, deny, "
                                "refuse, redirect, transparent, "
                                "typetransparent, inform, inform_deny, "
-                               "inform_redirect, always_transparent, "
+                               "inform_redirect, always_transparent, block_a,"
                                "always_refuse, always_nxdomain, "
                                "always_nodata, always_deny, always_null, "
                                "noview, nodefault or ipset");