Working around Pi-hole handling of onion queries (again)

I have a local DNS resolver which resolves "onion" hostnames (in order to enable conditional routing scenarios with TOR). I need some clients in my network to resolve "onion" hostnames using Pi-hole, so I need Pi-hole to forward requests for "onion" hostnames to a designated DNS resolver.

This should be done by adding a server=/onion/<local DNS resolver IPv4> line in dnsmasq configuration (for pihole-FTL, in a separate configuration file such as /etc/dnsmasq.d/XX-onion.conf if etc_dnsmasq_d is enabled, or directly in dnsmasq_lines). But this does not work. Regardless of the dnsmasq configuration options I tried and their order, Pi-hole was returning NXDOMAIN for any resolution query on a "onion" hostname.

Pihole-FTL (starting pihole-FTL version 6?) is applying some unalterable hardcoded dnsmasq configuration options (see /etc/pihole/dnsmasq.conf - this file is written by the pihole-FTL binary at start). One of these options makes that "onion" hostnames can only be resolved by locally-known addresses (ie. none by default, which would result in a NXDOMAIN response): server=/onion/.

This form of server option is of the highest priority (for a given TLD) when dnsmasq/pihole-FTL match hostnames with resolution directives:

  • server option parsing in one_opt shows how such option is parsed, setting the SERV_LITERAL_ADDRESS flag,
  • a server definition is then internally stored from the parsed server option, as per add_update_server,
  • queried hostnames matching with servers definitions happens in lookup_domain,
  • it looks for the server definition whose “domain” (in our case "onion") is the longest exact match for the right side of a queried hostname,
  • if several servers definitions with identical “domain” lengths match the queried hostname, then a server definition would be favoured because it is of highest priority. In particular, a server definition with the SERV_LITERAL_ADDRESS flag only (such as server=/onion/) has a higher priority than a server definition with the SERV_4ADDR flag (such as server=/onion/<local DNS resolver IPv4>).

In other words, a pihole-FTL user cannot redefine how "onion" hostnames are resolved (there used to be a way, before pihole-FTL 6, by commenting the server=/onion/ configuration option which was stored in /etc/dnsmasq.d/06-rfc6761.conf), as the hardcoded server option "server=/onion/" from pihole-FTL will be of highest priority compared to any other possible server option for the "onion" TLD.

This I believe might be an issue, and pihole-FTL could offer a way for users to decide how to process "onion" TLD (as well as maybe other TLDs which are also included in pihole-FTL hardcoded server options).

But meanwhile, I found a workaround for "onion" TLD: a server definition for the "*.onion" domain pattern will have an higher priority than any directive for "onion" TLD. If you need to override the way pihole-FTL >= 6 processes "onion" TLD by forwarding related queries to an upstream server of your choosing, you can:

  • enable etc_dnsmasq_d in pihole-FTL config,
  • create a /etc/dnsmasq.d/99-pihole.conf file with a server definition of the following format: server=/*.onion/<local resolver IP>#<port>,
  • restart the pihole-FTL service.

This has been done and tested as of FTL version v6.4.1 (latest was v6.4.1 at that time).

1 Like