[Dnsmasq-discuss] dnsmasq v2.87 --nftset and DNS reply race condition
Simon Kelley
simon at thekelleys.org.uk
Fri Feb 4 21:23:08 UTC 2022
On 31/01/2022 14:24, Alain Ducharme wrote:
> Hello,
>
> With: dnsmasq v2.87test5 running on localhost (Debian 11 bullseye PC).
>
> Trying: to use --nftset option to implement an allowlist outbound firewall with nftables.
>
> Result: when an application performs a DNS lookup prior to establishing an outbound connection: most of the time on my PC, but not always, the nft `add element` happens too late; therefore the outbound rules using the nft `ip daddr @set` do not work.
>
> To be clear: the IP addresses do get correctly added to the nft set(s), but only after the application has received a DNS reply from dnsmasq and already attempted a connection and failed.
>
> The problem: appears to be that nftset and DNS reply run concurrently (forks); despite `nftset.c` : `add_to_nftset()` technically being called first, the reply on my PC happens before the nft set is updated in the kernel (nftables can be relatively slow). (perhaps it might work better on a router due to network latency).
>
> Tested: at first I was hypothesizing that perhaps calls to `nft_ctx_output_set_flags(ctx, NFT_CTX_OUTPUT_ECHO);` and `nft_ctx_get_output_buffer(ctx)` in `nftset.c` might be required to wait for the set elements to be committed to the kernel (man libnftables), but that did not help. I added a `sleep(5);` in `nftset.c` just to see, and that confirmed dnsmasq does not wait for `add_to_nftset` to finish before sending a DNS reply to the client (it was instantaneous).
This surprises me: I can believe it's possible that whatever happens
after the call into nft_run_cmd_from_buffer() could run concurrently,
with nft_run_cmd_from_buffer() returning immediately, but if you put a
sleep(5) into add_to_nftset() I'd expect that to block the reply.
A possible explanation is that caching is confusing things. The first
time a query is made, it gets sent upstream and when the reply comes
back add_to_nftset() is called. Subsequent queries get answered from the
cache and add_to_nftset is not in the picture at all.
It would be good to clear this up first, since it clarifies where we
need to work on the code.
>
> The question is: would it be possible to have the DNS reply occur only after `add_to_nftset` has fully completed?
See above, I think this already happens, in which case the solution is
further into the NFT library code.
Cheers,
Simon.
>
> Thank you.
>
> _______________________________________________
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss at lists.thekelleys.org.uk
> https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss
>
More information about the Dnsmasq-discuss
mailing list