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