From 985c6a75ed5f7098568a05d4fe168ea3084b61ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Wed, 4 Jul 2018 12:38:44 +0200 Subject: [PATCH] Prefer local resolvers over direct root access. Enables successful trust anchor updates also when no direct queries are available, but local resolvers support dnssec. Fixes bug #1598078 --- unbound-1.7.3-anchor-fallback.patch | 182 ++++++++++++++++++++++++++++ unbound-anchor.service | 2 +- unbound.service | 2 +- unbound.spec | 7 +- 4 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 unbound-1.7.3-anchor-fallback.patch diff --git a/unbound-1.7.3-anchor-fallback.patch b/unbound-1.7.3-anchor-fallback.patch new file mode 100644 index 0000000..2470ce1 --- /dev/null +++ b/unbound-1.7.3-anchor-fallback.patch @@ -0,0 +1,182 @@ +From 81e9f82a8ddd811d7ebafe2fd0ee5af836d0b405 Mon Sep 17 00:00:00 2001 +From: Wouter Wijngaards +Date: Wed, 4 Jul 2018 10:02:16 +0000 +Subject: [PATCH] - Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will + not pass if DNSSEC is not enabled. New option -R allows fallback from + resolv.conf to direct queries. + +git-svn-id: file:///svn/unbound/trunk@4770 be551aaa-1e26-0410-a405-d3ace91eadb9 +--- + doc/unbound-anchor.8.in | 5 ++++ + smallapp/unbound-anchor.c | 66 ++++++++++++++++++++++++++++++++++------------- + 2 files changed, 53 insertions(+), 18 deletions(-) + +diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in +index 02a3e781..e114eb25 100644 +--- a/doc/unbound-anchor.8.in ++++ b/doc/unbound-anchor.8.in +@@ -109,6 +109,11 @@ It does so, because the tool when used for bootstrapping the recursive + resolver, cannot use that recursive resolver itself because it is bootstrapping + that server. + .TP ++.B \-R ++Allow fallback from \-f resolv.conf file to direct root servers query. ++It allows you to prefer local resolvers, but fallback automatically ++to direct root query if they do not respond or do not support DNSSEC. ++.TP + .B \-v + More verbose. Once prints informational messages, multiple times may enable + large debug amounts (such as full certificates or byte\-dumps of downloaded +diff --git a/smallapp/unbound-anchor.c b/smallapp/unbound-anchor.c +index b3009108..f3985090 100644 +--- a/smallapp/unbound-anchor.c ++++ b/smallapp/unbound-anchor.c +@@ -192,9 +192,10 @@ usage(void) + printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER); + printf("-4 work using IPv4 only\n"); + printf("-6 work using IPv6 only\n"); +- printf("-f resolv.conf use given resolv.conf to resolve -u name\n"); +- printf("-r root.hints use given root.hints to resolve -u name\n" ++ printf("-f resolv.conf use given resolv.conf\n"); ++ printf("-r root.hints use given root.hints\n" + " builtin root hints are used by default\n"); ++ printf("-R fallback from -f to root query on error\n"); + printf("-v more verbose\n"); + printf("-C conf debug, read config\n"); + printf("-P port use port for https connect, default 443\n"); +@@ -1920,8 +1921,7 @@ static int + do_certupdate(const char* root_anchor_file, const char* root_cert_file, + const char* urlname, const char* xmlname, const char* p7sname, + const char* p7signer, const char* res_conf, const char* root_hints, +- const char* debugconf, int ip4only, int ip6only, int port, +- struct ub_result* dnskey) ++ const char* debugconf, int ip4only, int ip6only, int port) + { + STACK_OF(X509)* cert; + BIO *xml, *p7s; +@@ -1961,7 +1961,6 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file, + #ifndef S_SPLINT_S + sk_X509_pop_free(cert, X509_free); + #endif +- ub_resolve_free(dnskey); + ip_list_free(ip_list); + return 1; + } +@@ -2199,16 +2198,33 @@ probe_date_allows_certupdate(const char* root_anchor_file) + return 0; + } + ++static struct ub_result * ++fetch_root_key(const char* root_anchor_file, const char* res_conf, ++ const char* root_hints, const char* debugconf, ++ int ip4only, int ip6only) ++{ ++ struct ub_ctx* ctx; ++ struct ub_result* dnskey; ++ ++ ctx = create_unbound_context(res_conf, root_hints, debugconf, ++ ip4only, ip6only); ++ add_5011_probe_root(ctx, root_anchor_file); ++ dnskey = prime_root_key(ctx); ++ ub_ctx_delete(ctx); ++ return dnskey; ++} ++ + /** perform the unbound-anchor work */ + static int + do_root_update_work(const char* root_anchor_file, const char* root_cert_file, + const char* urlname, const char* xmlname, const char* p7sname, + const char* p7signer, const char* res_conf, const char* root_hints, +- const char* debugconf, int ip4only, int ip6only, int force, int port) ++ const char* debugconf, int ip4only, int ip6only, int force, ++ int res_conf_fallback, int port) + { +- struct ub_ctx* ctx; + struct ub_result* dnskey; + int used_builtin = 0; ++ int rcode; + + /* see if builtin rootanchor needs to be provided, or if + * rootanchor is 'revoked-trust-point' */ +@@ -2217,12 +2233,22 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, + + /* make unbound context with 5011-probe for root anchor, + * and probe . DNSKEY */ +- ctx = create_unbound_context(res_conf, root_hints, debugconf, +- ip4only, ip6only); +- add_5011_probe_root(ctx, root_anchor_file); +- dnskey = prime_root_key(ctx); +- ub_ctx_delete(ctx); +- ++ dnskey = fetch_root_key(root_anchor_file, res_conf, ++ root_hints, debugconf, ip4only, ip6only); ++ rcode = dnskey->rcode; ++ ++ if (res_conf_fallback && res_conf && !dnskey->secure) { ++ if (verb) printf("%s failed, retrying direct\n", res_conf); ++ ub_resolve_free(dnskey); ++ /* try direct query without res_conf */ ++ dnskey = fetch_root_key(root_anchor_file, NULL, ++ root_hints, debugconf, ip4only, ip6only); ++ if (rcode != 0 && dnskey->rcode == 0) { ++ res_conf = NULL; ++ rcode = 0; ++ } ++ } ++ + /* if secure: exit */ + if(dnskey->secure && !force) { + if(verb) printf("success: the anchor is ok\n"); +@@ -2230,18 +2256,18 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file, + return used_builtin; + } + if(force && verb) printf("debug cert update forced\n"); ++ ub_resolve_free(dnskey); + + /* if not (and NOERROR): check date and do certupdate */ +- if((dnskey->rcode == 0 && ++ if((rcode == 0 && + probe_date_allows_certupdate(root_anchor_file)) || force) { + if(do_certupdate(root_anchor_file, root_cert_file, urlname, + xmlname, p7sname, p7signer, res_conf, root_hints, +- debugconf, ip4only, ip6only, port, dnskey)) ++ debugconf, ip4only, ip6only, port)) + return 1; + return used_builtin; + } + if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n"); +- ub_resolve_free(dnskey); + return used_builtin; + } + +@@ -2264,8 +2290,9 @@ int main(int argc, char* argv[]) + const char* root_hints = NULL; + const char* debugconf = NULL; + int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT; ++ int res_conf_fallback = 0; + /* parse the options */ +- while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) { ++ while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) { + switch(c) { + case 'l': + dolist = 1; +@@ -2300,6 +2327,9 @@ int main(int argc, char* argv[]) + case 'r': + root_hints = optarg; + break; ++ case 'R': ++ res_conf_fallback = 1; ++ break; + case 'C': + debugconf = optarg; + break; +@@ -2346,5 +2376,5 @@ int main(int argc, char* argv[]) + + return do_root_update_work(root_anchor_file, root_cert_file, urlname, + xmlname, p7sname, p7signer, res_conf, root_hints, debugconf, +- ip4only, ip6only, force, port); ++ ip4only, ip6only, force, res_conf_fallback, port); + } +-- +2.14.4 + diff --git a/unbound-anchor.service b/unbound-anchor.service index 26656b3..cd949e5 100644 --- a/unbound-anchor.service +++ b/unbound-anchor.service @@ -5,5 +5,5 @@ Documentation=man:unbound-anchor(8) [Service] Type=oneshot User=unbound -ExecStart=/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem +ExecStart=/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R SuccessExitStatus=1 diff --git a/unbound.service b/unbound.service index 7062e49..287fe8d 100644 --- a/unbound.service +++ b/unbound.service @@ -11,7 +11,7 @@ Wants=nss-lookup.target Type=simple EnvironmentFile=-/etc/sysconfig/unbound ExecStartPre=/usr/sbin/unbound-checkconf -ExecStartPre=-/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem +ExecStartPre=-/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem -f /etc/resolv.conf -R ExecStart=/usr/sbin/unbound -d $UNBOUND_OPTIONS ExecReload=/usr/sbin/unbound-control reload diff --git a/unbound.spec b/unbound.spec index 4bdba66..eaacab4 100644 --- a/unbound.spec +++ b/unbound.spec @@ -34,7 +34,7 @@ Summary: Validating, recursive, and caching DNS(SEC) resolver Name: unbound Version: 1.7.3 -Release: 2%{?extra_version:.%{extra_version}}%{?dist} +Release: 3%{?extra_version:.%{extra_version}}%{?dist} License: BSD Url: https://www.unbound.net/ Source: https://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz @@ -57,6 +57,7 @@ Source17: unbound-anchor.service Patch2: unbound-1.7.2-python3-devel.patch Patch3: unbound-1.7.2-python3-pkgconfig.patch +Patch4: unbound-1.7.3-anchor-fallback.patch BuildRequires: gcc, make BuildRequires: flex, openssl-devel @@ -163,6 +164,7 @@ Python 3 modules and extensions for unbound pushd %{pkgname} %patch2 -p1 -b .python3 %patch3 -p1 -b .python3 +%patch4 -p1 -b .anchor-fallback # only for snapshots # autoreconf -iv @@ -430,6 +432,9 @@ popd %attr(0644,root,root) %config %{_sysconfdir}/%{name}/root.key %changelog +* Wed Jul 04 2018 Petr Menšík - 1.7.3-3 +- Update trust anchors also behind firewall (#1598078) + * Mon Jul 02 2018 Miro Hrončok - 1.7.3-2 - Rebuilt for Python 3.7