Compare commits

...

No commits in common. "a9-deprecated" and "c8" have entirely different histories.

17 changed files with 1521 additions and 402 deletions

View File

@ -1,3 +1,2 @@
0f5de043b395311a58bcf4be9800f7118afd5f59 SOURCES/chrony-4.2.tar.gz 4661e5df181a9761b73caeaef2f2ab755bbe086a SOURCES/chrony-4.5.tar.gz
2e1fac8161ea8d92d76532c0b272fb31799bc310 SOURCES/clknetsim-824c48.tar.gz e021461c23fe4e5c46fd53c449587d8f6cc217ae SOURCES/clknetsim-5d1dc0.tar.gz
1395afa521d2e3302a31083edcf568bbc036aafc SOURCES/gpgkey-8F375C7E8D0EE125A3D3BD51537E2B76F7680DAC.asc

5
.gitignore vendored
View File

@ -1,3 +1,2 @@
SOURCES/chrony-4.2.tar.gz SOURCES/chrony-4.5.tar.gz
SOURCES/clknetsim-824c48.tar.gz SOURCES/clknetsim-5d1dc0.tar.gz
SOURCES/gpgkey-8F375C7E8D0EE125A3D3BD51537E2B76F7680DAC.asc

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEjzdcfo0O4SWj071RU34rdvdoDawFAmG7LoQACgkQU34rdvdo
Daw47w//fpF3YlqSJWQObHv/hMC6EGQSX6hRVzckXgzq7PFN2HaTX1iZV2UsP1KN
NtXfH3V7PxTdT4jT41bHUw++vN0HXkaAw3ccbm31MVTc353JFv5VUKT/OtK+I8dZ
CKGDy7X4REET7rCYTEfhgvAwjisIlc81xFq9fMYiGasj2LXZD9GUFHqu0JzvvyMz
R0PNGDSYaJX5Ex1GtbgULjDJNF0FRDE+T6SBjs8Xlej020DbNRb4MNZitzygMNum
ChN2MltzEccw/UegrsaN1UYQG2C4/Xgdjeqfa4ioiewBL0/79oPkNyJT0GCtOIUM
TCAdDRrwLuh7d3+Hl6szy8FxKRFN4s/TTjSTinwDCaexqqNgKeSRkJPFWPWhq4l1
2W+hh5cYtToP4wYNpFdadz+LJYrRzYEtAKdFMegYt2Q/MMVtsNji4qeJ/VOnyrUI
cJD6sWqDtrUQnegVky1QDwKIYLzO+h6kDaTEm7ZhaT3pR4gGC47umPR9HAcgch0/
QdmHd1dP1rutDdpiGmXRicvSV48M1Ol6AAs7rUERuQGJ4Tl/zoMGWmN93UQEpisS
9L1PBNdAjdutJaZKA3Bgq49BOPzcRGvhamH63fO5Q+h6uXCzxd9s8MDeY8wh3Idn
2aHcGnx32z3DNbpG/nXtKE3GeiSDbw6FmN4KUmKKBR552lCcgpA=
=F4BS
-----END PGP SIGNATURE-----

56
SOURCES/chrony-cmac.patch Normal file
View File

@ -0,0 +1,56 @@
commit 8eb5dd54efd13aa0209aea38dbad2a7904377f75
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Sep 17 13:00:43 2024 +0200
configure: enable AES-CMAC using gnutls
Allow gnutls to be used for AES-CMAC when nettle doesn't support it
without switching also hashing.
diff --git a/configure b/configure
index eefe5de8..0fb3aa38 100755
--- a/configure
+++ b/configure
@@ -937,14 +937,26 @@ if [ $feat_sechash = "1" ] && [ "x$HASH_LINK" = "x" ] && [ $try_gnutls = "1" ];
HASH_LINK="$test_link"
MYCPPFLAGS="$MYCPPFLAGS $test_cflags"
add_def FEAT_SECHASH
+ fi
+fi
- if test_code 'CMAC in gnutls' 'gnutls/crypto.h' "$test_cflags" "$test_link" \
- 'return gnutls_hmac_init((void *)1, GNUTLS_MAC_AES_CMAC_128, (void *)2, 0);'
- then
- add_def HAVE_CMAC
- EXTRA_OBJECTS="$EXTRA_OBJECTS cmac_gnutls.o"
- EXTRA_CLI_OBJECTS="$EXTRA_CLI_OBJECTS cmac_gnutls.o"
- fi
+if [ $feat_sechash = "1" ] && [ $try_gnutls = "1" ] &&
+ ! grep '#define HAVE_CMAC' config.h > /dev/null; then
+ if [ "$HASH_OBJ" = "hash_gnutls.o" ]; then
+ test_cflags=""
+ test_link=""
+ else
+ test_cflags="`pkg_config --cflags gnutls`"
+ test_link="`pkg_config --libs gnutls`"
+ fi
+ if test_code 'CMAC in gnutls' 'gnutls/crypto.h' "$test_cflags" "$test_link" \
+ 'return gnutls_hmac_init((void *)1, GNUTLS_MAC_AES_CMAC_128, (void *)2, 0);'
+ then
+ add_def HAVE_CMAC
+ EXTRA_OBJECTS="$EXTRA_OBJECTS cmac_gnutls.o"
+ EXTRA_CLI_OBJECTS="$EXTRA_CLI_OBJECTS cmac_gnutls.o"
+ LIBS="$LIBS $test_link"
+ MYCPPFLAGS="$MYCPPFLAGS $test_cflags"
fi
fi
@@ -978,7 +990,7 @@ EXTRA_CLI_OBJECTS="$EXTRA_CLI_OBJECTS $HASH_OBJ"
LIBS="$LIBS $HASH_LINK"
if [ $feat_ntp = "1" ] && [ $feat_nts = "1" ] && [ $try_gnutls = "1" ]; then
- if [ "$HASH_OBJ" = "hash_gnutls.o" ]; then
+ if echo "$HASH_OBJ $EXTRA_OBJECTS" | grep "_gnutls\.o" > /dev/null; then
test_cflags=""
test_link=""
else

View File

@ -0,0 +1,38 @@
diff -up chrony-4.1/examples/chrony.conf.example2.defconfig chrony-4.1/examples/chrony.conf.example2
--- chrony-4.1/examples/chrony.conf.example2.defconfig 2021-05-12 13:06:15.000000000 +0200
+++ chrony-4.1/examples/chrony.conf.example2 2019-05-10 12:22:57.000000000 +0200
@@ -1,5 +1,5 @@
# Use public servers from the pool.ntp.org project.
-# Please consider joining the pool (https://www.pool.ntp.org/join.html).
+# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool pool.ntp.org iburst
# Record the rate at which the system clock gains/losses time.
@@ -25,18 +25,9 @@ rtcsync
# Serve time even if not synchronized to a time source.
#local stratum 10
-# Require authentication (nts or key option) for all NTP sources.
-#authselectmode require
-
# Specify file containing keys for NTP authentication.
#keyfile /etc/chrony.keys
-# Save NTS keys and cookies.
-ntsdumpdir /var/lib/chrony
-
-# Insert/delete leap seconds by slewing instead of stepping.
-#leapsecmode slew
-
# Get TAI-UTC offset and leap seconds from the system tz database.
#leapsectz right/UTC
diff -up chrony-4.5/examples/chrony.keys.example.keys chrony-4.5/examples/chrony.keys.example
--- chrony-4.5/examples/chrony.keys.example.keys 2023-12-05 14:22:10.000000000 +0100
+++ chrony-4.5/examples/chrony.keys.example 2023-12-06 09:59:26.089508934 +0100
@@ -11,5 +11,3 @@
#1 MD5 AVeryLongAndRandomPassword
#2 MD5 HEX:12114855C7931009B4049EF3EFC48A139C3F989F
#3 SHA1 HEX:B2159C05D6A219673A3B7E896B6DE07F6A440995
-#4 AES128 HEX:2DA837C4B6573748CA692B8C828E4891
-#5 AES256 HEX:2666B8099BFF2D5BA20876121788ED24D2BE59111B8FFB562F0F56AE6EC7246E

View File

@ -0,0 +1,8 @@
[Unit]
Description=DNS SRV lookup of %I for chrony
After=chronyd.service network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/libexec/chrony-helper update-dnssrv-servers %I

View File

@ -0,0 +1,9 @@
[Unit]
Description=Periodic DNS SRV lookup of %I for chrony
[Timer]
OnActiveSec=0
OnUnitInactiveSec=1h
[Install]
WantedBy=timers.target

View File

