Resolving query[type=65] to local address for iOS clients in dnsmasq

I've just tested the new dnsmasq.init script and it seems to work as intended.

Here is my setup process, if anyone else wants to try and confirm it:

  1. Downloaded the new dnsnasmq.init file from https://raw.githubusercontent.com/systemcrash/openwrt/588237bffa310f6cba517546266efbfdf7fc4a29/package/network/services/dnsmasq/files/dnsmasq.init to ~/Desktop/dnsmasq-new/dnsmaq

  2. Made a backup of the current configuration via Luci > System > Backup > Generate archive

  3. Made a backup of the existing dnsmasq file from OpenWrt using this command in Terminal on macOS (after creating a folder called dnsmasq-backup on Desktop):
    scp -O root@192.168.1.1:/etc/init.d/dnsmasq ~/Desktop/dnsmasq-backup/

  4. Made the new dnsmasq file executable with this command:
    chmod +x ~/Desktop/dnsmasq-new/dnsmasq

  5. Uploaded the new dnsmasq file from the Desktop to OpenWrt:
    scp -O ~/Desktop/dnsmasq-new/dnsmasq root@192.168.1.1:/etc/init.d/

  6. Logged into OpenWrt using SSH, and used uci to setup the configuration as recommended:
    uci -q add dhcp 'filter_rr'
    uci -q set dhcp.@filter_rr[-1].rr_csv='AAAA,HTTPS,65'
    uci -q commit dhcp

  7. Restarted dnsmasq using the new init file:
    /etc/init.d/dnsmasq restart

and this is the output that I got:

root@OpenWrt:/etc/init.d# /etc/init.d/dnsmasq restart
udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: no lease, failing
/etc/rc.common: eval: line 600: ipcalc: not found

It seems to show an error ipcalc: not found, at least with the way I've tested it, but it does work.

To test it whether the filter-rr and dns replies work, I've used this command:
dig -t TYPE65 www.cloudflare.com

which gave a DNS answer before with TYPE65 (HTTPS), but now it properly filters it out.

Thank you again for your help and for creating this option!

Ah yes, you've downloaded my diff on the latest master which includes that ipcalc machinery (to calculate subnet ranges and so on). Are you on 23? I could make a commit which patches just 23. Perhaps better with it just under dnsmasq[0], and not its own record type.

1 Like

Thank you for the reply!

Yes, I'm on the official 23.05.2 (not using the snapshot), with only the Dnsmasq 2.90 version updated from within Luci > System > Software

You don't have to make a special commit just for my setup. I'm glad the feature works either way.

However, I would be happy to do more test if it helps

Ok, commit for v23. It's actually basically just a one-liner.

And is v23 with just this modification so it should remove that error.

Also, to configure, it's (almost) like you first guessed. Easier:

1 Like

Awesome! That was really fast. Thank you so much for creating it and for including it under the dnsmasq config.

I will try it out right away

1 Like

It seems to work great!

This is what I did:

  1. Downloaded the new dnsmasq.init for v23 from https://raw.githubusercontent.com/systemcrash/openwrt/cfe148c6370d19386cb2a444b2c0bcde64c3b777/package/network/services/dnsmasq/files/dnsmasq.init

  2. Used the same process to copy the new file from Desktop to OpenWrt from before:
    Resolving query[type=65] to local address for iOS clients in dnsmasq - #41 by GetVladimir

  3. Logged in to OpenWrt via SSH and removed the previous configuration using uci:
    uci delete dhcp.@filter_rr[0]

  4. Added the new configuration:
    uci set dhcp.@dnsmasq[0].filter_rr='AAAA,HTTPS,65'
    uci -q commit dhcp

  5. Restarted dnsmasq using the new init file:
    /etc/init.d/dnsmasq restart

And this is the output that I've received:

root@OpenWrt:/etc/init.d# /etc/init.d/dnsmasq restart
udhcpc: started, v1.36.1
udhcpc: broadcasting discover
udhcpc: no lease, failing

Everything works good and no ipcalc errors. I will continue using your commit on the router.

For the future, your new solution might also make the cache-rr easier to implement as well as an option under dnsmaq.

Thank you so much for everything!

1 Like

Yes, i meant plain old HTTP ..

@GetVladimir can I get your Tested-by: email? Not mandatory.

1 Like

Of course. It's ask@getvladimir.com

Great. Thanks. That's in the commit now. I've made a PR for this and the cache-rr thing also.

