]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will not pass
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 4 Jul 2018 10:02:16 +0000 (10:02 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 4 Jul 2018 10:02:16 +0000 (10:02 +0000)
  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/Changelog
doc/unbound-anchor.8.in
smallapp/unbound-anchor.c

index a736c045437e69de932c5ccb4b2329d413e6b85a..b1d451123bf182dc62c3633212ae7cd6bfbc438e 100644 (file)
@@ -1,3 +1,8 @@
+4 July 2018: Wouter
+       - 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.
+
 3 July 2018: Wouter
        - Better documentation for unblock-lan-zones and insecure-lan-zones
          config statements.
index 02a3e781b0c7c9539060f62761c283bff9dd5922..e114eb2560161e98ba909cd50f850f736ffdefc8 100644 (file)
@@ -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
index b30091088008fbdad462bee16645a7a12d4ab530..f398509018d92af3d960098ffaabf8b99a8742e0 100644 (file)
@@ -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);
 }