Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relation with cache plugin: how to restrict both before and after the cache with different configurations? #42

Open
norbjd opened this issue Nov 3, 2024 · 0 comments

Comments

@norbjd
Copy link

norbjd commented Nov 3, 2024

Hello 👋

Before starting, thanks for the plugin, it is very useful 💝

Depending on where the plugin is put in the plugin.cfg (or included in the directives in a go file), I have noticed that with the same configuration, we can control where the rate limiting takes place; either before the cache, or after the cache. For reference, I am using the following Corefile:

. {
    cache
    forward . /etc/resolv.conf
    rrl . {
        ipv4-prefix-length   32 # every different IP
        requests-per-second  20
        responses-per-second 20
    }
}

With this configuration:

  1. if rrl is declared before the cache plugin, rrl restricts all DNS queries, even if they appear to be cached
  2. if rrl is declared after the cache plugin, rrl only restricts DNS queries that resulted in a cache miss

I assume it is the way coredns chain of plugins work, so nothing new, but both cases have different impacts that do not fulfill what I want to do.

Solution (1) is obviously more restrictive, but there are some cases where we don't want to be as strict. For example, a user making many (but still reasonable) HTTP calls with curl to the same website might generate a lot of DNS queries (without even knowing it), but it is not necessary a problem as coredns is very effective when it comes to get cached records.

Solution (2) answers that issue but still protect the upstream resolvers. Though, it opens to flood as a bad user can send 10k DNS queries/sec with the same record, without triggering the rate limit.

I am wondering if it is possible to have both:

  • a "global" rate limit, enforced before the cache
  • a "new records" rate limit (not very inspired about the name), enforced after the cache

As an example, the "global" rate limit could be something like 1000 req/s/IP, while the "new records" rate limit could be 20 req/s/IP, to avoid abusers to flood the upstream resolvers (in /etc/resolv.conf in my previous example).

I assume that it is not possible out of the box, as rrl plugin before the cache know nothing about the cache, and after it, it can't filter things that cache plugin answered before 🤷. The simplest solution I can think of (not sure if it works) would be to have 2 rrl plugins, declared like this in plugin.cfg:

...
rrl-global:github.com/coredns/rrl
...
cache
...
rrl-new-records:github.com/coredns/rrl
...

And declare:

. {
    cache
    forward . /etc/resolv.conf
    rrl-global . {
        ipv4-prefix-length   32 # every different IP
        requests-per-second  1000
        responses-per-second 1000
    }
    rrl-new-records . {
        ipv4-prefix-length   32 # every different IP
        requests-per-second  20
        responses-per-second 20
    }
}

Do you see a better solution to restrict both "before the cache" to protect coredns, and "after the cache" to protect upstream resolvers? Maybe I'm just overengineering and rrl plugin before the cache is always useless, as it might take as much resources for coredns to reject the query as just answer what is in the cache.

Anyway, looking forward to read more if you have ideas.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant