CZ-NIC / knot-resolver

Knot Resolver - resolve DNS names like it's 2024
https://www.knot-resolver.cz/
Other
355 stars 59 forks source link

How can I disable IPv4/IPv6 resolution #84

Closed wolerine closed 1 year ago

wolerine commented 1 year ago

Hello,

I am running two Knot Resolvers. I would like to get only IPv4 results on fist instance, and only IPv6 on second instance.

Is there any way to disable IPv4/IPv6 resolution?

Thank you

vcunat commented 1 year ago

You mean, block receiving A queries from clients on one instance and AAAA queries on the other one?

wolerine commented 1 year ago

Yes, I want to exactly do that that

vcunat commented 1 year ago

Sounds rather fishy, meaning risks of unexpected interactions with usual DNS clients, etc. Anyway, you can compose it with this function – there's even an example deciding based on QTYPE https://knot-resolver.readthedocs.io/en/stable/modules-policy.html#policy.custom_filter

wolerine commented 1 year ago

You are right, sound risky. Let me tell you about my infrastracture a bit.

In front of both Knot Resolver's, SmartDNS is running. It balances fastest-ip over results. I have two IPv4 connections over PPPoE. Unfortunately my ISP does not provide any IPv6 connection. I got my own ASN number and running a small hobby BGP IPv6 only network. My core router is located in Frankfurt. My home router connected core router over Wireguard and speaks iBGP.

IPv4 only Knot Resolver instance resolves correct IPv4 in my country according to EDNS. I am getting IP addreses on local CDN pops. And this instance also resolves IPv6 in my country. That's why I wanted to disable IPv6 resolution on this instance.

IPv6 only Knot Resolver instance resolves correct IPv6 on Germany. And also resolves IPv4 address in Germany as well. I wanted to disable IPv4 reslution on this instance to get correct IPv4 and IPv6 resolutions according to origin country. (In this case IPv4 for Turkey, IPv6 for Germany)

Thank you very much for you help.

Function below solved my problem.

function match_query_type(action, target_qtype)

return function (state, query)
    if query.stype == target_qtype then
        -- filter matched the query, return action function
        return action
    else
        -- filter did not match, continue with next filter
        return nil
    end
end

end policy.add(match_query_type(policy.DROP, kres.type.AAAA))

vcunat commented 1 year ago

I see, quite interesting. So it's about tailoring of auth-NS answers based on (detected) resolver's location, in case where routing of v4 and v6 differs too much. This gets complicated by the fact that A vs. AAAA query is independent of which protocol is used to query the nameserver (v4 or v6).

I'd further assume that you'd want net.ipv6 = false in the v4 resolver. I'm not sure about net.ipv4 = false in the v6 resolver, as penetration of IPv6 among auth-NS deployments isn't perfect. (There's no way of configuring this per-request, nor configuring preference of v4/v6 as transport to upstream.)

wolerine commented 1 year ago

For sorting A and AAAA results, I use SmartDNS in front of both Knot Resolvers.

Following results from my IPv6 knot https://imgur.com/XU9PPYy

Following results from my IPv4 knot https://imgur.com/kaIjHNs

And SmartDNS sorts results based on latency and selects for fastest one. https://imgur.com/tU81neC