[ldns-users] ldns_dnssec_verify_denial() usage

Willem Toorop willem at nlnetlabs.nl
Mon Jun 18 16:00:12 UTC 2018


Op 18-06-18 om 17:01 schreef Vladimir Levijev:
> On Mon, Jun 18, 2018 at 5:52 PM Willem Toorop <willem at nlnetlabs.nl> wrote:
>> Op 18-06-18 om 16:08 schreef Vladimir Levijev:
>>> On Mon, Jun 18, 2018 at 3:34 PM Willem Toorop <willem at nlnetlabs.nl> wrote:
>>>> Op 15-06-18 om 15:31 schreef Jurijs Klopovskis:
>>>>
>>>>> I have a question about using ldns_dnssec_verify_denial() and
>>>>> ldns_dnssec_verify_denial_nsec3() functions.
>>>>>
>>>>> Right now in out code we perform denial of existence checks with these
>>>>> functions only if ldns_verify() function has failed with
>>>>> LDNS_STATUS_CRYPTO_NO_MATCHING_KEYTAG_DNSKEY.
>>>>>
>>>>> Is this sane?
>>>>
>>>> Did you start out with a ldns_pkt?
>>>>
>>>> If there were no RRsets for qname and qtype in the pkt, you can skip
>>>> ldns_verify() and start looking for NSECs (for
>>>> ldns_dnssec_verify_denial() ) or NSEC3s (for
>>>> ldns_dnssec_verify_denial_nsec3() ) right away.
>>>>
>>>> But even when you did found RRsets for qname and qtype and ldns_verify()
>>>> returned LDNS_STATUS_OK, you still have to check whether it validated a
>>>> wildcard match, in which case you have to verify that a more specific
>>>> qname/qtype did not exist.
>>>>
>>>> Note that getdns has a more convenient higher level function for this:
>>>>
>>>> https://getdnsapi.net/functions/getdns_validate_dnssec.html
>>>> https://getdnsapi.net/functions/getdns_validate_dnssec2.html
>>>>
>>>> Which can take a whole DNS message/packet as input and return the DNSSEC
>>>> status, regardless of whether the reply is for a NOERROR, NXDOMAIN or
>>>> NODATA response.  Also wildcard responses are validated correctly
>>>> automatically with that function.  (and you don't have to handle NSECs
>>>> and NSEC3s differently either).
>>>
>>> Did I understand correctly that in case of getdns I do not have a way
>>> to specify the Name Server I want to query?
>>
>> The default is full recursive, but you can configure getdns for stub
>> resolution mode in which case it will target the configured upstreams.
>> The below example will send A and AAAA queries (simultaneously) for
>> nlnetlabs.nl to 9.9.9.9.
>>
>> #include <getdns/getdns_extra.h>
>>
>> int main(int argc, char **argv)
>> {
>>         getdns_context *context      = NULL;
>>         getdns_list    *upstreams    = NULL;
>>         getdns_dict    *response     = NULL;
>>         char           *response_str = NULL;
>>         getdns_return_t r;
>>
>>         if ((r = getdns_context_create(&context, 0)))
>>                 fprintf(stderr, "Could not create context");
>>
>>         else if ((r = getdns_context_set_resolution_type(
>>             context, GETDNS_RESOLUTION_STUB)))
>>                 fprintf(stderr, "Could not set resolution type");
>>
>>         else if ((r = getdns_str2list("[9.9.9.9]", &upstreams)))
>>                 fprintf(stderr, "Error converting upstreams list");
>>
>>         else if ((r = getdns_context_set_upstream_recursive_servers(
>>             context, upstreams)))
>>                 fprintf(stderr, "Could not set upstreams");
>>
>>         else if ((r = getdns_address_sync(
>>             context, "nlnetlabs.nl", NULL, &response)))
>>                 fprintf(stderr, "Could not query");
>>
>>         else if (!(response_str = getdns_pretty_print_dict(response)))
>>                 fprintf(stderr, "Could not print response dict\n");
>>         else
>>                 printf("%s\n", response_str);
>>
>>         if (response_str)
>>                 free(response_str);
>>         if (response)
>>                 getdns_dict_destroy(response);
>>         if (upstreams)
>>                 getdns_list_destroy(upstreams);
>>         if (context)
>>                 getdns_context_destroy(context);
>>         if (r)
>>                 fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r));
>>
>>         return r ? EXIT_FAILURE : EXIT_SUCCESS;
>> }
> 
> Thank you for the example!
> 
> I'm afraid though our case is completely vice versa-ish, we would like
> to send the same query to specified list of name servers, to test each
> of them. E. g. send A and AAAA queries (simultaneously) for
> nlnetlabs.nl to 1.1.1.1, 2.2.2.2, 3.3.3.3, 4.4.4.4 and 5.5.5.5 . :-)

