Dnscrypt-proxy: Improvement: Cache responses from entries in IP blacklist

Created on 24 Jul 2020  路  6Comments  路  Source: DNSCrypt/dnscrypt-proxy

An upstream DNS response whose IP pattern is listed in the IP blacklist is correctly blocked, but is not cached by dnscrypt-proxy.

Whereas entries in the name-based blacklist are blocked and cached as expected.

Who will that feature be useful to?

IP blacklist users where hosts are regularly resolved to blocked IPs which can cause a large number of redundant queries to the upstream server.

How do we replicate the issue?

  • Enable IP blacklist and query logging
  • Add an IP to the list with a consistent host such as 1.1.1.1
    - Keep the default reject_ttl = 600 in dnscrypt-proxy.toml
  • Restart dnscrypt-proxy
  • dig 1dot1dot1dot1.cloudflare-dns.com (response should be HINFO block message)
  • Repeat dig 1dot1dot1dot1.cloudflare-dns.com a few times and check the query log:
1dot1dot1dot1.cloudflare-dns.com    A   REJECT  15ms    cloudflare
1dot1dot1dot1.cloudflare-dns.com    A   REJECT  14ms    cloudflare
1dot1dot1dot1.cloudflare-dns.com    A   REJECT  17ms    cloudflare

Every request is sent upstream as it isn't cached.

Expected behavior (i.e. solution)

Subsequent queries should be cached during the reject_ttl period:

1dot1dot1dot1.cloudflare-dns.com    A   REJECT  0ms -
1dot1dot1dot1.cloudflare-dns.com    A   REJECT  1ms -
1dot1dot1dot1.cloudflare-dns.com    A   REJECT  0ms -
feature request timeout

All 6 comments

Are you sure about name-based blocks being cached? I had a quick look at the code:

  • For outbound queries, name-based blocking happens before checking the cache, which would of course happen very quickly just like a cached response and also wouldn't send anything to any server.
  • For inbound responses, both IP- and name-based blocking happens before (and prevents) caching, which means you need to wait for a response every time before it will be blocked.

The reject_ttl setting is used to set the TTL on the response packet sent back to clients, not to store the rejection in the cache. Perhaps that's something we could improve, but I'd probably call this a feature or improvement rather than a bug.

Thanks for checking the code and clarifying the purpose of the reject_ttl setting.

You're right, outbound name-based blocks wouldn't need to be cached. I misinterpreted the log entries of name-based blocks like REJECT 0ms - as cached responses.

I'll reword this as a feature request!

For inbound responses, both IP- and name-based blocking happens before (and prevents) caching

Yes, this is something that can be improved.

But this is not as easy as caching before blocking. By doing so, the first response would be properly blocked, but the next ones would be directly served from the cache, so they wouldn't be blocked.

We can't cache responses after they have been modified either, as it would prevent things such as time-based blocking from working as expected.

Thanks @jedisct1, it sounds like implementing this would be more tricky than I imagined.

I'll take a look myself when I can.

Are you sure about name-based blocks being cached? I had a quick look at the code:

  • For outbound queries, name-based blocking happens before checking the cache, which would of course happen very quickly just like a cached response and also wouldn't send anything to any server.
  • For inbound responses, both IP- and name-based blocking happens before (and prevents) caching, which means you need to wait for a response every time before it will be blocked.

The reject_ttl setting is used to set the TTL on the response packet sent back to clients, not to store the rejection in the cache. Perhaps that's something we could improve, but I'd probably call this a feature or improvement rather than a bug.

is it possible to disable reject_ttl ? i have no blocklists in dnscrypt proxy and i am not blocking ipv6 but i am interested in a performance boost if i can disable an unnecessary feature

is it necessary to use
blocked_query_response ?

is it possible to disable reject_ttl ? i have no blocklists in dnscrypt proxy and i am not blocking ipv6 but i am interested in a performance boost if i can disable an unnecessary feature

is it necessary to use
blocked_query_response ?

The settings are loaded at startup and use default values if you don't set them. reject_ttl is stored as a uint32 in 2 places, each instance of which will consume 4 bytes of memory (I'm not sure if this is to allow other plugins to override, perhaps there's a very minor saving to be made here). blocked_query_response is parsed at startup, if you don't set IP addresses then all it does is set a bool which takes up 1 byte of memory. All these values are only used when generating a REJECT response. Since you already are not generating such responses, there is no performance to be gained.

Was this page helpful?
0 / 5 - 0 ratings