mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 03:55:07 -05:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0639205617 | ||
|
|
3916c3366b | ||
|
|
f0a33e7b28 | ||
|
|
c9b8f8bc70 | ||
|
|
983b0723f6 | ||
|
|
02c38934ea | ||
|
|
c28c2cde43 | ||
|
|
349323dec7 | ||
|
|
ddfaf2e542 | ||
|
|
3177474ae8 | ||
|
|
cc535632d1 | ||
|
|
cb8ee57b9e | ||
|
|
c0b19b3fea | ||
|
|
8235da6885 | ||
|
|
f6625717cd | ||
|
|
fdfcabd79b | ||
|
|
2bb88b45c6 | ||
|
|
9820c22c1d | ||
|
|
bcd7bad467 | ||
|
|
83ea9fe284 | ||
|
|
c74d6e458d | ||
|
|
ff466439fc | ||
|
|
0fcdf4389b | ||
|
|
9cb9021c87 | ||
|
|
9c36236742 | ||
|
|
adebb027be | ||
|
|
7d3798d7cd | ||
|
|
b7c7c293e5 | ||
|
|
9ca250755f | ||
|
|
bd3b36865e | ||
|
|
538e1c5eb1 |
9
NEWS
9
NEWS
@@ -8,11 +8,13 @@ Enhancements
|
||||
* Add authselectmode directive to control selection of unauthenticated sources
|
||||
* Add binddevice, bindacqdevice, bindcmddevice directives
|
||||
* Add confdir directive to better support fragmented configuration
|
||||
* Add sourcedir directive and "reload sources" command to support
|
||||
dynamic NTP sources specified in files
|
||||
* Add sourcedir directive and "reload sources" command to support dynamic
|
||||
NTP sources specified in files
|
||||
* Add clockprecision directive
|
||||
* Add dscp directive to set Differentiated Services Code Point (DSCP)
|
||||
* Add -L option to limit log messages by severity
|
||||
* Add -p option to print whole configuration with included files
|
||||
* Add -U option to allow start under non-root user
|
||||
* Allow maxsamples to be set to 1 for faster update with -q/-Q option
|
||||
* Avoid replacing NTP sources with sources that have unreachable address
|
||||
* Improve pools to repeat name resolution to get "maxsources" sources
|
||||
@@ -38,6 +40,9 @@ Bug fixes
|
||||
Removed features
|
||||
----------------
|
||||
* Drop support for RIPEMD keys (RMD128, RMD160, RMD256, RMD320)
|
||||
* Drop support for long (non-standard) MACs in NTPv4 packets (chrony 2.x
|
||||
clients using non-MD5/SHA1 keys need to use option "version 3")
|
||||
* Drop support for line editing with GNU Readline
|
||||
|
||||
New in version 3.5.1
|
||||
====================
|
||||
|
||||
8
candm.h
8
candm.h
@@ -553,12 +553,12 @@ typedef struct {
|
||||
#define RPY_SD_MD_PEER 1
|
||||
#define RPY_SD_MD_REF 2
|
||||
|
||||
#define RPY_SD_ST_SYNC 0
|
||||
#define RPY_SD_ST_UNREACH 1
|
||||
#define RPY_SD_ST_SELECTED 0
|
||||
#define RPY_SD_ST_NONSELECTABLE 1
|
||||
#define RPY_SD_ST_FALSETICKER 2
|
||||
#define RPY_SD_ST_JITTERY 3
|
||||
#define RPY_SD_ST_CANDIDATE 4
|
||||
#define RPY_SD_ST_OUTLIER 5
|
||||
#define RPY_SD_ST_UNSELECTED 4
|
||||
#define RPY_SD_ST_SELECTABLE 5
|
||||
|
||||
typedef struct {
|
||||
IPAddr ip_addr;
|
||||
|
||||
23
client.c
23
client.c
@@ -4,7 +4,7 @@
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Lonnie Abelbeck 2016, 2018
|
||||
* Copyright (C) Miroslav Lichvar 2009-2018
|
||||
* Copyright (C) Miroslav Lichvar 2009-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -44,12 +44,7 @@
|
||||
#include "util.h"
|
||||
|
||||
#ifdef FEAT_READLINE
|
||||
#ifdef USE_EDITLINE
|
||||
#include <editline/readline.h>
|
||||
#else
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ================================================== */
|
||||
@@ -1267,7 +1262,7 @@ give_help(void)
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
/* Tab-completion when editline/readline is available */
|
||||
/* Tab-completion when editline is available */
|
||||
|
||||
#ifdef FEAT_READLINE
|
||||
|
||||
@@ -2146,8 +2141,8 @@ process_cmd_sources(char *line)
|
||||
if (verbose) {
|
||||
printf("\n");
|
||||
printf(" .-- Source mode '^' = server, '=' = peer, '#' = local clock.\n");
|
||||
printf(" / .- Source state '*' = current synced, '+' = combined , '-' = not combined,\n");
|
||||
printf("| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.\n");
|
||||
printf(" / .- Source state '*' = current best, '+' = combined, '-' = not combined,\n");
|
||||
printf("| / 'x' = may be in error, '~' = too variable, '?' = unusable.\n");
|
||||
printf("|| .- xxxx [ yyyy ] +/- zzzz\n");
|
||||
printf("|| Reachability register (octal) -. | xxxx = adjusted offset,\n");
|
||||
printf("|| Log2(Polling interval) --. | | yyyy = measured offset,\n");
|
||||
@@ -2189,10 +2184,10 @@ process_cmd_sources(char *line)
|
||||
}
|
||||
|
||||
switch (ntohs(reply.data.source_data.state)) {
|
||||
case RPY_SD_ST_SYNC:
|
||||
case RPY_SD_ST_SELECTED:
|
||||
state_ch = '*';
|
||||
break;
|
||||
case RPY_SD_ST_UNREACH:
|
||||
case RPY_SD_ST_NONSELECTABLE:
|
||||
state_ch = '?';
|
||||
break;
|
||||
case RPY_SD_ST_FALSETICKER:
|
||||
@@ -2201,10 +2196,10 @@ process_cmd_sources(char *line)
|
||||
case RPY_SD_ST_JITTERY:
|
||||
state_ch = '~';
|
||||
break;
|
||||
case RPY_SD_ST_CANDIDATE:
|
||||
case RPY_SD_ST_UNSELECTED:
|
||||
state_ch = '+';
|
||||
break;
|
||||
case RPY_SD_ST_OUTLIER:
|
||||
case RPY_SD_ST_SELECTABLE:
|
||||
state_ch = '-';
|
||||
break;
|
||||
default:
|
||||
@@ -3476,7 +3471,7 @@ static void
|
||||
display_gpl(void)
|
||||
{
|
||||
printf("chrony version %s\n"
|
||||
"Copyright (C) 1997-2003, 2007, 2009-2019 Richard P. Curnow and others\n"
|
||||
"Copyright (C) 1997-2003, 2007, 2009-2020 Richard P. Curnow and others\n"
|
||||
"chrony comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"
|
||||
"you are welcome to redistribute it under certain conditions. See the\n"
|
||||
"GNU General Public License version 2 for details.\n\n",
|
||||
|
||||
48
cmdmon.c
48
cmdmon.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009-2016, 2018
|
||||
* Copyright (C) Miroslav Lichvar 2009-2016, 2018-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -294,10 +294,16 @@ CAM_OpenUnixSocket(void)
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
transmit_reply(int sock_fd, SCK_Message *message)
|
||||
transmit_reply(int sock_fd, int request_length, SCK_Message *message)
|
||||
{
|
||||
message->length = PKL_ReplyLength((CMD_Reply *)message->data);
|
||||
|
||||
if (request_length < message->length) {
|
||||
DEBUG_LOG("Response longer than request req_len=%d res_len=%d",
|
||||
request_length, message->length);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't require responses to non-link-local addresses to use the same
|
||||
interface */
|
||||
if (!SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
|
||||
@@ -572,11 +578,8 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
tx_message->data.source_data.stratum = htons(report.stratum);
|
||||
tx_message->data.source_data.poll = htons(report.poll);
|
||||
switch (report.state) {
|
||||
case RPT_SYNC:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_SYNC);
|
||||
break;
|
||||
case RPT_UNREACH:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_UNREACH);
|
||||
case RPT_NONSELECTABLE:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_NONSELECTABLE);
|
||||
break;
|
||||
case RPT_FALSETICKER:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_FALSETICKER);
|
||||
@@ -584,11 +587,14 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||
case RPT_JITTERY:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_JITTERY);
|
||||
break;
|
||||
case RPT_CANDIDATE:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_CANDIDATE);
|
||||
case RPT_SELECTABLE:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_SELECTABLE);
|
||||
break;
|
||||
case RPT_OUTLIER:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_OUTLIER);
|
||||
case RPT_UNSELECTED:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_UNSELECTED);
|
||||
break;
|
||||
case RPT_SELECTED:
|
||||
tx_message->data.source_data.state = htons(RPY_SD_ST_SELECTED);
|
||||
break;
|
||||
}
|
||||
switch (report.mode) {
|
||||
@@ -1427,7 +1433,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
||||
|
||||
if (rx_message.version >= PROTO_VERSION_MISMATCH_COMPAT_SERVER) {
|
||||
tx_message.status = htons(STT_BADPKTVERSION);
|
||||
transmit_reply(sock_fd, sck_message);
|
||||
transmit_reply(sock_fd, read_length, sck_message);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1437,7 +1443,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
||||
DEBUG_LOG("Command packet has invalid command %d", rx_command);
|
||||
|
||||
tx_message.status = htons(STT_INVALID);
|
||||
transmit_reply(sock_fd, sck_message);
|
||||
transmit_reply(sock_fd, read_length, sck_message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1446,7 +1452,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
||||
expected_length);
|
||||
|
||||
tx_message.status = htons(STT_BADPKTLENGTH);
|
||||
transmit_reply(sock_fd, sck_message);
|
||||
transmit_reply(sock_fd, read_length, sck_message);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1733,19 +1739,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
|
||||
}
|
||||
|
||||
/* Transmit the response */
|
||||
{
|
||||
/* Include a simple way to lose one message in three to test resend */
|
||||
|
||||
static int do_it=1;
|
||||
|
||||
if (do_it) {
|
||||
transmit_reply(sock_fd, sck_message);
|
||||
}
|
||||
|
||||
#if 0
|
||||
do_it = ((do_it + 1) % 3);
|
||||
#endif
|
||||
}
|
||||
transmit_reply(sock_fd, read_length, sck_message);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
13
conf.c
13
conf.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009-2017
|
||||
* Copyright (C) Miroslav Lichvar 2009-2017, 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -100,6 +100,7 @@ static double correction_time_ratio = 3.0;
|
||||
static double max_clock_error = 1.0; /* in ppm */
|
||||
static double max_drift = 500000.0; /* in ppm */
|
||||
static double max_slew_rate = 1e6 / 12.0; /* in ppm */
|
||||
static double clock_precision = 0.0; /* in seconds */
|
||||
|
||||
static SRC_AuthSelectMode authselect_mode = SRC_AUTHSELECT_MIX;
|
||||
static double max_distance = 3.0;
|
||||
@@ -544,6 +545,8 @@ CNF_ParseLine(const char *filename, int number, char *line)
|
||||
parse_broadcast(p);
|
||||
} else if (!strcasecmp(command, "clientloglimit")) {
|
||||
parse_clientloglimit(p);
|
||||
} else if (!strcasecmp(command, "clockprecision")) {
|
||||
parse_double(p, &clock_precision);
|
||||
} else if (!strcasecmp(command, "cmdallow")) {
|
||||
parse_allow_deny(p, cmd_restrictions, 1);
|
||||
} else if (!strcasecmp(command, "cmddeny")) {
|
||||
@@ -2048,6 +2051,14 @@ CNF_GetMaxSlewRate(void)
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
CNF_GetClockPrecision(void)
|
||||
{
|
||||
return clock_precision;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
double
|
||||
CNF_GetMaxDistance(void)
|
||||
{
|
||||
|
||||
1
conf.h
1
conf.h
@@ -95,6 +95,7 @@ extern double CNF_GetMaxClockError(void);
|
||||
extern double CNF_GetMaxDrift(void);
|
||||
extern double CNF_GetCorrectionTimeRatio(void);
|
||||
extern double CNF_GetMaxSlewRate(void);
|
||||
extern double CNF_GetClockPrecision(void);
|
||||
|
||||
extern SRC_AuthSelectMode CNF_GetAuthSelectMode(void);
|
||||
extern double CNF_GetMaxDistance(void);
|
||||
|
||||
62
configure
vendored
62
configure
vendored
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Copyright (C) Richard P. Curnow 1997-2003
|
||||
# Copyright (C) Bryan Christianson 2016
|
||||
# Copyright (C) Miroslav Lichvar 2009, 2012-2018
|
||||
# Copyright (C) Miroslav Lichvar 2009, 2012-2020
|
||||
# Copyright (C) Stefan R. Filipek 2019
|
||||
#
|
||||
# =======================================================================
|
||||
@@ -108,11 +108,7 @@ for instance \`--prefix=$HOME'.
|
||||
|
||||
For better control, use the options below.
|
||||
--disable-readline Disable line editing support
|
||||
--without-readline Don't use GNU readline even if it is available
|
||||
--without-editline Don't use editline even if it is available
|
||||
--with-readline-includes=DIR Specify where readline include directory is
|
||||
--with-readline-library=DIR Specify where readline lib directory is
|
||||
--with-ncurses-library=DIR Specify where ncurses lib directory is
|
||||
--disable-sechash Disable support for hashes other than MD5
|
||||
--without-nettle Don't use nettle even if it is available
|
||||
--without-nss Don't use NSS even if it is available
|
||||
@@ -225,7 +221,6 @@ feat_cmdmon=1
|
||||
feat_ntp=1
|
||||
feat_refclock=1
|
||||
feat_readline=1
|
||||
try_readline=1
|
||||
try_editline=1
|
||||
feat_sechash=1
|
||||
try_nettle=1
|
||||
@@ -241,9 +236,6 @@ try_clockctl=0
|
||||
feat_scfilter=0
|
||||
try_seccomp=-1
|
||||
priv_ops=""
|
||||
readline_lib=""
|
||||
readline_inc=""
|
||||
ncurses_lib=""
|
||||
feat_ipv6=1
|
||||
feat_phc=1
|
||||
try_phc=0
|
||||
@@ -274,21 +266,9 @@ do
|
||||
--disable-readline )
|
||||
feat_readline=0
|
||||
;;
|
||||
--without-readline )
|
||||
try_readline=0
|
||||
;;
|
||||
--without-editline )
|
||||
try_editline=0
|
||||
;;
|
||||
--with-readline-library=* )
|
||||
readline_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--with-readline-includes=* )
|
||||
readline_inc=-I`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--with-ncurses-library=* )
|
||||
ncurses_lib=-L`echo $option | sed -e 's/^.*=//;'`
|
||||
;;
|
||||
--prefix=* | --install_prefix=* )
|
||||
SETPREFIX=`echo $option | sed -e 's/[^=]*=//;'`
|
||||
;;
|
||||
@@ -804,10 +784,12 @@ if [ $feat_scfilter = "1" ] && [ $try_seccomp = "1" ] && \
|
||||
'seccomp_init(SCMP_ACT_KILL);'
|
||||
then
|
||||
add_def FEAT_SCFILTER
|
||||
# NAME2IPADDRESS shouldn't be enabled with other operations as the helper
|
||||
# process works on one request at the time and the async resolver could
|
||||
# block the main thread
|
||||
if [ $feat_ntp = "1" ]; then
|
||||
# NAME2IPADDRESS shouldn't be enabled together with a privops operation
|
||||
# used by the main thread as the helper process works on one request at
|
||||
# a time and the async resolver would block the main thread
|
||||
priv_ops="NAME2IPADDRESS RELOADDNS"
|
||||
fi
|
||||
EXTRA_LIBS="$EXTRA_LIBS -lseccomp"
|
||||
fi
|
||||
|
||||
@@ -876,37 +858,11 @@ fi
|
||||
READLINE_LINK=""
|
||||
if [ $feat_readline = "1" ]; then
|
||||
if [ $try_editline = "1" ]; then
|
||||
if test_code editline 'stdio.h editline/readline.h' \
|
||||
"$readline_inc" "$readline_lib -ledit" \
|
||||
if test_code editline 'stdio.h editline/readline.h' '' '-ledit' \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
add_def USE_EDITLINE
|
||||
MYCPPFLAGS="$MYCPPFLAGS $readline_inc"
|
||||
READLINE_LINK="$readline_lib -ledit"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$READLINE_LINK" = "x" ] && [ $try_readline = "1" ]; then
|
||||
if test_code readline 'stdio.h readline/readline.h readline/history.h' \
|
||||
"$readline_inc" "$readline_lib -lreadline" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
MYCPPFLAGS="$MYCPPFLAGS $readline_inc"
|
||||
READLINE_LINK="$readline_lib -lreadline"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "x$READLINE_LINK" = "x" ] && [ $try_readline = "1" ]; then
|
||||
if test_code 'readline with -lncurses' \
|
||||
'stdio.h readline/readline.h readline/history.h' \
|
||||
"$readline_inc" "$readline_lib $ncurses_lib -lreadline -lncurses" \
|
||||
'add_history(readline("prompt"));'
|
||||
then
|
||||
add_def FEAT_READLINE
|
||||
MYCPPFLAGS="$MYCPPFLAGS $readline_inc"
|
||||
READLINE_LINK="$readline_lib $ncurses_lib -lreadline -lncurses"
|
||||
READLINE_LINK="-ledit"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -972,7 +928,7 @@ if [ $feat_ntp = "1" ] && [ $feat_nts = "1" ] && [ $try_gnutls = "1" ]; then
|
||||
test_link="`pkg_config --libs gnutls`"
|
||||
if test_code 'gnutls' 'gnutls/gnutls.h' \
|
||||
"$test_cflags" "$test_link" '
|
||||
return gnutls_init(NULL, 0) +
|
||||
return gnutls_init(NULL, 0) + GNUTLS_TLS1_3 +
|
||||
gnutls_priority_init2(NULL, "", NULL, GNUTLS_PRIORITY_INIT_DEF_APPEND) +
|
||||
gnutls_prf_rfc5705(NULL, 0, "", 0, "", 16, NULL);'
|
||||
then
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Copyright (C) Richard P. Curnow 1997-2003
|
||||
// Copyright (C) Stephen Wadeley 2016
|
||||
// Copyright (C) Bryan Christianson 2017
|
||||
// Copyright (C) Miroslav Lichvar 2009-2017
|
||||
// Copyright (C) Miroslav Lichvar 2009-2020
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -32,12 +32,14 @@ chrony.conf - chronyd configuration file
|
||||
== DESCRIPTION
|
||||
|
||||
This file configures the *chronyd* daemon. The compiled-in location is
|
||||
_@SYSCONFDIR@/chrony.conf_, but other locations can be specified on the
|
||||
_@SYSCONFDIR@/chrony.conf_. Other locations can be specified on the
|
||||
*chronyd* command line with the *-f* option.
|
||||
|
||||
Each directive in the configuration file is placed on a separate line. The
|
||||
following sections describe each of the directives in turn. The directives can
|
||||
occur in any order in the file and they are not case-sensitive.
|
||||
following sections describe each of the directives in turn. The directives are
|
||||
not case-sensitive. Generally, the directives can occur in any order in the file
|
||||
and if a directive is specified multiple times, only the last one will be
|
||||
effective. Exceptions are noted in the descriptions.
|
||||
|
||||
The configuration directives can also be specified directly on the *chronyd*
|
||||
command line. In this case each argument is parsed as a new line and the
|
||||
@@ -61,9 +63,10 @@ source. The client-server relationship is strictly hierarchical: a client might
|
||||
synchronise its system time to that of the server, but the server's system time
|
||||
will never be influenced by that of a client.
|
||||
+
|
||||
The *server* directive is immediately followed by either the name of the
|
||||
server, or its IP address. The *server* directive supports the following
|
||||
options:
|
||||
This directive can be used multiple times to specify multiple servers.
|
||||
+
|
||||
The directive is immediately followed by either the name of the
|
||||
server, or its IP address. It supports the following options:
|
||||
+
|
||||
*minpoll* _poll_:::
|
||||
This option specifies the minimum interval between requests sent to the server
|
||||
@@ -276,6 +279,8 @@ directive, except that it is used to specify a pool of NTP servers rather than
|
||||
a single NTP server. The pool name is expected to resolve to multiple addresses
|
||||
which might change over time.
|
||||
+
|
||||
This directive can be used multiple times to specify multiple pools.
|
||||
+
|
||||
All options valid in the <<server,*server*>> directive can be used in this
|
||||
directive too. There is one option specific to the *pool* directive:
|
||||
+
|
||||
@@ -306,6 +311,8 @@ is mainly useful when the NTP implementation of the peer (e.g. *ntpd*) supports
|
||||
ephemeral symmetric associations and does not need to be configured with an
|
||||
address of this host. *chronyd* does not support ephemeral associations.
|
||||
+
|
||||
This directive can be used multiple times to specify multiple peers.
|
||||
+
|
||||
The following options of the *server* directive do not work in the *peer*
|
||||
directive: *iburst*, *burst*, *nts*, *presend*.
|
||||
+
|
||||
@@ -398,6 +405,8 @@ driver-specific parameter. The two parameters are followed by zero or more
|
||||
refclock options. Some drivers have special options, which can be appended to
|
||||
the driver-specific parameter using the *:* character.
|
||||
+
|
||||
This directive can be used multiple times to specify multiple reference clocks.
|
||||
+
|
||||
There are four drivers included in *chronyd*:
|
||||
+
|
||||
*PPS*:::
|
||||
@@ -610,12 +619,13 @@ behaviour, whereas the *settime* command allows samples of manually entered
|
||||
time to be provided.)
|
||||
|
||||
[[acquisitionport]]*acquisitionport* _port_::
|
||||
By default, *chronyd* uses a separate client socket for each configured server
|
||||
and their source port is chosen arbitrarily by the operating system. However,
|
||||
you can use the *acquisitionport* directive to explicitly specify a port and
|
||||
use only one socket (per IPv4 or IPv6 address family) for all configured servers.
|
||||
This can be useful for getting through some firewalls. If set to 0, the source
|
||||
port of the socket will be chosen arbitrarily.
|
||||
By default, *chronyd* as an NTP client opens a new socket for each request with
|
||||
the source port chosen randomly by the operating system. The *acquisitionport*
|
||||
directive can be used to specify the source port and use only one socket (per
|
||||
IPv4 or IPv6 address family) for all configured servers. This can be useful for
|
||||
getting through some firewalls. It should not be used if not necessary as there
|
||||
is a small impact on security of the client. If set to 0, the source port of
|
||||
the permanent socket will be chosen randomly by the operating system.
|
||||
+
|
||||
It can be set to the same port as is used by the NTP server (which can be
|
||||
configured with the <<port,*port*>> directive) to use only one socket for all
|
||||
@@ -632,8 +642,8 @@ You could then persuade the firewall administrator to open that port.
|
||||
|
||||
[[bindacqaddress]]*bindacqaddress* _address_::
|
||||
The *bindacqaddress* directive specifies a local IP address to which
|
||||
*chronyd* will bind its NTP client sockets. The syntax is similar to the
|
||||
<<bindaddress,*bindaddress*>> and <<bindcmdaddress,*bindcmdaddress*>>
|
||||
*chronyd* will bind its NTP and NTS-KE client sockets. The syntax is similar to
|
||||
the <<bindaddress,*bindaddress*>> and <<bindcmdaddress,*bindcmdaddress*>>
|
||||
directives.
|
||||
+
|
||||
For each of the IPv4 and IPv6 protocols, only one *bindacqaddress* directive
|
||||
@@ -908,6 +918,27 @@ distances are in milliseconds.
|
||||
|
||||
=== System clock
|
||||
|
||||
[[clockprecision]]*clockprecision* _precision_::
|
||||
The *clockprecision* directive specifies the precision of the system clock (in
|
||||
seconds). It is used by *chronyd* to estimate the minimum noise in NTP
|
||||
measurements and randomise low-order bits of timestamps in NTP responses. By
|
||||
default, the precision is measured on start as the minimum time to read the
|
||||
clock.
|
||||
+
|
||||
The measured value works well in most cases. However, it generally
|
||||
overestimates the precision and it can be sensitive to the CPU speed, which can
|
||||
change over time to save power. In some cases with a high-precision clocksource
|
||||
(e.g. the Time Stamp Counter of the CPU) and hardware timestamping, setting the
|
||||
precision on the server to a smaller value can improve stability of clients'
|
||||
NTP measurements. The server's precision is reported on clients by the
|
||||
<<chronyc.adoc#ntpdata,*ntpdata*>> command.
|
||||
+
|
||||
An example setting the precision to 8 nanoseconds is:
|
||||
+
|
||||
----
|
||||
clockprecision 8e-9
|
||||
----
|
||||
|
||||
[[corrtimeratio]]*corrtimeratio* _ratio_::
|
||||
When *chronyd* is slewing the system clock to correct an offset, the rate at
|
||||
which it is slewing adds to the frequency error of the clock. On all supported
|
||||
@@ -1039,7 +1070,7 @@ A recommended configuration to enable a server leap smear is:
|
||||
----
|
||||
leapsecmode slew
|
||||
maxslewrate 1000
|
||||
smoothtime 400 0.001 leaponly
|
||||
smoothtime 400 0.001024 leaponly
|
||||
----
|
||||
+
|
||||
The first directive is necessary to disable the clock step which would reset
|
||||
@@ -1047,11 +1078,17 @@ the smoothing process. The second directive limits the slewing rate of the
|
||||
local clock to 1000 ppm, which improves the stability of the smoothing process
|
||||
when the local correction starts and ends. The third directive enables the
|
||||
server time smoothing process. It will start when the clock gets to 00:00:00
|
||||
UTC and it will take 17 hours 34 minutes to finish. The frequency offset will
|
||||
be changing by 0.001 ppm per second and will reach a maximum of 31.623 ppm. The
|
||||
*leaponly* option makes the duration of the leap smear constant and allows the
|
||||
clients to safely synchronise with multiple identically configured leap
|
||||
smearing servers.
|
||||
UTC and it will take 62500 seconds (about 17.36 hours) to finish. The frequency
|
||||
offset will be changing by 0.001024 ppm per second and will reach a maximum of
|
||||
32 ppm in 31250 seconds. The *leaponly* option makes the duration of the leap
|
||||
smear constant and allows the clients to safely synchronise with multiple
|
||||
identically configured leap smearing servers.
|
||||
+
|
||||
The duration of the leap smear can be calculated from the specified wander as
|
||||
+
|
||||
----
|
||||
duration = sqrt(4 / wander)
|
||||
----
|
||||
|
||||
[[leapsectz]]*leapsectz* _timezone_::
|
||||
This directive specifies a timezone in the system tz database which *chronyd*
|
||||
@@ -1221,7 +1258,7 @@ coefficients _T0_, _k0_, _k1_, _k2_.
|
||||
The frequency compensation is calculated (in ppm) as
|
||||
+
|
||||
----
|
||||
k0 + (T - T0) * k1 + (T - T0)^2 * k2
|
||||
comp = k0 + (T - T0) * k1 + (T - T0)^2 * k2
|
||||
----
|
||||
+
|
||||
The result has to be between -10 ppm and 10 ppm, otherwise the measurement is
|
||||
@@ -1272,12 +1309,15 @@ _tempcomp.log_ file if enabled by the <<log,*log tempcomp*>> directive.
|
||||
|
||||
[[allow]]*allow* [*all*] [_subnet_]::
|
||||
The *allow* directive is used to designate a particular subnet from which NTP
|
||||
clients are allowed to access the computer as an NTP server.
|
||||
clients are allowed to access the computer as an NTP server. It also controls
|
||||
access of NTS-KE clients when NTS is enabled on the server.
|
||||
+
|
||||
The default is that no clients are allowed access, i.e. *chronyd* operates
|
||||
purely as an NTP client. If the *allow* directive is used, *chronyd* will be
|
||||
both a client of its servers, and a server to other clients.
|
||||
+
|
||||
This directive can be used multiple times.
|
||||
+
|
||||
Examples of the use of the directive are as follows:
|
||||
+
|
||||
----
|
||||
@@ -1344,18 +1384,19 @@ client access by this computer for it to work.
|
||||
|
||||
[[deny]]*deny* [*all*] [_subnet_]::
|
||||
This is similar to the <<allow,*allow*>> directive, except that it denies NTP
|
||||
client access to a particular subnet or host, rather than allowing it.
|
||||
and NTS-KE client access to a particular subnet or host, rather than allowing
|
||||
it.
|
||||
+
|
||||
The syntax is identical.
|
||||
The syntax is identical and the directive can be used multiple times too.
|
||||
+
|
||||
There is also a *deny all* directive with similar behaviour to the *allow all*
|
||||
directive.
|
||||
|
||||
[[bindaddress]]*bindaddress* _address_::
|
||||
The *bindaddress* directive binds the socket on which *chronyd* listens for NTP
|
||||
requests to a local address of the computer. On systems other than Linux, the
|
||||
address of the computer needs to be already configured when *chronyd* is
|
||||
started.
|
||||
The *bindaddress* directive binds the sockets on which *chronyd* listens for
|
||||
NTP and NTS-KE requests to a local address of the computer. On systems other
|
||||
than Linux, the address of the computer needs to be already configured when
|
||||
*chronyd* is started.
|
||||
+
|
||||
An example of the use of the directive is:
|
||||
+
|
||||
@@ -1368,9 +1409,9 @@ directive can be specified. Therefore, it is not useful on computers which
|
||||
should serve NTP on multiple network interfaces.
|
||||
|
||||
[[binddevice]]*binddevice* _interface_::
|
||||
The *binddevice* directive binds the NTP server sockets to a network device
|
||||
specified by the interface name. This directive can specify only one interface
|
||||
and it is supported on Linux only.
|
||||
The *binddevice* directive binds the NTP and NTS-KE server sockets to a network
|
||||
device specified by the interface name. This directive can specify only one
|
||||
interface and it is supported on Linux only.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
@@ -1384,6 +1425,8 @@ chronyd should send packets in the NTP broadcast mode (i.e. make *chronyd* act
|
||||
as a broadcast server). Broadcast clients on that subnet will be able to
|
||||
synchronise.
|
||||
+
|
||||
This directive can be used multiple times to specify multiple addresses.
|
||||
+
|
||||
The syntax is as follows:
|
||||
+
|
||||
----
|
||||
@@ -1483,7 +1526,9 @@ configuration and to be synchronised to one another, without confusing clients
|
||||
that poll more than one server. Each server needs to be configured to poll all
|
||||
other servers with the *local* directive. This ensures only the server with the
|
||||
smallest reference ID has the local reference active and others are
|
||||
synchronised to it. When that server fails, another will take over.
|
||||
synchronised to it. If that server stops responding, the server with the second
|
||||
smallest reference ID will take over when its local reference mode activates
|
||||
(root distance reaches the threshold configured by the *distance* option).
|
||||
+
|
||||
The *orphan* mode is compatible with the *ntpd*'s orphan mode (enabled by the
|
||||
*tos orphan* command).
|
||||
@@ -1492,7 +1537,7 @@ The *orphan* mode is compatible with the *ntpd*'s orphan mode (enabled by the
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
local stratum 10 orphan
|
||||
local stratum 10 orphan distance 0.1
|
||||
----
|
||||
|
||||
[[ntpsigndsocket]]*ntpsigndsocket* _directory_::
|
||||
@@ -1822,7 +1867,8 @@ The *rtcautotrim* directive is used to keep the RTC close to the system clock
|
||||
automatically. When the system clock is synchronised and the estimated error
|
||||
between the two clocks is larger than the specified threshold, *chronyd* will
|
||||
trim the RTC as if the <<chronyc.adoc#trimrtc,*trimrtc*>> command in *chronyc*
|
||||
was issued.
|
||||
was issued. The trimming operation is accurate to only about 1 second, which is
|
||||
the minimum effective threshold.
|
||||
+
|
||||
This directive is effective only with the <<rtcfile,*rtcfile*>> directive.
|
||||
+
|
||||
@@ -2202,6 +2248,8 @@ name, only the first file in the order of the specified directories will be
|
||||
included. This enables a fragmented configuration where existing fragments can
|
||||
be replaced by adding files to a different directory.
|
||||
+
|
||||
This directive can be used multiple times.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
@@ -2217,6 +2265,8 @@ reloaded by the <<chronyc.adoc#reload,*reload sources*>> command in
|
||||
received from a DHCP server, which can be written to a file specific to the
|
||||
network interface by a networking script.
|
||||
+
|
||||
This directive can be used multiple times.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
@@ -2229,6 +2279,8 @@ files if a wildcard pattern is specified. Unlike with the *confdir* directive,
|
||||
the full name of the files needs to be specified and at least one file is
|
||||
required to exist.
|
||||
+
|
||||
This directive can be used multiple times.
|
||||
+
|
||||
An example of the directive is:
|
||||
+
|
||||
----
|
||||
@@ -2264,8 +2316,9 @@ indicated in the _measurements.log_ file if enabled by the <<log,*log
|
||||
measurements*>> directive, and the <<chronyc.adoc#ntpdata,*ntpdata*>> report in
|
||||
*chronyc*.
|
||||
+
|
||||
If the specified interface is _*_, *chronyd* will try to enable HW timestamping
|
||||
on all available interfaces.
|
||||
This directive can be used multiple times to enable HW timestamping on multiple
|
||||
interfaces. If the specified interface is _*_, *chronyd* will try to enable HW
|
||||
timestamping on all available interfaces.
|
||||
+
|
||||
The *hwtimestamp* directive has the following options:
|
||||
+
|
||||
@@ -2497,6 +2550,20 @@ makestep 1.0 3
|
||||
rtcsync
|
||||
----
|
||||
|
||||
If the servers (or pool) support the Network Time Security (NTS)
|
||||
authentication mechanism and *chronyd* is compiled with NTS support, the *nts*
|
||||
option will enable a secure synchronisation to the servers. The configuration
|
||||
file could look like:
|
||||
|
||||
----
|
||||
server foo.example.net iburst nts
|
||||
server bar.example.net iburst nts
|
||||
server baz.example.net iburst nts
|
||||
driftfile @CHRONYVARDIR@/drift
|
||||
makestep 1.0 3
|
||||
rtcsync
|
||||
----
|
||||
|
||||
=== NTP client with infrequent connection to NTP servers
|
||||
|
||||
This section shows how to configure *chronyd* for computers that have
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// Copyright (C) Richard P. Curnow 1997-2003
|
||||
// Copyright (C) Stephen Wadeley 2016
|
||||
// Copyright (C) Miroslav Lichvar 2009-2017
|
||||
// Copyright (C) Miroslav Lichvar 2009-2017, 2019-2020
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -39,7 +39,7 @@ running.
|
||||
If no commands are specified on the command line, *chronyc* will expect input
|
||||
from the user. The prompt _chronyc>_ will be displayed when it is being run
|
||||
from a terminal. If *chronyc*'s input or output are redirected from or to a file,
|
||||
the prompt is not shown.
|
||||
the prompt will not be shown.
|
||||
|
||||
There are two ways *chronyc* can access *chronyd*. One is the Internet
|
||||
Protocol (IPv4 or IPv6) and the other is a Unix domain socket, which is
|
||||
@@ -60,9 +60,7 @@ default, the commands are accepted only from localhost (127.0.0.1 or ::1).
|
||||
|
||||
All other commands are allowed only through the Unix domain socket. When sent
|
||||
over the network, *chronyd* will respond with a '`Not authorised`' error, even
|
||||
if it is from localhost. In chrony versions before 2.2 they were allowed
|
||||
from the network if they were authenticated with a password, but that is no
|
||||
longer supported.
|
||||
if it is from localhost.
|
||||
|
||||
Having full access to *chronyd* via *chronyc* is more or less equivalent to
|
||||
being able to modify the *chronyd*'s configuration file and restart it.
|
||||
@@ -183,10 +181,12 @@ speeding up or slowing down the system clock until the error has been removed,
|
||||
and then returning to the system clock's normal speed. A consequence of this is
|
||||
that there will be a period when the system clock (as read by other programs)
|
||||
will be different from *chronyd*'s estimate of the current true time (which it
|
||||
reports to NTP clients when it is operating in server mode). The value reported
|
||||
reports to NTP clients when it is operating as a server). The value reported
|
||||
on this line is the difference due to this effect.
|
||||
*Last offset*:::
|
||||
This is the estimated local offset on the last clock update.
|
||||
This is the estimated local offset on the last clock update. A positive value
|
||||
indicates the local time (as previously estimated true time) was ahead of the
|
||||
time sources.
|
||||
*RMS offset*:::
|
||||
This is a long-term average of the offset value.
|
||||
*Frequency*:::
|
||||
@@ -317,18 +317,23 @@ The columns are as follows:
|
||||
This indicates the mode of the source. _^_ means a server, _=_ means a peer
|
||||
and _#_ indicates a locally connected reference clock.
|
||||
*S*:::
|
||||
This column indicates the state of the source.
|
||||
* _*_ indicates the source to which *chronyd* is currently synchronised.
|
||||
* _+_ indicates acceptable sources which are combined with the selected
|
||||
source.
|
||||
* _-_ indicates acceptable sources which are excluded by the combining
|
||||
algorithm.
|
||||
* _?_ indicates sources to which connectivity has been lost or whose packets
|
||||
do not pass all tests. It is also shown at start-up, until at least 3 samples
|
||||
have been gathered from it.
|
||||
* _x_ indicates a clock which *chronyd* thinks is a falseticker (i.e. its
|
||||
time is inconsistent with a majority of other sources).
|
||||
This column indicates the selection state of the source.
|
||||
* _*_ indicates the best source which is currently selected for
|
||||
synchronisation.
|
||||
* _+_ indicates other sources selected for synchronisation, which are combined
|
||||
with the best source.
|
||||
* _-_ indicates a source which is considered to be selectable for
|
||||
synchronisation, but not currently selected.
|
||||
* _x_ indicates a source which *chronyd* thinks is a falseticker (i.e. its
|
||||
time is inconsistent with a majority of other sources, or sources specified
|
||||
with the *trust* option).
|
||||
* _~_ indicates a source whose time appears to have too much variability.
|
||||
* _?_ indicates a source which is not considered to be selectable for
|
||||
synchronisation for other reasons (e.g. unreachable, not synchronised, or
|
||||
does not have enough measurements).
|
||||
{blank}:::
|
||||
The <<selectdata,*selectdata*>> command can be used to get more details about
|
||||
the selection state.
|
||||
*Name/IP address*:::
|
||||
This shows the name or the IP address of the source, or reference ID for reference
|
||||
clocks.
|
||||
@@ -1328,10 +1333,7 @@ purged. An example of how to do this is shown below.
|
||||
----
|
||||
# mv /var/log/chrony/measurements.log /var/log/chrony/measurements1.log
|
||||
# chronyc cyclelogs
|
||||
# ls -l /var/log/chrony
|
||||
-rw-r--r-- 1 root root 0 Jun 8 18:17 measurements.log
|
||||
-rw-r--r-- 1 root root 12345 Jun 8 18:17 measurements1.log
|
||||
# rm -f measurements1.log
|
||||
# rm /var/log/chrony/measurements1.log
|
||||
----
|
||||
|
||||
[[dump]]*dump*::
|
||||
@@ -1356,7 +1358,9 @@ The *reset sources* command causes *chronyd* to drop all measurements and
|
||||
switch to the unsynchronised state. This command can help *chronyd* with
|
||||
recovery when the measurements are known to be no longer valid or accurate,
|
||||
e.g. due to moving the computer to a different network, or resuming the
|
||||
computer from a low-power state (which resets the system clock).
|
||||
computer from a low-power state (which resets the system clock). *chronyd* will
|
||||
drop the measurements automatically when it detects the clock has made an
|
||||
unexpected jump, but the detection is not completely reliable.
|
||||
|
||||
[[shutdown]]*shutdown*::
|
||||
The *shutdown* command causes *chronyd* to exit. This is equivalent to sending
|
||||
@@ -1423,7 +1427,13 @@ keygen 73 SHA1 256
|
||||
+
|
||||
which generates a 256-bit SHA1 key with number 73. The printed line should
|
||||
then be securely transferred and added to the key files on both server and
|
||||
client, or peers.
|
||||
client, or peers. A different key should be generated for each client or peer.
|
||||
+
|
||||
An example using the AES128 cipher is:
|
||||
+
|
||||
----
|
||||
keygen 151 AES128
|
||||
----
|
||||
|
||||
[[exit]]*exit*::
|
||||
[[quit]]*quit*::
|
||||
|
||||
@@ -55,7 +55,7 @@ IPv6 sockets will be created.
|
||||
|
||||
*-f* _file_::
|
||||
This option can be used to specify an alternate location for the configuration
|
||||
file. The default value is _@SYSCONFDIR@/chrony.conf_.
|
||||
file. The compiled-in default value is _@SYSCONFDIR@/chrony.conf_.
|
||||
|
||||
*-n*::
|
||||
When run in this mode, the program will not detach itself from the terminal.
|
||||
@@ -137,7 +137,7 @@ running, but still allow it to adjust the frequency of the system clock.
|
||||
*-u* _user_::
|
||||
This option sets the name of the system user to which *chronyd* will switch
|
||||
after start in order to drop root privileges. It overrides the
|
||||
<<chrony.conf.adoc#user,*user*>> directive. The default value is
|
||||
<<chrony.conf.adoc#user,*user*>> directive. The compiled-in default value is
|
||||
_@DEFAULT_USER@_.
|
||||
+
|
||||
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
||||
@@ -145,6 +145,16 @@ On macOS, FreeBSD, NetBSD and Solaris *chronyd* forks into two processes.
|
||||
The child process retains root privileges, but can only perform a very limited
|
||||
range of privileged system calls on behalf of the parent.
|
||||
|
||||
*-U*::
|
||||
This option disables a check for root privileges to allow *chronyd* to be
|
||||
started under a non-root user, assuming the process will have all capabilities
|
||||
(e.g. provided by the service manager) and access to all files, directories,
|
||||
and devices, needed to operate correctly in the specified configuration. Note
|
||||
that different capabilities might be needed with different configurations and
|
||||
different Linux kernel versions. Starting *chronyd* under a non-root user is
|
||||
not recommended when the configuration is not known, or at least limited to
|
||||
specific directives.
|
||||
|
||||
*-F* _level_::
|
||||
This option configures a system call filter when *chronyd* is compiled with
|
||||
support for the Linux secure computing (seccomp) facility. In level 1 the
|
||||
@@ -152,10 +162,10 @@ process is killed when a forbidden system call is made, in level -1 the SIGSYS
|
||||
signal is thrown instead and in level 0 the filter is disabled. The default
|
||||
value is 0.
|
||||
+
|
||||
It's recommended to enable the filter only when it's known to work on the
|
||||
It is recommended to enable the filter only when it is known to work on the
|
||||
version of the system where *chrony* is installed as the filter needs to allow
|
||||
also system calls made from libraries that *chronyd* is using (e.g. libc) and
|
||||
different versions or implementations of the libraries may make different
|
||||
different versions or implementations of the libraries might make different
|
||||
system calls. If the filter is missing some system call, *chronyd* could be
|
||||
killed even in normal operation.
|
||||
|
||||
@@ -174,10 +184,8 @@ This mode is only supported on Linux.
|
||||
This option disables the control of the system clock. *chronyd* will not try to
|
||||
make any adjustments of the clock. It will assume the clock is free running and
|
||||
still track its offset and frequency relative to the estimated true time. This
|
||||
option allows *chronyd* to run without the capability to adjust or set the
|
||||
system clock (e.g. in some containers) in order to operate as an NTP server. It
|
||||
is not recommended to run *chronyd* (with or without *-x*) when another process
|
||||
is controlling the system clock.
|
||||
option allows *chronyd* to be started without the capability to adjust or set
|
||||
the system clock (e.g. in some containers) to operate as an NTP server.
|
||||
|
||||
*-v*::
|
||||
With this option *chronyd* will print version number to the terminal and exit.
|
||||
|
||||
248
doc/faq.adoc
248
doc/faq.adoc
@@ -1,7 +1,7 @@
|
||||
// This file is part of chrony
|
||||
//
|
||||
// Copyright (C) Richard P. Curnow 1997-2003
|
||||
// Copyright (C) Miroslav Lichvar 2014-2016
|
||||
// Copyright (C) Miroslav Lichvar 2014-2016, 2020
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -24,17 +24,20 @@
|
||||
|
||||
=== How does `chrony` compare to `ntpd`?
|
||||
|
||||
`chronyd` was designed to work well in a wide range of conditions and it can
|
||||
usually synchronise the system clock faster and with better time accuracy. It
|
||||
doesn't implement some of the less useful NTP modes like broadcast client or
|
||||
multicast server/client.
|
||||
`chrony` and `ntpd` are two different implementations of the Network Time
|
||||
Protocol (NTP).
|
||||
|
||||
`chrony` is a newer implementation, which was designed to work well in a wider
|
||||
range of conditions. It can usually synchronise the system clock faster and
|
||||
with better time accuracy. It has many features, but it does not implement some
|
||||
of the less useful NTP modes like broadcast client or multicast server/client.
|
||||
|
||||
If your computer is connected to the Internet only for few minutes at a time,
|
||||
the network connection is often congested, you turn your computer off or
|
||||
suspend it frequently, the clock is not very stable (e.g. there are rapid
|
||||
changes in the temperature or it's a virtual machine), or you want to use NTP
|
||||
changes in the temperature or it is a virtual machine), or you want to use NTP
|
||||
on an isolated network with no hardware reference clocks in sight, `chrony`
|
||||
will probably work much better for you.
|
||||
will probably work better for you.
|
||||
|
||||
For a more detailed comparison of features and performance, see the
|
||||
https://chrony.tuxfamily.org/comparison.html[comparison page] on the `chrony`
|
||||
@@ -59,7 +62,7 @@ slewing, which would take a very long time. The `makestep` directive does
|
||||
that.
|
||||
|
||||
In order to keep the real-time clock (RTC) close to the true time, so the
|
||||
system time is reasonably close to the true time when it's initialised on the
|
||||
system time is reasonably close to the true time when it is initialised on the
|
||||
next boot from the RTC, the `rtcsync` directive enables a mode in which the
|
||||
system time is periodically copied to the RTC. It is supported on Linux and
|
||||
macOS.
|
||||
@@ -75,52 +78,36 @@ makestep 1 3
|
||||
rtcsync
|
||||
----
|
||||
|
||||
=== How do I make an NTP server from an NTP client?
|
||||
=== How do I make an NTP server?
|
||||
|
||||
You need to add an `allow` directive to the _chrony.conf_ file in order to open
|
||||
the NTP port and allow `chronyd` to reply to client requests. `allow` with no
|
||||
specified subnet allows access from all IPv4 and IPv6 addresses.
|
||||
|
||||
=== I have several computers on a LAN. Should be all clients of an external server?
|
||||
=== Should all computers on a LAN be clients of an external server?
|
||||
|
||||
The best configuration is usually to make one computer the server, with
|
||||
the others as clients of it. Add a `local` directive to the server's
|
||||
_chrony.conf_ file. This configuration will be better because
|
||||
It depends on the requirements. Usually, the best configuration is to make one
|
||||
computer the server, with the others as clients of it. Add a `local` directive
|
||||
to the server's _chrony.conf_ file. This configuration will be better because
|
||||
|
||||
* the load on the external connection is less
|
||||
* the load on the external NTP server(s) is less
|
||||
* if your external connection goes down, the computers on the LAN
|
||||
will maintain a common time with each other.
|
||||
|
||||
=== Must I specify servers by IP address if DNS is not available on chronyd start?
|
||||
=== Must I specify servers by IP address if DNS is not available on `chronyd` start?
|
||||
|
||||
No. Starting from version 1.25, `chronyd` will keep trying to resolve
|
||||
No, `chronyd` will keep trying to resolve
|
||||
the names specified by the `server`, `pool`, and `peer` directives in an
|
||||
increasing interval until it succeeds. The `online` command can be issued from
|
||||
`chronyc` to force `chronyd` to try to resolve the names immediately.
|
||||
|
||||
=== How can I make `chronyd` more secure?
|
||||
|
||||
If you don't need to serve time to NTP clients or peers, you can add `port 0`
|
||||
to the _chrony.conf_ file to completely disable the NTP server functionality
|
||||
and prevent NTP requests from reaching `chronyd`. Starting from version 2.0,
|
||||
the NTP server port is open only when client access is allowed by the `allow`
|
||||
directive or command, an NTP peer is configured, or the `broadcast` directive
|
||||
is used.
|
||||
|
||||
If you don't need to use `chronyc` remotely, you can add the following
|
||||
directives to the configuration file to bind the command sockets to the
|
||||
loopback interface. This is done by default since version 2.0.
|
||||
|
||||
----
|
||||
bindcmdaddress 127.0.0.1
|
||||
bindcmdaddress ::1
|
||||
----
|
||||
|
||||
If you don't need to use `chronyc` at all or you need to run `chronyc` only
|
||||
If you do not need to use `chronyc`, or you want to run `chronyc` only
|
||||
under the root or _chrony_ user (which can access `chronyd` through a Unix
|
||||
domain socket since version 2.2), you can disable the internet command sockets
|
||||
completely by adding `cmdport 0` to the configuration file.
|
||||
domain socket), you can disable the IPv4 and IPv6 command sockets (by default
|
||||
listening on localhost) by adding `cmdport 0` to the configuration file.
|
||||
|
||||
You can specify an unprivileged user with the `-u` option, or the `user`
|
||||
directive in the _chrony.conf_ file, to which `chronyd` will switch after start
|
||||
@@ -133,23 +120,23 @@ a very limited range of privileged system calls on behalf of the parent.
|
||||
Also, if `chronyd` is compiled with support for the Linux secure computing
|
||||
(seccomp) facility, you can enable a system call filter with the `-F` option.
|
||||
It will significantly reduce the kernel attack surface and possibly prevent
|
||||
kernel exploits from the `chronyd` process if it's compromised. It's
|
||||
recommended to enable the filter only when it's known to work on the version of
|
||||
kernel exploits from the `chronyd` process if it is compromised. It is
|
||||
recommended to enable the filter only when it is known to work on the version of
|
||||
the system where `chrony` is installed as the filter needs to allow also system
|
||||
calls made from libraries that `chronyd` is using (e.g. libc) and different
|
||||
versions or implementations of the libraries may make different system calls.
|
||||
versions or implementations of the libraries might make different system calls.
|
||||
If the filter is missing some system call, `chronyd` could be killed even in
|
||||
normal operation.
|
||||
|
||||
=== How can I improve the accuracy of the system clock with NTP sources?
|
||||
|
||||
Select NTP servers that are well synchronised, stable and close to your
|
||||
network. It's better to use more than one server, three or four is usually
|
||||
network. It is better to use more than one server, three or four is usually
|
||||
recommended as the minimum, so `chronyd` can detect servers that serve false
|
||||
time and combine measurements from multiple sources.
|
||||
|
||||
If you have a network card with hardware timestamping supported on Linux, it
|
||||
can be enabled by the *hwtimestamp* directive in the _chrony.conf_ file. It
|
||||
can be enabled by the `hwtimestamp` directive in the _chrony.conf_ file. It
|
||||
should make local receive and transmit timestamps of NTP packets much more
|
||||
accurate.
|
||||
|
||||
@@ -163,8 +150,8 @@ default values are 6 (64 seconds) for `minpoll`, 10 (1024 seconds) for
|
||||
`maxpoll` and 8 (samples) for `polltarget`. The default values should be used
|
||||
for general servers on the Internet. With your own NTP servers, or if you have
|
||||
permission to poll some servers more frequently, setting these options for
|
||||
shorter polling intervals may significantly improve the accuracy of the system
|
||||
clock.
|
||||
shorter polling intervals might significantly improve the accuracy of the
|
||||
system clock.
|
||||
|
||||
The optimal polling interval depends mainly on two factors, stability of the
|
||||
network latency and stability of the system clock (which mainly depends on the
|
||||
@@ -174,7 +161,7 @@ temperature change).
|
||||
Generally, if the `sourcestats` command usually reports a small number of
|
||||
samples retained for a source (e.g. fewer than 16), a shorter polling interval
|
||||
should be considered. If the number of samples is usually at the maximum of 64,
|
||||
a longer polling interval may work better.
|
||||
a longer polling interval might work better.
|
||||
|
||||
An example of the directive for an NTP server on the Internet that you are
|
||||
allowed to poll frequently could be
|
||||
@@ -210,7 +197,7 @@ server ntp.local minpoll 2 maxpoll 4 xleave
|
||||
|
||||
When combined with local hardware timestamping, good network switches, and even
|
||||
shorter polling intervals, a sub-microsecond accuracy and stability of a few
|
||||
tens of nanoseconds may be possible. For example:
|
||||
tens of nanoseconds might be possible. For example:
|
||||
|
||||
----
|
||||
server ntp.local minpoll 0 maxpoll 0 xleave
|
||||
@@ -221,10 +208,11 @@ For best stability, the CPU should be running at a constant frequency (i.e.
|
||||
disabled power saving and performance boosting). Energy-Efficient Ethernet
|
||||
(EEE) should be disabled in the network. The switches should be configured to
|
||||
prioritize NTP packets, especially if the network is expected to be heavily
|
||||
loaded.
|
||||
loaded. The `dscp` directive can be used to set the Differentiated Services
|
||||
Code Point in transmitted NTP packets if needed.
|
||||
|
||||
If it is acceptable for NTP clients in the network to send requests at an
|
||||
excessive rate, a sub-second polling interval may be specified. A median filter
|
||||
If it is acceptable for NTP clients in the network to send requests at a high
|
||||
rate, a sub-second polling interval can be specified. A median filter
|
||||
can be enabled in order to update the clock at a reduced rate with more stable
|
||||
measurements. For example:
|
||||
|
||||
@@ -237,7 +225,7 @@ hwtimestamp eth0 minpoll -6
|
||||
|
||||
Yes. With the `-q` option `chronyd` will set the system clock once and exit.
|
||||
With the `-Q` option it will print the measured offset without setting the
|
||||
clock. If you don't want to use a configuration file, NTP servers can be
|
||||
clock. If you do not want to use a configuration file, NTP servers can be
|
||||
specified on the command line. For example:
|
||||
|
||||
----
|
||||
@@ -249,17 +237,28 @@ well synchronised and responding to all requests. If not synchronised or
|
||||
responding, it would take about 10 seconds for `chronyd` to give up and exit
|
||||
with a non-zero status. A faster configuration is possible. A single server can
|
||||
be used instead of four servers, the number of measurements can be reduced with
|
||||
the `maxsamples` option, and a timeout can be specified with the `-t` option.
|
||||
The following command would take only up to about 1 second.
|
||||
the `maxsamples` option to one (supported in `chrony` version 4.0), and a
|
||||
timeout can be specified with the `-t` option. The following command would take
|
||||
only up to about one second.
|
||||
|
||||
----
|
||||
# chronyd -q -t 1 'server pool.ntp.org iburst maxsamples 1'
|
||||
----
|
||||
|
||||
It is not recommended to run `chronyd` with the `-q` option periodically (e.g.
|
||||
from a cron job) as a replacement for the daemon mode, because it performs
|
||||
significantly worse (e.g. the clock is stepped and its frequency is not
|
||||
corrected). If you must run it this way and you are using a public NTP server,
|
||||
make sure `chronyd` does not always start around the first second of a minute,
|
||||
e.g. by adding a random sleep before the `chronyd` command. Public servers
|
||||
typically receive large bursts of requests around the first second as there is
|
||||
a large number of NTP clients started from cron with no delay.
|
||||
|
||||
=== Can `chronyd` be configured to control the clock like `ntpd`?
|
||||
|
||||
It is not possible to perfectly emulate `ntpd`, but there are some options that
|
||||
can configure `chronyd` to behave more like `ntpd`.
|
||||
can configure `chronyd` to behave more like `ntpd` if there is a reason to
|
||||
prefer that.
|
||||
|
||||
In the following example the `minsamples` directive slows down the response to
|
||||
changes in the frequency and offset of the clock. The `maxslewrate` and
|
||||
@@ -279,10 +278,56 @@ maxchange 1000 1 1
|
||||
maxclockerror 15
|
||||
----
|
||||
|
||||
Note that increasing `minsamples` may cause the offsets in the `tracking` and
|
||||
Note that increasing `minsamples` might cause the offsets in the `tracking` and
|
||||
`sourcestats` reports/logs to be significantly smaller than the actual offsets
|
||||
and be unsuitable for monitoring.
|
||||
|
||||
=== Can NTP server be separated from NTP client?
|
||||
|
||||
Yes, it is possible to run multiple instances of `chronyd` on the same
|
||||
computer. One can be configured as an NTP client, and another as a server. They
|
||||
need to use different pidfiles, NTP ports, command ports, and Unix domain
|
||||
command sockets. The server instance should be started with the `-x` option to
|
||||
avoid touching the clock. It can be configured to serve the system time with
|
||||
the `local` directive, or synchronise its NTP clock to the client instance
|
||||
running on localhost using a non-standard NTP port.
|
||||
|
||||
On Linux, starting with `chrony` version 4.0, it is also possible to run
|
||||
multiple server instances sharing a port to utilise multiple cores of the CPU.
|
||||
Note that the client/server interleaved mode requires that all packets from an
|
||||
address are handled by the same server instance.
|
||||
|
||||
=== Should be a leap smear enabled on NTP server?
|
||||
|
||||
With the `smoothtime` and `leapsecmode` directives it is possible to enable a
|
||||
server leap smear in order to hide leap seconds from clients and force them to
|
||||
follow a slow server's adjustment instead.
|
||||
|
||||
This feature should be used only in local networks and only when necessary,
|
||||
e.g. when the clients cannot be configured to handle the leap seconds as
|
||||
needed, or their number is so large that configuring them all would be
|
||||
impractical. The clients should use only one leap-smearing server, or multiple
|
||||
identically configured leap-smearing servers. Note that some clients can get
|
||||
leap seconds from external sources (e.g. with the `leapsectz` directive in
|
||||
`chrony`) and they will not work correctly with a leap smearing server.
|
||||
|
||||
=== Does `chrony` support PTP?
|
||||
|
||||
No, the Precision Time Protocol (PTP) is not supported and there are no plans
|
||||
to support it. It is a complex protocol, which shares some issues with the
|
||||
NTP broadcast mode. One of the main differences between NTP and PTP is that PTP
|
||||
was designed to be easily supported in hardware (e.g. network switches and
|
||||
routers) in order to make more stable and accurate measurements. PTP relies on
|
||||
the hardware support. NTP does not rely on any support in the hardware, but if
|
||||
it had the same support as PTP, it could perform equally well.
|
||||
|
||||
On Linux, `chrony` supports hardware clocks that some NICs have for PTP. They
|
||||
are called PTP hardware clocks (PHC). They can be used as reference clocks
|
||||
(specified by the `refclock` directive) and for hardware timestamping of NTP
|
||||
packets (enabled by the `hwtimestamp` directive) if the NIC can timestamp other
|
||||
packets than PTP, which is usually the case at least for transmitted packets.
|
||||
The `ethtool -T` command can be used to verify the timestamping support.
|
||||
|
||||
=== What happened to the `commandkey` and `generatecommandkey` directives?
|
||||
|
||||
They were removed in version 2.2. Authentication is no longer supported in the
|
||||
@@ -299,11 +344,11 @@ following questions.
|
||||
|
||||
=== Behind a firewall?
|
||||
|
||||
Check the `Reach` value printed by the ``chronyc``'s `sources` command. If it's
|
||||
zero, it means `chronyd` did not get any valid responses from the NTP server
|
||||
Check the `Reach` value printed by the ``chronyc``'s `sources` command. If it
|
||||
is zero, it means `chronyd` did not get any valid responses from the NTP server
|
||||
you are trying to use. If there is a firewall between you and the server, the
|
||||
packets may be blocked. Try using a tool like `wireshark` or `tcpdump` to see
|
||||
if you're getting any responses from the server.
|
||||
packets might be blocked. Try using a tool like `wireshark` or `tcpdump` to see
|
||||
if you are getting any responses from the server.
|
||||
|
||||
When `chronyd` is receiving responses from the servers, the output of the
|
||||
`sources` command issued few minutes after `chronyd` start might look like
|
||||
@@ -320,9 +365,10 @@ MS Name/IP address Stratum Poll Reach LastRx Last sample
|
||||
|
||||
=== Are NTP servers specified with the `offline` option?
|
||||
|
||||
Check that you're using ``chronyc``'s `online` and `offline` commands
|
||||
appropriately. The `activity` command prints the number of sources that are
|
||||
currently online and offline. For example:
|
||||
Check that the ``chronyc``'s `online` and `offline` commands are used
|
||||
appropriately (e.g. in the system networking scripts). The `activity` command
|
||||
prints the number of sources that are currently online and offline. For
|
||||
example:
|
||||
|
||||
----
|
||||
200 OK
|
||||
@@ -349,9 +395,9 @@ makestep 1 3
|
||||
----
|
||||
|
||||
the clock would be stepped in the first three updates if its offset was larger
|
||||
than one second. Normally, it's recommended to allow the step only in the first
|
||||
than one second. Normally, it is recommended to allow the step only in the first
|
||||
few updates, but in some cases (e.g. a computer without an RTC or virtual
|
||||
machine which can be suspended and resumed with an incorrect time) it may be
|
||||
machine which can be suspended and resumed with an incorrect time) it might be
|
||||
necessary to allow the step on any clock update. The example above would change
|
||||
to
|
||||
|
||||
@@ -363,7 +409,7 @@ makestep 1 -1
|
||||
|
||||
A common issue with Windows NTP servers is that they report a very large root
|
||||
dispersion (e.g. three seconds or more), which causes `chronyd` to ignore the
|
||||
server for being too inaccurate. The `sources` command may show a valid
|
||||
server for being too inaccurate. The `sources` command might show a valid
|
||||
measurement, but the server is not selected for synchronisation. You can check
|
||||
the root dispersion of the server with the ``chronyc``'s `ntpdata` command.
|
||||
|
||||
@@ -374,6 +420,29 @@ synchronisation to such a server. For example:
|
||||
maxdistance 16.0
|
||||
----
|
||||
|
||||
=== An unreachable source is selected?
|
||||
|
||||
When `chronyd` is configured with multiple time sources, it tries to select the
|
||||
most accurate and stable sources for synchronisation of the system clock. They
|
||||
are marked with the _*_ or _+_ symbol in the report printed by the `sources`
|
||||
command.
|
||||
|
||||
When the best source (marked with the _*_ symbol) becomes unreachable (e.g. NTP
|
||||
server stops responding), or the measurements are no longer accepted (e.g. a
|
||||
change in network routing adds a delay), `chronyd` will not immediately switch
|
||||
to the second best source in an attempt to minimise the error of the clock. It
|
||||
will let the clock run free for as long as its estimated error (in terms of
|
||||
root distance) based on previous measurements is smaller than the estimated
|
||||
error of the second source, and there is still an interval which contains some
|
||||
measurements from both sources.
|
||||
|
||||
If the first source was significantly better than the second source, it can
|
||||
take many hours (up to 64 times the maximum polling interval) before the second
|
||||
source is selected. If you do not like this behaviour, you can force a faster
|
||||
reselection by increasing the clock error rate (`maxclockerror` directive),
|
||||
shortening the polling interval (`maxpoll` option), or reducing the number of
|
||||
samples (`maxsamples` option).
|
||||
|
||||
=== Using a PPS reference clock?
|
||||
|
||||
A pulse-per-second (PPS) reference clock requires a non-PPS time source to
|
||||
@@ -409,15 +478,15 @@ to be used for synchronisation.
|
||||
When accessing `chronyd` remotely, make sure that the _chrony.conf_ file (on
|
||||
the computer where `chronyd` is running) has a `cmdallow` entry for the
|
||||
computer you are running `chronyc` on and an appropriate `bindcmdaddress`
|
||||
directive. This isn't necessary for localhost.
|
||||
directive. This is not necessary for localhost.
|
||||
|
||||
Perhaps `chronyd` is not running. Try using the `ps` command (e.g. on Linux,
|
||||
`ps -auxw`) to see if it's running. Or try `netstat -a` and see if the ports
|
||||
123/udp and 323/udp are listening. If `chronyd` is not running, you may have a
|
||||
problem with the way you are trying to start it (e.g. at boot time).
|
||||
`ps -auxw`) to see if it is running. Or try `netstat -a` and see if the UDP
|
||||
port 323 is listening. If `chronyd` is not running, you might have a problem
|
||||
with the way you are trying to start it (e.g. at boot time).
|
||||
|
||||
Perhaps you have a firewall set up in a way that blocks packets on port
|
||||
323/udp. You need to amend the firewall configuration in this case.
|
||||
Perhaps you have a firewall set up in a way that blocks packets on the UDP
|
||||
port 323. You need to amend the firewall configuration in this case.
|
||||
|
||||
=== I keep getting the error `501 Not authorised`
|
||||
|
||||
@@ -426,20 +495,16 @@ socket instead of the Unix domain socket (e.g. _/var/run/chrony/chronyd.sock_),
|
||||
which is required for some commands. For security reasons, only the root and
|
||||
_chrony_ users are allowed to access the socket.
|
||||
|
||||
It is also possible that the socket doesn't exist. `chronyd` will not create
|
||||
It is also possible that the socket does not exist. `chronyd` will not create
|
||||
the socket if the directory has a wrong owner or permissions. In this case
|
||||
there should be an error message from `chronyd` in the system log.
|
||||
|
||||
With versions older than 2.2, which don't use the Unix domain socket, you need
|
||||
to authenticate with the `password` command first,
|
||||
or use the `-a` option to authenticate automatically on start. The
|
||||
configuration file needs to specify a file which contains keys (`keyfile`
|
||||
directive) and which key in the key file should be used for `chronyc`
|
||||
authentication (`commandkey` directive).
|
||||
=== What is the reference ID reported by the `tracking` command?
|
||||
|
||||
=== Why does `chronyc tracking` always print an IPv4 address as reference ID?
|
||||
The reference ID is a 32-bit value used in NTP to prevent synchronisation
|
||||
loops.
|
||||
|
||||
The reference ID is a 32-bit value and in versions before 3.0 it was printed in
|
||||
In `chrony` versions before 3.0 it was printed in the
|
||||
quad-dotted notation, even if the reference source did not actually have an
|
||||
IPv4 address. For IPv4 addresses, the reference ID is equal to the address, but
|
||||
for IPv6 addresses it is the first 32 bits of the MD5 sum of the address. For
|
||||
@@ -463,7 +528,7 @@ Only by the source code. See _cmdmon.c_ (`chronyd` side) and _client.c_
|
||||
=== What is the real-time clock (RTC)?
|
||||
|
||||
This is the clock which keeps the time even when your computer is turned off.
|
||||
It is used to initialise the system clock on boot. It normally doesn't drift
|
||||
It is used to initialise the system clock on boot. It normally does not drift
|
||||
more than few seconds per day.
|
||||
|
||||
There are two approaches how `chronyd` can work with it. One is to use the
|
||||
@@ -478,17 +543,17 @@ monitor the rate at which the RTC gains or loses time. When `chronyd` is
|
||||
started with the `-s` option on the next boot, it will set the system time from
|
||||
the RTC and also compensate for the drift it has measured previously. The
|
||||
`rtcautotrim` directive can be used to keep the RTC close to the true time, but
|
||||
it's not strictly necessary if its only purpose is to set the system clock when
|
||||
it is not strictly necessary if its only purpose is to set the system clock when
|
||||
`chronyd` is started on boot. See the documentation for details.
|
||||
|
||||
=== I want to use ``chronyd``'s RTC support. Must I disable `hwclock`?
|
||||
=== Does `hwclock` have to be disabled?
|
||||
|
||||
The `hwclock` program is often set-up by default in the boot and shutdown
|
||||
scripts with many Linux installations. With the kernel RTC synchronisation
|
||||
(`rtcsync` directive), the RTC will be set also every 11 minutes as long as the
|
||||
system clock is synchronised. If you want to use ``chronyd``'s RTC monitoring
|
||||
(`rtcfile` directive), it's important to disable `hwclock` in the shutdown
|
||||
procedure. If you don't, it will over-write the RTC with a new value, unknown
|
||||
(`rtcfile` directive), it is important to disable `hwclock` in the shutdown
|
||||
procedure. If you do not that, it will over-write the RTC with a new value, unknown
|
||||
to `chronyd`. At the next reboot, `chronyd` started with the `-s` option will
|
||||
compensate this (wrong) time with its estimate of how far the RTC has drifted
|
||||
whilst the power was off, giving a meaningless initial system time.
|
||||
@@ -507,7 +572,7 @@ things
|
||||
|
||||
=== I get `Could not open /dev/rtc, Device or resource busy` in my syslog file
|
||||
|
||||
Some other program running on the system may be using the device.
|
||||
Some other program running on the system might be using the device.
|
||||
|
||||
=== What if my computer does not have an RTC or backup battery?
|
||||
|
||||
@@ -522,7 +587,7 @@ observe backward steps.
|
||||
=== Can `chronyd` be driven from broadcast/multicast NTP servers?
|
||||
|
||||
No, the broadcast/multicast client mode is not supported and there is currently
|
||||
no plan to implement it. While the mode may be useful to simplify configuration
|
||||
no plan to implement it. While this mode can simplify configuration
|
||||
of clients in large networks, it is inherently less accurate and less secure
|
||||
(even with authentication) than the ordinary client/server mode.
|
||||
|
||||
@@ -539,7 +604,8 @@ thousands of clients using the ordinary client/server mode.
|
||||
|
||||
Yes, the `broadcast` directive can be used to enable the broadcast server mode
|
||||
to serve time to clients in the network which support the broadcast client mode
|
||||
(it's not supported in `chronyd`, see the previous question).
|
||||
(it is not supported in `chronyd`). Note that this mode should generally be
|
||||
avoided. See the previous question.
|
||||
|
||||
=== Can `chronyd` keep the system clock a fixed offset away from real time?
|
||||
|
||||
@@ -555,9 +621,21 @@ offline, `chronyd` would make new measurements immediately after issuing the
|
||||
`online` command.
|
||||
|
||||
Unless the network connection lasts only few minutes (less than the maximum
|
||||
polling interval), the delay is usually not a problem, and it may be acceptable
|
||||
polling interval), the delay is usually not a problem, and it might be acceptable
|
||||
to keep all sources online all the time.
|
||||
|
||||
=== Why is an offset measured between two computers synchronised to each another?
|
||||
|
||||
When two computers are synchronised to each other using the client/server or
|
||||
symmetric NTP mode, there is an expectation that NTP measurements between the
|
||||
two computers made on both ends show an average offset close to zero.
|
||||
|
||||
With `chronyd` that can be expected only when the interleaved mode (`xleave`
|
||||
option) is enabled. Otherwise, `chronyd` will use different transmit timestamps
|
||||
(e.g. daemon timestamp vs kernel timestamp) for serving time and
|
||||
synchronisation of its own clock, which creates an asymmetry in the
|
||||
timestamping and causes the other end to measure a significant offset.
|
||||
|
||||
== Operating systems
|
||||
|
||||
=== Does `chrony` support Windows?
|
||||
|
||||
@@ -100,7 +100,7 @@ than MD5, which can be used for NTP authentication with a symmetric key. If you
|
||||
don't want to enable the support, specify the `--disable-sechash` flag to
|
||||
`configure`.
|
||||
|
||||
If development files for the editline or readline library are available,
|
||||
If development files for the editline library are available,
|
||||
`chronyc` will be built with line editing support. If you don't want this,
|
||||
specify the `--disable-readline` flag to `configure`.
|
||||
|
||||
@@ -170,43 +170,6 @@ https://github.com/seccomp/libseccomp[libseccomp] library and the
|
||||
the kernel attack surface and possibly prevent kernel exploits from `chronyd`
|
||||
if it is compromised.
|
||||
|
||||
== Support for line editing libraries
|
||||
|
||||
`chronyc` can be built with support for line editing, this allows you to use
|
||||
the cursor keys to replay and edit old commands. Two libraries are supported
|
||||
which provide such functionality, editline and GNU readline.
|
||||
|
||||
Please note that readline since version 6.0 is licensed under GPLv3+ which is
|
||||
incompatible with chrony's license GPLv2. You should use editline instead if
|
||||
you don't want to use older readline versions.
|
||||
|
||||
The `configure` script will automatically enable the line editing support if
|
||||
one of the supported libraries is available. If they are both available, the
|
||||
editline library will be used.
|
||||
|
||||
If you don't want to use it (in which case `chronyc` will use a minimal command
|
||||
line interface), invoke `configure` like this:
|
||||
|
||||
----
|
||||
./configure --disable-readline other-options...
|
||||
----
|
||||
|
||||
If you have editline, readline or ncurses installed in locations that aren't
|
||||
normally searched by the compiler and linker, you need to use extra options:
|
||||
|
||||
`--with-readline-includes=directory_name`::
|
||||
This defines the name of the directory above the one where `readline.h` is.
|
||||
`readline.h` is assumed to be in `editline` or `readline` subdirectory of the
|
||||
named directory.
|
||||
|
||||
`--with-readline-library=directory_name`::
|
||||
This defines the directory containing the `libedit.a` or `libedit.so` file,
|
||||
or `libreadline.a` or `libreadline.so` file.
|
||||
|
||||
`--with-ncurses-library=directory_name`::
|
||||
This defines the directory containing the `libncurses.a` or `libncurses.so`
|
||||
file.
|
||||
|
||||
== Extra options for package builders
|
||||
|
||||
The `configure` and `make` procedures have some extra options that may be
|
||||
|
||||
@@ -8,9 +8,11 @@ Wants=time-sync.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# Wait up to ~10 minutes for chronyd to synchronize and the remaining
|
||||
# clock correction to be less than 0.1 seconds
|
||||
ExecStart=/usr/bin/chronyc -h 127.0.0.1,::1 waitsync 600 0.1 0.0 1
|
||||
# Wait for chronyd to update the clock and the remaining
|
||||
# correction to be less than 0.1 seconds
|
||||
ExecStart=/usr/bin/chronyc -h 127.0.0.1,::1 waitsync 0 0.1 0.0 1
|
||||
# Wait for at most 3 minutes
|
||||
TimeoutStartSec=180
|
||||
RemainAfterExit=yes
|
||||
StandardOutput=null
|
||||
|
||||
|
||||
2
keys.c
2
keys.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2012-2016
|
||||
* Copyright (C) Miroslav Lichvar 2012-2016, 2019-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
28
local.c
28
local.c
@@ -108,8 +108,8 @@ static double max_clock_error;
|
||||
|
||||
#define NSEC_PER_SEC 1000000000
|
||||
|
||||
static void
|
||||
calculate_sys_precision(void)
|
||||
static double
|
||||
measure_clock_precision(void)
|
||||
{
|
||||
struct timespec ts, old_ts;
|
||||
int iters, diff, best;
|
||||
@@ -135,18 +135,7 @@ calculate_sys_precision(void)
|
||||
|
||||
assert(best > 0);
|
||||
|
||||
precision_quantum = 1.0e-9 * best;
|
||||
|
||||
/* Get rounded log2 value of the measured precision */
|
||||
precision_log = 0;
|
||||
while (best < 707106781) {
|
||||
precision_log--;
|
||||
best *= 2;
|
||||
}
|
||||
|
||||
assert(precision_log >= -30);
|
||||
|
||||
DEBUG_LOG("Clock precision %.9f (%d)", precision_quantum, precision_log);
|
||||
return 1.0e-9 * best;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -170,7 +159,16 @@ LCL_Initialise(void)
|
||||
current_freq_ppm = 0.0;
|
||||
temp_comp_ppm = 0.0;
|
||||
|
||||
calculate_sys_precision();
|
||||
precision_quantum = CNF_GetClockPrecision();
|
||||
if (precision_quantum <= 0.0)
|
||||
precision_quantum = measure_clock_precision();
|
||||
|
||||
precision_quantum = CLAMP(1.0e-9, precision_quantum, 1.0);
|
||||
precision_log = round(log(precision_quantum) / log(2.0));
|
||||
/* NTP code doesn't support smaller log than -30 */
|
||||
assert(precision_log >= -30);
|
||||
|
||||
DEBUG_LOG("Clock precision %.9f (%d)", precision_quantum, precision_log);
|
||||
|
||||
/* This is the maximum allowed frequency offset in ppm, the time must
|
||||
never stop or run backwards */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011-2014, 2018
|
||||
* Copyright (C) Miroslav Lichvar 2011-2014, 2018-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
14
main.c
14
main.c
@@ -4,7 +4,7 @@
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) John G. Hasler 2009
|
||||
* Copyright (C) Miroslav Lichvar 2012-2018
|
||||
* Copyright (C) Miroslav Lichvar 2012-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -411,7 +411,7 @@ int main
|
||||
int do_init_rtc = 0, restarted = 0, client_only = 0, timeout = -1;
|
||||
int scfilter_level = 0, lock_memory = 0, sched_priority = 0;
|
||||
int clock_control = 1, system_log = 1, log_severity = LOGS_INFO;
|
||||
int config_args = 0, print_config = 0;
|
||||
int user_check = 1, config_args = 0, print_config = 0;
|
||||
|
||||
do_platform_checks();
|
||||
|
||||
@@ -431,7 +431,7 @@ int main
|
||||
optind = 1;
|
||||
|
||||
/* Parse short command-line options */
|
||||
while ((opt = getopt(argc, argv, "46df:F:hl:L:mnpP:qQrRst:u:vx")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "46df:F:hl:L:mnpP:qQrRst:u:Uvx")) != -1) {
|
||||
switch (opt) {
|
||||
case '4':
|
||||
case '6':
|
||||
@@ -462,7 +462,7 @@ int main
|
||||
break;
|
||||
case 'p':
|
||||
print_config = 1;
|
||||
client_only = 1;
|
||||
user_check = 0;
|
||||
nofork = 1;
|
||||
system_log = 0;
|
||||
break;
|
||||
@@ -479,6 +479,7 @@ int main
|
||||
ref_mode = REF_ModePrintOnce;
|
||||
nofork = 1;
|
||||
client_only = 1;
|
||||
user_check = 0;
|
||||
clock_control = 0;
|
||||
system_log = 0;
|
||||
break;
|
||||
@@ -497,6 +498,9 @@ int main
|
||||
case 'u':
|
||||
user = optarg;
|
||||
break;
|
||||
case 'U':
|
||||
user_check = 0;
|
||||
break;
|
||||
case 'v':
|
||||
print_version();
|
||||
return 0;
|
||||
@@ -509,7 +513,7 @@ int main
|
||||
}
|
||||
}
|
||||
|
||||
if (getuid() && !client_only)
|
||||
if (user_check && getuid() != 0)
|
||||
LOG_FATAL("Not superuser");
|
||||
|
||||
/* Turn into a daemon */
|
||||
|
||||
19
ntp_auth.c
19
ntp_auth.c
@@ -2,7 +2,7 @@
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2019
|
||||
* Copyright (C) Miroslav Lichvar 2019-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -300,21 +300,9 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
if (remainder >= NTP_MIN_MAC_LENGTH && remainder <= NTP_MAX_V4_MAC_LENGTH)
|
||||
break;
|
||||
|
||||
/* The NTPv4-specific limit for MAC length enables deterministic parsing of
|
||||
packets with extension fields (RFC 7822), but we support longer MACs in
|
||||
packets with no extension fields for compatibility with older chrony
|
||||
clients. Check if the longer MAC would authenticate the packet before
|
||||
trying to parse the data as an extension field. */
|
||||
if (parsed == NTP_HEADER_LENGTH &&
|
||||
remainder > NTP_MAX_V4_MAC_LENGTH && remainder <= NTP_MAX_MAC_LENGTH &&
|
||||
KEY_CheckAuth(ntohl(*(uint32_t *)(data + parsed)), data, parsed,
|
||||
data + parsed + 4, remainder - 4, NTP_MAX_MAC_LENGTH - 4))
|
||||
break;
|
||||
|
||||
/* Check if this is a valid NTPv4 extension field and skip it */
|
||||
if (!NEF_ParseField(packet, info->length, parsed, &ef_length, &ef_type, NULL, NULL)) {
|
||||
/* Invalid MAC or format error */
|
||||
DEBUG_LOG("Invalid format or MAC");
|
||||
DEBUG_LOG("Invalid format");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -340,9 +328,6 @@ NAU_ParsePacket(NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
/* No MAC */
|
||||
return 1;
|
||||
} else if (remainder >= NTP_MIN_MAC_LENGTH) {
|
||||
/* This is not 100% reliable as a MAC could fail to authenticate and could
|
||||
pass as an extension field, leaving reminder smaller than the minimum MAC
|
||||
length */
|
||||
info->auth.mode = NTP_AUTH_SYMMETRIC;
|
||||
info->auth.mac.start = parsed;
|
||||
info->auth.mac.length = remainder;
|
||||
|
||||
14
ntp_core.c
14
ntp_core.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009-2018
|
||||
* Copyright (C) Miroslav Lichvar 2009-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -2095,15 +2095,6 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
|
||||
CLG_LogAuthNtpRequest();
|
||||
}
|
||||
|
||||
/* If it is an NTPv4 packet with a long MAC and no extension fields,
|
||||
respond with an NTPv3 packet to avoid breaking RFC 7822 and keep
|
||||
the length symmetric. Otherwise, respond with the same version. */
|
||||
if (info.version == 4 && info.ext_fields == 0 && info.auth.mode == NTP_AUTH_SYMMETRIC &&
|
||||
info.auth.mac.length > NTP_MAX_V4_MAC_LENGTH)
|
||||
version = 3;
|
||||
else
|
||||
version = info.version;
|
||||
|
||||
local_ntp_rx = local_ntp_tx = NULL;
|
||||
tx_ts = NULL;
|
||||
interleaved = 0;
|
||||
@@ -2133,6 +2124,9 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
|
||||
poll = CLG_GetNtpMinPoll();
|
||||
poll = MAX(poll, message->poll);
|
||||
|
||||
/* Respond with the same version */
|
||||
version = info.version;
|
||||
|
||||
/* Send a reply */
|
||||
transmit_packet(my_mode, interleaved, poll, version, kod, NULL,
|
||||
&message->receive_ts, &message->transmit_ts,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2019
|
||||
* Copyright (C) Miroslav Lichvar 2019-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
2
ntp_io.c
2
ntp_io.c
@@ -4,7 +4,7 @@
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Timo Teras 2009
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2013-2016, 2018
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2013-2016, 2018-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
@@ -200,7 +200,8 @@ add_interface(CNF_HwTsInterface *conf_iface)
|
||||
req.ifr_data = (char *)&ts_config;
|
||||
|
||||
if (ioctl(sock_fd, SIOCSHWTSTAMP, &req)) {
|
||||
DEBUG_LOG("ioctl(%s) failed : %s", "SIOCSHWTSTAMP", strerror(errno));
|
||||
LOG(errno == EPERM ? LOGS_ERR : LOGS_DEBUG,
|
||||
"ioctl(%s) failed : %s", "SIOCSHWTSTAMP", strerror(errno));
|
||||
|
||||
/* Check the current timestamping configuration in case this interface
|
||||
allows only reading of the configuration and it was already configured
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011-2012, 2014, 2016
|
||||
* Copyright (C) Miroslav Lichvar 2011-2012, 2014, 2016, 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
@@ -335,15 +335,17 @@ NKC_Start(NKC_Instance inst)
|
||||
local_addr.port = 0;
|
||||
iface = CNF_GetBindAcquisitionInterface();
|
||||
|
||||
sock_fd = SCK_OpenTcpSocket(&inst->address, &local_addr, iface, 0);
|
||||
if (sock_fd < 0)
|
||||
return 0;
|
||||
|
||||
/* Make a label containing both the address and name of the server */
|
||||
if (snprintf(label, sizeof (label), "%s (%s)",
|
||||
UTI_IPSockAddrToString(&inst->address), inst->name) >= sizeof (label))
|
||||
;
|
||||
|
||||
sock_fd = SCK_OpenTcpSocket(&inst->address, &local_addr, iface, 0);
|
||||
if (sock_fd < 0) {
|
||||
LOG(LOGS_ERR, "Could not connect to %s", label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Start an NTS-KE session */
|
||||
if (!NKSN_StartSession(inst->session, sock_fd, label, client_credentials, CLIENT_TIMEOUT)) {
|
||||
SCK_CloseSocket(sock_fd);
|
||||
|
||||
@@ -53,6 +53,7 @@ struct NNC_Instance_Record {
|
||||
const IPSockAddr *ntp_address;
|
||||
IPSockAddr nts_address;
|
||||
char *name;
|
||||
|
||||
NKC_Instance nke;
|
||||
SIV_Instance siv;
|
||||
|
||||
@@ -66,6 +67,7 @@ struct NNC_Instance_Record {
|
||||
NKE_Cookie cookies[NTS_MAX_COOKIES];
|
||||
int num_cookies;
|
||||
int cookie_index;
|
||||
int auth_ready;
|
||||
int nak_response;
|
||||
int ok_response;
|
||||
unsigned char nonce[NTS_MIN_UNPADDED_NONCE_LENGTH];
|
||||
@@ -82,6 +84,13 @@ static void load_cookies(NNC_Instance inst);
|
||||
static void
|
||||
reset_instance(NNC_Instance inst)
|
||||
{
|
||||
if (inst->nke)
|
||||
NKC_DestroyInstance(inst->nke);
|
||||
inst->nke = NULL;
|
||||
if (inst->siv)
|
||||
SIV_DestroyInstance(inst->siv);
|
||||
inst->siv = NULL;
|
||||
|
||||
inst->load_attempt = 0;
|
||||
inst->nke_attempts = 0;
|
||||
inst->next_nke_attempt = 0.0;
|
||||
@@ -92,6 +101,7 @@ reset_instance(NNC_Instance inst)
|
||||
memset(inst->cookies, 0, sizeof (inst->cookies));
|
||||
inst->num_cookies = 0;
|
||||
inst->cookie_index = 0;
|
||||
inst->auth_ready = 0;
|
||||
inst->nak_response = 0;
|
||||
inst->ok_response = 1;
|
||||
memset(inst->nonce, 0, sizeof (inst->nonce));
|
||||
@@ -125,10 +135,7 @@ NNC_DestroyInstance(NNC_Instance inst)
|
||||
{
|
||||
save_cookies(inst);
|
||||
|
||||
if (inst->nke)
|
||||
NKC_DestroyInstance(inst->nke);
|
||||
if (inst->siv)
|
||||
SIV_DestroyInstance(inst->siv);
|
||||
reset_instance(inst);
|
||||
|
||||
Free(inst->name);
|
||||
Free(inst);
|
||||
@@ -276,6 +283,8 @@ get_cookies(NNC_Instance inst)
|
||||
int
|
||||
NNC_PrepareForAuth(NNC_Instance inst)
|
||||
{
|
||||
inst->auth_ready = 0;
|
||||
|
||||
/* Try to reload saved keys and cookies (once for the NTS-KE address) */
|
||||
if (!inst->load_attempt) {
|
||||
load_cookies(inst);
|
||||
@@ -301,6 +310,8 @@ NNC_PrepareForAuth(NNC_Instance inst)
|
||||
UTI_GetRandomBytes(inst->uniq_id, sizeof (inst->uniq_id));
|
||||
UTI_GetRandomBytes(inst->nonce, sizeof (inst->nonce));
|
||||
|
||||
inst->auth_ready = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -314,7 +325,7 @@ NNC_GenerateRequestAuth(NNC_Instance inst, NTP_Packet *packet,
|
||||
int i, req_cookies;
|
||||
void *ef_body;
|
||||
|
||||
if (inst->num_cookies == 0 || !inst->siv)
|
||||
if (!inst->auth_ready || inst->num_cookies == 0 || !inst->siv)
|
||||
return 0;
|
||||
|
||||
if (info->mode != MODE_CLIENT)
|
||||
@@ -345,6 +356,7 @@ NNC_GenerateRequestAuth(NNC_Instance inst, NTP_Packet *packet,
|
||||
|
||||
inst->num_cookies--;
|
||||
inst->cookie_index = (inst->cookie_index + 1) % NTS_MAX_COOKIES;
|
||||
inst->auth_ready = 0;
|
||||
inst->nak_response = 0;
|
||||
inst->ok_response = 0;
|
||||
|
||||
@@ -427,7 +439,7 @@ NNC_CheckResponseAuth(NNC_Instance inst, NTP_Packet *packet,
|
||||
return 0;
|
||||
|
||||
/* Accept at most one response per request */
|
||||
if (inst->ok_response)
|
||||
if (inst->ok_response || inst->auth_ready)
|
||||
return 0;
|
||||
|
||||
if (!inst->siv ||
|
||||
@@ -506,11 +518,6 @@ NNC_ChangeAddress(NNC_Instance inst, IPAddr *address)
|
||||
{
|
||||
save_cookies(inst);
|
||||
|
||||
if (inst->nke)
|
||||
NKC_DestroyInstance(inst->nke);
|
||||
|
||||
inst->nke = NULL;
|
||||
inst->num_cookies = 0;
|
||||
inst->nts_address.ip_addr = *address;
|
||||
|
||||
reset_instance(inst);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009-2018
|
||||
* Copyright (C) Miroslav Lichvar 2009-2018, 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
@@ -36,7 +36,14 @@ typedef struct {
|
||||
int stratum;
|
||||
int poll;
|
||||
enum {RPT_NTP_CLIENT, RPT_NTP_PEER, RPT_LOCAL_REFERENCE} mode;
|
||||
enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_CANDIDATE, RPT_OUTLIER} state;
|
||||
enum {
|
||||
RPT_NONSELECTABLE,
|
||||
RPT_FALSETICKER,
|
||||
RPT_JITTERY,
|
||||
RPT_SELECTABLE,
|
||||
RPT_UNSELECTED,
|
||||
RPT_SELECTED,
|
||||
} state;
|
||||
|
||||
int reachability;
|
||||
unsigned long latest_meas_ago; /* seconds */
|
||||
|
||||
@@ -204,6 +204,9 @@ SIV_Encrypt(SIV_Instance instance,
|
||||
{
|
||||
size_t clen = ciphertext_length;
|
||||
|
||||
if (!instance->cipher)
|
||||
return 0;
|
||||
|
||||
if (nonce_length < 1 || assoc_length < 0 ||
|
||||
plaintext_length < 0 || ciphertext_length < 0)
|
||||
return 0;
|
||||
@@ -232,6 +235,9 @@ SIV_Decrypt(SIV_Instance instance,
|
||||
{
|
||||
size_t plen = plaintext_length;
|
||||
|
||||
if (!instance->cipher)
|
||||
return 0;
|
||||
|
||||
if (nonce_length < 1 || assoc_length < 0 ||
|
||||
plaintext_length < 0 || ciphertext_length < 0)
|
||||
return 0;
|
||||
|
||||
10
siv_nettle.c
10
siv_nettle.c
@@ -39,6 +39,7 @@
|
||||
|
||||
struct SIV_Instance_Record {
|
||||
struct siv_cmac_aes128_ctx siv;
|
||||
int key_set;
|
||||
};
|
||||
|
||||
/* ================================================== */
|
||||
@@ -52,6 +53,7 @@ SIV_CreateInstance(SIV_Algorithm algorithm)
|
||||
return NULL;
|
||||
|
||||
instance = MallocNew(struct SIV_Instance_Record);
|
||||
instance->key_set = 0;
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -86,6 +88,8 @@ SIV_SetKey(SIV_Instance instance, const unsigned char *key, int length)
|
||||
|
||||
siv_cmac_aes128_set_key(&instance->siv, key);
|
||||
|
||||
instance->key_set = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -108,6 +112,9 @@ SIV_Encrypt(SIV_Instance instance,
|
||||
const void *plaintext, int plaintext_length,
|
||||
unsigned char *ciphertext, int ciphertext_length)
|
||||
{
|
||||
if (!instance->key_set)
|
||||
return 0;
|
||||
|
||||
if (nonce_length < SIV_MIN_NONCE_SIZE || assoc_length < 0 ||
|
||||
plaintext_length < 0 || plaintext_length > ciphertext_length ||
|
||||
plaintext_length + SIV_DIGEST_SIZE != ciphertext_length)
|
||||
@@ -130,6 +137,9 @@ SIV_Decrypt(SIV_Instance instance,
|
||||
const unsigned char *ciphertext, int ciphertext_length,
|
||||
void *plaintext, int plaintext_length)
|
||||
{
|
||||
if (!instance->key_set)
|
||||
return 0;
|
||||
|
||||
if (nonce_length < SIV_MIN_NONCE_SIZE || assoc_length < 0 ||
|
||||
plaintext_length < 0 || plaintext_length > ciphertext_length ||
|
||||
plaintext_length + SIV_DIGEST_SIZE != ciphertext_length)
|
||||
|
||||
2
socket.c
2
socket.c
@@ -4,7 +4,7 @@
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Timo Teras 2009
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2013-2019
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2013-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
11
sources.c
11
sources.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2011-2016, 2018
|
||||
* Copyright (C) Miroslav Lichvar 2011-2016, 2018, 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -1499,22 +1499,21 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now)
|
||||
case SRC_JITTERY:
|
||||
report->state = RPT_JITTERY;
|
||||
break;
|
||||
case SRC_UNTRUSTED:
|
||||
case SRC_WAITS_SOURCES:
|
||||
case SRC_NONPREFERRED:
|
||||
case SRC_WAITS_UPDATE:
|
||||
case SRC_DISTANT:
|
||||
case SRC_OUTLIER:
|
||||
report->state = RPT_OUTLIER;
|
||||
report->state = RPT_SELECTABLE;
|
||||
break;
|
||||
case SRC_UNSELECTED:
|
||||
report->state = RPT_CANDIDATE;
|
||||
report->state = RPT_UNSELECTED;
|
||||
break;
|
||||
case SRC_SELECTED:
|
||||
report->state = RPT_SYNC;
|
||||
report->state = RPT_SELECTED;
|
||||
break;
|
||||
default:
|
||||
report->state = RPT_UNREACH;
|
||||
report->state = RPT_NONSELECTABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
2
stubs.c
2
stubs.c
@@ -49,7 +49,7 @@
|
||||
#include "sched.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef FEAT_ASYNCDNS
|
||||
#if defined(FEAT_NTP) && !defined(FEAT_ASYNCDNS)
|
||||
|
||||
/* This is a blocking implementation used when asynchronous resolving is not available */
|
||||
|
||||
|
||||
17
sys_linux.c
17
sys_linux.c
@@ -437,13 +437,16 @@ SYS_Linux_DropRoot(uid_t uid, gid_t gid, int clock_control)
|
||||
|
||||
UTI_DropRoot(uid, gid);
|
||||
|
||||
/* Keep CAP_NET_BIND_SERVICE if the NTP server sockets may need to be bound.
|
||||
Keep CAP_NET_RAW if an NTP socket may need to be bound to a device.
|
||||
/* Keep CAP_NET_BIND_SERVICE if the NTP server sockets may need to be bound
|
||||
to a privileged port.
|
||||
Keep CAP_NET_RAW if an NTP socket may need to be bound to a device on
|
||||
kernels before 5.7.
|
||||
Keep CAP_SYS_TIME if the clock control is enabled. */
|
||||
if (snprintf(cap_text, sizeof (cap_text), "%s %s %s",
|
||||
CNF_GetNTPPort() ? "cap_net_bind_service=ep" : "",
|
||||
CNF_GetBindNtpInterface() || CNF_GetBindAcquisitionInterface() ?
|
||||
"cap_net_raw=ep" : "",
|
||||
(CNF_GetNTPPort() > 0 && CNF_GetNTPPort() < 1024) ?
|
||||
"cap_net_bind_service=ep" : "",
|
||||
(CNF_GetBindNtpInterface() || CNF_GetBindAcquisitionInterface()) &&
|
||||
!SYS_Linux_CheckKernelVersion(5, 7) ? "cap_net_raw=ep" : "",
|
||||
clock_control ? "cap_sys_time=ep" : "") >= sizeof (cap_text))
|
||||
assert(0);
|
||||
|
||||
@@ -533,7 +536,11 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_SystemCallContext context)
|
||||
SCMP_SYS(getdents),
|
||||
SCMP_SYS(getdents64),
|
||||
SCMP_SYS(lseek),
|
||||
SCMP_SYS(lstat),
|
||||
SCMP_SYS(lstat64),
|
||||
SCMP_SYS(newfstatat),
|
||||
SCMP_SYS(readlink),
|
||||
SCMP_SYS(readlinkat),
|
||||
SCMP_SYS(rename),
|
||||
SCMP_SYS(renameat),
|
||||
SCMP_SYS(renameat2),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2001
|
||||
* Copyright (C) J. Hannken-Illjes 2001
|
||||
* Copyright (C) Bryan Christianson 2015, 2017
|
||||
* Copyright (C) Bryan Christianson 2015, 2017, 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
23
sys_timex.c
23
sys_timex.c
@@ -68,6 +68,25 @@ static int sys_tai_offset;
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static double
|
||||
convert_timex_frequency(const struct timex *txc)
|
||||
{
|
||||
double freq_ppm;
|
||||
|
||||
freq_ppm = txc->freq / FREQ_SCALE;
|
||||
|
||||
#ifdef MACOSX
|
||||
/* Temporary workaround for Apple bug treating freq as unsigned number */
|
||||
if (freq_ppm > 32767) {
|
||||
freq_ppm -= 65536;
|
||||
}
|
||||
#endif
|
||||
|
||||
return -freq_ppm;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
static double
|
||||
read_frequency(void)
|
||||
{
|
||||
@@ -77,7 +96,7 @@ read_frequency(void)
|
||||
|
||||
SYS_Timex_Adjust(&txc, 0);
|
||||
|
||||
return txc.freq / -FREQ_SCALE;
|
||||
return convert_timex_frequency(&txc);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -92,7 +111,7 @@ set_frequency(double freq_ppm)
|
||||
|
||||
SYS_Timex_Adjust(&txc, 0);
|
||||
|
||||
return txc.freq / -FREQ_SCALE;
|
||||
return convert_timex_frequency(&txc);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -17,12 +17,15 @@ for opts in \
|
||||
"--disable-rtc" \
|
||||
"--disable-sechash" \
|
||||
"--disable-cmdmon" \
|
||||
"--disable-cmdmon --enable-scfilter" \
|
||||
"--disable-ntp" \
|
||||
"--disable-ntp --enable-scfilter" \
|
||||
"--disable-nts" \
|
||||
"--disable-refclock" \
|
||||
"--disable-timestamping" \
|
||||
"--disable-timestamping --disable-ntp" \
|
||||
"--disable-cmdmon --disable-ntp" \
|
||||
"--disable-cmdmon --disable-ntp --enable-scfilter" \
|
||||
"--disable-cmdmon --disable-refclock" \
|
||||
"--disable-cmdmon --disable-ntp --disable-refclock"
|
||||
do
|
||||
|
||||
@@ -52,15 +52,15 @@ test_freqrange(void)
|
||||
|
||||
printf("freq range:\n");
|
||||
|
||||
for (i = 0; i <= 1000; i += 50) {
|
||||
for (i = -1000; i <= 1000; i += 50) {
|
||||
t.modes = MOD_FREQUENCY;
|
||||
t.freq = i << 16;
|
||||
t.freq = i * (1 << 16);
|
||||
printf("%4d ppm => ", i);
|
||||
if (try_ntpadjtime(&t) < 0)
|
||||
continue;
|
||||
|
||||
printf("%4ld ppm : ", t.freq / (1 << 16));
|
||||
printf("%s\n", t.freq == i << 16 ? "ok" : "fail");
|
||||
printf("%s\n", t.freq == i * (1 << 16) ? "ok" : "fail");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
305
test/unit/ntp_auth.c
Normal file
305
test/unit/ntp_auth.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) Miroslav Lichvar 2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sysincl.h>
|
||||
#include <conf.h>
|
||||
#include <keys.h>
|
||||
#include <local.h>
|
||||
#include <ntp_ext.h>
|
||||
#include <ntp_signd.h>
|
||||
#include <nts_ntp_server.h>
|
||||
#include <socket.h>
|
||||
#include "test.h"
|
||||
|
||||
#ifdef FEAT_NTP
|
||||
|
||||
#include <ntp_auth.c>
|
||||
|
||||
static void
|
||||
prepare_packet(NTP_AuthMode auth_mode, NTP_Packet *packet, NTP_PacketInfo *info, int req)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
int i, version;
|
||||
NTP_Mode mode;
|
||||
|
||||
switch (auth_mode) {
|
||||
case NTP_AUTH_MSSNTP:
|
||||
case NTP_AUTH_MSSNTP_EXT:
|
||||
version = 3;
|
||||
mode = random() % 2 ? (req ? MODE_CLIENT : MODE_SERVER) :
|
||||
(req ? MODE_ACTIVE : MODE_PASSIVE);
|
||||
break;
|
||||
case NTP_AUTH_NTS:
|
||||
version = 4;
|
||||
mode = req ? MODE_CLIENT : MODE_SERVER;
|
||||
break;
|
||||
default:
|
||||
version = 3 + random() % 2;
|
||||
mode = random() % 2 ? (req ? MODE_CLIENT : MODE_SERVER) :
|
||||
(req ? MODE_ACTIVE : MODE_PASSIVE);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(packet, 0, sizeof (*packet));
|
||||
memset(info, 0, sizeof (*info));
|
||||
packet->lvm = NTP_LVM(LEAP_Normal, version, mode);
|
||||
info->length = NTP_HEADER_LENGTH;
|
||||
info->version = version;
|
||||
info->mode = mode;
|
||||
|
||||
if (version == 4) {
|
||||
memset(buf, 0, sizeof (buf));
|
||||
for (i = random() % 5; i > 0; i--)
|
||||
TEST_CHECK(NEF_AddField(packet, info, 0, buf, sizeof (buf)));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_dummy_auth(NTP_AuthMode auth_mode, uint32_t key_id, NTP_Packet *packet, NTP_PacketInfo *info)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
int len, fill;
|
||||
|
||||
info->auth.mode = auth_mode;
|
||||
|
||||
switch (auth_mode) {
|
||||
case NTP_AUTH_NONE:
|
||||
break;
|
||||
case NTP_AUTH_SYMMETRIC:
|
||||
case NTP_AUTH_MSSNTP:
|
||||
case NTP_AUTH_MSSNTP_EXT:
|
||||
switch (auth_mode) {
|
||||
case NTP_AUTH_SYMMETRIC:
|
||||
len = 16 + random() % 2 * 4;
|
||||
fill = 1 + random() % 255;
|
||||
break;
|
||||
case NTP_AUTH_MSSNTP:
|
||||
len = 16;
|
||||
fill = 0;
|
||||
break;
|
||||
case NTP_AUTH_MSSNTP_EXT:
|
||||
len = 68;
|
||||
fill = 0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
assert(info->length + 4 + len <= sizeof (*packet));
|
||||
|
||||
*(uint32_t *)((unsigned char *)packet + info->length) = htonl(key_id);
|
||||
info->auth.mac.key_id = key_id;
|
||||
info->length += 4;
|
||||
|
||||
memset((unsigned char *)packet + info->length, fill, len);
|
||||
info->length += len;
|
||||
break;
|
||||
case NTP_AUTH_NTS:
|
||||
memset(buf, 0, sizeof (buf));
|
||||
TEST_CHECK(NEF_AddField(packet, info, NTP_EF_NTS_AUTH_AND_EEF, buf, sizeof (buf)));
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
int i, j, can_auth_req, can_auth_res;
|
||||
NTP_PacketInfo req_info, res_info;
|
||||
NTP_Packet req, res;
|
||||
NAU_Instance inst;
|
||||
RPT_AuthReport report;
|
||||
NTP_AuthMode mode;
|
||||
IPSockAddr nts_addr;
|
||||
uint32_t key_id, kod;
|
||||
char conf[][100] = {
|
||||
"keyfile ntp_core.keys"
|
||||
};
|
||||
|
||||
CNF_Initialise(0, 0);
|
||||
for (i = 0; i < sizeof conf / sizeof conf[0]; i++)
|
||||
CNF_ParseLine(NULL, i + 1, conf[i]);
|
||||
|
||||
LCL_Initialise();
|
||||
|
||||
TST_SuspendLogging();
|
||||
KEY_Initialise();
|
||||
TST_ResumeLogging();
|
||||
|
||||
NSD_Initialise();
|
||||
NNS_Initialise();
|
||||
|
||||
SCK_GetAnyLocalIPAddress(IPADDR_INET4, &nts_addr.ip_addr);
|
||||
nts_addr.port = 0;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
TST_SuspendLogging();
|
||||
|
||||
key_id = INACTIVE_AUTHKEY;
|
||||
|
||||
switch (i % 5) {
|
||||
case 0:
|
||||
inst = NAU_CreateNoneInstance();
|
||||
TEST_CHECK(!NAU_IsAuthEnabled(inst));
|
||||
TEST_CHECK(NAU_GetSuggestedNtpVersion(inst) == 4);
|
||||
mode = NTP_AUTH_NONE;
|
||||
can_auth_req = 1;
|
||||
can_auth_res = 1;
|
||||
break;
|
||||
case 1:
|
||||
key_id = random() % 7 + 2;
|
||||
inst = NAU_CreateSymmetricInstance(key_id);
|
||||
TEST_CHECK(NAU_IsAuthEnabled(inst));
|
||||
TEST_CHECK(NAU_GetSuggestedNtpVersion(inst) ==
|
||||
(KEY_KeyKnown(inst->key_id) && KEY_GetAuthLength(inst->key_id) > 20 ? 3 : 4));
|
||||
mode = NTP_AUTH_SYMMETRIC;
|
||||
can_auth_req = KEY_KeyKnown(key_id);
|
||||
can_auth_res = can_auth_req;
|
||||
break;
|
||||
case 2:
|
||||
inst = NAU_CreateNtsInstance(&nts_addr, "test", &nts_addr);
|
||||
TEST_CHECK(NAU_IsAuthEnabled(inst));
|
||||
TEST_CHECK(NAU_GetSuggestedNtpVersion(inst) == 4);
|
||||
mode = NTP_AUTH_NTS;
|
||||
can_auth_req = 0;
|
||||
can_auth_res = 0;
|
||||
break;
|
||||
case 3:
|
||||
key_id = 1 + random() % 100;
|
||||
inst = NULL;
|
||||
mode = NTP_AUTH_MSSNTP;
|
||||
can_auth_req = 1;
|
||||
can_auth_res = 0;
|
||||
break;
|
||||
case 4:
|
||||
key_id = 1 + random() % 100;
|
||||
inst = NULL;
|
||||
mode = NTP_AUTH_MSSNTP_EXT;
|
||||
can_auth_req = 0;
|
||||
can_auth_res = 0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
TST_ResumeLogging();
|
||||
|
||||
DEBUG_LOG("iteration %d auth=%d key_id=%d", i, (int)mode, (int)key_id);
|
||||
|
||||
prepare_packet(mode, &req, &req_info, 1);
|
||||
|
||||
if (inst) {
|
||||
TEST_CHECK(inst->mode == mode);
|
||||
TEST_CHECK(inst->key_id == key_id);
|
||||
|
||||
NAU_DumpData(inst);
|
||||
NAU_GetReport(inst, &report);
|
||||
if (random() % 2)
|
||||
NAU_ChangeAddress(inst, &nts_addr.ip_addr);
|
||||
|
||||
if (inst->mode == NTP_AUTH_NTS) {
|
||||
TST_SuspendLogging();
|
||||
for (j = random() % 5; j > 0; j--)
|
||||
#ifdef FEAT_NTS
|
||||
TEST_CHECK(!NAU_PrepareRequestAuth(inst));
|
||||
#else
|
||||
TEST_CHECK(NAU_PrepareRequestAuth(inst));
|
||||
#endif
|
||||
TEST_CHECK(!NAU_GenerateRequestAuth(inst, &req, &req_info));
|
||||
TST_ResumeLogging();
|
||||
} else if (can_auth_req) {
|
||||
TEST_CHECK(NAU_PrepareRequestAuth(inst));
|
||||
TEST_CHECK(NAU_GenerateRequestAuth(inst, &req, &req_info));
|
||||
} else {
|
||||
TEST_CHECK(NAU_PrepareRequestAuth(inst));
|
||||
TEST_CHECK(!NAU_GenerateRequestAuth(inst, &req, &req_info));
|
||||
}
|
||||
}
|
||||
|
||||
if (!inst || !can_auth_req)
|
||||
add_dummy_auth(mode, key_id, &req, &req_info);
|
||||
|
||||
TEST_CHECK(req_info.auth.mode == mode);
|
||||
|
||||
memset(&req_info.auth, 0, sizeof (req_info.auth));
|
||||
TEST_CHECK(NAU_ParsePacket(&req, &req_info));
|
||||
TEST_CHECK(req_info.auth.mode == mode);
|
||||
TEST_CHECK(req_info.auth.mac.key_id == key_id);
|
||||
|
||||
kod = 1;
|
||||
TEST_CHECK(NAU_CheckRequestAuth(&req, &req_info, &kod) == can_auth_req);
|
||||
TEST_CHECK(kod == 0);
|
||||
|
||||
if (inst) {
|
||||
for (j = NTP_AUTH_NONE; j <= NTP_AUTH_NTS; j++) {
|
||||
if (j == mode && j == NTP_AUTH_NONE)
|
||||
continue;
|
||||
|
||||
prepare_packet(j, &res, &res_info, 0);
|
||||
add_dummy_auth(j, key_id ? key_id : 1, &res, &res_info);
|
||||
|
||||
TEST_CHECK(res_info.auth.mode == j);
|
||||
TEST_CHECK(!NAU_CheckResponseAuth(inst, &res, &res_info));
|
||||
}
|
||||
}
|
||||
|
||||
prepare_packet(mode, &res, &res_info, 0);
|
||||
TEST_CHECK(NAU_GenerateResponseAuth(&req, &req_info, &res, &res_info, NULL, NULL, kod) ==
|
||||
can_auth_res);
|
||||
if (!can_auth_res)
|
||||
add_dummy_auth(mode, key_id, &res, &res_info);
|
||||
|
||||
memset(&res_info.auth, 0, sizeof (res_info.auth));
|
||||
TEST_CHECK(NAU_ParsePacket(&res, &res_info));
|
||||
TEST_CHECK(res_info.auth.mode == mode);
|
||||
TEST_CHECK(res_info.auth.mac.key_id == key_id);
|
||||
|
||||
if (inst) {
|
||||
if (mode == NTP_AUTH_SYMMETRIC) {
|
||||
res_info.auth.mac.key_id ^= 1;
|
||||
TEST_CHECK(!NAU_CheckResponseAuth(inst, &res, &res_info));
|
||||
res_info.auth.mac.key_id ^= 1;
|
||||
}
|
||||
|
||||
TEST_CHECK(NAU_CheckResponseAuth(inst, &res, &res_info) == can_auth_res);
|
||||
|
||||
NAU_GetReport(inst, &report);
|
||||
NAU_DestroyInstance(inst);
|
||||
}
|
||||
}
|
||||
|
||||
NNS_Finalise();
|
||||
NSD_Finalise();
|
||||
KEY_Finalise();
|
||||
LCL_Finalise();
|
||||
CNF_Finalise();
|
||||
HSH_Finalise();
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
test_unit(void)
|
||||
{
|
||||
TEST_REQUIRE(0);
|
||||
}
|
||||
#endif
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <cmdparse.h>
|
||||
#include <conf.h>
|
||||
#include <keys.h>
|
||||
#include <ntp_ext.h>
|
||||
#include <ntp_io.h>
|
||||
#include <sched.h>
|
||||
#include <local.h>
|
||||
@@ -138,7 +139,7 @@ send_response(int interleaved, int authenticated, int allow_update, int valid_ts
|
||||
{
|
||||
NTP_Packet *req, *res;
|
||||
uint32_t key_id = 0;
|
||||
int auth_len = 0;
|
||||
int i, auth_len = 0, ef_len, efs;
|
||||
|
||||
req = &req_buffer;
|
||||
res = &res_buffer;
|
||||
@@ -184,51 +185,85 @@ send_response(int interleaved, int authenticated, int allow_update, int valid_ts
|
||||
}
|
||||
}
|
||||
|
||||
res_length = NTP_HEADER_LENGTH;
|
||||
|
||||
if (NTP_LVM_TO_VERSION(res->lvm) == 4 && random() % 2) {
|
||||
unsigned char buf[128];
|
||||
|
||||
memset(buf, 0, sizeof (buf));
|
||||
efs = random() % 5;
|
||||
|
||||
for (i = 0; i < efs; i++) {
|
||||
ef_len = (i + 1 == efs ? NTP_MAX_V4_MAC_LENGTH + 4 : NTP_MIN_EF_LENGTH) +
|
||||
4 * (random() % 10);
|
||||
TEST_CHECK(NEF_SetField((unsigned char *)res, sizeof (*res), res_length, 0,
|
||||
buf, ef_len - 4, &ef_len));
|
||||
res_length += ef_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (authenticated) {
|
||||
key_id = ntohl(*(uint32_t *)req->extensions);
|
||||
if (key_id == 0)
|
||||
key_id = get_random_key_id();
|
||||
auth_len = KEY_GetAuthLength(key_id);
|
||||
assert(auth_len);
|
||||
if (NTP_LVM_TO_VERSION(res->lvm) == 4 && random() % 2)
|
||||
if (NTP_LVM_TO_VERSION(res->lvm) == 4)
|
||||
auth_len = MIN(auth_len, NTP_MAX_V4_MAC_LENGTH - 4);
|
||||
|
||||
if (KEY_GenerateAuth(key_id, (unsigned char *)res, NTP_HEADER_LENGTH,
|
||||
res->extensions + 4, auth_len) != auth_len)
|
||||
if (KEY_GenerateAuth(key_id, res, res_length,
|
||||
(unsigned char *)res + res_length + 4, auth_len) != auth_len)
|
||||
assert(0);
|
||||
res_length = NTP_HEADER_LENGTH + 4 + auth_len;
|
||||
} else {
|
||||
res_length = NTP_HEADER_LENGTH;
|
||||
res_length += 4 + auth_len;
|
||||
}
|
||||
|
||||
if (!valid_auth && authenticated) {
|
||||
assert(auth_len);
|
||||
|
||||
switch (random() % 4) {
|
||||
switch (random() % 5) {
|
||||
case 0:
|
||||
key_id++;
|
||||
break;
|
||||
case 1:
|
||||
key_id ^= 1;
|
||||
if (KEY_GenerateAuth(key_id, (unsigned char *)res, NTP_HEADER_LENGTH,
|
||||
res->extensions + 4, auth_len) != auth_len)
|
||||
if (KEY_GenerateAuth(key_id, res, res_length - auth_len - 4,
|
||||
(unsigned char *)res + res_length - auth_len, auth_len) != auth_len)
|
||||
assert(0);
|
||||
break;
|
||||
case 2:
|
||||
res->extensions[4 + random() % auth_len]++;
|
||||
((unsigned char *)res)[res_length - auth_len + random() % auth_len]++;
|
||||
break;
|
||||
case 3:
|
||||
res_length = NTP_HEADER_LENGTH + 4 * (random() % ((4 + auth_len) / 4));
|
||||
if (NTP_LVM_TO_VERSION(res->lvm) == 4 &&
|
||||
res_length == NTP_HEADER_LENGTH + NTP_MAX_V4_MAC_LENGTH)
|
||||
res_length -= 4;
|
||||
res_length -= 4 + auth_len;
|
||||
auth_len = 4 * (random() % (auth_len / 4));
|
||||
res_length += 4 + auth_len;
|
||||
break;
|
||||
case 4:
|
||||
if (NTP_LVM_TO_VERSION(res->lvm) == 4 && random() % 2 &&
|
||||
KEY_GetAuthLength(key_id) > NTP_MAX_V4_MAC_LENGTH - 4) {
|
||||
res_length -= 4 + auth_len;
|
||||
auth_len += 4 + 4 * (random() %
|
||||
((KEY_GetAuthLength(key_id) - NTP_MAX_V4_MAC_LENGTH - 4) / 4));
|
||||
if (KEY_GenerateAuth(key_id, res, res_length,
|
||||
(unsigned char *)res + res_length + 4, auth_len) != auth_len)
|
||||
assert(0);
|
||||
res_length += 4 + auth_len;
|
||||
} else {
|
||||
memset((unsigned char *)res + res_length, 0, 4);
|
||||
auth_len += 4;
|
||||
res_length += 4;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
*(uint32_t *)res->extensions = htonl(key_id);
|
||||
assert(res_length <= sizeof (*res));
|
||||
assert(res_length >= NTP_HEADER_LENGTH + auth_len);
|
||||
|
||||
if (authenticated)
|
||||
*(uint32_t *)((unsigned char *)res + res_length - auth_len - 4) = htonl(key_id);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -149,6 +149,17 @@ test_unit(void)
|
||||
|
||||
TEST_CHECK(SIV_GetKeyLength(tests[i].algorithm) == tests[i].key_length);
|
||||
|
||||
r = SIV_Encrypt(siv, tests[i].nonce, tests[i].nonce_length,
|
||||
tests[i].assoc, tests[i].assoc_length,
|
||||
tests[i].plaintext, tests[i].plaintext_length,
|
||||
ciphertext, tests[i].ciphertext_length);
|
||||
TEST_CHECK(!r);
|
||||
r = SIV_Decrypt(siv, tests[i].nonce, tests[i].nonce_length,
|
||||
tests[i].assoc, tests[i].assoc_length,
|
||||
tests[i].ciphertext, tests[i].ciphertext_length,
|
||||
plaintext, tests[i].plaintext_length);
|
||||
TEST_CHECK(!r);
|
||||
|
||||
for (j = -1; j < 1024; j++) {
|
||||
r = SIV_SetKey(siv, tests[i].key, j);
|
||||
TEST_CHECK(r == (j == tests[i].key_length));
|
||||
|
||||
2
util.c
2
util.c
@@ -3,7 +3,7 @@
|
||||
|
||||
**********************************************************************
|
||||
* Copyright (C) Richard P. Curnow 1997-2003
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2012-2018
|
||||
* Copyright (C) Miroslav Lichvar 2009, 2012-2020
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
|
||||
Reference in New Issue
Block a user