[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