diff --git a/CHANGELOG.md b/CHANGELOG.md index 29b5bc7..2b806e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,247 @@ The format is **not** based on [Keep a Changelog][kec], since the project +## AGDNS-1761 / Build 702 + + * The property `upstream` has been modified. Its property `timeout` has been + replaced with the new property `servers.timeout` for each server in the + `servers` list. Concomitantly the `fallback.timeout` has been replaced with + `fallback.servers.timeout` for each fallback server. The `fallback.servers` + now supports not only the addresses of the servers, but URLs in the + `[scheme://]ip:port` format like it's done with the main servers. So replace + this: + + ```yaml + upstream: + # … + servers: + - 'tcp://1.1.1.1:53' + - '127.0.0.1:5358' + timeout: 2s + fallback: + servers: + - 8.8.4.4:53 + timeout: 1s + ``` + + with this: + + ```yaml + upstream: + # … + servers: + - address: 'tcp://1.1.1.1:53' + timeout: 2s + - address: '127.0.0.1:5358' + timeout: 2s + fallback: + servers: + - address: '8.8.4.4:53' + timeout: 1s + ``` + + Adjust the value and add new ones, if necessary. + + + +## AGDNS-698 / Build 701 + + * The object `dns` has new properties: `read_timeout`, `tcp_idle_timeout`, and + `write_timeout`. So replace this: + + ```yaml + dns: + max_udp_response_size: 1024B + ``` + + with this: + + ```yaml + dns: + read_timeout: 2s + tcp_idle_timeout: 30s + write_timeout: 2s + handle_timeout: 1s + max_udp_response_size: 1024B + ``` + + The values in the example are previous defaults. + + + +## AGDNS-1751 / Build 691 + + * The property `upstream.server` has been removed. Its former content is + moved to the newly added property `servers`, which now extended to contain + a list of URLs of main upstream servers. So replace this: + + ```yaml + upstream: + # … + server: `8.8.8.8:53` + ``` + + with this: + + ```yaml + upstream: + # … + servers: + - `8.8.8.8:53` + ``` + + Adjust the value and add new ones, if necessary. + + + +## AGDNS-1759 / Build 684 + + * The object `backend` has a new property, `full_refresh_retry_interval`. So + replace this: + + ```yaml + backend: + # … + full_refresh_interval: 24h + ``` + + with this: + + ```yaml + backend: + # … + full_refresh_interval: 24h + full_refresh_retry_interval: 1h + ``` + + Adjust the value, if necessary. + + + +## AGDNS-1744 / Build 681 + + * Metric `forward_request_total` has a new label `network`. This label + describes the network type (`tcp` or `udp`), over which an upstream has + finished processing request. + + + +## AGDNS-1738 / Build 678 + + * Object `dns` has a new property, describing maximum size of DNS response + over UDP protocol. + + ```yaml + dns: + max_udp_response_size: 1024B + handle_timeout: 1s + ``` + + + +## AGDNS-1735 / Build 677 + + * The property `upstream.fallback` has been changed. Its former content is + moved to the newly added property `servers`. The new property `timeout`, + which describes query timeout to fallback servers, was added. So replace + this: + + ```yaml + upstream: + fallback: + - 1.1.1.1:53 + - 8.8.8.8:53 + ``` + + with this: + + ```yaml + upstream: + fallback: + servers: + - 1.1.1.1:53 + - 8.8.8.8:53 + timeout: 1s + ``` + + Adjust the new values, if necessary. Note that the query timeout to fallback + servers was previously defined with `upstream.timeout` property, which now + describes the query timeout to the primary servers only. + + + +## AGDNS-1178 / Build 676 + + * The new object `dns` has been added: + + ```yaml + dns: + handle_timeout: 1s + ``` + + + +## AGDNS-1620 / Build 673 + + * Object `ratelimit` has two new properties: `quic` and `tcp`. They configure + QUIC and TCP connection limits. Example configuration: + + ```yaml + ratelimit: + # … + quic: + enabled: true + max_streams_per_peer: 100 + tcp: + enabled: true + max_pipeline_count: 100 + ``` + + + +## AGDNS-1684 / Build 661 + + * Profile's file cache version was incremented. The new field `access` has + been added. + + + +## AGDNS-1664 / Build 636 + + * The environment variables `BILLSTAT_URL` and `PROFILES_URL` no longer + support HTTP(s) endpoints. Use GRPC(S) instead. + + + +## AGDNS-1667 / Build 633 + +* `ratelimit` configuration properties `back_off_count`, `back_off_duration` + and `back_off_period` have been renamed to `backoff_count`, + `backoff_duration` and `backoff_period`. So replace this: + + ```yaml + ratelimit: + back_off_period: 10m + back_off_count: 1000 + back_off_duration: 30m + ``` + + with this: + + ```yaml + ratelimit: + backoff_period: 10m + backoff_count: 1000 + backoff_duration: 30m + ``` + + + ## AGDNS-1607 / Build 617 -* New configuration `access` has been added, it has an a list of AdBlock rules - to block requests, and a lists of client subnets to block access from. - Example configuration: + * New configuration `access` has been added, it has an a list of AdBlock rules + to block requests, and a lists of client subnets to block access from. + Example configuration: ```yaml access: @@ -31,10 +267,11 @@ The format is **not** based on [Keep a Changelog][kec], since the project ## AGDNS-1619 / Build 611 -* Added a new metric `bill_stat_upload_duration` that counts the duration of - billing statistics upload. -* The environment variable `BILLSTAT_URL`, which describes the endpoint for - backend billing statistics uploader API, now supports GRPC endpoints. + * Added a new metric `bill_stat_upload_duration` that counts the duration of + billing statistics upload. + + * The environment variable `BILLSTAT_URL`, which describes the endpoint for + backend billing statistics uploader API, now supports GRPC endpoints. @@ -57,7 +294,7 @@ The format is **not** based on [Keep a Changelog][kec], since the project * The optional property `bind_interfaces` of `server_groups.*.servers` objects has been changed, property `subnet` is now an array and has been - ranamed to `subnets`. So replace this: + renamed to `subnets`. So replace this: ```yaml bind_interfaces: @@ -98,6 +335,7 @@ The format is **not** based on [Keep a Changelog][kec], since the project ## AGDNS-1580 / Build 562 * The environment variable `DNSDB_PATH` has been removed. + * New configuration `dnsdb` has been added, it has an enabled/disabled flag and the property `max_size` which describes the maximum amount of records in the in-memory buffer. Example configuration: @@ -944,7 +1182,7 @@ The format is **not** based on [Keep a Changelog][kec], since the project identifiers, grouped by endpoint identifier and known server names. All unknown server names are grouped in `other` label: - ``` + ```none # TYPE dns_tls_handshake_total counter dns_tls_handshake_total{cipher_suite="TLS_AES_128_GCM_SHA256",did_resume="0",negotiated_proto="",proto="tls",server_name="default_dot: other",tls_version="tls1.3"} 4 ``` diff --git a/Makefile b/Makefile index 66973fe..d5d91df 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,7 @@ VERBOSE.MACRO = $${VERBOSE:-0} BRANCH = $$( git rev-parse --abbrev-ref HEAD ) GOAMD64 = v1 GOPROXY = https://goproxy.cn|https://proxy.golang.org|direct +GOTOOLCHAIN = go1.21.5 RACE = 0 REVISION = $$( git rev-parse --short HEAD ) VERSION = 0 @@ -32,6 +33,7 @@ ENV = env\ GO="$(GO.MACRO)"\ GOAMD64='$(GOAMD64)'\ GOPROXY='$(GOPROXY)'\ + GOTOOLCHAIN='$(GOTOOLCHAIN)'\ PATH="$${PWD}/bin:$$( "$(GO.MACRO)" env GOPATH )/bin:$${PATH}"\ RACE='$(RACE)'\ REVISION="$(REVISION)"\ @@ -51,6 +53,7 @@ test: go-test go-bench: ; $(ENV) "$(SHELL)" ./scripts/make/go-bench.sh go-build: ; $(ENV) "$(SHELL)" ./scripts/make/go-build.sh go-deps: ; $(ENV) "$(SHELL)" ./scripts/make/go-deps.sh +go-fuzz: ; $(ENV) "$(SHELL)" ./scripts/make/go-fuzz.sh go-gen: ; $(ENV) "$(SHELL)" ./scripts/make/go-gen.sh go-lint: ; $(ENV) "$(SHELL)" ./scripts/make/go-lint.sh go-test: ; $(ENV) RACE='1' "$(SHELL)" ./scripts/make/go-test.sh @@ -70,4 +73,11 @@ go-os-check: txt-lint: ; $(ENV) "$(SHELL)" ./scripts/make/txt-lint.sh +# TODO(a.garipov): Consider adding to scripts/ and the common project +# structure. +go-upd-tools: + cd ./internal/tools/ &&\ + "$(GO.MACRO)" get -u &&\ + "$(GO.MACRO)" mod tidy + sync-github: ; $(ENV) "$(SHELL)" ./scripts/make/github-sync.sh diff --git a/config.dist.yaml b/config.dist.yaml index 72763f3..378047b 100644 --- a/config.dist.yaml +++ b/config.dist.yaml @@ -24,15 +24,13 @@ ratelimit: subnet_key_len: 48 # The time during which to count the number of times a client has hit the # rate limit for a back off. - # - # TODO(a.garipov): Rename to "backoff_period" along with others. - back_off_period: 10m + backoff_period: 10m # How many times a client hits the rate limit before being held in the back # off. - back_off_count: 1000 + backoff_count: 1000 # How much a client that has hit the rate limit too often stays in the back # off. - back_off_duration: 30m + backoff_duration: 30m # Configuration for the allowlist. allowlist: @@ -52,6 +50,19 @@ ratelimit: stop: 1000 resume: 800 + # Configuration of QUIC streams limiting. + quic: + enabled: true + # The maximum number of concurrent streams that a peer is allowed to + # open. + max_streams_per_peer: 100 + + # Configuration of TCP pipeline limiting. + tcp: + enabled: true + # The maximum number of processing TCP messages per one connection. + max_pipeline_count: 100 + # Access settings. access: # Domains to block. @@ -78,11 +89,17 @@ cache: # DNS upstream configuration. upstream: - server: '8.8.8.8:53' - timeout: 2s + servers: + - address: 'tcp://1.1.1.1:53' + timeout: 2s + - address: '8.8.4.4:53' + timeout: 2s fallback: - - 1.1.1.1:53 - - 8.8.8.8:53 + servers: + - address: '1.1.1.1:53' + timeout: 1s + - address: '8.8.8.8:53' + timeout: 1s healthcheck: enabled: true interval: 2s @@ -90,6 +107,25 @@ upstream: backoff_duration: 30s domain_template: '${RANDOM}.neverssl.com' +# Common DNS settings. +# +# TODO(a.garipov): Consider making these settings per-server-group. +dns: + # The timeout for any read from a UDP connection or the first read from + # a TCP/TLS connection. It currently doesn't affect DNSCrypt, QUIC, or + # HTTPS. + read_timeout: 2s + # The timeout for consecutive reads from a TCP/TLS connection. It currently + # doesn't affect DNSCrypt, QUIC, or HTTPS. + tcp_idle_timeout: 30s + # The timeout for writing to a UDP or TCP/TLS connection. It currently + # doesn't affect DNSCrypt, QUIC, or HTTPS. + write_timeout: 2s + # The timeout for the entire handling of a single query. + handle_timeout: 1s + # UDP response size limit. + max_udp_response_size: 1024B + # DNSDB configuration. dnsdb: enabled: true @@ -106,6 +142,9 @@ backend: refresh_interval: 15s # How often AdGuard DNS performs full synchronization. full_refresh_interval: 24h + # How long to wait before attempting a new full synchronization after a + # failure. + full_refresh_retry_interval: 1h # How often AdGuard DNS sends the billing statistics to the backend. bill_stat_interval: 15s diff --git a/doc/configuration.md b/doc/configuration.md index 8ec88db..ee99059 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -15,6 +15,7 @@ configuration file with comments. * [Cache](#cache) * [Upstream](#upstream) * [Healthcheck](#upstream-healthcheck) + * [Common DNS settings](#dns) * [DNSDB](#dnsdb) * [Backend](#backend) * [Query log](#query_log) @@ -130,13 +131,13 @@ The `ratelimit` object has the following properties: **Example:** `1KB`. - * `back_off_period`: + * `backoff_period`: The time during which to count the number of requests that a client has sent over the RPS. **Example:** `10m`. - * `back_off_duration`: + * `backoff_duration`: How long a client that has hit the RPS too often stays in the backoff state. **Example:** `30m`. @@ -159,10 +160,10 @@ The `ratelimit` object has the following properties: The `ipv6` configuration object has the same properties as the `ipv4` one above. - * `back_off_count`: - Maximum number of requests a client can make above the RPS within - a `back_off_period`. When a client exceeds this limit, requests aren't - allowed from client's subnet until `back_off_duration` ends. + * `backoff_count`: + Maximum number of requests a client can make above the RPS within a + `backoff_period`. When a client exceeds this limit, requests aren't allowed + from client's subnet until `backoff_duration` ends. **Example:** `1000`. @@ -188,11 +189,11 @@ The `ratelimit` object has the following properties: **Example:** `30s`. -For example, if `back_off_period` is `1m`, `back_off_count` is `10`, and +For example, if `backoff_period` is `1m`, `backoff_count` is `10`, and `ipv4-rps` is `5`, a client (meaning all IP addresses within the subnet defined by `ipv4-subnet_key_len`) that made 15 requests in one second or 6 requests (one above `rps`) every second for 10 seconds within one minute, the client is -blocked for `back_off_duration`. +blocked for `backoff_duration`. ### Stream connection limit @@ -218,6 +219,35 @@ The `connection_limit` object has the following properties: See also [notes on these parameters](#recommended-connection_limit). + ### QUIC rate limiting + +The `quic` object has the following properties: + + * `enabled`: + Whether or not the QUIC connections rate limiting should be enforced. + + **Example:** `true`. + + * `max_streams_per_peer`: + The maximum number of concurrent streams that a peer is allowed to open. + + **Example:** `1000`. + + ### TCP rate limiting + +The `tcp` object has the following properties: + + * `enabled`: + Whether or not the TCP rate limiting should be enforced. + + **Example:** `true`. + + * `max_pipeline_count`: + The maximum number of simultaneously processing TCP messages per one + connection. + + **Example:** `1000`. + [env-consul_allowlist_url]: environment.md#CONSUL_ALLOWLIST_URL @@ -269,26 +299,45 @@ The `cache` object has the following properties: The `upstream` object has the following properties: - * `server`: - The URL of the main upstream server, in the `[scheme://]ip:port` format. + * `servers`: + The array of the main upstream servers URLs, in the `[scheme://]ip:port` + format and its timeouts for main upstream DNS requests, as a human-readable + duration. - **Examples:** + **Property example:** - - `8.8.8.8:53`: regular DNS (over UDP with TCP fallback). - - `tcp://1.1.1.1:53`: regular DNS (over TCP). - - `udp://1.1.1.1:53`: regular DNS (over UDP). - - * `timeout`: - Timeout for all outgoing DNS requests, as a human-readable duration. - - **Example:** `2s`. + ```yaml + 'servers': + # Regular DNS (over UDP with TCP fallback). + - address: '8.8.8.8:53' + timeout: 2s + # Regular DNS (over TCP). + - address: 'tcp://1.1.1.1:53' + timeout: 2s + # Regular DNS (over UDP). + - address: 'udp://1.1.1.1:53' + timeout: 2s + ``` * `fallback`: - The array of addresses of the fallback upstream servers, in the `ip:port` - format. These are use used in case a network error occurs while requesting - the main upstream server. + Fallback servers configuration. It has the following properties: - **Example:** `['1.1.1.1:53', '[2001:4860:4860::8888]:53']`. + * `servers`: + The array of the fallback upstream servers URLs, in the + `[scheme://]ip:port` format and its timeouts for upstream DNS requests, + as a human-readable duration. These are use used in case a network error + occurs while requesting the main upstream server. This property has the + same format as [`upstream-servers`](#upstream-servers) above. + + **Property example:** + + ```yaml + 'servers': + - address: '1.1.1.1:53' + timeout: 2s + - address: '[2001:4860:4860::8888]:53' + timeout: 2s + ``` * `healthcheck`: Healthcheck configuration. See [below](#upstream-healthcheck). @@ -341,9 +390,46 @@ connection to the main upstream as restored, and requests are routed back to it. +## DNS + +The `dns` object has the following properties: + + * `read_timeout`: + The timeout for any read from a UDP connection or the first read from + a TCP/TLS connection, as a human-readable duration. It currently doesn't + affect DNSCrypt, QUIC, or HTTPS. + + **Example:** `2s`. + + * `tcp_idle_timeout`: + The timeout for consecutive reads from a TCP/TLS connection, as a + human-readable duration. It currently doesn't affect DNSCrypt, QUIC, or + HTTPS. + + **Example:** `30s`. + + * `write_timeout`: + The timeout for writing to a UDP or TCP/TLS connection, as a human-readable + duration. It currently doesn't affect DNSCrypt, QUIC, or HTTPS. + + **Example:** `2s`. + + * `handle_timeout`: + The timeout for the entire handling of a single query, as a human-readable + duration. + + **Example:** `1s`. + + * `max_udp_response_size`: + The maximum size of DNS response over UDP protocol. + + **Example:** `1024B`. + + + ## DNSDB -The `DNSDB` object has the following properties: +The `dnsdb` object has the following properties: * `enabled`: If true, the DNSDB memory buffer is enabled. @@ -382,6 +468,13 @@ The `backend` object has the following properties: **Example:** `24h`. + * `full_refresh_retry_interval`: + How long to wait before attempting a new full profile synchronization after + a failure, as a human-readable duration. It is recommended to keep this + value greater than [`refresh_interval`](#backend-refresh_interval). + + **Example:** `1h`. + * `bill_stat_interval`: How often AdGuard DNS sends the billing statistics to the backend, as a human-readable duration. @@ -552,9 +645,9 @@ The optional `web` object has the following properties: The optional listen addresses and optional TLS configuration for the web service in addition to the ones in the DNS-over-HTTPS handlers. The `certificates` array has the same format as the one in a server group's [TLS - settings](#sg-*-tls). In the special case of `GET /robots.txt` requests, a - special response is served; this response could be overwritten with static - content. + settings](#server_groups-*-tls). In the special case of `GET /robots.txt` + requests, a special response is served; this response could be overwritten + with static content. **Property example:** @@ -604,7 +697,6 @@ The optional `web` object has the following properties: **Example:** `30s`. [http-block-pages]: http.md#block-pages -[http-dnscheck-test]: http.md#dhscheck-test [http-linked-ip-proxy]: http.md#linked-ip-proxy @@ -677,7 +769,7 @@ The `filters` object has the following properties: * `refresh_interval`: How often AdGuard DNS refreshes the rule-list filters from the filter index, as well as the blocked services list from the [blocked list - index][env-blocked_services)]. + index][env-blocked_services]. **Example:** `1h`. diff --git a/doc/development.md b/doc/development.md index 6b52219..5020058 100644 --- a/doc/development.md +++ b/doc/development.md @@ -13,7 +13,7 @@ Development is supported on Linux and macOS (aka Darwin) systems. -1. Install Go 1.20 or later. +1. Install Go 1.21 or later. 1. Call `make init` to set up the Git pre-commit hook. @@ -74,11 +74,14 @@ This is not an extensive list. See `../Makefile`.