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 prevent an attacker sending requests with spoofed source address
from blocking responses to the address completely. */ from blocking responses to the address completely. */
#define MIN_LEAK_RATE 0 #define MIN_LEAK_RATE 1
#define MAX_LEAK_RATE 4 #define MAX_LEAK_RATE 4
static int ntp_leak_rate; static int ntp_leak_rate;
@ -305,19 +305,29 @@ CLG_Initialise(void)
{ {
int interval, burst, leak_rate; int interval, burst, leak_rate;
CNF_GetNTPRateLimit(&interval, &burst, &leak_rate); max_ntp_tokens = max_cmd_tokens = 0;
set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet, ntp_tokens_per_packet = cmd_tokens_per_packet = 0;
&ntp_token_shift); ntp_token_shift = cmd_token_shift = 0;
ntp_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE); ntp_leak_rate = cmd_leak_rate = 0;
CNF_GetCommandRateLimit(&interval, &burst, &leak_rate); if (CNF_GetNTPRateLimit(&interval, &burst, &leak_rate)) {
set_bucket_params(interval, burst, &max_cmd_tokens, &cmd_tokens_per_packet, set_bucket_params(interval, burst, &max_ntp_tokens, &ntp_tokens_per_packet,
&cmd_token_shift); &ntp_token_shift);
cmd_leak_rate = CLAMP(MIN_LEAK_RATE, leak_rate, MAX_LEAK_RATE); 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(); 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; return;
}
/* Calculate the maximum number of slots that can be allocated in the /* Calculate the maximum number of slots that can be allocated in the
configured memory limit. Take into account expanding of the hash configured memory limit. Take into account expanding of the hash
@ -520,7 +530,7 @@ CLG_LimitNTPResponseRate(int index)
Record *record; Record *record;
int drop; int drop;
if (!ntp_leak_rate) if (!ntp_tokens_per_packet)
return 0; return 0;
record = ARR_GetElement(records, index); record = ARR_GetElement(records, index);
@ -561,7 +571,7 @@ CLG_LimitCommandResponseRate(int index)
{ {
Record *record; Record *record;
if (!cmd_leak_rate) if (!cmd_tokens_per_packet)
return 0; return 0;
record = ARR_GetElement(records, index); 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_mailonchange(char *);
static void parse_makestep(char *); static void parse_makestep(char *);
static void parse_maxchange(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_refclock(char *);
static void parse_smoothtime(char *); static void parse_smoothtime(char *);
static void parse_source(char *line, NTP_Source_Type type, int pool); 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; static char *pidfile;
/* Rate limiting parameters */ /* Rate limiting parameters */
static int ntp_ratelimit_interval = -10; static int ntp_ratelimit_enabled = 0;
static int ntp_ratelimit_burst = 16; static int ntp_ratelimit_interval = 3;
static int ntp_ratelimit_leak = 2; static int ntp_ratelimit_burst = 8;
static int cmd_ratelimit_interval = -10; 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_burst = 16;
static int cmd_ratelimit_leak = 0; static int cmd_ratelimit_leak = 2;
/* Smoothing constants */ /* Smoothing constants */
static double smooth_max_freq = 0.0; /* in ppm */ 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")) { } else if (!strcasecmp(command, "cmdport")) {
parse_int(p, &cmd_port); parse_int(p, &cmd_port);
} else if (!strcasecmp(command, "cmdratelimit")) { } 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")) { } else if (!strcasecmp(command, "combinelimit")) {
parse_double(p, &combine_limit); parse_double(p, &combine_limit);
} else if (!strcasecmp(command, "corrtimeratio")) { } else if (!strcasecmp(command, "corrtimeratio")) {
@ -532,7 +536,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
} else if (!strcasecmp(command, "port")) { } else if (!strcasecmp(command, "port")) {
parse_int(p, &ntp_port); parse_int(p, &ntp_port);
} else if (!strcasecmp(command, "ratelimit")) { } 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")) { } else if (!strcasecmp(command, "refclock")) {
parse_refclock(p); parse_refclock(p);
} else if (!strcasecmp(command, "reselectdist")) { } else if (!strcasecmp(command, "reselectdist")) {
@ -637,11 +642,13 @@ parse_source(char *line, NTP_Source_Type type, int pool)
/* ================================================== */ /* ================================================== */
static void 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; int n, val;
char *opt; char *opt;
*enabled = 1;
while (*line) { while (*line) {
opt = line; opt = line;
line = CPS_SplitWord(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; *interval = ntp_ratelimit_interval;
*burst = ntp_ratelimit_burst; *burst = ntp_ratelimit_burst;
*leak = ntp_ratelimit_leak; *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; *interval = cmd_ratelimit_interval;
*burst = cmd_ratelimit_burst; *burst = cmd_ratelimit_burst;
*leak = cmd_ratelimit_leak; *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_GetSchedPriority(void);
extern int CNF_GetLockMemory(void); extern int CNF_GetLockMemory(void);
extern void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak); extern int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
extern void CNF_GetCommandRateLimit(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_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); 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. <<acquisitionport,*acquisitionport*>> directive.
[[ratelimit]]*ratelimit* [_option_]...:: [[ratelimit]]*ratelimit* [_option_]...::
This directive configures response rate limiting for NTP packets. Its purpose This directive enables response rate limiting for NTP packets. Its purpose is
is to reduce network traffic with misconfigured or broken NTP clients that are to reduce network traffic with misconfigured or broken NTP clients that are
polling the server too frequently. The limits are applied to individual IP 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 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 NAT), the sum of their traffic will be limited. If a client that increases its
@ -1237,40 +1237,35 @@ in any order):
+ +
*interval*::: *interval*:::
This option sets the minimum interval between responses. It is defined as a 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 power of 2 in seconds. The default value is 3 (8 seconds). The minimum value
packets per second). The minimum value is -19 (524288 packets per second) and is -19 and the maximum value is 12. Note that with values below -4 the rate
the maximum value is 12 (one packet per 4096 seconds). Note that with values limiting is coarse (responses are allowed in bursts, even if the interval
below -4 the rate limiting is coarse (responses are allowed in bursts, even if between them is shorter than the specified interval).
the interval between them is shorter than the specified interval).
*burst*::: *burst*:::
This option sets the maximum number of responses that can be sent in a 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 temporarily exceeding the limit specified by the *interval* option. This is
useful for clients that make rapid measurements on start (e.g. *chronyd* with 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. maximum value is 255.
*leak*::: *leak*:::
This option sets the rate at which responses are randomly allowed even if the 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 limits specified by the *interval* and *burst* options are exceeded. This is
necessary to prevent an attacker who is sending requests with a spoofed necessary to prevent an attacker who is sending requests with a spoofed
source address from completely blocking responses to that address. The leak 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 rate is defined as a power of 1/2 and it is 3 by default, i.e. on average at
least every fourth request has a response. The minimum value is 0, which least every eighth request has a response. The minimum value is 1 and the
disables the rate limiting, and the maximum value is 4 (one response per 16 maximum value is 4.
requests).
:: ::
+ +
An example use of the directive is: 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 This would reduce the response rate for IP addresses that send packets on
more than once per 2 seconds, or sending packets in bursts of more than 8 average more frequently than once per 16 seconds or send packets in bursts
packets, by up to 75% (with default *leak* of 2). of more than 4 packets.
+
Rate limiting can be disabled by setting the *leak* option to 0, or by the
<<noclientlog,*noclientlog*>> directive.
[[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]:: [[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]::
The *smoothtime* directive can be used to enable smoothing of the time that 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.) need to be run with the *-p 257* switch to inter-operate correctly.)
[[cmdratelimit]]*cmdratelimit* [_option_]...:: [[cmdratelimit]]*cmdratelimit* [_option_]...::
This directive is identical to the <<ratelimit,*ratelimit*>> directive, except This directive enables response rate limiting for command packets. It is
it configures rate limiting for command packets and responses to localhost are similar to the <<ratelimit,*ratelimit*>> directive, except responses to
never limited. It is disabled by default (the default *leak* is 0). 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: 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) === 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 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 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 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 bandwidth on misconfigured and broken NTP clients. The *-r* option with the
*dumpdir* directive shortens the time for which *chronyd* will not serve time *dumpdir* directive shortens the time for which *chronyd* will not serve time
to its clients when it needs to be restarted for any reason. 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 makestep 1.0 3
rtcsync rtcsync
allow allow
ratelimit interval 1 ratelimit interval 2 burst 10
driftfile @CHRONYVARDIR@/drift driftfile @CHRONYVARDIR@/drift
dumpdir @CHRONYRUNDIR@ dumpdir @CHRONYRUNDIR@
dumponexit dumponexit