@ -1,146 +1,67 @@
commit 5bd13c8d593a74ad168057efe94dd2b3aeeffe14 First, revert upstream changes since 4.2
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Feb 7 13:27:25 2022 +0100
examples: support DHCPv6 NTP servers in NM dispatcher script
Latest NetworkManager code provides NTP servers from the DHCPv6 NTP
option (RFC 5908) in the DHCP6_DHCP6_NTP_SERVERS variable to dispatcher
scripts.
Check for invalid characters (which can come from the FQDN suboption)
and include the servers in the interface-specific sources file.
diff --git a/examples/chrony.nm-dispatcher.dhcp b/examples/chrony.nm-dispatcher.dhcp diff --git a/examples/chrony.nm-dispatcher.dhcp b/examples/chrony.nm-dispatcher.dhcp
index 6ea4c370..4454f037 100644 index 547ce83f..6ea4c370 100644
--- a/examples/chrony.nm-dispatcher.dhcp --- a/examples/chrony.nm-dispatcher.dhcp
+++ b/examples/chrony.nm-dispatcher.dhcp +++ b/examples/chrony.nm-dispatcher.dhcp
@@ -1,8 +1,7 @@ @@ -1,7 +1,8 @@
#!/bin/sh #!/bin/sh
# This is a NetworkManager dispatcher script for chronyd to update # This is a NetworkManager dispatcher script for chronyd to update
-# its NTP sources passed from DHCP options. Note that this script is -# its NTP sources with servers from DHCP options passed by NetworkManager
-# specific to NetworkManager-dispatcher due to use of the -# in the DHCP4_NTP_SERVERS and DHCP6_DHCP6_NTP_SERVERS environment variables.
-# DHCP4_NTP_SERVERS environment variable. +# its NTP sources passed from DHCP options. Note that this script is
+# its NTP sources with servers from DHCP options passed by NetworkManager +# specific to NetworkManager-dispatcher due to use of the
+# in the DHCP4_NTP_SERVERS and DHCP6_DHCP6_NTP_SERVERS environment variables. +# DHCP4_NTP_SERVERS environment variable.
export LC_ALL=C export LC_ALL=C
@@ -10,17 +9,19 @@ interface=$1 @@ -9,23 +10,17 @@ interface=$1
action=$2 action=$2
chronyc=/usr/bin/chronyc chronyc=/usr/bin/chronyc
-default_server_options=iburst -server_options=iburst
+server_options=iburst +default_server_options=iburst
server_dir=/var/run/chrony-dhcp server_dir=/var/run/chrony-dhcp
dhcp_server_file=$server_dir/$interface.sources dhcp_server_file=$server_dir/$interface.sources
-# DHCP4_NTP_SERVERS is passed from DHCP options by NetworkManager. -dhcp_ntp_servers="$DHCP4_NTP_SERVERS $DHCP6_DHCP6_NTP_SERVERS"
-nm_dhcp_servers=$DHCP4_NTP_SERVERS +# DHCP4_NTP_SERVERS is passed from DHCP options by NetworkManager.
+dhcp_ntp_servers="$DHCP4_NTP_SERVERS $DHCP6_DHCP6_NTP_SERVERS" +nm_dhcp_servers=$DHCP4_NTP_SERVERS
add_servers_from_dhcp() { add_servers_from_dhcp() {
rm -f "$dhcp_server_file" rm -f "$dhcp_server_file"
- for server in $nm_dhcp_servers; do - for server in $dhcp_ntp_servers; do
- echo "server $server $default_server_options" >> "$dhcp_server_file" - # Check for invalid characters (from the DHCPv6 NTP FQDN suboption)
+ for server in $dhcp_ntp_servers; do - len1=$(printf '%s' "$server" | wc -c)
+ # Check for invalid characters (from the DHCPv6 NTP FQDN suboption) - len2=$(printf '%s' "$server" | tr -d -c 'A-Za-z0-9:.-' | wc -c)
+ printf '%s\n' "$server" | grep -E -q '^[-A-Za-z0-9:.]{1,255}$' || continue - if [ "$len1" -ne "$len2" ] || [ "$len2" -lt 1 ] || [ "$len2" -gt 255 ]; then
+ - continue
+ printf 'server %s %s\n' "$server" "$server_options" >> "$dhcp_server_file" - fi
-
- printf 'server %s %s\n' "$server" "$server_options" >> "$dhcp_server_file"
+ for server in $nm_dhcp_servers; do
+ echo "server $server $default_server_options" >> "$dhcp_server_file"
done done
$chronyc reload sources > /dev/null 2>&1 || : $chronyc reload sources > /dev/null 2>&1 || :
} }
@@ -34,10 +35,11 @@ clear_servers_from_dhcp() { @@ -39,11 +34,10 @@ clear_servers_from_dhcp() {
mkdir -p $server_dir mkdir -p $server_dir
-if [ "$action" = "up" ] || [ "$action" = "dhcp4-change" ]; then -case "$action" in
- add_servers_from_dhcp - up|dhcp4-change|dhcp6-change)
-elif [ "$action" = "down" ]; then - add_servers_from_dhcp;;
- clear_servers_from_dhcp - down)
-fi - clear_servers_from_dhcp;;
+case "$action" in -esac
+ up|dhcp4-change|dhcp6-change) +if [ "$action" = "up" ] || [ "$action" = "dhcp4-change" ]; then
+ add_servers_from_dhcp;; + add_servers_from_dhcp
+ down) +elif [ "$action" = "down" ]; then
+ clear_servers_from_dhcp;; + clear_servers_from_dhcp
+esac +fi
exit 0 exit 0
commit e55f174bd3a7ae82fb24afd43443d0b55d5536cf
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Feb 7 13:27:48 2022 +0100
examples: handle more actions in NM dispatcher script
Run the chronyc onoffline command also when the connectivity-change
and dhcp6-change actions are reported by the NetworkManager dispatcher.
The latter should not be necessary, but there currently doesn't seem to
be any action for IPv6 becoming routable after duplicate address
detection, so at least in networks using DHCPv6, IPv6 NTP servers should
not be stuck in the offline state from a previously reported action.
diff --git a/examples/chrony.nm-dispatcher.onoffline b/examples/chrony.nm-dispatcher.onoffline
index 34cfa0db..01e6fdb1 100644
--- a/examples/chrony.nm-dispatcher.onoffline
+++ b/examples/chrony.nm-dispatcher.onoffline
@@ -7,8 +7,18 @@ export LC_ALL=C
chronyc=/usr/bin/chronyc
-# For NetworkManager consider only up/down events
-[ $# -ge 2 ] && [ "$2" != "up" ] && [ "$2" != "down" ] && exit 0
+# For NetworkManager consider only selected events
+if [ $# -ge 2 ]; then
+ case "$2" in
+ up|down|connectivity-change)
+ ;;
+ dhcp6-change)
+ # No other action is reported for routable IPv6
+ ;;
+ *)
+ exit 0;;
+ esac
+fi
# Note: for networkd-dispatcher routable.d ~= on and off.d ~= off
commit fca8966adaaf8376536af86ba2afe02501463588
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Wed Mar 23 15:17:03 2022 +0100
examples: replace grep command in NM dispatcher script
Some grep implementations detect binary data and return success without
matching whole line. This might be an issue for the DHCPv6 NTP FQDN
check. The GNU grep in the C locale seems to check only for the NUL
character, which cannot be passed in an environment variable, but other
implementations might behave differently and there doesn't seem to be a
portable way to force matching the whole line.
Instead of the grep command, check for invalid characters by comparing
the length of the input passed through "tr -d -c".
diff --git a/examples/chrony.nm-dispatcher.dhcp b/examples/chrony.nm-dispatcher.dhcp
index 4454f037..547ce83f 100644
--- a/examples/chrony.nm-dispatcher.dhcp
+++ b/examples/chrony.nm-dispatcher.dhcp
@@ -19,7 +19,11 @@ add_servers_from_dhcp() {
rm -f "$dhcp_server_file"
for server in $dhcp_ntp_servers; do
# Check for invalid characters (from the DHCPv6 NTP FQDN suboption)
- printf '%s\n' "$server" | grep -E -q '^[-A-Za-z0-9:.]{1,255}$' || continue
+ len1=$(printf '%s' "$server" | wc -c)
+ len2=$(printf '%s' "$server" | tr -d -c 'A-Za-z0-9:.-' | wc -c)
+ if [ "$len1" -ne "$len2" ] || [ "$len2" -lt 1 ] || [ "$len2" -gt 255 ]; then
+ continue
+ fi
printf 'server %s %s\n' "$server" "$server_options" >> "$dhcp_server_file"
done
From: Robert Fairley <rfairley@redhat.com> From: Robert Fairley <rfairley@redhat.com>
Date: Wed, 17 Jun 2020 10:14:19 -0400 Date: Wed, 17 Jun 2020 10:14:19 -0400
Subject: [PATCH] examples/nm-dispatcher.dhcp: use sysconfig Subject: [PATCH] examples/nm-dispatcher.dhcp: use sysconfig
@ -154,29 +75,90 @@ diff --git a/examples/chrony.nm-dispatcher.dhcp b/examples/chrony.nm-dispatcher.
index 6ea4c37..a6ad35a 100644 index 6ea4c37..a6ad35a 100644
--- a/examples/chrony.nm-dispatcher.dhcp --- a/examples/chrony.nm-dispatcher.dhcp
+++ b/examples/chrony.nm-dispatcher.dhcp +++ b/examples/chrony.nm-dispatcher.dhcp
@@ -8,15 +8,23 @@ export LC_ALL=C @@ -6,16 +6,24 @@
interface=$1
action=$2 chronyc=/usr/bin/chronyc
default_server_options=iburst
-server_dir=/var/run/chrony-dhcp
+server_dir=/run/chrony-dhcp
dhcp_server_file=$server_dir/$interface.sources
# DHCP4_NTP_SERVERS is passed from DHCP options by NetworkManager.
nm_dhcp_servers=$DHCP4_NTP_SERVERS
+[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network +[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
+[ -f /etc/sysconfig/network-scripts/ifcfg-"${interface}" ] && \ +[ -f /etc/sysconfig/network-scripts/ifcfg-"${interface}" ] && \
+ . /etc/sysconfig/network-scripts/ifcfg-"${interface}" + . /etc/sysconfig/network-scripts/ifcfg-"${interface}"
+ +
chronyc=/usr/bin/chronyc
-server_options=iburst
-server_dir=/var/run/chrony-dhcp
+server_options=${NTPSERVERARGS:-iburst}
+server_dir=/run/chrony-dhcp
dhcp_server_file=$server_dir/$interface.sources
dhcp_ntp_servers="$DHCP4_NTP_SERVERS $DHCP6_DHCP6_NTP_SERVERS"
add_servers_from_dhcp() { add_servers_from_dhcp() {
rm -f "$dhcp_server_file" rm -f "$dhcp_server_file"
+ +
+ # Don't add NTP servers if PEERNTP=no specified; return early. + # Don't add NTP servers if PEERNTP=no specified; return early.
+ [ "$PEERNTP" = "no" ] && return + [ "$PEERNTP" = "no" ] && return
+ +
for server in $dhcp_ntp_servers; do for server in $nm_dhcp_servers; do
# Check for invalid characters (from the DHCPv6 NTP FQDN suboption) - echo "server $server $default_server_options" >> "$dhcp_server_file"
len1=$(printf '%s' "$server" | wc -c) + echo "server $server ${NTPSERVERARGS:-$default_server_options}" >> "$dhcp_server_file"
done
$chronyc reload sources > /dev/null 2>&1 || :
}
--
2.29.2
Use chrony-helper instead of chronyc to avoid changes in default chrony.conf
diff -up chrony-4.1/examples/chrony.nm-dispatcher.dhcp.nm-dispatcher-dhcp chrony-4.1/examples/chrony.nm-dispatcher.dhcp
--- chrony-4.1/examples/chrony.nm-dispatcher.dhcp.nm-dispatcher-dhcp 2021-06-09 11:10:30.997416152 +0200
+++ chrony-4.1/examples/chrony.nm-dispatcher.dhcp 2021-06-09 11:16:23.598381336 +0200
@@ -9,11 +9,12 @@ export LC_ALL=C
interface=$1
action=$2
-chronyc=/usr/bin/chronyc
+helper=/usr/libexec/chrony-helper
default_server_options=iburst
-server_dir=/run/chrony-dhcp
+server_dir=/run/chrony-helper
-dhcp_server_file=$server_dir/$interface.sources
+dhcp_server_tmpfile=$server_dir/tmp-nm-dhcp.$interface
+dhcp_server_file=$server_dir/nm-dhcp.$interface
# DHCP4_NTP_SERVERS is passed from DHCP options by NetworkManager.
nm_dhcp_servers=$DHCP4_NTP_SERVERS
@@ -24,24 +24,30 @@ nm_dhcp_servers=$DHCP4_NTP_SERVERS
add_servers_from_dhcp() {
rm -f "$dhcp_server_file"
+ # Remove servers saved by the dhclient script before it detected NM.
+ rm -f "/var/lib/dhclient/chrony.servers.$interface"
+
# Don't add NTP servers if PEERNTP=no specified; return early.
[ "$PEERNTP" = "no" ] && return
+ # Create the directory with correct SELinux context.
+ $helper create-helper-directory > /dev/null 2>&1
+
for server in $nm_dhcp_servers; do
- echo "server $server ${NTPSERVERARGS:-$default_server_options}" >> "$dhcp_server_file"
+ echo "$server ${NTPSERVERARGS:-$default_server_options}" >> "$dhcp_server_tmpfile"
done
+ [ -e "$dhcp_server_tmpfile" ] && mv "$dhcp_server_tmpfile" "$dhcp_server_file"
- $chronyc reload sources > /dev/null 2>&1 || :
+
+ $helper update-daemon > /dev/null 2>&1 || :
}
clear_servers_from_dhcp() {
if [ -f "$dhcp_server_file" ]; then
rm -f "$dhcp_server_file"
- $chronyc reload sources > /dev/null 2>&1 || :
+ $helper update-daemon > /dev/null 2>&1 || :
fi
}
-mkdir -p $server_dir
-
if [ "$action" = "up" ] || [ "$action" = "dhcp4-change" ]; then
add_servers_from_dhcp
elif [ "$action" = "down" ]; then

View File

@ -0,0 +1,86 @@
commit f49be7f06343ee27fff2950937d7f6742f53976f
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Tue Mar 12 14:30:27 2024 +0100
conf: don't load sourcedir during initstepslew and RTC init
If the reload sources command was received in the chronyd start-up
sequence with initstepslew and/or RTC init (-s option), the sources
loaded from sourcedirs caused a crash due to failed assertion after
adding sources specified in the config.
Ignore the reload sources command until chronyd enters the normal
operation mode.
Fixes: 519796de3756 ("conf: add sourcedirs directive")
diff --git a/conf.c b/conf.c
index 6eae11c9..8849bdce 100644
--- a/conf.c
+++ b/conf.c
@@ -298,6 +298,8 @@ static ARR_Instance ntp_sources;
static ARR_Instance ntp_source_dirs;
/* Array of uint32_t corresponding to ntp_sources (for sourcedirs reload) */
static ARR_Instance ntp_source_ids;
+/* Flag indicating ntp_sources and ntp_source_ids are used for sourcedirs */
+static int conf_ntp_sources_added = 0;
/* Array of RefclockParameters */
static ARR_Instance refclock_sources;
@@ -1689,8 +1691,12 @@ reload_source_dirs(void)
NSR_Status s;
int d, pass;
+ /* Ignore reload command before adding configured sources */
+ if (!conf_ntp_sources_added)
+ return;
+
prev_size = ARR_GetSize(ntp_source_ids);
- if (prev_size > 0 && ARR_GetSize(ntp_sources) != prev_size)
+ if (ARR_GetSize(ntp_sources) != prev_size)
assert(0);
/* Save the current sources and their configuration IDs */
@@ -1859,7 +1865,10 @@ CNF_AddSources(void)
Free(source->params.name);
}
+ /* The arrays will be used for sourcedir (re)loading */
ARR_SetSize(ntp_sources, 0);
+ ARR_SetSize(ntp_source_ids, 0);
+ conf_ntp_sources_added = 1;
reload_source_dirs();
}
diff --git a/test/simulation/203-initreload b/test/simulation/203-initreload
new file mode 100755
index 00000000..cf7924b8
--- /dev/null
+++ b/test/simulation/203-initreload
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+. ./test.common
+
+check_config_h 'FEAT_CMDMON 1' || test_skip
+
+# Test fix "conf: don't load sourcedir during initstepslew and RTC init"
+
+test_start "reload during initstepslew"
+
+client_conf="initstepslew 5 192.168.123.1
+sourcedir tmp"
+client_server_conf="#"
+chronyc_conf="reload sources"
+chronyc_start=4
+
+echo 'server 192.168.123.1' > tmp/sources.sources
+
+run_test || test_fail
+check_chronyd_exit || test_fail
+check_source_selection || test_fail
+check_sync || test_fail
+
+check_log_messages "Added source 192\.168\.123\.1" 1 1 || test_fail
+
+test_pass

View File

@ -1,31 +0,0 @@
commit 8bb8f15a7d049ed26c69d95087065b381f76ec4d
Author: Michael Hudson-Doyle <michael.hudson@canonical.com>
Date: Wed Feb 9 09:06:13 2022 +0100
sys_linux: allow rseq in seccomp filter
Libc 2.35 will use rseq syscalls [1][2] by default and thereby
break chrony in seccomp isolation.
[1]: https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/
[2]: https://sourceware.org/pipermail/libc-alpha/2022-February/136040.html
Tested-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Reviewed-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Signed-off-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
diff --git a/sys_linux.c b/sys_linux.c
index 9cab2efa..cc3c9311 100644
--- a/sys_linux.c
+++ b/sys_linux.c
@@ -497,6 +497,9 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
SCMP_SYS(getrlimit),
SCMP_SYS(getuid),
SCMP_SYS(getuid32),
+#ifdef __NR_rseq
+ SCMP_SYS(rseq),
+#endif
SCMP_SYS(rt_sigaction),
SCMP_SYS(rt_sigreturn),
SCMP_SYS(rt_sigprocmask),

View File

@ -0,0 +1,39 @@
commit e11b518a1ffa704986fb1f1835c425844ba248ef
Author: Miroslav Lichvar <mlichvar@redhat.com>
Date: Mon Jan 8 11:35:56 2024 +0100
ntp: fix authenticated requests in serverstats
Fix the CLG_UpdateNtpStats() call to count requests passing the
authentication check instead of requests triggering a KoD response
(i.e. NTS NAK).
diff --git a/ntp_core.c b/ntp_core.c
index 023e60b2..35801744 100644
--- a/ntp_core.c
+++ b/ntp_core.c
@@ -2736,7 +2736,7 @@ NCR_ProcessRxUnknown(NTP_Remote_Address *remote_addr, NTP_Local_Address *local_a
CLG_DisableNtpTimestamps(&ntp_rx);
}
- CLG_UpdateNtpStats(kod != 0 && info.auth.mode != NTP_AUTH_NONE &&
+ CLG_UpdateNtpStats(kod == 0 && info.auth.mode != NTP_AUTH_NONE &&
info.auth.mode != NTP_AUTH_MSSNTP,
rx_ts->source, interleaved ? tx_ts->source : NTP_TS_DAEMON);
diff --git a/test/system/010-nts b/test/system/010-nts
index 8d92bbc8..b215efa3 100755
--- a/test/system/010-nts
+++ b/test/system/010-nts
@@ -45,6 +45,11 @@ check_chronyc_output "^Name/IP address Mode KeyID Type KLen Last Atm
=========================================================================
127\.0\.0\.1 NTS 1 (30|15) (128|256) [0-9] 0 0 [78] ( 64|100)$" || test_fail
+run_chronyc "serverstats" || test_fail
+check_chronyc_output "NTS-KE connections accepted: 1
+NTS-KE connections dropped : 0
+Authenticated NTP packets : [1-9][0-9]*" || test_fail
+
stop_chronyd || test_fail
check_chronyd_messages || test_fail
check_chronyd_files || test_fail

View File

@ -0,0 +1,12 @@
diff -up chrony-4.1/examples/chronyd.service.service-helper chrony-4.1/examples/chronyd.service
--- chrony-4.1/examples/chronyd.service.service-helper 2021-05-12 13:06:15.000000000 +0200
+++ chrony-4.1/examples/chronyd.service 2021-06-15 09:01:56.948968576 +0200
@@ -10,6 +10,8 @@ Type=forking
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
+ExecStartPost=/usr/libexec/chrony-helper update-daemon
+ExecStopPost=/usr/libexec/chrony-helper remove-daemon-state
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full

View File

@ -1,38 +1,81 @@
diff -up chrony-4.2/examples/chronyd.service.services chrony-4.2/examples/chronyd.service
--- chrony-4.2/examples/chronyd.service.services 2021-12-16 13:17:42.000000000 +0100
+++ chrony-4.2/examples/chronyd.service 2022-01-19 13:55:59.066677473 +0100
@@ -32,8 +32,7 @@ ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectProc=invisible
-ProtectSystem=strict
-ReadWritePaths=/run /var/lib/chrony -/var/log
+ProtectSystem=full
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=yes
RestrictSUIDSGID=yes
@@ -42,7 +41,6 @@ SystemCallFilter=~@cpu-emulation @debug
# Adjust restrictions for /usr/sbin/sendmail (mailonchange directive)
NoNewPrivileges=no
-ReadWritePaths=-/var/spool
RestrictAddressFamilies=AF_NETLINK
[Install]
Avoid a SELinux issue
diff --git a/examples/chrony-wait.service b/examples/chrony-wait.service diff --git a/examples/chrony-wait.service b/examples/chrony-wait.service
index 72b028f2..57646950 100644 index 72b028f2..b3aa7aa2 100644
--- a/examples/chrony-wait.service --- a/examples/chrony-wait.service
+++ b/examples/chrony-wait.service +++ b/examples/chrony-wait.service
@@ -18,7 +18,7 @@ StandardOutput=null @@ -16,31 +16,5 @@ TimeoutStartSec=180
RemainAfterExit=yes
StandardOutput=null
CapabilityBoundingSet= -CapabilityBoundingSet=
DevicePolicy=closed -DevicePolicy=closed
-DynamicUser=yes -DynamicUser=yes
+#DynamicUser=yes -IPAddressAllow=localhost
IPAddressAllow=localhost -IPAddressDeny=any
IPAddressDeny=any -LockPersonality=yes
LockPersonality=yes -MemoryDenyWriteExecute=yes
-PrivateDevices=yes
-PrivateUsers=yes
-ProtectClock=yes
-ProtectControlGroups=yes
-ProtectHome=yes
-ProtectHostname=yes
-ProtectKernelLogs=yes
-ProtectKernelModules=yes
-ProtectKernelTunables=yes
-ProtectProc=invisible
-ProtectSystem=strict
-RestrictAddressFamilies=AF_INET AF_INET6
-RestrictNamespaces=yes
-RestrictRealtime=yes
-SystemCallArchitectures=native
-SystemCallFilter=@system-service
-SystemCallFilter=~@privileged @resources
-UMask=0777
-
[Install]
WantedBy=multi-user.target
diff --git a/examples/chronyd.service b/examples/chronyd.service
index 4fb930ef..289548cb 100644
--- a/examples/chronyd.service
+++ b/examples/chronyd.service
@@ -10,39 +10,9 @@ Type=forking
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
-
-CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
-CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE
-CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE CAP_MKNOD CAP_SYS_ADMIN
-CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_MODULE CAP_SYS_PACCT
-CapabilityBoundingSet=~CAP_SYS_PTRACE CAP_SYS_RAWIO CAP_SYS_TTY_CONFIG CAP_WAKE_ALARM
-DeviceAllow=char-pps rw
-DeviceAllow=char-ptp rw
-DeviceAllow=char-rtc rw
-DevicePolicy=closed
-LockPersonality=yes
-MemoryDenyWriteExecute=yes
-NoNewPrivileges=yes
PrivateTmp=yes
-ProtectControlGroups=yes
ProtectHome=yes
-ProtectHostname=yes
-ProtectKernelLogs=yes
-ProtectKernelModules=yes
-ProtectKernelTunables=yes
-ProtectProc=invisible
-ProtectSystem=strict
-ReadWritePaths=/run /var/lib/chrony -/var/log
-RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
-RestrictNamespaces=yes
-RestrictSUIDSGID=yes
-SystemCallArchitectures=native
-SystemCallFilter=~@cpu-emulation @debug @module @mount @obsolete @raw-io @reboot @swap
-
-# Adjust restrictions for /usr/sbin/sendmail (mailonchange directive)
-NoNewPrivileges=no
-ReadWritePaths=-/var/spool
-RestrictAddressFamilies=AF_NETLINK
+ProtectSystem=full
[Install]
WantedBy=multi-user.target

View File

@ -1,7 +1,6 @@
#!/bin/bash #!/bin/bash
CHRONY_SOURCEDIR=/run/chrony-dhcp SERVERFILE=$SAVEDIR/chrony.servers.$interface
SERVERFILE=$CHRONY_SOURCEDIR/$interface.sources
chrony_config() { chrony_config() {
# Disable modifications if called from a NM dispatcher script # Disable modifications if called from a NM dispatcher script
@ -9,11 +8,10 @@ chrony_config() {
rm -f "$SERVERFILE" rm -f "$SERVERFILE"
if [ "$PEERNTP" != "no" ]; then if [ "$PEERNTP" != "no" ]; then
mkdir -p $CHRONY_SOURCEDIR
for server in $new_ntp_servers; do for server in $new_ntp_servers; do
echo "server $server ${NTPSERVERARGS:-iburst}" >> "$SERVERFILE" echo "$server ${NTPSERVERARGS:-iburst}" >> "$SERVERFILE"
done done
/usr/bin/chronyc reload sources > /dev/null 2>&1 || : /usr/libexec/chrony-helper update-daemon || :
fi fi
} }
@ -22,6 +20,6 @@ chrony_restore() {
if [ -f "$SERVERFILE" ]; then if [ -f "$SERVERFILE" ]; then
rm -f "$SERVERFILE" rm -f "$SERVERFILE"
/usr/bin/chronyc reload sources > /dev/null 2>&1 || : /usr/libexec/chrony-helper update-daemon || :
fi fi
} }

285
SOURCES/chrony.helper Normal file
View File

@ -0,0 +1,285 @@
#!/bin/bash
# This script configures running chronyd to use NTP servers obtained from
# DHCP and _ntp._udp DNS SRV records. Files with servers from DHCP are managed
# externally (e.g. by a dhclient script). Files with servers from DNS SRV
# records are updated here using the dig utility. The script can also list
# and set static sources in the chronyd configuration file.
chronyc=/usr/bin/chronyc
chrony_conf=/etc/chrony.conf
chrony_service=chronyd.service
helper_dir=/run/chrony-helper
added_servers_file=$helper_dir/added_servers
network_sysconfig_file=/etc/sysconfig/network
nm_servers_files="$helper_dir/nm-dhcp.*"
dhclient_servers_files="/var/lib/dhclient/chrony.servers.*"
dnssrv_servers_files="$helper_dir/dnssrv@*"
dnssrv_timer_prefix=chrony-dnssrv@
. $network_sysconfig_file &> /dev/null
chrony_command() {
$chronyc -n -m "$@"
}
is_running() {
chrony_command "tracking" &> /dev/null
}
get_servers_files() {
[ "$PEERNTP" != "no" ] && echo "$nm_servers_files"
[ "$PEERNTP" != "no" ] && echo "$dhclient_servers_files"
echo "$dnssrv_servers_files"
}
is_update_needed() {
for file in $(get_servers_files) $added_servers_file; do
[ -e "$file" ] && return 0
done
return 1
}
remove_daemon_state() {
rm -f $added_servers_file
}
update_daemon() {
local all_servers_with_args all_servers added_servers
if ! is_running; then
remove_daemon_state
return 0
fi
all_servers_with_args=$(cat $(get_servers_files) 2> /dev/null)
all_servers=$(
echo "$all_servers_with_args" |
while read -r server serverargs; do
echo "$server"
done | sort -u)
added_servers=$( (
cat $added_servers_file 2> /dev/null
echo "$all_servers_with_args" |
while read -r server serverargs; do
[ -z "$server" ] && continue
chrony_command "add server $server $serverargs" &> /dev/null &&
echo "$server"
done) | sort -u)
comm -23 <(echo -n "$added_servers") <(echo -n "$all_servers") |
while read -r server; do
chrony_command -c sources -a 2>/dev/null |
while IFS=, read -r type _ address _; do
[ "$type" = "^" ] || continue
[ "$(chrony_command "sourcename $address")" = "$server" ] || continue
chrony_command "delete $address" &> /dev/null
break
done
done
added_servers=$(comm -12 <(echo -n "$added_servers") <(echo -n "$all_servers"))
if [ -n "$added_servers" ]; then
echo "$added_servers" > $added_servers_file
else
rm -f $added_servers_file
fi
}
get_dnssrv_servers() {
local name=$1 output
if ! command -v dig &> /dev/null; then
echo "Missing dig (DNS lookup utility)" >&2
return 1
fi
output=$(dig "$name" srv +short +ndots=2 +search 2> /dev/null) || return 0
echo "$output" | while read -r _ _ port target; do
server=${target%.}
[ -z "$server" ] && continue
echo "$server port $port ${NTPSERVERARGS:-iburst}"
done
}
check_dnssrv_name() {
local name=$1
if [ -z "$name" ]; then
echo "No DNS SRV name specified" >&2
return 1
fi
if [ "${name:0:9}" != _ntp._udp ]; then
echo "DNS SRV name $name doesn't start with _ntp._udp" >&2
return 1
fi
}
update_dnssrv_servers() {
local name=$1
local srv_file=$helper_dir/dnssrv@$name servers
check_dnssrv_name "$name" || return 1
servers=$(get_dnssrv_servers "$name")
if [ -n "$servers" ]; then
echo "$servers" > "$srv_file"
else
rm -f "$srv_file"
fi
}
set_dnssrv_timer() {
local state=$1 name=$2
local srv_file=$helper_dir/dnssrv@$name servers
local timer
timer=$dnssrv_timer_prefix$(systemd-escape "$name").timer || return 1
check_dnssrv_name "$name" || return 1
if [ "$state" = enable ]; then
systemctl enable "$timer"
systemctl start "$timer"
elif [ "$state" = disable ]; then
systemctl stop "$timer"
systemctl disable "$timer"
rm -f "$srv_file"
fi
}
list_dnssrv_timers() {
systemctl --all --full -t timer list-units | grep "^$dnssrv_timer_prefix" | \
sed "s|^$dnssrv_timer_prefix\(.*\)\.timer.*|\1|" |
while read -r name; do
systemd-escape --unescape "$name"
done
}
prepare_helper_dir() {
mkdir -p $helper_dir
exec 100> $helper_dir/lock
if ! flock -w 20 100; then
echo "Failed to lock $helper_dir" >&2
return 1
fi
}
is_source_line() {
local pattern="^[ \t]*(server|pool|peer|refclock)[ \t]+[^ \t]+"
[[ "$1" =~ $pattern ]]
}
list_static_sources() {
while read -r line; do
if is_source_line "$line"; then
echo "$line"
fi
done < $chrony_conf
}
set_static_sources() {
local new_config tmp_conf
new_config=$(
sources=$(
while read -r line; do
is_source_line "$line" && echo "$line"
done)
while read -r line; do
if ! is_source_line "$line"; then
echo "$line"
continue
fi
tmp_sources=$(
local removed=0
echo "$sources" | while read -r line2; do
if [ "$removed" -ne 0 ] || [ "$line" != "$line2" ]; then
echo "$line2"
else
removed=1
fi
done)
[ "$sources" == "$tmp_sources" ] && continue
sources=$tmp_sources
echo "$line"
done < $chrony_conf
echo "$sources"
)
tmp_conf=${chrony_conf}.tmp
cp -a $chrony_conf $tmp_conf &&
echo "$new_config" > $tmp_conf &&
mv $tmp_conf $chrony_conf || return 1
systemctl try-restart $chrony_service
}
print_help() {
echo "Usage: $0 COMMAND"
echo
echo "Commands:"
echo " create-helper-directory"
echo " update-daemon"
echo " remove-daemon-state"
echo " update-dnssrv-servers NAME"
echo " enable-dnssrv NAME"
echo " disable-dnssrv NAME"
echo " list-dnssrv"
echo " list-static-sources"
echo " set-static-sources < sources.list"
echo " is-running"
echo " command CHRONYC-COMMAND"
}
case "$1" in
create-helper-directory)
prepare_helper_dir
;;
update-daemon|add-dhclient-servers|remove-dhclient-servers)
is_update_needed || exit 0
prepare_helper_dir && update_daemon
;;
remove-daemon-state)
remove_daemon_state
;;
update-dnssrv-servers)
prepare_helper_dir && update_dnssrv_servers "$2" && update_daemon
;;
enable-dnssrv)
set_dnssrv_timer enable "$2"
;;
disable-dnssrv)
set_dnssrv_timer disable "$2" && prepare_helper_dir && update_daemon
;;
list-dnssrv)
list_dnssrv_timers
;;
list-static-sources)
list_static_sources
;;
set-static-sources)
set_static_sources
;;
is-running)
is_running
;;
command|forced-command)
chrony_command "$2"
;;
*)
print_help
exit 2
esac
exit $?

