Bug 24255 - resolver should handle special domains correctly
Summary: resolver should handle special domains correctly
Status: UNCONFIRMED
Alias: None
Product: glibc
Classification: Unclassified
Component: network (show other bugs)
Version: unspecified
: P2 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-02-21 14:18 UTC by Cristian Rodríguez
Modified: 2024-02-24 08:00 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Cristian Rodríguez 2019-02-21 14:18:06 UTC
Here there are examples of special domains the resolver does not handle as required by the relevant RFC..first the most concerning..

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>

#ifndef   NI_MAXHOST
#define   NI_MAXHOST 1025
#endif

int main(void)
{
    struct addrinfo* result;
    struct addrinfo* res;
    int error;

    /* resolve the domain name into a list of addresses */
    error = getaddrinfo("foo.onion", NULL, NULL, &result);
    if (error != 0) {
        if (error == EAI_SYSTEM) {
            perror("getaddrinfo");
        } else {
            fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
        }
        exit(EXIT_FAILURE);
    }

    /* loop over all returned results and do inverse lookup */
    for (res = result; res != NULL; res = res->ai_next) {
        char hostname[NI_MAXHOST];
        error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
        if (error != 0) {
            fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
            continue;
        }
        if (*hostname != '\0')
            printf("hostname: %s\n", hostname);
    }

    freeaddrinfo(result);
    return 0;
}

glibc resolver does not know how to tor rendevous, therefore it must return whatever error code is equivalent to NXDOMAIN, and definately not send it to a DNS server. (rfc7686)

tshark -i veth45d962a -Y "udp.port == 53" 
Running as user "root" and group "root". This could be dangerous.
Capturing on 'veth45d962a'
    1 0.000000000  10.37.105.2 → 8.8.8.8      DNS 69 Standard query 0x1908 A foo.onion
    2 0.024157070      8.8.8.8 → 10.37.105.2  DNS 144 Standard query response 0x1908 No such name A foo.onion SOA a.root-servers.net

This can compromise user's privacy pretty heavily.

The same problem exists with multiple domains.. I 'll list them here..


 The domain "localhost." and any names falling within ".localhost."

No matter if   /etc/hosts contains localhost. or not or if /etc/nsswitch.conf contains files or not, it should return the adddress of the local loopback. currently glibc tries to send "whatever.localhost."  to the DNS server.

"Name resolution APIs and libraries SHOULD recognize localhost
       names as special and SHOULD always return the IP loopback address
       for address queries and negative responses for all other query
       types.  Name resolution APIs SHOULD NOT send queries for
       localhost names to their configured caching DNS server(s)." (rfc6761)


The domain "invalid." and any names falling within ".invalid." 

"Name resolution APIs and libraries SHOULD recognize "invalid"
       names as special and SHOULD always return immediate negative
       responses.  Name resolution APIs SHOULD NOT send queries for
       "invalid" names to their configured caching DNS server(s)."

Fortunately if you run unbound in localhost, it will stop this misbehaviour and will not send this queries to the outer world, systemd-resolved will also stop the .localhost. mishandling, in general caching nameservers will stop you.. but I think you should fix the resolver instead.
Comment 1 Petr Menšík 2023-06-12 13:32:10 UTC
I do not think this is a good idea. If one is running a local cache on his machine, he might be able to forward onion. zone and all requests to it into TOR network to appropriate DNS servers.

That would be no longer possible if glibc blocked that query from DNS. I think we want it blocked only from forwarding to 3rd party servers. For example unbound or bind will create empty zones for it, blocking forwarding it to upstream DNS servers. That is what we want. It either handles it or blocks it.

I don't think this can be decided by glibc, it is not aware of configuration details of DNS. I would instead propose to have optional NSS hosts plugin with configurable blocklist, which could be put before dns in /etc/nsswitch.conf. If you would include onion in it, it would authoritatively say does not exist without allowing that in DNS. If you would have local dns cache able to configure this properly, it would not use such module.
Comment 2 Cristian Rodríguez 2023-06-12 13:55:35 UTC
(In reply to Petr Menšík from comment #1)
> I do not think this is a good idea. If one is running a local cache on his
> machine, he might be able to forward onion. zone and all requests to it into
> TOR network to appropriate DNS servers.
> 
> That would be no longer possible if glibc blocked that query from DNS. I
> think we want it blocked only from forwarding to 3rd party servers. For
> example unbound or bind will create empty zones for it, blocking forwarding
> it to upstream DNS servers. That is what we want. It either handles it or
> blocks it.
> 
> I don't think this can be decided by glibc, it is not aware of configuration
> details of DNS. I would instead propose to have optional NSS hosts plugin
> with configurable blocklist, which could be put before dns in
> /etc/nsswitch.conf. If you would include onion in it, it would
> authoritatively say does not exist without allowing that in DNS. If you
> would have local dns cache able to configure this properly, it would not use
> such module.

This is not what the relevant standards say though.

" 3.  Name Resolution APIs and Libraries: Resolvers MUST either respond
       to requests for .onion names by resolving them according to
       [tor-rendezvous] or by responding with NXDOMAIN [RFC1035]."

glibc does not know and will probably never know by itself  how to tor-rendezvous, it could of course do it using an nss-module which must come before dns or files in /etc/nsswitch.conf ..but the dns and files module must return NXDOMAIN on such names.
Comment 3 Petr Menšík 2023-06-12 14:15:55 UTC
I do not think we ever want to override output of files database. If the user defines his own example.onion name in /etc/hosts, then he should receive it in queries. He wants it and we should not filter his wishes.

And for DNS, we cannot know if that the server is connected to Tor or not. I guess we could block DNS query if the server were not sent to ::1 or 127.0.0.0/8. But handling this at dns plugin seems wrong to me. And it should be possible to configure it for unusual setups, where we want it forwarded anyway.

I think system services like Network Manager or systemd-networkd would be better suited to decide whether such queries should be forwarded or discarded on low level. Perhaps Tor service could remove onion domain from blocked list on startup and return it when shut down.
Comment 4 milahu 2024-02-24 08:00:09 UTC
> for DNS, we cannot know if that the server is connected to Tor or not

imo, the optimal solution would be
to extend /etc/resolv.conf with something like

> option allow-domains *.onion

... to make tools like curl and git "just work"
on machines behind a transparent tor proxy
where these tools currently throw the error

> Not resolving .onion address (RFC 7686)

... and currently
we need non-transparent workarounds like

> curl --proxy socks5h://127.0.0.1:9050
> git -c remote.origin.proxy=socks5h://127.0.0.1:9050

... or expensive workarounds like "rebuild curl"
which on systems like nixos or guix means "rebuild the world"



this config belongs to /etc/resolv.conf
because its a machine-level config
which affects all DNS clients on that machine

the default config would be something like

> option deny-domains *.onion *.i2p



see also

https://github.com/curl/curl/discussions/11125
I want to resolve onion addresses

https://gitlab.torproject.org/tpo/core/torspec/-/issues/202
Formalize toggle override for non-Tor applications that follow RFC 7686