0

I have a question on how to setup the filtering as described in the following scenario:

I see that systemd-resolved listens on port 53 and sends all the DNS requests to the real DNS resolvers.

I am looking for a way to do this:

  1. Catch the response from the DNS resolver that is about to go into the systemd-resolved at port 53
  2. Hold this packet, read its content (see the actual IP address response), do something with this IP
  3. Release the response packet to go through to port 53

Is this something that can be achieved with iptables, libpcap or any other available solution?

I know it's possible to install my own listener at port 53 but I really don't want to cut short the systemd-resolver here, and I am looking for a transparent solution.

1 Answer 1

1

I see that systemd-resolved listens on port 53 and sends all the DNS requests to the real DNS resolvers.

systemd-resolvd is a "real" resolver (just as real as any other recursive resolver): it needs to the resolvers responsible for some zones about answers; that's how DNS works

Catch the response from the DNS resolver that is about to go into the systemd-resolved at port 53

Nope, that's not how that works: DNS requests will come from a randomized port, going to port 53 at the remote resolver, which will then answer on the same port the request was made from.

53 is the destination port, not the source port for the request. For the reply, the source port (on the remote DNS server) is 53 and the destination port (on your machine) is the same as the random source port number chosen by the requester.

Hold this packet, read its content (see the actual IP address response), do something with this IP

You would usually just implement that by having a resolver that you configure your resolver to use. You already have systemd-resolved, which is pretty much that, so the question here becomes what you're doing this for, and whether there isn't functionality that already is in your system, which can fulfill that purpose.

Is this something that can be achieved with iptables, libpcap or any other available solution?

Sure, you could implement the minimal amount of request/reply tracking in eBPF and let this run on the kernel side. Then you'd invent some way to do whatever you mean with "do something with this IP" in the kernel, or a protocol for your kernel side to exchange that information with a userland process that knows how to do that.

But that's just really putting the job of a resolver proxy userland program in the kernel, and it sounds like a lot more work and much more intrusive than just making systemd-resolved do what you want, either by itself, or by configuring it to use your own resolver implementation.

looking for a transparent solution

DNS is by design recursive anyways. Adding one more level is nothing special, and thus "transparent" to any program using DNS.

8
  • Thanks for the answer, Marcus. "so the question here becomes what you're doing this for, and whether there isn't functionality that already is in your system, which can fulfill that purpose" - I am doing this for dynamically routing specific outbound traffic inside or outside a VPN tunnel. I know only the domain name of the endpoints and need to dynamically retrieve the IPs based on DNS responses and apply routes based on that (and hold off the DNS response until routes are applied). Commented Aug 22, 2024 at 12:49
  • I think you are right, creating a local DNS resolver would be the easiest here. I also oscillate between that or creating a kernel module and intercept traffic with nf_register_net_hook and then make decisions based on it. Thanks again for your answer. Commented Aug 22, 2024 at 12:52
  • @AndreiGlingeanu uff, and there's no more sensible solution since as routing whole subnets? I ask because if your clients use DNS over HTTP, or DNS over TLS, as many browsers do by default, for example, or simply cache IP addresses for longer than your routes live, than this will go very wrong. Commented Aug 22, 2024 at 13:01
  • @AndreiGlingeanu (note that if your problem is as general as you describe it here, your routes need to have "lifetimes": the moment the validity of a DNS response expires, you can't be sure anymore that the route still points to the domain you meant it to, so you need to automatically re-do the DNS resolution that lead to that route to be sure it should be renewed, and if the result changes, adjust your routes. And that gets really interesting with domains that round-robin resolve to different IP addresses every time you ask. Plus, I really hope your organization is is the one controlling Commented Aug 22, 2024 at 13:06
  • Yes, I totally understand that. We don't have issue with DNS over non-UDP, because we already handle those cases. I have a big issue right now specifically with traditional DNS over UDP on Linux. This is what's giving me the most issues right now. Yes, I totally understand your point about TTL of routes. This is, of course, taken into consideration. Commented Aug 22, 2024 at 13:10

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.