clientlog: enable NTP response rate limiting by default
Change the default interval of both NTP and command rate limiting to -10 (1024 packets per second) and the burst to 16. The default NTP leak is 2 (rate limiting is enabled by default) and the default command leak is 0 (rate limiting is disabled by default).
This commit is contained in:
parent
5059019535
commit
50022e9286
4 changed files with 53 additions and 65 deletions
22
clientlog.c
22
clientlog.c
|
@ -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 1
|
||||
#define MIN_LEAK_RATE 0
|
||||
#define MAX_LEAK_RATE 4
|
||||
|
||||
static int ntp_leak_rate;
|
||||
|
@ -305,29 +305,19 @@ CLG_Initialise(void)
|
|||
{
|
||||
int interval, burst, 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;
|
||||
|
||||
if (CNF_GetNTPRateLimit(&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);
|
||||
}
|
||||
|
||||
if (CNF_GetCommandRateLimit(&interval, &burst, &leak_rate)) {
|
||||
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 (ntp_leak_rate || cmd_leak_rate)
|
||||
LOG_FATAL(LOGF_ClientLog, "ratelimit cannot be used with noclientlog");
|
||||
if (!active)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the maximum number of slots that can be allocated in the
|
||||
configured memory limit. Take into account expanding of the hash
|
||||
|
@ -530,7 +520,7 @@ CLG_LimitNTPResponseRate(int index)
|
|||
Record *record;
|
||||
int drop;
|
||||
|
||||
if (!ntp_tokens_per_packet)
|
||||
if (!ntp_leak_rate)
|
||||
return 0;
|
||||
|
||||
record = ARR_GetElement(records, index);
|
||||
|
@ -571,7 +561,7 @@ CLG_LimitCommandResponseRate(int index)
|
|||
{
|
||||
Record *record;
|
||||
|
||||
if (!cmd_tokens_per_packet)
|
||||
if (!cmd_leak_rate)
|
||||
return 0;
|
||||
|
||||
record = ARR_GetElement(records, index);
|
||||
|
|
31
conf.c
31
conf.c
|
@ -66,8 +66,7 @@ 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 *enabled, int *interval,
|
||||
int *burst, int *leak);
|
||||
static void parse_ratelimit(char *line, 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);
|
||||
|
@ -191,14 +190,12 @@ static char *ntp_signd_socket = NULL;
|
|||
static char *pidfile;
|
||||
|
||||
/* Rate limiting parameters */
|
||||
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 ntp_ratelimit_interval = -10;
|
||||
static int ntp_ratelimit_burst = 16;
|
||||
static int ntp_ratelimit_leak = 2;
|
||||
static int cmd_ratelimit_interval = -10;
|
||||
static int cmd_ratelimit_burst = 16;
|
||||
static int cmd_ratelimit_leak = 2;
|
||||
static int cmd_ratelimit_leak = 0;
|
||||
|
||||
/* Smoothing constants */
|
||||
static double smooth_max_freq = 0.0; /* in ppm */
|
||||
|
@ -455,8 +452,7 @@ 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_enabled, &cmd_ratelimit_interval,
|
||||
&cmd_ratelimit_burst, &cmd_ratelimit_leak);
|
||||
parse_ratelimit(p, &cmd_ratelimit_interval, &cmd_ratelimit_burst, &cmd_ratelimit_leak);
|
||||
} else if (!strcasecmp(command, "combinelimit")) {
|
||||
parse_double(p, &combine_limit);
|
||||
} else if (!strcasecmp(command, "corrtimeratio")) {
|
||||
|
@ -536,8 +532,7 @@ 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_enabled, &ntp_ratelimit_interval,
|
||||
&ntp_ratelimit_burst, &ntp_ratelimit_leak);
|
||||
parse_ratelimit(p, &ntp_ratelimit_interval, &ntp_ratelimit_burst, &ntp_ratelimit_leak);
|
||||
} else if (!strcasecmp(command, "refclock")) {
|
||||
parse_refclock(p);
|
||||
} else if (!strcasecmp(command, "reselectdist")) {
|
||||
|
@ -642,13 +637,11 @@ parse_source(char *line, NTP_Source_Type type, int pool)
|
|||
/* ================================================== */
|
||||
|
||||
static void
|
||||
parse_ratelimit(char *line, int *enabled, int *interval, int *burst, int *leak)
|
||||
parse_ratelimit(char *line, int *interval, int *burst, int *leak)
|
||||
{
|
||||
int n, val;
|
||||
char *opt;
|
||||
|
||||
*enabled = 1;
|
||||
|
||||
while (*line) {
|
||||
opt = line;
|
||||
line = CPS_SplitWord(line);
|
||||
|
@ -1830,22 +1823,20 @@ CNF_GetLockMemory(void)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
|
||||
void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak)
|
||||
{
|
||||
*interval = ntp_ratelimit_interval;
|
||||
*burst = ntp_ratelimit_burst;
|
||||
*leak = ntp_ratelimit_leak;
|
||||
return ntp_ratelimit_enabled;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak)
|
||||
void 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
4
conf.h
|
@ -102,8 +102,8 @@ extern void CNF_SetupAccessRestrictions(void);
|
|||
extern int CNF_GetSchedPriority(void);
|
||||
extern int CNF_GetLockMemory(void);
|
||||
|
||||
extern int CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
|
||||
extern int CNF_GetCommandRateLimit(int *interval, int *burst, int *leak);
|
||||
extern void CNF_GetNTPRateLimit(int *interval, int *burst, int *leak);
|
||||
extern void 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);
|
||||
|
||||
|
|
|
@ -1221,8 +1221,8 @@ source port used in NTP client requests can be set by the
|
|||
<<acquisitionport,*acquisitionport*>> directive.
|
||||
|
||||
[[ratelimit]]*ratelimit* [_option_]...::
|
||||
This directive enables response rate limiting for NTP packets. Its purpose is
|
||||
to reduce network traffic with misconfigured or broken NTP clients that are
|
||||
This directive configures 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,35 +1237,40 @@ 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 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).
|
||||
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).
|
||||
*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 8. The minimum value is 1 and the
|
||||
the *iburst* option). The default value is 16. 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 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.
|
||||
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).
|
||||
::
|
||||
+
|
||||
An example use of the directive is:
|
||||
+
|
||||
----
|
||||
ratelimit interval 4 burst 4
|
||||
ratelimit interval 1 burst 8
|
||||
----
|
||||
+
|
||||
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.
|
||||
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.
|
||||
|
||||
[[smoothtime]]*smoothtime* _max-freq_ _max-wander_ [*leaponly*]::
|
||||
The *smoothtime* directive can be used to enable smoothing of the time that
|
||||
|
@ -1392,16 +1397,18 @@ 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 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.
|
||||
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).
|
||||
+
|
||||
An example of the use of the directive is:
|
||||
+
|
||||
----
|
||||
cmdratelimit interval 2
|
||||
cmdratelimit interval -2 burst 128 leak 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)
|
||||
|
||||
|
@ -2220,7 +2227,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. Rate limiting can be enabled to not waste too much
|
||||
servers in the pool. The rate limiting interval can be increased to save more
|
||||
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.
|
||||
|
@ -2235,7 +2242,7 @@ pool pool.ntp.org iburst
|
|||
makestep 1.0 3
|
||||
rtcsync
|
||||
allow
|
||||
ratelimit interval 2 burst 10
|
||||
ratelimit interval 1
|
||||
driftfile @CHRONYVARDIR@/drift
|
||||
dumpdir @CHRONYRUNDIR@
|
||||
dumponexit
|
||||
|
|
Loading…
Reference in a new issue