From 0c935402a1b1bd34a2f5664a84480206cb267cf0 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 13 May 2025 14:49:08 +0000 Subject: [PATCH] import UBI unbound-1.16.2-17.el9 --- SOURCES/module-setup.sh | 44 ++++ SOURCES/tmpfiles-unbound.conf | 2 +- SOURCES/unbound-1.16-control-t-flag.patch | 129 +++++++++++ SOURCES/unbound-1.21-CVE-2024-8508.patch | 249 ---------------------- SOURCES/unbound-as112-networks.conf | 118 ++++++++++ SOURCES/unbound-initrd.conf | 5 + SOURCES/unbound-local-root.conf | 30 +++ SOURCES/unbound.conf | 42 ++-- SOURCES/unbound.service | 4 +- SOURCES/unbound.sysusers | 1 + SPECS/unbound.spec | 90 ++++++-- 11 files changed, 428 insertions(+), 286 deletions(-) create mode 100644 SOURCES/module-setup.sh create mode 100644 SOURCES/unbound-1.16-control-t-flag.patch delete mode 100644 SOURCES/unbound-1.21-CVE-2024-8508.patch create mode 100644 SOURCES/unbound-as112-networks.conf create mode 100644 SOURCES/unbound-initrd.conf create mode 100644 SOURCES/unbound-local-root.conf create mode 100644 SOURCES/unbound.sysusers diff --git a/SOURCES/module-setup.sh b/SOURCES/module-setup.sh new file mode 100644 index 0000000..439bc6d --- /dev/null +++ b/SOURCES/module-setup.sh @@ -0,0 +1,44 @@ +#!/usr/bin/bash + +check() { + require_binaries unbound unbound-checkconf unbound-control || return 1 + # the module will be only included if explicitly required either + # by configuration or another module + return 255 +} + +depends() { + # because of pid file we need sysusers to create unbound user + echo systemd systemd-sysusers + return 0 +} + +install() { + # We have to make unbound wanted by network-online target to make sure + # there is a synchronization point when other services are able + # to make queries + inst_simple "$moddir"/unbound-initrd.conf /etc/systemd/system/unbound.service.d/unbound-initrd.conf + + # /etc and /var/lib do not have its variables + inst_multiple -o \ + "$systemdsystemunitdir"/unbound.service \ + /etc/unbound/conf.d/remote-control.conf \ + /etc/unbound/openssl-sha1.conf \ + /usr/share/unbound/fedora-defaults.conf \ + /usr/share/unbound/conf.d/*.conf \ + /etc/unbound/local.d/*.conf \ + /etc/unbound/keys.d/*.key \ + /etc/unbound/unbound.conf \ + /etc/unbound/unbound_control.key \ + /etc/unbound/unbound_control.pem \ + /etc/unbound/unbound_server.key \ + /etc/unbound/unbound_server.pem \ + "$sysusers"/unbound.conf \ + "$tmpfilesdir"/unbound.conf \ + /var/lib/unbound/root.key \ + unbound \ + unbound-checkconf \ + unbound-control + + $SYSTEMCTL -q --root "$initdir" enable unbound.service +} diff --git a/SOURCES/tmpfiles-unbound.conf b/SOURCES/tmpfiles-unbound.conf index bb88f01..c09cc75 100644 --- a/SOURCES/tmpfiles-unbound.conf +++ b/SOURCES/tmpfiles-unbound.conf @@ -1 +1 @@ -D /run/unbound 0755 unbound unbound - +D /run/unbound 0775 unbound root - diff --git a/SOURCES/unbound-1.16-control-t-flag.patch b/SOURCES/unbound-1.16-control-t-flag.patch new file mode 100644 index 0000000..581db24 --- /dev/null +++ b/SOURCES/unbound-1.16-control-t-flag.patch @@ -0,0 +1,129 @@ +commit 6d1e61173bbf44dae458c361be63217f7e9e5599 +Author: W.C.A. Wijngaards +Date: Thu Mar 28 09:58:03 2024 +0100 + + - Fix #1034: DoT forward-zone via unbound-control. + +diff --git a/unbound-1.16.2/daemon/remote.c b/unbound-1.16.2/daemon/remote.c +index 5d79eafd..cbce1198 100644 +--- a/unbound-1.16.2/daemon/remote.c ++++ b/unbound-1.16.2/daemon/remote.c +@@ -2097,7 +2097,7 @@ do_forward(RES* ssl, struct worker* worker, char* args) + + static int + parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp, +- int* insecure, int* prime) ++ int* insecure, int* prime, int* tls) + { + char* zonename; + char* rest; +@@ -2112,6 +2112,8 @@ parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp, + *insecure = 1; + else if(*args == 'p' && prime) + *prime = 1; ++ else if(*args == 't' && tls) ++ *tls = 1; + else { + (void)ssl_printf(ssl, "error: unknown option %s\n", args); + return 0; +@@ -2144,11 +2146,13 @@ static void + do_forward_add(RES* ssl, struct worker* worker, char* args) + { + struct iter_forwards* fwd = worker->env.fwds; +- int insecure = 0; ++ int insecure = 0, tls = 0; + uint8_t* nm = NULL; + struct delegpt* dp = NULL; +- if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL)) ++ if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL, &tls)) + return; ++ if(tls) ++ dp->ssl_upstream = 1; + if(insecure && worker->env.anchors) { + if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, + nm)) { +@@ -2174,7 +2178,7 @@ do_forward_remove(RES* ssl, struct worker* worker, char* args) + struct iter_forwards* fwd = worker->env.fwds; + int insecure = 0; + uint8_t* nm = NULL; +- if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) ++ if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL)) + return; + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, +@@ -2189,11 +2193,13 @@ static void + do_stub_add(RES* ssl, struct worker* worker, char* args) + { + struct iter_forwards* fwd = worker->env.fwds; +- int insecure = 0, prime = 0; ++ int insecure = 0, prime = 0, tls = 0; + uint8_t* nm = NULL; + struct delegpt* dp = NULL; +- if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime)) ++ if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime, &tls)) + return; ++ if(tls) ++ dp->ssl_upstream = 1; + if(insecure && worker->env.anchors) { + if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, + nm)) { +@@ -2232,7 +2238,7 @@ do_stub_remove(RES* ssl, struct worker* worker, char* args) + struct iter_forwards* fwd = worker->env.fwds; + int insecure = 0; + uint8_t* nm = NULL; +- if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) ++ if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL, NULL)) + return; + if(insecure && worker->env.anchors) + anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, +diff --git a/unbound-1.16.2/doc/unbound-control.8.in b/unbound-1.16.2/doc/unbound-control.8.in +index 7823de3a..642b4c94 100644 +--- a/unbound-1.16.2/doc/unbound-control.8.in ++++ b/unbound-1.16.2/doc/unbound-control.8.in +@@ -239,22 +239,24 @@ still be bogus, use \fBflush_zone\fR to remove it), does not affect the config f + .B insecure_remove \fIzone + Removes domain\-insecure for the given zone. + .TP +-.B forward_add \fR[\fI+i\fR] \fIzone addr ... ++.B forward_add \fR[\fI+it\fR] \fIzone addr ... + Add a new forward zone to running Unbound. With +i option also adds a + \fIdomain\-insecure\fR for the zone (so it can resolve insecurely if you have + a DNSSEC root trust anchor configured for other names). + The addr can be IP4, IP6 or nameserver names, like \fIforward-zone\fR config + in unbound.conf. ++The +t option sets it to use tls upstream, like \fIforward\-tls\-upstream\fR: yes. + .TP + .B forward_remove \fR[\fI+i\fR] \fIzone + Remove a forward zone from running Unbound. The +i also removes a + \fIdomain\-insecure\fR for the zone. + .TP +-.B stub_add \fR[\fI+ip\fR] \fIzone addr ... ++.B stub_add \fR[\fI+ipt\fR] \fIzone addr ... + Add a new stub zone to running Unbound. With +i option also adds a + \fIdomain\-insecure\fR for the zone. With +p the stub zone is set to prime, + without it it is set to notprime. The addr can be IP4, IP6 or nameserver + names, like the \fIstub-zone\fR config in unbound.conf. ++The +t option sets it to use tls upstream, like \fIstub\-tls\-upstream\fR: yes. + .TP + .B stub_remove \fR[\fI+i\fR] \fIzone + Remove a stub zone from running Unbound. The +i also removes a +diff --git a/unbound-1.16.2/smallapp/unbound-control.c b/unbound-1.16.2/smallapp/unbound-control.c +index c4f73006..57b0787d 100644 +--- a/unbound-1.16.2/smallapp/unbound-control.c ++++ b/unbound-1.16.2/smallapp/unbound-control.c +@@ -150,12 +150,13 @@ usage(void) + printf(" list_local_data list local-data RRs in use\n"); + printf(" insecure_add zone add domain-insecure zone\n"); + printf(" insecure_remove zone remove domain-insecure zone\n"); +- printf(" forward_add [+i] zone addr.. add forward-zone with servers\n"); ++ printf(" forward_add [+it] zone addr.. add forward-zone with servers\n"); + printf(" forward_remove [+i] zone remove forward zone\n"); +- printf(" stub_add [+ip] zone addr.. add stub-zone with servers\n"); ++ printf(" stub_add [+ipt] zone addr.. add stub-zone with servers\n"); + printf(" stub_remove [+i] zone remove stub zone\n"); + printf(" +i also do dnssec insecure point\n"); + printf(" +p set stub to use priming\n"); ++ printf(" +t set to use tls upstream\n"); + printf(" forward [off | addr ...] without arg show forward setup\n"); + printf(" or off to turn off root forwarding\n"); + printf(" or give list of ip addresses\n"); diff --git a/SOURCES/unbound-1.21-CVE-2024-8508.patch b/SOURCES/unbound-1.21-CVE-2024-8508.patch deleted file mode 100644 index 36b3cdd..0000000 --- a/SOURCES/unbound-1.21-CVE-2024-8508.patch +++ /dev/null @@ -1,249 +0,0 @@ -From 34de24d58bb5aa6fe3551512fc17cac08f65d93e Mon Sep 17 00:00:00 2001 -From: Yorgos Thessalonikefs -Date: Thu, 3 Oct 2024 14:46:57 +0200 -Subject: [PATCH] - Fix CVE-2024-8508, unbounded name compression could lead to - denial of service. - ---- - unbound-1.16.2/util/data/msgencode.c | 77 +++++++++++++++++----------- - 1 file changed, 46 insertions(+), 31 deletions(-) - -diff --git a/unbound-1.16.2/util/data/msgencode.c b/unbound-1.16.2/util/data/msgencode.c -index fe21cfb..f9e95e6 100644 ---- a/unbound-1.16.2/util/data/msgencode.c -+++ b/unbound-1.16.2/util/data/msgencode.c -@@ -62,6 +62,10 @@ - #define RETVAL_TRUNC -4 - /** return code that means all is peachy keen. Equal to DNS rcode NOERROR */ - #define RETVAL_OK 0 -+/** Max compressions we are willing to perform; more than that will result -+ * in semi-compressed messages, or truncated even on TCP for huge messages, to -+ * avoid locking the CPU for long */ -+#define MAX_COMPRESSION_PER_MESSAGE 120 - - /** - * Data structure to help domain name compression in outgoing messages. -@@ -284,15 +288,17 @@ write_compressed_dname(sldns_buffer* pkt, uint8_t* dname, int labs, - - /** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */ - static int --compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, -- struct regional* region, struct compress_tree_node** tree, -- size_t owner_pos, uint16_t* owner_ptr, int owner_labs) -+compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, -+ struct regional* region, struct compress_tree_node** tree, -+ size_t owner_pos, uint16_t* owner_ptr, int owner_labs, -+ size_t* compress_count) - { - struct compress_tree_node* p; - struct compress_tree_node** insertpt = NULL; - if(!*owner_ptr) { - /* compress first time dname */ -- if((p = compress_tree_lookup(tree, key->rk.dname, -+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE && -+ (p = compress_tree_lookup(tree, key->rk.dname, - owner_labs, &insertpt))) { - if(p->labs == owner_labs) - /* avoid ptr chains, since some software is -@@ -301,6 +307,7 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - if(!write_compressed_dname(pkt, key->rk.dname, - owner_labs, p)) - return RETVAL_TRUNC; -+ (*compress_count)++; - /* check if typeclass+4 ttl + rdatalen is available */ - if(sldns_buffer_remaining(pkt) < 4+4+2) - return RETVAL_TRUNC; -@@ -313,7 +320,8 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - if(owner_pos <= PTR_MAX_OFFSET) - *owner_ptr = htons(PTR_CREATE(owner_pos)); - } -- if(!compress_tree_store(key->rk.dname, owner_labs, -+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE && -+ !compress_tree_store(key->rk.dname, owner_labs, - owner_pos, region, p, insertpt)) - return RETVAL_OUTMEM; - } else { -@@ -333,20 +341,24 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - - /** compress any domain name to the packet, return RETVAL_* */ - static int --compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs, -- struct regional* region, struct compress_tree_node** tree) -+compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs, -+ struct regional* region, struct compress_tree_node** tree, -+ size_t* compress_count) - { - struct compress_tree_node* p; - struct compress_tree_node** insertpt = NULL; - size_t pos = sldns_buffer_position(pkt); -- if((p = compress_tree_lookup(tree, dname, labs, &insertpt))) { -+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE && -+ (p = compress_tree_lookup(tree, dname, labs, &insertpt))) { - if(!write_compressed_dname(pkt, dname, labs, p)) - return RETVAL_TRUNC; -+ (*compress_count)++; - } else { - if(!dname_buffer_write(pkt, dname)) - return RETVAL_TRUNC; - } -- if(!compress_tree_store(dname, labs, pos, region, p, insertpt)) -+ if(*compress_count < MAX_COMPRESSION_PER_MESSAGE && -+ !compress_tree_store(dname, labs, pos, region, p, insertpt)) - return RETVAL_OUTMEM; - return RETVAL_OK; - } -@@ -364,9 +376,9 @@ type_rdata_compressable(struct ub_packed_rrset_key* key) - - /** compress domain names in rdata, return RETVAL_* */ - static int --compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen, -- struct regional* region, struct compress_tree_node** tree, -- const sldns_rr_descriptor* desc) -+compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen, -+ struct regional* region, struct compress_tree_node** tree, -+ const sldns_rr_descriptor* desc, size_t* compress_count) - { - int labs, r, rdf = 0; - size_t dname_len, len, pos = sldns_buffer_position(pkt); -@@ -380,8 +392,8 @@ compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen, - switch(desc->_wireformat[rdf]) { - case LDNS_RDF_TYPE_DNAME: - labs = dname_count_size_labels(rdata, &dname_len); -- if((r=compress_any_dname(rdata, pkt, labs, region, -- tree)) != RETVAL_OK) -+ if((r=compress_any_dname(rdata, pkt, labs, region, -+ tree, compress_count)) != RETVAL_OK) - return r; - rdata += dname_len; - todolen -= dname_len; -@@ -449,7 +461,8 @@ static int - packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - uint16_t* num_rrs, time_t timenow, struct regional* region, - int do_data, int do_sig, struct compress_tree_node** tree, -- sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset) -+ sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset, -+ size_t* compress_count) - { - size_t i, j, owner_pos; - int r, owner_labs; -@@ -477,9 +490,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - for(i=0; icount; i++) { - /* rrset roundrobin */ - j = (i + rr_offset) % data->count; -- if((r=compress_owner(key, pkt, region, tree, -- owner_pos, &owner_ptr, owner_labs)) -- != RETVAL_OK) -+ if((r=compress_owner(key, pkt, region, tree, -+ owner_pos, &owner_ptr, owner_labs, -+ compress_count)) != RETVAL_OK) - return r; - sldns_buffer_write(pkt, &key->rk.type, 2); - sldns_buffer_write(pkt, &key->rk.rrset_class, 2); -@@ -489,8 +502,8 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust); - if(c) { - if((r=compress_rdata(pkt, data->rr_data[j], -- data->rr_len[j], region, tree, c)) -- != RETVAL_OK) -+ data->rr_len[j], region, tree, c, -+ compress_count)) != RETVAL_OK) - return r; - } else { - if(sldns_buffer_remaining(pkt) < data->rr_len[j]) -@@ -510,9 +523,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt, - return RETVAL_TRUNC; - sldns_buffer_write(pkt, &owner_ptr, 2); - } else { -- if((r=compress_any_dname(key->rk.dname, -- pkt, owner_labs, region, tree)) -- != RETVAL_OK) -+ if((r=compress_any_dname(key->rk.dname, -+ pkt, owner_labs, region, tree, -+ compress_count)) != RETVAL_OK) - return r; - if(sldns_buffer_remaining(pkt) < - 4+4+data->rr_len[i]) -@@ -544,7 +557,8 @@ static int - insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, - sldns_buffer* pkt, size_t rrsets_before, time_t timenow, - struct regional* region, struct compress_tree_node** tree, -- sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset) -+ sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset, -+ size_t* compress_count) - { - int r; - size_t i, setstart; -@@ -560,7 +574,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, - setstart = sldns_buffer_position(pkt); - if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], - pkt, num_rrs, timenow, region, 1, 1, tree, -- s, qtype, dnssec, rr_offset)) -+ s, qtype, dnssec, rr_offset, compress_count)) - != RETVAL_OK) { - /* Bad, but if due to size must set TC bit */ - /* trim off the rrset neatly. */ -@@ -573,7 +587,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, - setstart = sldns_buffer_position(pkt); - if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], - pkt, num_rrs, timenow, region, 1, 0, tree, -- s, qtype, dnssec, rr_offset)) -+ s, qtype, dnssec, rr_offset, compress_count)) - != RETVAL_OK) { - sldns_buffer_set_position(pkt, setstart); - return r; -@@ -584,7 +598,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs, - setstart = sldns_buffer_position(pkt); - if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i], - pkt, num_rrs, timenow, region, 0, 1, tree, -- s, qtype, dnssec, rr_offset)) -+ s, qtype, dnssec, rr_offset, compress_count)) - != RETVAL_OK) { - sldns_buffer_set_position(pkt, setstart); - return r; -@@ -677,6 +691,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - struct compress_tree_node* tree = 0; - int r; - size_t rr_offset; -+ size_t compress_count=0; - - sldns_buffer_clear(buffer); - if(udpsize < sldns_buffer_limit(buffer)) -@@ -723,7 +738,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - arep.rrsets = &qinfo->local_alias->rrset; - if((r=insert_section(&arep, 1, &ancount, buffer, 0, - timezero, region, &tree, LDNS_SECTION_ANSWER, -- qinfo->qtype, dnssec, rr_offset)) != RETVAL_OK) { -+ qinfo->qtype, dnssec, rr_offset, &compress_count)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* create truncated message */ - sldns_buffer_write_u16_at(buffer, 6, ancount); -@@ -738,7 +753,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - /* insert answer section */ - if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer, - 0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype, -- dnssec, rr_offset)) != RETVAL_OK) { -+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* create truncated message */ - sldns_buffer_write_u16_at(buffer, 6, ancount); -@@ -756,7 +771,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer, - rep->an_numrrsets, timenow, region, &tree, - LDNS_SECTION_AUTHORITY, qinfo->qtype, -- dnssec, rr_offset)) != RETVAL_OK) { -+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* create truncated message */ - sldns_buffer_write_u16_at(buffer, 8, nscount); -@@ -773,7 +788,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep, - if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer, - rep->an_numrrsets + rep->ns_numrrsets, timenow, region, - &tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype, -- dnssec, rr_offset)) != RETVAL_OK) { -+ dnssec, rr_offset, &compress_count)) != RETVAL_OK) { - if(r == RETVAL_TRUNC) { - /* no need to set TC bit, this is the additional */ - sldns_buffer_write_u16_at(buffer, 10, arcount); --- -2.47.0 - diff --git a/SOURCES/unbound-as112-networks.conf b/SOURCES/unbound-as112-networks.conf new file mode 100644 index 0000000..96c291f --- /dev/null +++ b/SOURCES/unbound-as112-networks.conf @@ -0,0 +1,118 @@ +# Allow forwarding of private ranges, which are marked forwardable by IANA +# https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml +# https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml +# https://www.iana.org/assignments/special-use-domain-names/special-use-domain-names.xhtml +# RFC 6303: Locally Served DNS Zones (https://www.rfc-editor.org/rfc/rfc6303.html) +# +# Using this configuration file will simplify forwarding to potentially private ranges. +# Enables forwarding of networks marked as forwardable at IANA special registry. +# This is useful when upstream forwarder may be still inside private network. That is the case +# when unbound works as a localhost DNS cache, not network wide resolver. + +server: + # RFC 8375: Special-Use Domain 'home.arpa.' + local-zone: "home.arpa." nodefault + + # RFC 1918: Address Allocation for Private Internets + local-zone: "10.in-addr.arpa." nodefault + local-zone: "16.172.in-addr.arpa." nodefault + local-zone: "17.172.in-addr.arpa." nodefault + local-zone: "18.172.in-addr.arpa." nodefault + local-zone: "19.172.in-addr.arpa." nodefault + local-zone: "20.172.in-addr.arpa." nodefault + local-zone: "21.172.in-addr.arpa." nodefault + local-zone: "22.172.in-addr.arpa." nodefault + local-zone: "23.172.in-addr.arpa." nodefault + local-zone: "24.172.in-addr.arpa." nodefault + local-zone: "25.172.in-addr.arpa." nodefault + local-zone: "26.172.in-addr.arpa." nodefault + local-zone: "27.172.in-addr.arpa." nodefault + local-zone: "28.172.in-addr.arpa." nodefault + local-zone: "29.172.in-addr.arpa." nodefault + local-zone: "30.172.in-addr.arpa." nodefault + local-zone: "31.172.in-addr.arpa." nodefault + local-zone: "168.192.in-addr.arpa." nodefault + # RFC 6598: IANA-Reserved IPv4 Prefix for Shared Address Space + local-zone: "64.100.in-addr.arpa." nodefault + local-zone: "65.100.in-addr.arpa." nodefault + local-zone: "66.100.in-addr.arpa." nodefault + local-zone: "67.100.in-addr.arpa." nodefault + local-zone: "68.100.in-addr.arpa." nodefault + local-zone: "69.100.in-addr.arpa." nodefault + local-zone: "70.100.in-addr.arpa." nodefault + local-zone: "71.100.in-addr.arpa." nodefault + local-zone: "72.100.in-addr.arpa." nodefault + local-zone: "73.100.in-addr.arpa." nodefault + local-zone: "74.100.in-addr.arpa." nodefault + local-zone: "75.100.in-addr.arpa." nodefault + local-zone: "76.100.in-addr.arpa." nodefault + local-zone: "77.100.in-addr.arpa." nodefault + local-zone: "78.100.in-addr.arpa." nodefault + local-zone: "79.100.in-addr.arpa." nodefault + local-zone: "80.100.in-addr.arpa." nodefault + local-zone: "81.100.in-addr.arpa." nodefault + local-zone: "82.100.in-addr.arpa." nodefault + local-zone: "83.100.in-addr.arpa." nodefault + local-zone: "84.100.in-addr.arpa." nodefault + local-zone: "85.100.in-addr.arpa." nodefault + local-zone: "86.100.in-addr.arpa." nodefault + local-zone: "87.100.in-addr.arpa." nodefault + local-zone: "88.100.in-addr.arpa." nodefault + local-zone: "89.100.in-addr.arpa." nodefault + local-zone: "90.100.in-addr.arpa." nodefault + local-zone: "91.100.in-addr.arpa." nodefault + local-zone: "92.100.in-addr.arpa." nodefault + local-zone: "93.100.in-addr.arpa." nodefault + local-zone: "94.100.in-addr.arpa." nodefault + local-zone: "95.100.in-addr.arpa." nodefault + local-zone: "96.100.in-addr.arpa." nodefault + local-zone: "97.100.in-addr.arpa." nodefault + local-zone: "98.100.in-addr.arpa." nodefault + local-zone: "99.100.in-addr.arpa." nodefault + local-zone: "100.100.in-addr.arpa." nodefault + local-zone: "101.100.in-addr.arpa." nodefault + local-zone: "102.100.in-addr.arpa." nodefault + local-zone: "103.100.in-addr.arpa." nodefault + local-zone: "104.100.in-addr.arpa." nodefault + local-zone: "105.100.in-addr.arpa." nodefault + local-zone: "106.100.in-addr.arpa." nodefault + local-zone: "107.100.in-addr.arpa." nodefault + local-zone: "108.100.in-addr.arpa." nodefault + local-zone: "109.100.in-addr.arpa." nodefault + local-zone: "110.100.in-addr.arpa." nodefault + local-zone: "111.100.in-addr.arpa." nodefault + local-zone: "112.100.in-addr.arpa." nodefault + local-zone: "113.100.in-addr.arpa." nodefault + local-zone: "114.100.in-addr.arpa." nodefault + local-zone: "115.100.in-addr.arpa." nodefault + local-zone: "116.100.in-addr.arpa." nodefault + local-zone: "117.100.in-addr.arpa." nodefault + local-zone: "118.100.in-addr.arpa." nodefault + local-zone: "119.100.in-addr.arpa." nodefault + local-zone: "120.100.in-addr.arpa." nodefault + local-zone: "121.100.in-addr.arpa." nodefault + local-zone: "122.100.in-addr.arpa." nodefault + local-zone: "123.100.in-addr.arpa." nodefault + local-zone: "124.100.in-addr.arpa." nodefault + local-zone: "125.100.in-addr.arpa." nodefault + local-zone: "126.100.in-addr.arpa." nodefault + local-zone: "127.100.in-addr.arpa." nodefault + + # RFC 4193: Unique Local IPv6 Unicast Addresses + local-zone: "d.f.ip6.arpa." nodefault + + # RFC 2606: Reserved Top Level DNS Names + local-zone: "test." nodefault + domain-insecure: "test" + domain-insecure: "example" + + # RFC 6762: Multicast DNS, Appendix G + domain-insecure: "local" + domain-insecure: "intranet" + domain-insecure: "private" + domain-insecure: "corp" + domain-insecure: "home" + domain-insecure: "lan" + + # draft-davies-internal-tld + domain-insecure: "internal" diff --git a/SOURCES/unbound-initrd.conf b/SOURCES/unbound-initrd.conf new file mode 100644 index 0000000..7838b3d --- /dev/null +++ b/SOURCES/unbound-initrd.conf @@ -0,0 +1,5 @@ +[Unit] +Before=network-online.target + +[Install] +WantedBy=network-online.target diff --git a/SOURCES/unbound-local-root.conf b/SOURCES/unbound-local-root.conf new file mode 100644 index 0000000..4ba5e9d --- /dev/null +++ b/SOURCES/unbound-local-root.conf @@ -0,0 +1,30 @@ +# Authority zones +# The data for these zones is kept locally, from a file or downloaded. +# The data can be served to downstream clients, or used instead of the +# upstream (which saves a lookup to the upstream). +# +# Download local root copy and answer TLD queries from it. Because +# auth-zone has higher precedence, defined forward-zones to internal +# only TLD will not work. Use stub-zone or disable this zone. +# Good for a network-wide resolvers, worse for a localhost caching forwarder. +auth-zone: + name: "." + primary: 170.247.170.2 # 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: 2801:1b8:10::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 diff --git a/SOURCES/unbound.conf b/SOURCES/unbound.conf index 18fad43..803d5ac 100644 --- a/SOURCES/unbound.conf +++ b/SOURCES/unbound.conf @@ -1071,27 +1071,27 @@ include: /etc/unbound/conf.d/*.conf # 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 +#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 # auth-zone: # name: "example.org" diff --git a/SOURCES/unbound.service b/SOURCES/unbound.service index 49dc7bd..ce4aaa9 100644 --- a/SOURCES/unbound.service +++ b/SOURCES/unbound.service @@ -8,10 +8,10 @@ Before=nss-lookup.target Wants=nss-lookup.target [Service] -Type=simple +Type=notify EnvironmentFile=-/etc/sysconfig/unbound ExecStartPre=/usr/sbin/unbound-checkconf -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' +ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_UNBOUND_ANCHOR" == "yes" ] && [ ! -f /run/unbound/anchor-disable ]; 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 diff --git a/SOURCES/unbound.sysusers b/SOURCES/unbound.sysusers new file mode 100644 index 0000000..6614682 --- /dev/null +++ b/SOURCES/unbound.sysusers @@ -0,0 +1 @@ +u unbound - "Unbound DNS resolver" /var/lib/unbound /sbin/nologin diff --git a/SPECS/unbound.spec b/SPECS/unbound.spec index 13c7907..34e7f66 100644 --- a/SPECS/unbound.spec +++ b/SPECS/unbound.spec @@ -2,7 +2,7 @@ %{?!with_python3: %global with_python3 1} %{?!with_munin: %global with_munin 1} %bcond_without dnstap -%bcond_with systemd +%bcond_without systemd %bcond_without doh %global _hardened_build 1 @@ -30,7 +30,7 @@ Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound Version: 1.16.2 -Release: 8%{?extra_version:.%{extra_version}}%{?dist}.1 +Release: 17%{?extra_version:.%{extra_version}}%{?dist} License: BSD Url: https://nlnetlabs.nl/projects/unbound/ Source: https://nlnetlabs.nl/downloads/%{name}/%{name}-%{version}%{?extra_version}.tar.gz @@ -53,13 +53,18 @@ Source17: unbound-anchor.service Source18: https://nlnetlabs.nl/downloads/%{name}/%{name}-%{version}%{?extra_version}.tar.gz.asc Source19: http://keys.gnupg.net/pks/lookup?op=get&search=0x9F6F1C2D7E045F8D#/wouter.nlnetlabs.nl.key Source21: remote-control.conf +Source22: unbound-local-root.conf +Source23: module-setup.sh +Source24: unbound-initrd.conf +Source25: unbound.sysusers +Source26: unbound-as112-networks.conf # https://github.com/NLnetLabs/unbound/commit/137719522a8ea5b380fbb6206d2466f402f5b554 Patch1: unbound-1.16-CVE-2022-3204.patch # https://nlnetlabs.nl/downloads/unbound/patch_CVE-2023-50387_CVE-2023-50868.diff Patch4: unbound-1.16-CVE-2023-50387-CVE-2023-50868.patch -# https://github.com/NLnetLabs/unbound/commit/b7c61d7cc256d6a174e6179622c7fa968272c259 -Patch3: unbound-1.21-CVE-2024-8508.patch +# https://github.com/NLnetLabs/unbound/commit/6d1e61173 +Patch5: unbound-1.16-control-t-flag.patch BuildRequires: gcc, make BuildRequires: flex, openssl-devel @@ -129,7 +134,7 @@ The devel package contains the unbound library and the include files %package libs Summary: Libraries used by the unbound server and client applications -Requires(pre): shadow-utils +%{?sysusers_requires_compat} %if ! 0%{with_python2} # Make explicit conflict with no longer provided python package Obsoletes: python2-unbound < 1.9.3 @@ -163,6 +168,14 @@ Conflicts: python2-unbound < 1.9.3 Python 3 modules and extensions for unbound %endif +%package dracut +Summary: Unbound dracut module +Requires: dracut%{?_isa} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description dracut +Unbound dracut module allowing use of Unbound for name resolution +in initramfs. %prep %if 0%{?fedora} @@ -274,6 +287,7 @@ install -p -m 0644 %{SOURCE17} %{buildroot}%{_unitdir}/unbound-anchor.service install -p -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/unbound install -p -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/unbound install -p -m 0644 %{SOURCE14} %{buildroot}%{_sysconfdir}/sysconfig/unbound +install -p -D -m 0644 %{SOURCE25} %{buildroot}%{_sysusersdir}/%{name}.conf %if %{with_munin} # Install munin plugin and its softlinks install -d -m 0755 %{buildroot}%{_sysconfdir}/munin/plugin-conf.d @@ -300,6 +314,9 @@ install -m 0644 %{SOURCE8} %{buildroot}%{_tmpfilesdir}/unbound.conf install -m 0644 %{SOURCE5} %{buildroot}%{_sysconfdir}/unbound/ install -m 0644 %{SOURCE13} %{buildroot}%{_sharedstatedir}/unbound/root.key +# local root zone fetch to separated configuration file +install -p -m 0644 %{SOURCE22} %{buildroot}%{_sysconfdir}/unbound/ + # remove static library from install (fedora packaging guidelines) rm %{buildroot}%{_libdir}/*.la @@ -321,16 +338,22 @@ install -p %{SOURCE9} %{buildroot}%{_sysconfdir}/unbound/keys.d/ install -p %{SOURCE10} %{buildroot}%{_sysconfdir}/unbound/conf.d/ install -p %{SOURCE11} %{buildroot}%{_sysconfdir}/unbound/local.d/ install -p -m 0644 %{SOURCE21} %{buildroot}%{_sysconfdir}/unbound/conf.d/ +ln -s ../unbound-local-root.conf %{buildroot}%{_sysconfdir}/unbound/conf.d/unbound-local-root.conf + +mkdir -p %{buildroot}%{_datadir}/%{name}/conf.d +install -p -m 0644 %{SOURCE26} %{buildroot}%{_datadir}/%{name}/conf.d/ # Link unbound-control-setup.8 manpage to unbound-control.8 echo ".so man8/unbound-control.8" > %{buildroot}/%{_mandir}/man8/unbound-control-setup.8 +# install dracut module +mkdir -p %{buildroot}%{_prefix}/lib/dracut/modules.d/99unbound + +install -p -m 0755 %{SOURCE23} %{buildroot}%{_prefix}/lib/dracut/modules.d/99unbound +install -p -m 0644 %{SOURCE24} %{buildroot}%{_prefix}/lib/dracut/modules.d/99unbound %pre libs -getent group unbound >/dev/null || groupadd -r unbound -getent passwd unbound >/dev/null || \ -useradd -r -g unbound -d %{_sysconfdir}/unbound -s /sbin/nologin \ --c "Unbound DNS resolver" unbound +%sysusers_create_compat %{SOURCE25} %post %systemd_post unbound.service @@ -382,14 +405,17 @@ popd %doc doc/CREDITS doc/FEATURES %{_unitdir}/%{name}.service %{_unitdir}/%{name}-keygen.service -%attr(0755,unbound,unbound) %dir %{_rundir}/%{name} +%attr(0775,unbound,root) %dir %{_rundir}/%{name} %attr(0644,root,root) %{_tmpfilesdir}/unbound.conf %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound.conf +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound-local-root.conf %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %dir %attr(0755,root,unbound) %{_sysconfdir}/%{name}/keys.d %attr(0644,root,unbound) %config(noreplace) %{_sysconfdir}/%{name}/keys.d/*.key %dir %attr(0755,root,unbound) %{_sysconfdir}/%{name}/conf.d -%attr(0644,root,unbound) %config(noreplace) %{_sysconfdir}/%{name}/conf.d/*.conf +%attr(0644,root,unbound) %config(noreplace) %{_sysconfdir}/%{name}/conf.d/example.com.conf +%attr(0644,root,unbound) %config(noreplace) %{_sysconfdir}/%{name}/conf.d/remote-control.conf +%verify(not mtime) %config(missingok, noreplace) %{_sysconfdir}/%{name}/conf.d/unbound-local-root.conf %dir %attr(0755,root,unbound) %{_sysconfdir}/%{name}/local.d %attr(0644,root,unbound) %config(noreplace) %{_sysconfdir}/%{name}/local.d/*.conf %ghost %attr(0640,root,unbound) %{_sysconfdir}/%{name}/unbound_control.pem @@ -406,6 +432,7 @@ popd %{_mandir}/man5/* %exclude %{_mandir}/man8/unbound-anchor* %{_mandir}/man8/* +%{_datadir}/%{name}/ %if 0%{with_python2} %files -n python2-unbound @@ -441,6 +468,7 @@ popd %doc doc/README %license doc/LICENSE %attr(0755,root,root) %dir %{_sysconfdir}/%{name} +%{_sysusersdir}/%{name}.conf %{_sbindir}/unbound-anchor %{_libdir}/libunbound.so.* %{_mandir}/man8/unbound-anchor* @@ -454,9 +482,45 @@ popd # just left for backwards compat with user changed unbound.conf files - format is different! %attr(0644,root,root) %config %{_sysconfdir}/%{name}/root.key +%files dracut +%{_prefix}/lib/dracut/modules.d/99unbound + %changelog -* Tue Nov 12 2024 Petr Menšík - 1.16.2-8.1 -- Prevent unbounded name compression (CVE-2024-8508) +* Mon Feb 10 2025 Tomas Korbar - 1.16.2-17 +- Add as112 networks config file +- Resolves: RHEL-78696 + +* Mon Feb 10 2025 Tomas Korbar - 1.16.2-16 +- Add possibility to disable unbound-anchor by file presence +- Resolves: RHEL-78694 + +* Sun Feb 09 2025 Tomas Korbar - 1.16.2-15 +- Add sysusers support needed to propagate user to initramfs +- Resolves: RHEL-77789 + +* Sun Feb 09 2025 Tomas Korbar - 1.16.2-14 +- Change service type to notify +- Resolves: RHEL-77790 + +* Wed Feb 05 2025 Tomas Korbar - 1.16.2-13 +- Add noreplace to root zone config link +- Resolves: RHEL-77788 + +* Tue Feb 04 2025 Tomas Korbar - 1.16.2-12 +- Backport +t flag to forward_add and stub_add control commands +- Resolves: RHEL-77791 + +* Tue Feb 04 2025 Tomas Korbar - 1.16.2-11 +- Enabled libsystemd and change unbound service type to notify-reload +- Resolves: RHEL-77790 + +* Tue Feb 04 2025 Tomas Korbar - 1.16.2-10 +- Add dracut module +- Resolves: RHEL-77789 + +* Tue Feb 04 2025 Tomas Korbar - 1.16.2-9 +- Move automatic root zone fetching to drop-in +- Resolves: RHEL-77788 * Mon Mar 11 2024 Petr Menšík - 1.16.2-8 - Ensure group access correction reaches also updated configs (CVE-2024-1488)