It might not possible to set a upstream on a per query basis (at least
not via the usual extension mechanism).  It might be possible by
configuring a new upstream list before scheduling a new query; I'll have
to try that out.

However if asynchronicity is not important, it is possible to provide a
big list of upstreams and query them all in turn with the
getdns_context_set_round_robin_upstreams() function.

This works only in synchronously because the next upstream is only
selected after a query is received.  I consider this a bug which needs
to be addressed in the future, but to give the example that illustrates
the gist:


#include <getdns/getdns_extra.h>

int main(int argc, char **argv)
{
        getdns_context *context      = NULL;
        getdns_list    *upstreams    = NULL;
        size_t          n_upstreams, i;
        getdns_dict    *extensions   = NULL;
        getdns_dict    *response     = NULL;
        char           *response_str = NULL;
        getdns_return_t r;

        if ((r = getdns_context_create(&context, 0)))
                fprintf(stderr, "Could not create context");

        else if ((r = getdns_context_set_resolution_type(
            context, GETDNS_RESOLUTION_STUB)))
                fprintf(stderr, "Could not set resolution type");

        else if ((r = getdns_str2list(
            "[1.1.1.1, 8.8.8.8, 9.9.9.9, 64.6.64.6]", &upstreams)))
                fprintf(stderr, "Error converting upstreams list");

        else if ((r = getdns_list_get_length(upstreams, &n_upstreams)))
                fprintf(stderr, "Could not get upstreams length");

        else if ((r = getdns_context_set_upstream_recursive_servers(
            context, upstreams)))
                fprintf(stderr, "Could not set upstreams");

        else if ((r = getdns_context_set_round_robin_upstreams(
            context, 1)))
                fprintf(stderr, "Could not set round robin upstreams");

        else if ((r = getdns_str2dict(
            "{ return_call_reporting: GETDNS_EXTENSION_TRUE }",
	    &extensions)))
                fprintf(stderr, "Error converting extensions dict");

        else for (i = 0; i < n_upstreams; i++) {
                getdns_bindata *upstream;
                getdns_bindata *address;
                char *upstream_str = NULL;
                char *address_str = NULL;

                if ((r = getdns_general_sync(context, "nlnetlabs.nl",
                    GETDNS_RRTYPE_A, extensions, &response))) {
                        fprintf(stderr, "Could not schedule query");
                        break;
                }

                if (!getdns_dict_get_bindata(response,
                    "/call_reporting/0/query_to/address_data",
		    &upstream)
                &&  !getdns_dict_get_bindata(response,
                    "/just_address_answers/0/address_data", &address)
                &&  (upstream_str = getdns_display_ip_address(upstream))
                &&  (address_str = getdns_display_ip_address(address)))
                        printf( "%s returned %s\n"
                              , upstream_str, address_str);

                if (upstream_str)
                        free(upstream_str);
                if (address_str)
                        free(address_str);
                getdns_dict_destroy(response);
        }
        if (extensions)
                getdns_dict_destroy(extensions);
        if (upstreams)
                getdns_list_destroy(upstreams);
        if (context)
                getdns_context_destroy(context);
        if (r)
                fprintf(stderr, ": %s\n", getdns_get_errorstr_by_id(r));

        return r ? EXIT_FAILURE : EXIT_SUCCESS;
}



This displays:

1.1.1.1 returned 185.49.140.10
8.8.8.8 returned 185.49.140.10
9.9.9.9 returned 185.49.140.10
64.6.64.6 returned 185.49.140.10

Cheers,
-- Willem

> 
> Cheers,
> 
> VL
> 




More information about the ldns-users mailing list