clientlog: disable NTP response rate limiting by default

This reverts commit 50022e9286.

Testing showed that ntpd as an NTP client performs poorly when it's
getting only 25% of responses. At least for now, disable rate limiting
by default again.
This commit is contained in:
Miroslav Lichvar 2017-01-03 11:34:34 +01:00
parent 14bb9f29a3
commit dbfb49384b
4 changed files with 65 additions and 53 deletions

View file

@ -119,7 +119,7 @@ static int cmd_token_shift;
prevent an attacker sending requests with spoofed source address
from blocking responses to the address completely. */
#define MIN_LEAK_RATE 0
#define MIN_LEAK_RATE 1
#define MAX_LEAK_RATE 4
static int ntp_leak_rate;
@ -305,19 +305,29 @@ CLG_Initialise(void)
{
int interval, burst, leak_rate;
CNF_GetNTPRateLimit(&interval, &burst, &leak_rate);
set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet,
&ntp_token_shift);
ntp_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
max_ntp_tokens = max_cmd_tokens = 0;
ntp_tokens_per_packet = cmd_tokens_per_packet = 0;
ntp_token_shift = cmd_token_shift = 0;
ntp_leak_rate = cmd_leak_rate = 0;
CNF_GetCommandRateLimit(&interval, &burst, &leak_rate);
set_bucket_params(interval, burst, &max_cmd_tokens, &cmd_tokens_per_packet,
&cmd_token_shift);
cmd_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
if (CNF_GetNTPRateLimit(&interval, &burst, &leak_rate)) {
set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet,
&ntp_token_shift);
ntp_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
}
if (CNF_GetCommandRateLimit(&interval, &burst, &leak_rate)) {
set_bucket_params(interval, burst, &max_cmd_tokens, &cmd_tokens_per_packet,
&cmd_token_shift);
cmd_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE);
}
active = !CNF_GetNoClientLog();
if (!active)
if (!active) {
if (ntp_leak_rate || cmd_leak_rate)
LOG_FATAL(LOGF_ClientLog, "ratelimit cannot be used with noclientlog");
return;
}
/* Calculate the maximum number of slots that can be allocated in the
configured memory limit. Take into account expanding of the hash
@ -520,7 +530,7 @@ CLG_LimitNTPResponseRate(int index)
Record *record;
int drop;
if (!ntp_leak_rate)
if (!ntp_tokens_per_packet)
return 0;
record = ARR_GetElement(records, index);
@ -561,7 +571,7 @@ CLG_LimitCommandResponseRate(int index)
{
Record *record;
if (!cmd_leak_rate)
if (!cmd_tokens_per_packet)
return 0;
record = ARR_GetElement(records, index);

31
conf.c
View file

@ -66,7 +66,8 @@ static void parse_log(char *);
static void parse_mailonchange(char *);
static void parse_makestep(char *);
static void parse_maxchange(char *);
static void parse_ratelimit(char *line, int *interval, int *burst, int *leak);
static void parse_ratelimit(char *line, int *enabled, int *interval,
int *burst, int *leak);
static void parse_refclock(char *);
static void parse_smoothtime(char *);
static void parse_source(char *line, NTP_Source_Type type, int pool);
@ -190,12 +191,14 @@ static char *ntp_signd_socket = NULL;
static char *pidfile;
/* Rate limiting parameters */
static int ntp_ratelimit_interval = -10;
static int ntp_ratelimit_burst = 16;
static int ntp_ratelimit_leak = 2;
static int cmd_ratelimit_interval = -10;
static int ntp_ratelimit_enabled = 0;
static int ntp_ratelimit_interval = 3;
static int ntp_ratelimit_burst = 8;
static int ntp_ratelimit_leak = 3;
static int cmd_ratelimit_enabled = 0;
static int cmd_ratelimit_interval = 1;
static int cmd_ratelimit_burst = 16;
static int cmd_ratelimit_leak = 0;
static int cmd_ratelimit_leak = 2;
/* Smoothing constants */
static double smooth_max_freq = 0.0; /* in ppm */
@ -452,7 +455,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
} else if (!strcasecmp(command, "cmdport")) {
parse_int(p, &cmd_port);
} else if (!strcasecmp(command, "cmdratelimit")) {
parse_ratelimit(p, &cmd_ratelimit_interval, &cmd_ratelimit_burst, &cmd_ratelimit_leak);
parse_ratelimit(p, &cmd_ratelimit_enabled, &cmd_ratelimit_interval,
&cmd_ratelimit_burst, &cmd_ratelimit_leak);
} else if (!strcasecmp(command, "combinelimit")) {
parse_double(p, &combine_limit);
} else if (!strcasecmp(command, "corrtimeratio")) {
@ -532,7 +536,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
} else if (!strcasecmp(command, "port")) {
parse_int(p, &ntp_port);
} else if (!strcasecmp(command, "ratelimit")) {
parse_ratelimit(p, &ntp_ratelimit_interval, &ntp_ratelimit_burst, &ntp_ratelimit_leak);
parse_ratelimit(p, &ntp_ratelimit_enabled, &ntp_ratelimit_interval,
&ntp_ratelimit_burst, &ntp_ratelimit_leak);
} else if (!strcasecmp(command, "refclock")) {
parse_refclock(p);
} else if (!strcasecmp(command, "reselectdist")) {
@ -637,11 +642,13 @@ parse_source(char *line, NTP_Source_Type type, int pool)
/* ================================================== */
static void
parse_ratelimit(char *line, int *interval, int *burst, int *leak)
parse_ratelimit(char *line, int *enabled, int *interval, int *burst, int *leak)
{
int n, val;
char *opt;
*enabled = 1;
while (*line) {
opt = line;
line = CPS_SplitWord(line);
@ -1823,20 +1830,22 @@ CNF_GetLockMemory(void)
/* ================================================== */
void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
{
*interval = ntp_ratelimit_interval;
*burst = ntp_ratelimit_burst;
*leak = ntp_ratelimit_leak;
return ntp_ratelimit_enabled;
}
/* ================================================== */
void CNF_GetCommandRateLimit(int *interval, int *burst, int *leak)
int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak)
{
*interval = cmd_ratelimit_interval;
*burst = cmd_ratelimit_burst;
*leak = cmd_ratelimit_leak;
return cmd_ratelimit_enabled;
}
/* ================================================== */

4
conf.h
View file

@ -102,8 +102,8 @@ extern void CNF_SetupAccessRestrictions(void);
extern int CNF_GetSchedPriority(void);
extern int CNF_GetLockMemory(void);
extern void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
extern void CNF_GetCommandRateLimit(int *interval, int *burst, int *leak);
extern int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
extern int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak);
extern void CNF_GetSmooth(double *max_freq, double *max_wander, int *leap_only);
extern void CNF_GetTempComp(char **file, double *interval, char **point_file, double *T0, double *k0, double *k1, double *k2);

View file

@ -1221,8 +1221,8 @@ source port used in NTP client requests can be set by the
<<acquisitionport,*acquisitionport*>> directive.
[[ratelimit]]*ratelimit* [_option_]...::
This directive configures response rate limiting for NTP packets. Its purpose
is to reduce network traffic with misconfigured or broken NTP clients that are
This directive enables response rate limiting for NTP packets. Its purpose is
to reduce network traffic with misconfigured or broken NTP clients that are
polling the server too frequently. The limits are applied to individual IP
addresses. If multiple clients share one IP address (e.g. multiple hosts behind
NAT), the sum of their traffic will be limited. If a client that increases its
@ -1237,40 +1237,35 @@ in any order):
+
*interval*:::
This option sets the minimum interval between responses. It is defined as a
power of 2 in seconds. The default value is -10 (1/1024 of a second, or 1024
packets per second). The minimum value is -19 (524288 packets per second) and
the maximum value is 12 (one packet per 4096 seconds). Note that with values
below -4 the rate limiting is coarse (responses are allowed in bursts, even if
the interval between them is shorter than the specified interval).
power of 2 in seconds. The default value is 3 (8 seconds). The minimum value
is -19 and the maximum value is 12. Note that with values below -4 the rate
limiting is coarse (responses are allowed in bursts, even if the interval
between them is shorter than the specified interval).
*burst*:::
This option sets the maximum number of responses that can be sent in a burst,
temporarily exceeding the limit specified by the *interval* option. This is
useful for clients that make rapid measurements on start (e.g. *chronyd* with
the *iburst* option). The default value is 16. The minimum value is 1 and the
the *iburst* option). The default value is 8. The minimum value is 1 and the
maximum value is 255.
*leak*:::
This option sets the rate at which responses are randomly allowed even if the
limits specified by the *interval* and *burst* options are exceeded. This is
necessary to prevent an attacker who is sending requests with a spoofed
source address from completely blocking responses to that address. The leak
rate is defined as a power of 1/2 and it is 2 by default, i.e. on average at
least every fourth request has a response. The minimum value is 0, which
disables the rate limiting, and the maximum value is 4 (one response per 16
requests).
rate is defined as a power of 1/2 and it is 3 by default, i.e. on average at
least every eighth request has a response. The minimum value is 1 and the
maximum value is 4.
::
+
An example use of the directive is:
+
----
ratelimit interval 1 burst 8
ratelimit interval 4 burst 4
----
+
This would reduce the response rate for IP addresses sending packets on average
more than once per 2 seconds, or sending packets in bursts of more than 8
packets, by up to 75% (with default *leak* of 2).
+
Rate limiting can be disabled by setting the *leak* option to 0, or by the
<<noclientlog,*noclientlog*>> directive.
This would reduce the response rate for IP addresses that send packets on
average more frequently than once per 16 seconds or send packets in bursts
of more than 4 packets.
[[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]::
The *smoothtime* directive can be used to enable smoothing of the time that
@ -1397,18 +1392,16 @@ This would make *chronyd* use UDP 257 as its command port. (*chronyc* would
need to be run with the *-p 257* switch to inter-operate correctly.)
[[cmdratelimit]]*cmdratelimit* [_option_]...::
This directive is identical to the <<ratelimit,*ratelimit*>> directive, except
it configures rate limiting for command packets and responses to localhost are
never limited. It is disabled by default (the default *leak* is 0).
This directive enables response rate limiting for command packets. It is
similar to the <<ratelimit,*ratelimit*>> directive, except responses to
localhost are never limited and the default interval is 1 (2 seconds), the default
burst is 16, and the default leak rate is 2.
+
An example of the use of the directive is:
+
----
cmdratelimit interval -2 burst 128 leak 2
cmdratelimit interval 2
----
+
This would reduce response rate for addresses that send more than 4 requests
per second, or bursts of more than 128 packets, by up to 75%.
=== Real-time clock (RTC)
@ -2227,7 +2220,7 @@ http://www.pool.ntp.org/en/join.html[pool.ntp.org] project. The configuration
is similar to the NTP client with permanent connection, except it needs to
allow client access from all addresses. It is recommended to handpick at least
few good servers, and possibly combine them with a random selection of other
servers in the pool. The rate limiting interval can be increased to save more
servers in the pool. Rate limiting can be enabled to not waste too much
bandwidth on misconfigured and broken NTP clients. The *-r* option with the
*dumpdir* directive shortens the time for which *chronyd* will not serve time
to its clients when it needs to be restarted for any reason.
@ -2242,7 +2235,7 @@ pool pool.ntp.org iburst
makestep 1.0 3
rtcsync
allow
ratelimit interval 1
ratelimit interval 2 burst 10
driftfile @CHRONYVARDIR@/drift
dumpdir @CHRONYRUNDIR@
dumponexit