680
SOURCES/ntp2chrony.py Normal file
View File

@ -0,0 +1,680 @@
#!/usr/bin/python3
#
# Convert ntp configuration to chrony
#
# Copyright (C) 2018-2019 Miroslav Lichvar <mlichvar@redhat.com>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import argparse
import ipaddress
import logging
import os
import re
import subprocess
import sys
# python2 compatibility hacks
if sys.version_info[0] < 3:
from io import open
reload(sys)
sys.setdefaultencoding("utf-8")
class NtpConfiguration(object):
def __init__(self, root_dir, ntp_conf, step_tickers):
self.root_dir = root_dir if root_dir != "/" else ""
self.ntp_conf_path = ntp_conf
self.step_tickers_path = step_tickers
# Read and write files using an 8-bit transparent encoding
self.file_encoding = "latin-1"
self.enabled_services = set()
self.step_tickers = []
self.time_sources = []
self.fudges = {}
self.restrictions = {
# Built-in defaults
ipaddress.ip_network(u"0.0.0.0/0"): set(),
ipaddress.ip_network(u"::/0"): set(),
}
self.keyfile = ""
self.keys = []
self.trusted_keys = []
self.driftfile = ""
self.statistics = []
self.leapfile = ""
self.tos_options = {}
self.ignored_directives = set()
self.ignored_lines = []
# self.detect_enabled_services()
self.parse_step_tickers()
self.parse_ntp_conf()
def detect_enabled_services(self):
for service in ["ntpdate", "ntpd", "ntp-wait"]:
service_path = os.path.join(self.root_dir,
"etc/systemd/system/multi-user.target.wants/{}.service".format(service))
if os.path.islink(service_path):
self.enabled_services.add(service)
logging.info("Enabled services found in /etc/systemd/system: %s",
" ".join(self.enabled_services))
def parse_step_tickers(self):
if not self.step_tickers_path:
return
path = os.path.join(self.root_dir, self.step_tickers_path)
if not os.path.isfile(path):
logging.info("Missing %s", path)
return
with open(path, encoding=self.file_encoding) as f:
for line in f:
line = line[:line.find('#')]
words = line.split()
if not words:
continue
self.step_tickers.extend(words)
def parse_ntp_conf(self, path=None):
if path is None:
path = os.path.join(self.root_dir, self.ntp_conf_path)
with open(path, encoding=self.file_encoding) as f:
logging.info("Reading %s", path)
for line in f:
line = line[:line.find('#')]
words = line.split()
if not words:
continue
if not self.parse_directive(words):
self.ignored_lines.append(line)
def parse_directive(self, words):
name = words.pop(0)
if name.startswith("logconfig"):
name = "logconfig"
if words:
if name in ["server", "peer", "pool"]:
return self.parse_source(name, words)
elif name == "fudge":
return self.parse_fudge(words)
elif name == "restrict":
return self.parse_restrict(words)
elif name == "tos":
return self.parse_tos(words)
elif name == "includefile":
return self.parse_includefile(words)
elif name == "keys":
return self.parse_keys(words)
elif name == "trustedkey":
return self.parse_trustedkey(words)
elif name == "driftfile":
self.driftfile = words[0]
elif name == "statistics":
self.statistics = words
elif name == "leapfile":
self.leapfile = words[0]
else:
self.ignored_directives.add(name)
return False
else:
self.ignored_directives.add(name)
return False
return True
def parse_source(self, source_type, words):
ipv4_only = False
ipv6_only = False
source = {
"type": source_type,
"options": []
}
if words[0] == "-4":
ipv4_only = True
words.pop(0)
elif words[0] == "-6":
ipv6_only = True
words.pop(0)
if not words:
return False
source["address"] = words.pop(0)
# Check if -4/-6 corresponds to the address and ignore hostnames
if ipv4_only or ipv6_only:
try:
version = ipaddress.ip_address(source["address"]).version
if (ipv4_only and version != 4) or (ipv6_only and version != 6):
return False
except ValueError:
return False
if source["address"].startswith("127.127."):
if not source["address"].startswith("127.127.1."):
# Ignore non-LOCAL refclocks
return False
while words:
if len(words) >= 2 and words[0] in ["minpoll", "maxpoll", "version", "key"]:
source["options"].append((words[0], words[1]))
words = words[2:]
elif words[0] in ["burst", "iburst", "noselect", "prefer", "true", "xleave"]:
source["options"].append((words[0],))
words.pop(0)
else:
return False
self.time_sources.append(source)
return True
def parse_fudge(self, words):
address = words.pop(0)
options = {}
while words:
if len(words) >= 2 and words[0] in ["stratum"]:
if not words[1].isdigit():
return False
options[words[0]] = int(words[1])
words = words[2:]
elif len(words) >= 2:
words = words[2:]
else:
return False
self.fudges[address] = options
return True
def parse_restrict(self, words):
ipv4_only = False
ipv6_only = False
flags = set()
mask = ""
if words[0] == "-4":
ipv4_only = True
words.pop(0)
elif words[0] == "-6":
ipv6_only = True
words.pop(0)
if not words:
return False
address = words.pop(0)
while words:
if len(words) >= 2 and words[0] == "mask":
mask = words[1]
words = words[2:]
else:
if words[0] not in ["kod", "nomodify", "notrap", "nopeer", "noquery",
"limited", "ignore", "noserve"]:
return False
flags.add(words[0])
words.pop(0)
# Convert to IP network(s), ignoring restrictions with hostnames
networks = []
if address == "default" and not mask:
if not ipv6_only:
networks.append(ipaddress.ip_network(u"0.0.0.0/0"))
if not ipv4_only:
networks.append(ipaddress.ip_network(u"::/0"))
else:
try:
if mask:
# Count bits in the mask (ipaddress does not support
# expanded IPv6 netmasks)
mask_ip = ipaddress.ip_address(mask)
mask_str = "{0:0{1}b}".format(int(mask_ip), mask_ip.max_prefixlen)
networks.append(ipaddress.ip_network(
u"{}/{}".format(address, len(mask_str.rstrip('0')))))
else:
networks.append(ipaddress.ip_network(address))
except ValueError:
return False
if (ipv4_only and networks[-1].version != 4) or \
(ipv6_only and networks[-1].version != 6):
return False
for network in networks:
self.restrictions[network] = flags
return True
def parse_tos(self, words):
options = {}
while words:
if len(words) >= 2 and words[0] in ["minsane", "orphan"]:
if not words[1].isdigit():
return False
options[words[0]] = int(words[1])
words = words[2:]
elif len(words) >= 2 and words[0] in ["maxdist"]:
# Check if it is a float value
if not words[1].replace('.', '', 1).isdigit():
return False
options[words[0]] = float(words[1])
words = words[2:]
else:
return False
self.tos_options.update(options)
return True
def parse_includefile(self, words):
path = os.path.join(self.root_dir, words[0])
if not os.path.isfile(path):
return False
self.parse_ntp_conf(path)
return True
def parse_keys(self, words):
keyfile = words[0]
path = os.path.join(self.root_dir, keyfile)
if not os.path.isfile(path):
logging.info("Missing %s", path)
return False
with open(path, encoding=self.file_encoding) as f:
logging.info("Reading %s", path)
keys = []
for line in f:
words = line.split()
if len(words) < 3 or not words[0].isdigit():
continue
keys.append((int(words[0]), words[1], words[2]))
self.keyfile = keyfile
self.keys = keys
return True
def parse_trustedkey(self, words):
key_ranges = []
for word in words:
if word.isdigit():
key_ranges.append((int(word), int(word)))
elif re.match("^[0-9]+-[0-9]+$", word):
first, last = word.split("-")
key_ranges.append((int(first), int(last)))
else:
return False
self.trusted_keys = key_ranges
return True
def write_chrony_configuration(self, chrony_conf_path, chrony_keys_path,
dry_run=False, backup=False):
chrony_conf = self.get_chrony_conf(chrony_keys_path)
logging.debug("Generated %s:\n%s", chrony_conf_path, chrony_conf)
if not dry_run:
self.write_file(chrony_conf_path, 0o644, chrony_conf, backup)
chrony_keys = self.get_chrony_keys()
if chrony_keys:
logging.debug("Generated %s:\n%s", chrony_keys_path, chrony_keys)
if not dry_run:
self.write_file(chrony_keys_path, 0o640, chrony_keys, backup)
def get_processed_time_sources(self):
# Convert {0,1,2,3}.*pool.ntp.org servers to 2.*pool.ntp.org pools
# Make shallow copies of all sources (only type will be modified)
time_sources = [s.copy() for s in self.time_sources]
pools = {}
for source in time_sources:
if source["type"] != "server":
continue
m = re.match("^([0123])(\\.\\w+)?\\.pool\\.ntp\\.org$", source["address"])
if m is None:
continue
number = m.group(1)
zone = m.group(2)
if zone not in pools:
pools[zone] = []
pools[zone].append((int(number), source))
remove_servers = set()
for zone, pool in pools.items():
# sort and skip all pools not in [0, 3] range
pool.sort()
if [number for number, source in pool] != [0, 1, 2, 3]:
# only exact group of 4 servers can be converted, nothing to do here
continue
# verify that parameters are the same for all servers in the pool
if not all([p[1]["options"] == pool[0][1]["options"] for p in pool]):
break
remove_servers.update([pool[i][1]["address"] for i in [0, 1, 3]])
pool[2][1]["type"] = "pool"
processed_sources = []
for source in time_sources:
if source["type"] == "server" and source["address"] in remove_servers:
continue
processed_sources.append(source)
return processed_sources
def get_chrony_conf_sources(self):
conf = ""
if self.step_tickers:
conf += "# Specify NTP servers used for initial correction.\n"
conf += "initstepslew 0.1 {}\n".format(" ".join(self.step_tickers))
conf += "\n"
conf += "# Specify time sources.\n"
for source in self.get_processed_time_sources():
address = source["address"]
if address.startswith("127.127."):
if address.startswith("127.127.1."):
continue
# No other refclocks are expected from the parser
assert False
else:
conf += "{} {}".format(source["type"], address)
for option in source["options"]:
if option[0] in ["minpoll", "maxpoll", "version", "key",
"iburst", "noselect", "prefer", "xleave"]:
conf += " {}".format(" ".join(option))
elif option[0] == "burst":
conf += " presend 6"
elif option[0] == "true":
conf += " trust"
else:
# No other options are expected from the parser
assert False
conf += "\n"
conf += "\n"
return conf
def get_chrony_conf_allows(self):
allowed_networks = filter(lambda n: "ignore" not in self.restrictions[n] and
"noserve" not in self.restrictions[n],
self.restrictions.keys())
conf = ""
for network in sorted(allowed_networks, key=lambda n: (n.version, n)):
if network.num_addresses > 1:
conf += "allow {}\n".format(network)
else:
conf += "allow {}\n".format(network.network_address)
if conf:
conf = "# Allow NTP client access.\n" + conf
conf += "\n"
return conf
def get_chrony_conf_cmdallows(self):
allowed_networks = filter(lambda n: "ignore" not in self.restrictions[n] and
"noquery" not in self.restrictions[n] and
n != ipaddress.ip_network(u"127.0.0.1/32") and
n != ipaddress.ip_network(u"::1/128"),
self.restrictions.keys())
ip_versions = set()
conf = ""
for network in sorted(allowed_networks, key=lambda n: (n.version, n)):
ip_versions.add(network.version)
if network.num_addresses > 1:
conf += "cmdallow {}\n".format(network)
else:
conf += "cmdallow {}\n".format(network.network_address)
if conf:
conf = "# Allow remote monitoring.\n" + conf
if 4 in ip_versions:
conf += "bindcmdaddress 0.0.0.0\n"
if 6 in ip_versions:
conf += "bindcmdaddress ::\n"
conf += "\n"
return conf
def get_chrony_conf(self, chrony_keys_path):
local_stratum = 0
maxdistance = 0.0
minsources = 1
orphan_stratum = 0
logs = []
for source in self.time_sources:
address = source["address"]
if address.startswith("127.127.1."):
if address in self.fudges and "stratum" in self.fudges[address]:
local_stratum = self.fudges[address]["stratum"]
else:
local_stratum = 5
if "maxdist" in self.tos_options:
maxdistance = self.tos_options["maxdist"]
if "minsane" in self.tos_options:
minsources = self.tos_options["minsane"]
if "orphan" in self.tos_options:
orphan_stratum = self.tos_options["orphan"]
if "clockstats" in self.statistics:
logs.append("refclocks")
if "loopstats" in self.statistics:
logs.append("tracking")
if "peerstats" in self.statistics:
logs.append("statistics")
if "rawstats" in self.statistics:
logs.append("measurements")
conf = "# This file was converted from {}{}.\n".format(
self.ntp_conf_path,
" and " + self.step_tickers_path if self.step_tickers_path else "")
conf += "\n"
if self.ignored_lines:
conf += "# The following directives were ignored in the conversion:\n"
for line in self.ignored_lines:
# Remove sensitive information
line = re.sub(r"\s+pw\s+\S+", " pw XXX", line.rstrip())
conf += "# " + line + "\n"
conf += "\n"
conf += self.get_chrony_conf_sources()
conf += "# Record the rate at which the system clock gains/losses time.\n"
if not self.driftfile:
conf += "#"
conf += "driftfile /var/lib/chrony/drift\n"
conf += "\n"
conf += "# Allow the system clock to be stepped in the first three updates\n"
conf += "# if its offset is larger than 1 second.\n"
conf += "makestep 1.0 3\n"
conf += "\n"
conf += "# Enable kernel synchronization of the real-time clock (RTC).\n"
conf += "rtcsync\n"
conf += "\n"
conf += "# Enable hardware timestamping on all interfaces that support it.\n"
conf += "#hwtimestamp *\n"
conf += "\n"
if maxdistance > 0.0:
conf += "# Specify the maximum distance of sources to be selectable.\n"
conf += "maxdistance {}\n".format(maxdistance)
conf += "\n"
conf += "# Increase the minimum number of selectable sources required to adjust\n"
conf += "# the system clock.\n"
if minsources > 1:
conf += "minsources {}\n".format(minsources)
else:
conf += "#minsources 2\n"
conf += "\n"
conf += self.get_chrony_conf_allows()
conf += self.get_chrony_conf_cmdallows()
conf += "# Serve time even if not synchronized to a time source.\n"
if orphan_stratum > 0 and orphan_stratum < 16:
conf += "local stratum {} orphan\n".format(orphan_stratum)
elif local_stratum > 0 and local_stratum < 16:
conf += "local stratum {}\n".format(local_stratum)
else:
conf += "#local stratum 10\n"
conf += "\n"
conf += "# Specify file containing keys for NTP authentication.\n"
conf += "keyfile {}\n".format(chrony_keys_path)
conf += "\n"
conf += "# Get TAI-UTC offset and leap seconds from the system tz database.\n"
conf += "leapsectz right/UTC\n"
conf += "\n"
conf += "# Specify directory for log files.\n"
conf += "logdir /var/log/chrony\n"
conf += "\n"
conf += "# Select which information is logged.\n"
if logs:
conf += "log {}\n".format(" ".join(logs))
else:
conf += "#log measurements statistics tracking\n"
return conf
def get_chrony_keys(self):
if not self.keyfile:
return ""
keys = "# This file was converted from {}.\n".format(self.keyfile)
keys += "\n"
for key in self.keys:
key_id = key[0]
key_type = key[1]
password = key[2]
if key_type in ["m", "M"]:
key_type = "MD5"
elif key_type == "AES128CMAC":
key_type = "AES128"
elif key_type not in ["MD5", "SHA1", "SHA256", "SHA384", "SHA512"]:
continue
prefix = "ASCII" if len(password) <= 20 else "HEX"
for first, last in self.trusted_keys:
if first <= key_id <= last:
trusted = True
break
else:
trusted = False
# Disable keys that were not marked as trusted
if not trusted:
keys += "#"
keys += "{} {} {}:{}\n".format(key_id, key_type, prefix, password)
return keys
def write_file(self, path, mode, content, backup):
path = self.root_dir + path
if backup and os.path.isfile(path):
os.rename(path, path + ".old")
with open(os.open(path, os.O_CREAT | os.O_WRONLY | os.O_EXCL, mode), "w",
encoding=self.file_encoding) as f:
logging.info("Writing %s", path)
f.write(u"" + content)
# Fix SELinux context if restorecon is installed
try:
subprocess.call(["restorecon", path])
except OSError:
pass
def main():
parser = argparse.ArgumentParser(description="Convert ntp configuration to chrony.")
parser.add_argument("-r", "--root", dest="roots", default=["/"], nargs="+",
metavar="DIR", help="specify root directory (default /)")
parser.add_argument("--ntp-conf", action="store", default="/etc/ntp.conf",
metavar="FILE", help="specify ntp config (default /etc/ntp.conf)")
parser.add_argument("--step-tickers", action="store", default="",
metavar="FILE", help="specify ntpdate step-tickers config (no default)")
parser.add_argument("--chrony-conf", action="store", default="/etc/chrony.conf",
metavar="FILE", help="specify chrony config (default /etc/chrony.conf)")
parser.add_argument("--chrony-keys", action="store", default="/etc/chrony.keys",
metavar="FILE", help="specify chrony keyfile (default /etc/chrony.keys)")
parser.add_argument("-b", "--backup", action="store_true", help="backup existing configs before writing")
parser.add_argument("-L", "--ignored-lines", action="store_true", help="print ignored lines")
parser.add_argument("-D", "--ignored-directives", action="store_true",
help="print names of ignored directives")
parser.add_argument("-n", "--dry-run", action="store_true", help="don't make any changes")
parser.add_argument("-v", "--verbose", action="count", default=0, help="increase verbosity")
args = parser.parse_args()
logging.basicConfig(format="%(message)s",
level=[logging.ERROR, logging.INFO, logging.DEBUG][min(args.verbose, 2)])
for root in args.roots:
conf = NtpConfiguration(root, args.ntp_conf, args.step_tickers)
if args.ignored_lines:
for line in conf.ignored_lines:
print(line)
if args.ignored_directives:
for directive in conf.ignored_directives:
print(directive)
conf.write_chrony_configuration(args.chrony_conf, args.chrony_keys, args.dry_run, args.backup)
if __name__ == "__main__":
main()