1 Like

Thank you so much, I appreciate it!

1 Like

I would like dnsmasq to block/filter/discard outgoing Type 65 requests - nipping the whole HTTPS record business in the bud.

However the recent change to dnsmasq seems to work backwards: The documentation says 'Remove records of the specified type(s) from answers', which to me says it's going to proceed with forwarding the Type 65 request to the upstream server, and then trim down the response.

Am I missing something here?

Yes, indeed you are right that the filter is removing HTTPS from the answers only, but it's still forwarded upstream.

I've enabled Log queries to test it out and used this query:
dig blog.cloudflare.com -t TYPE65

Here were the results:

dnsmasq[1]: 84 192.168.1.10/59467 query[HTTPS] blog.cloudflare.com from 192.168.1.10
dnsmasq[1]: 84 192.168.1.10/59467 forwarded blog.cloudflare.com to 1.1.1.1
dnsmasq[1]: 84 192.168.1.10/59467 config blog.cloudflare.com is NODATA
dnsmasq[1]: 85 192.168.1.10/51671 query[HTTPS] blog.cloudflare.com from 192.168.1.10
dnsmasq[1]: 85 192.168.1.10/51671 config blog.cloudflare.com is NODATA
dnsmasq[1]: 86 192.168.1.10/60256 query[HTTPS] blog.cloudflare.com from 192.168.1.10
dnsmasq[1]: 86 192.168.1.10/60256 config blog.cloudflare.com is NODATA

From the output, it shows that the first request is forwarded upstream, and then the reply is from the configuration as NODATA.

However, I also have cache-rr enabled as well, so the following queries for the same domain didn't get forwarded at all (until the cache expires).

Hmmm. I guess using filter-rr and cache-rr together will somewhat reduce the HTTPS requests, so it's better than nothing.

I'd prefer that --filter-rr trim type 65 from the original request, and only forward it upstream if there remain other requested types. It should respond to the type 65 request immediately with NODATA.

Making the upstream request and then discarding it (as happens with --filter-rr) seems a waste (and counts against my DNS quota ;( ).

Cheers.

As somewhat of a workaround, you can test adding a domain in a hosts file with the IP reply.

For example:
0.0.0.0 example.com

This might give the answer from cache right away instead of forwarding it upstream first (need to be confirmed if it really works all the time).

Of course, this means that you'll need to manually add the domains, and it won't work if the IP needs to change.

This workaround didn't work before (it simply forwarded the HTTPS and gave that reply instead of reading the host file), but now seems to work as intended with the filter-rr and cache-rr options

The closest thing to what you want is provided today by e.g. --dns-rr=<name>,<RR-number>,[<hex data>] which I made a PR for a while back (go in and approve it).

--dns-rr is the generic parameter and works for all record types. dnsmasq will prevent a lookup only when there is an exactly matching locally configured --dns-rr.

I guess it would not be too complicated to add what you want. Ask for it: https://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss

Thanks for the tips. I've been using the hosts file for short term blocking of some sites and was also using this in the dnsmasq config file for more permanent blocking:

address=/fp.measure.office.com/#

Both were working quite well for A and AAAA records. When Type 65 came along, dnsmasq ignored both sources and always forwarded the request upstream.

I did find this in the documentation under --address:

Note that the behaviour for queries which don't match the specified address literal changed in version 2.86. Previous versions, configured with (eg) --address=/example.com/1.2.3.4 and then queried for a RR type other than A would return a NoData answer. From 2.86, the query is sent upstream. To restore the pre-2.86 behaviour, use the configuration --address=/example.com/1.2.3.4 --local=/example.com/

So I've added '--local' for the domains specified using '--address' in the config file, and that does seem to block Type 65 requests for those domains. This addresses my biggest issue.

For more transient blocking I've tried the new --filter-rr=HTTPS, but I don't want to block all Type=65 requests, just those on my list of 'bad' ones (specified in the hosts file). For now the I've switched to '--cache-rr' to lessen the number of requests that make it upstream, and become more aggressive at promoting transient blocking (hosts file) to permanent blocking (--address/--local in the config file).

Ah - that does have the desired effect of avoiding pushing the type 65 record upstream. Thanks for the tip. I'll look into it.

FWIW, I went to review and approve your change and found that the request has been closed.

1 Like

Yeah, thanks, I moved it into a newer PR.

The --local thing looks interesting.

1 Like

Edit: gah. Sorry, yeah, they're global filters for all replies.