Skip to content

Make DoH-quota separate and configurable, make it possible to limit the number of HTTP/2 streams per connection

Artem Boldariev requested to merge artem/doh-quota-integration into main

This MR adds support for http-listener-clients global options as well as ability to override the default in an HTTP server description, like:

http local-http-server {
    ...
    listener-clients 100;
    ...
};

This way we have ability to specify per-listener active connections quota globally and then override it when required. This is exactly what one of our customers requested: they wanted a functionality to specify quota globally and then override it for specific IPs. This change functionality makes such a configuration possible.

It makes sense: for example, one could have different quotas for internal and external clients. Or, for example, one could use BIND's internal ability to serve encrypted DoH with some sane quota value for internal clients, while having un-encrypted DoH listener without quota to put BIND behind a load balancer doing TLS offloading for external clients.

Moreover, the code no more shares the quota with TCP, which makes little sense anyway (see tcp-clients option), because of the nature of interaction of DoH clients: they tend to keep idle opened connections for longer periods of time, preventing the TCP and TLS client from being served. Thus, the need to have a separate, generally larger, quota for them.

Also, the change makes any option within http <name> { ... }; statement optional, making it easier to override only required default options.

By default, the active DoH connections number is limited to 300 per listener.

Also, this MR makes number of concurrent HTTP/2 streams per connection configurable as a mean to fight DDoS attacks. As soon as the limit is reached, BIND terminates the whole session.

The commit adds a global configuration option (http-streams-per-connection) which can be overridden in an http <name> {...}; statement like follows:

http local-http-server {
    ...
    streams-per-connection 100;
    ...
};

For now the default value is 100, which should be enough (e.g. NGINX uses 128, but it is a full-featured WEB-server). When using lower numbers (e.g. ~70), it is possible to hit the limit with e.g. flamethrower.

I think that this feature is a logical addition to the quota functionality: by using quotas we could limit the number of active HTTP/2 connections, while by using (http-)streams-per-connection we could limit the number of simultaneously streams in an HTTP/2 connection which are, in a way, virtual connections.

Basically, this MR adds all required knobs which are meant to help in a case of DDoS attack. I do not think that we should add any configuration options beyond the ones we will have as soon as this gets merged (Unless someone asks as to and could prove that it is going to be actually useful).

Closes:

Edited by Artem Boldariev

Merge request reports