View File

@ -1,44 +1,57 @@
%global _hardened_build 1 %global _hardened_build 1
%global clknetsim_ver 824c48 %global clknetsim_ver 5d1dc0
%global ntp2chrony_ver 233b75
%bcond_without debug %bcond_without debug
%bcond_without nts %bcond_without nts
%ifarch %{ix86} x86_64 %{arm} aarch64 mipsel mips64el ppc64 ppc64le s390 s390x
%bcond_without seccomp
%endif
Name: chrony Name: chrony
Version: 4.2 Version: 4.5
Release: 1%{?dist}.alma Release: 2%{?dist}
Summary: An NTP client/server Summary: An NTP client/server
Group: System Environment/Daemons
License: GPLv2 License: GPLv2
URL: https://chrony.tuxfamily.org URL: https://chrony-project.org
Source0: https://download.tuxfamily.org/chrony/chrony-%{version}%{?prerelease}.tar.gz Source0: https://chrony-project.org/releases/chrony-%{version}%{?prerelease}.tar.gz
Source1: https://download.tuxfamily.org/chrony/chrony-%{version}%{?prerelease}-tar-gz-asc.txt Source1: chrony.dhclient
Source2: https://chrony.tuxfamily.org/gpgkey-8F375C7E8D0EE125A3D3BD51537E2B76F7680DAC.asc Source2: chrony.helper
Source3: chrony.dhclient Source3: chrony-dnssrv@.service
Source4: chrony-dnssrv@.timer
# simulator for test suite # simulator for test suite
Source10: https://github.com/mlichvar/clknetsim/archive/%{clknetsim_ver}/clknetsim-%{clknetsim_ver}.tar.gz Source10: https://gitlab.com/chrony/clknetsim/-/archive/master/clknetsim-%{clknetsim_ver}.tar.gz
# script for converting ntp configuration to chrony
Source11: https://github.com/mlichvar/ntp2chrony/raw/%{ntp2chrony_ver}/ntp2chrony/ntp2chrony.py
%{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz} %{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz}
# add IPv6 support and distribution-specific bits to DHCP dispatcher # revert upstream changes in packaged service files
Patch0: chrony-services.patch
# modify NetworkManager DHCP dispatcher to work with chrony-helper and
# follow distribution-specific configuration
Patch1: chrony-nm-dispatcher-dhcp.patch Patch1: chrony-nm-dispatcher-dhcp.patch
# update seccomp filter for new glibc # add NTP servers from DHCP when starting service
Patch2: chrony-seccomp.patch Patch2: chrony-service-helper.patch
# revert some hardening options in service files # revert upstream changes in packaged configuration examples
Patch3: chrony-services.patch Patch3: chrony-defconfig.patch
# fix serverstats to correctly count authenticated packets
Patch4: chrony-serverstats.patch
# fix crash on reload command during start
Patch5: chrony-reload.patch
# enable AES-CMAC support using gnutls (but keep nettle for hashing)
Patch6: chrony-cmac.patch
BuildRequires: gnutls-devel libcap-devel libedit-devel pps-tools-devel BuildRequires: libcap-devel libedit-devel nettle-devel pps-tools-devel
BuildRequires: gcc gcc-c++ make bison systemd gnupg2 %ifarch %{ix86} x86_64 %{arm} aarch64 mipsel mips64el ppc64 ppc64le s390 s390x
%{?with_nts:BuildRequires: gnutls-utils} BuildRequires: libseccomp-devel
%{?with_seccomp:BuildRequires: libseccomp-devel} %endif
BuildRequires: gcc gcc-c++ make bison systemd
BuildRequires: kernel-headers > 4.18.0-87
%{?with_nts:BuildRequires: gnutls-devel gnutls-utils}
Requires(pre): shadow-utils Requires(pre): shadow-utils
%{?systemd_requires} %{?systemd_requires}
# Old NetworkManager expects the dispatcher scripts in a different place # install timedated implementation that can control chronyd service
Conflicts: NetworkManager < 1.20 Recommends: timedatex
# suggest drivers for hardware reference clocks # suggest drivers for hardware reference clocks
Suggests: ntp-refclock Suggests: ntp-refclock
@ -51,28 +64,31 @@ can also operate as an NTPv4 (RFC 5905) server and peer to provide a time
service to other computers in the network. service to other computers in the network.
%if 0%{!?vendorzone:1} %if 0%{!?vendorzone:1}
%global vendorzone rhel. %global vendorzone %(source /etc/os-release && echo ${ID}.)
%endif %endif
%prep %prep
%{gpgverify} --keyring=%{SOURCE2} --signature=%{SOURCE1} --data=%{SOURCE0}
%setup -q -n %{name}-%{version}%{?prerelease} -a 10 %setup -q -n %{name}-%{version}%{?prerelease} -a 10
%{?gitpatch:%patch0 -p1} %{?gitpatch:%patch0 -p1}
%patch0 -p1 -b .services
%patch1 -p1 -b .nm-dispatcher-dhcp %patch1 -p1 -b .nm-dispatcher-dhcp
%patch2 -p1 -b .seccomp %patch2 -p1 -b .service-helper
%patch3 -p1 -b .services %patch3 -p1 -b .defconfig
%patch4 -p1 -b .serverstats
%patch5 -p1
%patch6 -p1 -b .cmac
%{?gitpatch: echo %{version}-%{gitpatch} > version.txt} %{?gitpatch: echo %{version}-%{gitpatch} > version.txt}
# review changes in packaged configuration files and scripts # review changes in packaged configuration files and scripts
md5sum -c <<-EOF | (! grep -v 'OK$') md5sum -c <<-EOF | (! grep -v 'OK$')
222e652b95027289877fa77146d3b9b1 examples/chrony-wait.service bc563c1bcf67b2da774bd8c2aef55a06 examples/chrony-wait.service
2d01b94bc1a7b7fb70cbee831488d121 examples/chrony.conf.example2 e473a9fab7fe200cacce3dca8b66290b examples/chrony.conf.example2
96999221eeef476bd49fe97b97503126 examples/chrony.keys.example 96999221eeef476bd49fe97b97503126 examples/chrony.keys.example
6a3178c4670de7de393d9365e2793740 examples/chrony.logrotate 6a3178c4670de7de393d9365e2793740 examples/chrony.logrotate
c3992e2f985550739cd1cd95f98c9548 examples/chrony.nm-dispatcher.dhcp fabb5b3f127b802c27c82837feff0fe6 examples/chrony.nm-dispatcher.dhcp
2b81c60c020626165ac655b2633608eb examples/chrony.nm-dispatcher.onoffline 4e85d36595727318535af3387411070c examples/chrony.nm-dispatcher.onoffline
619dd00009ea312c7201beefde10341a examples/chronyd.service 56d221eba8ce8a2e03d3e0dd87999a81 examples/chronyd.service
EOF EOF
# don't allow packaging without vendor zone # don't allow packaging without vendor zone
@ -82,11 +98,9 @@ test -n "%{vendorzone}"
# - use our vendor zone (2.*pool.ntp.org names include IPv6 addresses) # - use our vendor zone (2.*pool.ntp.org names include IPv6 addresses)
# - enable leapsectz to get TAI-UTC offset and leap seconds from tzdata # - enable leapsectz to get TAI-UTC offset and leap seconds from tzdata
# - enable keyfile # - enable keyfile
# - use NTP servers from DHCP
sed -e 's|^\(pool \)\(pool.ntp.org\)|\12.%{vendorzone}\2|' \ sed -e 's|^\(pool \)\(pool.ntp.org\)|\12.%{vendorzone}\2|' \
-e 's|#\(leapsectz\)|\1|' \ -e 's|#\(leapsectz\)|\1|' \
-e 's|#\(keyfile\)|\1|' \ -e 's|#\(keyfile\)|\1|' \
-e 's|^pool.*pool.ntp.org.*|&\n\n# Use NTP servers from DHCP.\nsourcedir /run/chrony-dhcp|' \
< examples/chrony.conf.example2 > chrony.conf < examples/chrony.conf.example2 > chrony.conf
touch -r examples/chrony.conf.example2 chrony.conf touch -r examples/chrony.conf.example2 chrony.conf
@ -94,13 +108,15 @@ touch -r examples/chrony.conf.example2 chrony.conf
# regenerate the file from getdate.y # regenerate the file from getdate.y
rm -f getdate.c rm -f getdate.c
mv clknetsim-%{clknetsim_ver}* test/simulation/clknetsim mv clknetsim-*-%{clknetsim_ver}* test/simulation/clknetsim
install -m 644 -p %{SOURCE11} ntp2chrony.py
%build %build
%configure \ %configure \
%{?with_debug: --enable-debug} \ %{?with_debug: --enable-debug} \
--enable-ntp-signd \ --enable-ntp-signd \
%{?with_seccomp: --enable-scfilter} \ --enable-scfilter \
%{!?with_nts: --disable-nts} \ %{!?with_nts: --disable-nts} \
--chronyrundir=/run/chrony \ --chronyrundir=/run/chrony \
--docdir=%{_docdir} \ --docdir=%{_docdir} \
@ -108,45 +124,46 @@ mv clknetsim-%{clknetsim_ver}* test/simulation/clknetsim
--with-user=chrony \ --with-user=chrony \
--with-hwclockfile=%{_sysconfdir}/adjtime \ --with-hwclockfile=%{_sysconfdir}/adjtime \
--with-pidfile=/run/chrony/chronyd.pid \ --with-pidfile=/run/chrony/chronyd.pid \
--with-sendmail=%{_sbindir}/sendmail \ --with-sendmail=%{_sbindir}/sendmail
--without-nettle \ make %{?_smp_mflags}
--without-nss \
--without-tomcrypt
%make_build
%install %install
%make_install make install DESTDIR=$RPM_BUILD_ROOT
rm -rf $RPM_BUILD_ROOT%{_docdir} rm -rf $RPM_BUILD_ROOT%{_docdir}
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/{sysconfig,logrotate.d} mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/{sysconfig,logrotate.d}
mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/{lib,log}/chrony mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/{lib,log}/chrony
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dispatcher.d
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d
mkdir -p $RPM_BUILD_ROOT%{_libexecdir} mkdir -p $RPM_BUILD_ROOT%{_libexecdir}
mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/NetworkManager/dispatcher.d
mkdir -p $RPM_BUILD_ROOT{%{_unitdir},%{_prefix}/lib/systemd/ntp-units.d} mkdir -p $RPM_BUILD_ROOT{%{_unitdir},%{_prefix}/lib/systemd/ntp-units.d}
install -m 644 -p chrony.conf $RPM_BUILD_ROOT%{_sysconfdir}/chrony.conf install -m 644 -p chrony.conf $RPM_BUILD_ROOT%{_sysconfdir}/chrony.conf
install -m 640 -p examples/chrony.keys.example \ install -m 640 -p examples/chrony.keys.example \
$RPM_BUILD_ROOT%{_sysconfdir}/chrony.keys $RPM_BUILD_ROOT%{_sysconfdir}/chrony.keys
install -m 755 -p %{SOURCE3} \ install -m 755 -p examples/chrony.nm-dispatcher.onoffline \
$RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dispatcher.d/20-chrony-onoffline
install -m 755 -p examples/chrony.nm-dispatcher.dhcp \
$RPM_BUILD_ROOT%{_sysconfdir}/NetworkManager/dispatcher.d/20-chrony-dhcp
install -m 755 -p %{SOURCE1} \
$RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d/chrony.sh $RPM_BUILD_ROOT%{_sysconfdir}/dhcp/dhclient.d/chrony.sh
install -m 644 -p examples/chrony.logrotate \ install -m 644 -p examples/chrony.logrotate \
$RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/chrony $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/chrony
install -m 644 -p examples/chronyd.service \ install -m 644 -p examples/chronyd.service \
$RPM_BUILD_ROOT%{_unitdir}/chronyd.service $RPM_BUILD_ROOT%{_unitdir}/chronyd.service
install -m 755 -p examples/chrony.nm-dispatcher.onoffline \
$RPM_BUILD_ROOT%{_prefix}/lib/NetworkManager/dispatcher.d/20-chrony-onoffline
install -m 755 -p examples/chrony.nm-dispatcher.dhcp \
$RPM_BUILD_ROOT%{_prefix}/lib/NetworkManager/dispatcher.d/20-chrony-dhcp
install -m 644 -p examples/chrony-wait.service \ install -m 644 -p examples/chrony-wait.service \
$RPM_BUILD_ROOT%{_unitdir}/chrony-wait.service $RPM_BUILD_ROOT%{_unitdir}/chrony-wait.service
install -m 644 -p %{SOURCE3} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.service
install -m 644 -p %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/chrony-dnssrv@.timer
install -m 755 -p %{SOURCE2} $RPM_BUILD_ROOT%{_libexecdir}/chrony-helper
cat > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/chronyd <<EOF cat > $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/chronyd <<EOF
# Command-line options for chronyd # Command-line options for chronyd
OPTIONS="%{?with_seccomp:-F 2}" OPTIONS=""
EOF EOF
touch $RPM_BUILD_ROOT%{_localstatedir}/lib/chrony/{drift,rtc} touch $RPM_BUILD_ROOT%{_localstatedir}/lib/chrony/{drift,rtc}
@ -156,8 +173,8 @@ echo 'chronyd.service' > \
%check %check
# set random seed to get deterministic results # set random seed to get deterministic results
export CLKNETSIM_RANDOM_SEED=24505 export CLKNETSIM_RANDOM_SEED=24502
%make_build -C test/simulation/clknetsim make %{?_smp_mflags} -C test/simulation/clknetsim
make quickcheck make quickcheck
%pre %pre
@ -167,16 +184,16 @@ getent passwd chrony > /dev/null || /usr/sbin/useradd -r -g chrony \
: :
%post %post
# migrate from chrony-helper to sourcedir directive # fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2
if test -a %{_libexecdir}/chrony-helper; then if grep -q 'PIDFile=%{_localstatedir}/run/chronyd.pid' \
grep -qi 'sourcedir /run/chrony-dhcp$' %{_sysconfdir}/chrony.conf 2> /dev/null || \ %{_sysconfdir}/systemd/system/chronyd.service 2> /dev/null && \
echo -e '\n# Use NTP servers from DHCP.\nsourcedir /run/chrony-dhcp' >> \ ! grep -qi '^[ '$'\t'']*pidfile' %{_sysconfdir}/chrony.conf 2> /dev/null
%{_sysconfdir}/chrony.conf then
mkdir -p /run/chrony-dhcp sed -i '/PIDFile=/s|/run/|/run/chrony/|' \
for f in %{_localstatedir}/lib/dhclient/chrony.servers.*; do %{_sysconfdir}/systemd/system/chronyd.service
sed 's|.*|server &|' < $f > /run/chrony-dhcp/"${f##*servers.}.sources"
done 2> /dev/null
fi fi
# workaround for late reload of unit file (#1614751)
%{_bindir}/systemctl daemon-reload
%systemd_post chronyd.service chrony-wait.service %systemd_post chronyd.service chrony-wait.service
%preun %preun
@ -188,17 +205,19 @@ fi
%files %files
%{!?_licensedir:%global license %%doc} %{!?_licensedir:%global license %%doc}
%license COPYING %license COPYING
%doc FAQ NEWS README %doc FAQ NEWS README ntp2chrony.py
%config(noreplace) %{_sysconfdir}/chrony.conf %config(noreplace) %{_sysconfdir}/chrony.conf
%config(noreplace) %verify(not md5 size mtime) %attr(640,root,chrony) %{_sysconfdir}/chrony.keys %config(noreplace) %verify(not md5 size mtime) %attr(640,root,chrony) %{_sysconfdir}/chrony.keys
%config(noreplace) %{_sysconfdir}/logrotate.d/chrony %config(noreplace) %{_sysconfdir}/logrotate.d/chrony
%config(noreplace) %{_sysconfdir}/sysconfig/chronyd %config(noreplace) %{_sysconfdir}/sysconfig/chronyd
%{_sysconfdir}/NetworkManager/dispatcher.d/20-chrony*
%{_sysconfdir}/dhcp/dhclient.d/chrony.sh %{_sysconfdir}/dhcp/dhclient.d/chrony.sh
%{_bindir}/chronyc %{_bindir}/chronyc
%{_sbindir}/chronyd %{_sbindir}/chronyd
%{_prefix}/lib/NetworkManager %{_libexecdir}/chrony-helper
%{_prefix}/lib/systemd/ntp-units.d/*.list %{_prefix}/lib/systemd/ntp-units.d/*.list
%{_unitdir}/chrony*.service %{_unitdir}/chrony*.service
%{_unitdir}/chrony*.timer
%{_mandir}/man[158]/%{name}*.[158]* %{_mandir}/man[158]/%{name}*.[158]*
%dir %attr(750,chrony,chrony) %{_localstatedir}/lib/chrony %dir %attr(750,chrony,chrony) %{_localstatedir}/lib/chrony
%ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/drift %ghost %attr(-,chrony,chrony) %{_localstatedir}/lib/chrony/drift
@ -206,136 +225,49 @@ fi
%dir %attr(750,chrony,chrony) %{_localstatedir}/log/chrony %dir %attr(750,chrony,chrony) %{_localstatedir}/log/chrony
%changelog %changelog
* Tue Nov 15 2022 Eduard Abdullin <eabdullin@almalinux.org> - 4.2-1.alma * Wed Sep 18 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.5-2.el8_10
- use rhel ntp pool - fix crash on reload command during start (RHEL-59112)
- enable AES-CMAC support using gnutls (RHEL-59032)
* Wed Mar 23 2022 Miroslav Lichvar <mlichvar@redhat.com> 4.2-1 * Wed Jan 10 2024 Miroslav Lichvar <mlichvar@redhat.com> 4.5-1
- update to 4.2 (#2051441) - update to 4.5 (RHEL-21069 RHEL-10701)
- fully switch from nettle to gnutls (#1953463 #1954483)
- use NTP servers from DHCPv6 NTP server option (#2047415)
- drop obsolete workaround in scriptlet
* Tue Aug 10 2021 Miroslav Lichvar <mlichvar@redhat.com> 4.1-3
- update seccomp filter for new glibc (#1990589)
- remove unnecessary build requirement
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 4.1-2 * Thu Jul 14 2022 Miroslav Lichvar <mlichvar@redhat.com> 4.2-1
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - update to 4.2 (#2062356)
Related: rhbz#1991688 - fix chrony-helper to delete sources by their original name (#2061660)
- update ntp2chrony script (#2018045 #2063766)
* Thu May 13 2021 Miroslav Lichvar <mlichvar@redhat.com> 4.1-1 * Tue Jun 15 2021 Miroslav Lichvar <mlichvar@redhat.com> 4.1-1
- update to 4.1 - update to 4.1 (#1895003 #1847853 #1929157)
- enable seccomp filter by default (incompatible with mailonchange directive) - add NetworkManager dispatcher script to add servers from DHCP even without
dhclient (#1933139)
* Thu Apr 22 2021 Miroslav Lichvar <mlichvar@redhat.com> 4.1-0.1.pre1 - restrict permissions of /var/lib/chrony and /var/log/chrony (#1939295)
- update to 4.1-pre1 - reset chrony-helper state after stopping chronyd (#1971697)
- rework NM-dispatcher/dhclient detection - add gcc-c++ and make to build requirements
- enable LTO on s390x
* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> - 4.0-4
- Rebuilt for updated systemd-rpm-macros
See https://pagure.io/fesco/issue/2583.
* Tue Feb 02 2021 Miroslav Lichvar <mlichvar@redhat.com> 4.0-3
- update NM DHCP dispatcher script
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
- Add BuildRequires: make
- drop dnssrv service and timer
* Wed Oct 07 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-1
- update to 4.0
- update directory permissions to follow upstream
* Wed Sep 16 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-0.9.pre4
- update to 4.0-pre4
* Wed Aug 26 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-0.8.pre3
- update to 4.0-pre3
- switch to sourcedir directive for loading servers from DHCP
- add NetworkManager dispatcher script to save servers from DHCP when
dhclient is not installed (Robert Fairley)
- drop old migration code from scriptlet
- move default paths in /var/run to /run - move default paths in /var/run to /run
* Mon Aug 10 2020 Jeff Law <law@redhat.com> - 4.0-0.7.pre2 * Tue May 21 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-1
- Disable LTO on s390x - update to 3.5 (#1685469 #1677218)
- fix shellcheck warnings in helper scripts (#1711948)
- update ntp2chrony script
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-0.6.pre2 * Mon Aug 13 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-3
- Second attempt - Rebuilt for
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 4.0-0.5.pre2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> 4.0-0.4.pre2
- use make macros
* Mon May 04 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-0.3.pre2
- rebuild for new nettle
* Mon Apr 20 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-0.2.pre2
- update to 4.0-pre2
* Tue Mar 17 2020 Miroslav Lichvar <mlichvar@redhat.com> 4.0-0.1.pre1
- update to 4.0-pre1
- add net-tools to build requirements for testing
- add missing dependency on coreutils
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.5-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Jan 20 2020 Miroslav Lichvar <mlichvar@redhat.com> 3.5-7
- fix testing with new glibc (#1792854)
* Wed Oct 09 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-6
- drop timedatex recommendation
- verify upstream signatures
* Thu Aug 22 2019 Lubomir Rintel <lkundrak@v3.sk> - 3.5-5
- Move the NetworkManager dispatcher script out of /etc
* Wed Jul 24 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Tue Jul 16 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-3
- rebuild for new nettle
* Thu May 23 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-2
- fix shellcheck warnings in helper scripts
* Tue May 14 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-1
- update to 3.5
* Thu May 02 2019 Miroslav Lichvar <mlichvar@redhat.com> 3.5-0.1.pre1
- update to 3.5-pre1
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.4-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Sep 19 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.4-1
- update to 3.4
* Fri Aug 31 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.4-0.1.pre1
- update to 3.4-pre1
* Mon Aug 13 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-5
- fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2 - fix PIDFile in local chronyd.service on upgrades from chrony < 3.3-2
(#1614800)
- add workaround for late reload of unit file (#1614751) - add workaround for late reload of unit file (#1614751)
* Mon Jul 16 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-4
- add gcc-c++ to build requirements
* Thu Jul 12 2018 Fedora Release Engineering <releng@fedoraproject.org> - 3.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Mon Jun 18 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-2 * Mon Jun 18 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-2
- move pidfile to /var/run/chrony to allow chronyd to remove it on exit - move pidfile to /var/run/chrony to allow chronyd to remove it on exit
- avoid blocking in getrandom system call (#1584585)
- avoid blocking in getrandom system call (#1592425)
* Wed Apr 04 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-1 * Thu Apr 05 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-1
- update to 3.3 - update to 3.3
- enable keyfile by default again - enable keyfile by default again
- update ntp2chrony script
* Mon Mar 19 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-0.2.pre1
- include ntp2chrony script in documentation (#1530987)
* Thu Mar 15 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-0.1.pre1 * Thu Mar 15 2018 Miroslav Lichvar <mlichvar@redhat.com> 3.3-0.1.pre1
- update to 3.3-pre1 - update to 3.3-pre1